diff --git a/.editorconfig b/.editorconfig index e4ab4a9fd38..4ca23b300fd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,5 +11,8 @@ trim_trailing_whitespace = true [*.md] trim_trailing_whitespace = false +[*.yml] +indent_size = 2 + [Makefile] indent_style = tab diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index c71190ce394..08c14747e51 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -23,14 +23,14 @@ All good? Then proceed and fill out the items below. **Mods (complete and add to the following information):** - **Arma 3:** `x.xx` [e.g. 1.00 stable, rc, dev] - **CBA:** `3.x.x` [e.g. 3.0.0 stable, commit hash] -- **ACE3:** `3.x.x` [eg. 3.0.0 stable, commit hash] +- **ACE3:** `3.x.x` [e.g. 3.0.0 stable, commit hash] **Description:** A clear and concise description of what the bug is. **Steps to reproduce:** -_Follow [https://ace3.acemod.org/img/wiki/user/issue_flowchart.webp](this flowchart)!_ +_Follow [this flowchart](https://ace3.acemod.org/img/wiki/user/issue_flowchart.webp)!_ 1. _Go to ..._ 2. _Click ..._ diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 2ba4cbfcaf0..778d34fd9f0 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -11,11 +11,10 @@ sort-direction: ascending categories: - title: '**ADDED:**' labels: - - 'kind/feature request' - - 'kind/added feature' + - 'kind/feature' - title: '**FIXED:**' labels: - - 'kind/bug fix' + - 'kind/bug-fix' - title: '**IMPROVED:**' labels: - 'kind/enhancement' @@ -23,17 +22,16 @@ categories: - title: '**CHANGED:**' labels: - 'kind/cleanup' - - 'area/compatibility' - 'kind/change' - title: '**SETTINGS:**' labels: - 'kind/setting' - title: '**TRANSLATIONS:**' labels: - - 'area/translations' + - 'kind/translation' exclude-labels: - - 'ignore changelog' + - 'ignore-changelog' - 'dependencies' change-template: '- $TITLE (#$NUMBER)' diff --git a/.github/workflows/arma.yml b/.github/workflows/arma.yml index d0649a0adec..1af2e7e0602 100644 --- a/.github/workflows/arma.yml +++ b/.github/workflows/arma.yml @@ -27,15 +27,6 @@ jobs: - 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: @@ -52,3 +43,4 @@ jobs: with: name: ace3-${{ github.sha }}-nobin path: .hemttout/@* + include-hidden-files: true # Because .hemttout is a hidden directory diff --git a/.github/workflows/extensions.yml b/.github/workflows/extensions.yml index 9693d2df22b..ce475e5a006 100644 --- a/.github/workflows/extensions.yml +++ b/.github/workflows/extensions.yml @@ -1,29 +1,65 @@ name: Extensions on: - pull_request: + push: paths: - - 'extensions/**' + - 'extension/**' + - 'Cargo.toml' + - 'Cargo.lock' + - '.github/workflows/extensions.yml' jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout the source code + uses: actions/checkout@master + - name: Install dependencies + run: | + rustup toolchain update stable --no-self-update + rustup default stable + rustup component add clippy rustfmt + - name: Run rustfmt + run: cargo fmt -- --check + - name: Run clippy + run: cargo clippy --all -- -Dwarnings + + test: + runs-on: ubuntu-latest + container: + image: xd009642/tarpaulin + options: --security-opt seccomp=unconfined + steps: + - name: Checkout the source code + uses: actions/checkout@master + - name: Test & Coverage + run: cargo tarpaulin --verbose --no-default-features --workspace --timeout 240 + build: - runs-on: ${{ matrix.os }} strategy: matrix: - os: [windows-latest] - + arrays: [ + os: { tag: "windows-latest", target: "i686-pc-windows-msvc" }, + os: { tag: "windows-latest", target: "x86_64-pc-windows-msvc" }, + ] + runs-on: ${{ matrix.arrays.os.tag }} steps: - name: Checkout the source code uses: actions/checkout@v4 + - name: Install stable Rust + uses: actions-rs/toolchain@v1 + with: + target: ${{ matrix.arrays.os.target }} + toolchain: stable + default: true + - name: Rust Cache + uses: Swatinem/rust-cache@v2 - name: Build - shell: cmd - run: | - cd extensions - mkdir build - cd build - cmake .. && cmake --build . - - name: Upload Artifact + run: cargo build --verbose + - name: Upload uses: actions/upload-artifact@v4 with: - name: ace3_extensions-${{ matrix.os }}-debug - path: extensions/build + name: ${{ matrix.arrays.os.target }} + path: target/debug/ace.dll + if-no-files-found: error + retention-days: 30 diff --git a/.github/workflows/hemtt.yml b/.github/workflows/hemtt.yml index e606852285d..79286fc45c3 100644 --- a/.github/workflows/hemtt.yml +++ b/.github/workflows/hemtt.yml @@ -33,6 +33,8 @@ jobs: xcopy /e /h /q pullrequest\addons addons\ xcopy /e /h /q pullrequest\optionals optionals\ xcopy /e /h /q pullrequest\include include\ + xcopy /y /h /q pullrequest\ace.dll ace.dll + xcopy /y /h /q pullrequest\ace_x64.dll ace_x64.dll - name: Run HEMTT build run: hemtt build - name: Rename build folder @@ -42,3 +44,4 @@ jobs: with: name: ace3-${{ github.sha }} path: .hemttout/@* + include-hidden-files: true # Because .hemttout is a hidden directory diff --git a/.github/workflows/pboproject.yml b/.github/workflows/pboproject.yml index 71e36eb12bd..c16c810e7f2 100644 --- a/.github/workflows/pboproject.yml +++ b/.github/workflows/pboproject.yml @@ -15,7 +15,7 @@ jobs: with: toolsUrl: ${{ secrets.ARMA3_TOOLS_URL }} - name: Install Mikero Tools - uses: arma-actions/mikero-tools@2023-01-04 + uses: arma-actions/mikero-tools@2024-10-08 - name: Download game data run: | Invoke-WebRequest "$env:ARMA3_DATA_URL" -OutFile arma3.zip diff --git a/.gitignore b/.gitignore index 4ad0a5e1eb9..15cc59d0d5a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,6 @@ *.zip release/* releases/* -extensions/vcproj32/* -extensions/vcproj64/* .vscode/* hemtt hemtt.exe @@ -20,4 +18,5 @@ CHANGELOG.md sqfvm.exe ArmaScriptCompiler.exe *.sqfc +target/ !extras/**/*.zip diff --git a/.hemtt/launch.toml b/.hemtt/launch.toml new file mode 100644 index 00000000000..d0726cbdded --- /dev/null +++ b/.hemtt/launch.toml @@ -0,0 +1,31 @@ +[default] +workshop = [ + "450814997", # CBA_A3 +] + +[spe] +extends = "default" +dlc = [ + "Spearhead 1944" +] + +[vn] +extends = "default" +dlc = [ + "S.O.G. Prairie Fire", +] + +[ws] +extends = "default" +dlc = [ + "Western Sahara", +] + +[rhs] +extends = "default" +workshop = [ + "843425103", # RHS AFRF Workshop ID + "843577117", # RHS USAF Workshop ID + "843593391", # RHS GREF Workshop ID + "843632231", # RHS SAF Workshop ID +] diff --git a/.hemtt/lints.toml b/.hemtt/lints.toml new file mode 100644 index 00000000000..eac28147c00 --- /dev/null +++ b/.hemtt/lints.toml @@ -0,0 +1,5 @@ +[sqf.banned_commands] +options.ignore = [ + "addPublicVariableEventHandler", # Alt syntax is broken, we are using main syntax + "createSoundSource", # Greatly attenuated when in first person and in a vehicle +] diff --git a/.hemtt/project.toml b/.hemtt/project.toml index 206bf9573c5..6ab1c3a1afc 100644 --- a/.hemtt/project.toml +++ b/.hemtt/project.toml @@ -27,41 +27,3 @@ exclude = [ "common/functions/fnc_dummy.sqf", "zeus/functions/fnc_zeusAttributes.sqf", ] - -[hemtt.launch] -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 a11e39d78e4..4038d565e63 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -6,6 +6,7 @@ # request, preferably including an email address. # CORE TEAM +BaerMitUmlaut Brett Mayson bux578 commy2 @@ -25,6 +26,7 @@ Kieran kymckay mharis001 MikeMF +MiszczuZPolski NouberNou PabstMirror Ruthberg @@ -40,6 +42,7 @@ Walter Pearce 11RDP-LoupVert 654wak654 [BIG]Bull +Abogado "regiregi22" ACCtomeek adam3adam Adanteh @@ -56,7 +59,6 @@ Arcanum417 Arkhir ARV187 aka Spark23 Asgar Serran -BaerMitUmlaut Bamse Barman75 Bla1337 diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000000..9ce88373eeb --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1410 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ace" +version = "0.1.0" +dependencies = [ + "arboard", + "arma-rs", + "git2", + "rand", + "rand_chacha", + "rayon", + "uuid", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "arboard" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb4009533e8ff8f1450a5bcbc30f4242a1d34442221f72314bea1f5dc9c7f89" +dependencies = [ + "clipboard-win", + "core-graphics", + "image", + "log", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "parking_lot", + "windows-sys 0.48.0", + "x11rb", +] + +[[package]] +name = "arma-rs" +version = "1.11.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e722ed20b6266ceccf4334d32a528fcef9a2dca341b8bbcceb99eb7152081239" +dependencies = [ + "arma-rs-proc", + "crossbeam-channel", + "libc", + "link_args", + "log", + "seq-macro", + "state", + "uuid", + "winapi", + "windows 0.58.0", +] + +[[package]] +name = "arma-rs-proc" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936ed035ff4e775bd50ff94ccdb44f236d1ca012c376347b048fb6b9861833b7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2", +] + +[[package]] +name = "bytemuck" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "cc" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clipboard-win" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" +dependencies = [ + "error-code", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "error-code" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" + +[[package]] +name = "fdeflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "generator" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows 0.48.0", +] + +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.5", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "git2" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" +dependencies = [ + "bitflags 2.6.0", + "libc", + "libgit2-sys", + "log", + "openssl-probe", + "openssl-sys", + "url", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "image" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10" +dependencies = [ + "bytemuck", + "byteorder-lite", + "num-traits", + "png", + "tiff", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "libgit2-sys" +version = "0.17.0+1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" +dependencies = [ + "cc", + "libc", + "libssh2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", +] + +[[package]] +name = "libssh2-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc53a7799a7496ebc9fd29f31f7df80e83c9bda5299768af5f9e59eeea74647" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "link_args" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c7721e472624c9aaad27a5eb6b7c9c6045c7a396f2efb6dabaec1b640d5e89b" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "loom" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.6.0", + "block2", + "libc", + "objc2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-encode" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.6.0", + "block2", + "libc", + "objc2", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "png" +version = "0.17.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "seq-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" + +[[package]] +name = "serde" +version = "1.0.208" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.208" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "state" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8" +dependencies = [ + "loom", +] + +[[package]] +name = "syn" +version = "2.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "uuid" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "getrandom", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "x11rb" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" +dependencies = [ + "gethostname", + "rustix", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000000..a13ce613fd6 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[workspace] +resolver = "2" +members = [ + "extension" +] + +[profile.release] +opt-level = "z" +lto = true +codegen-units = 1 +strip = true diff --git a/README.md b/README.md index 49518481230..e5df6556e02 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

- ACE3 Version + ACE3 Version ACE3 Issues @@ -55,7 +55,7 @@ The mod is **built modularly**, so almost any included PBO can be easily removed - Carrying and dragging - Realistic names for vehicles and weapons - A fire control system (FCS) for armored vehicles and helicopters -- Realistic ballistics/FCS calculated in C/C++ extensions +- Realistic ballistics/FCS calculated in Rust extensions - Backblast area and overpressure simulation - Disposable launchers - Realistic G-forces diff --git a/ace.dll b/ace.dll new file mode 100644 index 00000000000..088ffda15ba Binary files /dev/null and b/ace.dll differ diff --git a/ace_advanced_ballistics.dll b/ace_advanced_ballistics.dll deleted file mode 100644 index f5686a5a3f8..00000000000 Binary files a/ace_advanced_ballistics.dll and /dev/null differ diff --git a/ace_advanced_ballistics_x64.dll b/ace_advanced_ballistics_x64.dll deleted file mode 100644 index f1802ce5e88..00000000000 Binary files a/ace_advanced_ballistics_x64.dll and /dev/null differ diff --git a/ace_artillerytables.dll b/ace_artillerytables.dll deleted file mode 100644 index 2f5855c81a3..00000000000 Binary files a/ace_artillerytables.dll and /dev/null differ diff --git a/ace_artillerytables_x64.dll b/ace_artillerytables_x64.dll deleted file mode 100644 index 97a061c2570..00000000000 Binary files a/ace_artillerytables_x64.dll and /dev/null differ diff --git a/ace_break_line.dll b/ace_break_line.dll deleted file mode 100644 index 8fc92175fe2..00000000000 Binary files a/ace_break_line.dll and /dev/null differ diff --git a/ace_break_line_x64.dll b/ace_break_line_x64.dll deleted file mode 100644 index d021bf25d23..00000000000 Binary files a/ace_break_line_x64.dll and /dev/null differ diff --git a/ace_clipboard.dll b/ace_clipboard.dll deleted file mode 100644 index 8cf6744964f..00000000000 Binary files a/ace_clipboard.dll and /dev/null differ diff --git a/ace_clipboard_x64.dll b/ace_clipboard_x64.dll deleted file mode 100644 index db7730f0fed..00000000000 Binary files a/ace_clipboard_x64.dll and /dev/null differ diff --git a/ace_fcs.dll b/ace_fcs.dll deleted file mode 100644 index 9c2a871b3d9..00000000000 Binary files a/ace_fcs.dll and /dev/null differ diff --git a/ace_fcs_x64.dll b/ace_fcs_x64.dll deleted file mode 100644 index 4ee8dc1d896..00000000000 Binary files a/ace_fcs_x64.dll and /dev/null differ diff --git a/ace_x64.dll b/ace_x64.dll new file mode 100644 index 00000000000..98d675bde45 Binary files /dev/null and b/ace_x64.dll differ diff --git a/addons/advanced_ballistics/XEH_postInit.sqf b/addons/advanced_ballistics/XEH_postInit.sqf index e6417f9a02f..25545d02aa0 100644 --- a/addons/advanced_ballistics/XEH_postInit.sqf +++ b/addons/advanced_ballistics/XEH_postInit.sqf @@ -2,15 +2,15 @@ #include "initKeybinds.inc.sqf" -GVAR(currentbulletID) = -1; - GVAR(Protractor) = false; GVAR(ProtractorStart) = CBA_missionTime; -GVAR(allBullets) = []; +GVAR(allBullets) = createHashMap; GVAR(currentGrid) = 0; if (!hasInterface) exitWith {}; +#include "initKeybinds.inc.sqf" + ["CBA_settingsInitialized", { //If not enabled, dont't add PFEH if (!GVAR(enabled)) exitWith {}; @@ -19,27 +19,11 @@ if (!hasInterface) exitWith {}; [] call FUNC(initializeTerrainExtension); // Register fire event handler - ["ace_firedPlayer", DFUNC(handleFired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerNonLocal", DFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerNonLocal", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; // Register Perframe Handler - [FUNC(handleFirePFH), GVAR(simulationInterval)] call CBA_fnc_addPerFrameHandler; - - //Add warnings for missing compat PBOs (only if AB is on) - { - _x params ["_modPBO", "_compatPBO"]; - 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 [ - ["RH_acc","ace_compat_rh_acc"], - ["RH_de_cfg","ace_compat_rh_de"], - ["RH_m4_cfg","ace_compat_rh_m4"], - ["RH_PDW","ace_compat_rh_pdw"], - ["RKSL_PMII","ace_compat_rksl_pm_ii"], - ["iansky_opt","ace_compat_sma3_iansky"], - ["R3F_Armes","ace_compat_r3f"] - ]; + [LINKFUNC(handleFirePFH), GVAR(simulationInterval)] call CBA_fnc_addPerFrameHandler; }] call CBA_fnc_addEventHandler; #ifdef DEBUG_MODE_FULL diff --git a/addons/advanced_ballistics/config.cpp b/addons/advanced_ballistics/config.cpp index 17647d0647d..e3fe6957d78 100644 --- a/addons/advanced_ballistics/config.cpp +++ b/addons/advanced_ballistics/config.cpp @@ -18,10 +18,3 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "RscTitles.hpp" #include "ACE_Settings.hpp" - -class ACE_Extensions { - class ace_advanced_ballistics { - windows = 1; - client = 1; - }; -}; diff --git a/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf b/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf index a2156349f6d..b3f4053bdd9 100644 --- a/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf +++ b/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf @@ -80,7 +80,7 @@ for "_i" from 0 to (count _cfgWeapons)-1 do { diag_log text format ["AB_Diagnose_barrelTwist,%1,%2,%3,%4,%5",_weapon,_magazine,_ammo,_twistDirection,_barrelTwist]; }; if (_barrelLength == 0) then { - diag_log text format ["AB_Diagnose_barrelLength,%1,%2,%3,%4,%5",_weapon,_magazine,_ammo,_barrelLength]; + diag_log text format ["AB_Diagnose_barrelLength,%1,%2,%3,%4",_weapon,_magazine,_ammo,_barrelLength]; }; }; } forEach _magazines; @@ -108,16 +108,16 @@ for "_i" from 0 to (count _cfgWeapons)-1 do { }; if (_weapons find _weapon == -1) then { _weapons pushBack _weapon; - _magIndex = _magazines find _magazine; - _magSpeed = _magazineInitSpeeds select _magIndex; + private _magIndex = _magazines find _magazine; + private _magSpeed = _magazineInitSpeeds select _magIndex; _weaponInitSpeeds pushBack (_abInitialSpeed / _magSpeed); }; } forEach _data; { _x params ["_magazineIndex", "_abInitialSpeed", "_magazine", "_weapon"]; - _magIndex = _magazines find _magazine; - _magSpeed = _magazineInitSpeeds select _magIndex; - _wepIndex = _weapons find _weapon; + private _magIndex = _magazines find _magazine; + private _magSpeed = _magazineInitSpeeds select _magIndex; + private _wepIndex = _weapons find _weapon; _wepSpeed = _weaponInitSpeeds select _wepIndex; } forEach _data; { diff --git a/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf b/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf index ceaef17badf..a426f6ba99a 100644 --- a/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf +++ b/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf @@ -50,7 +50,7 @@ GVAR(Protractor) = true; __ctrl1 ctrlSetTextColor [1, 1, 1, 1]; __ctrl2 ctrlSetScale 1; - __ctrl2 ctrlSetPosition [SafeZoneX + 0.001, SafeZoneY - 0.001 - 0.1074 * (-0.86 max ((ACE_player weaponDirection currentWeapon ACE_player) select 2) min 0.86), 0.2, 0.2 * 4/3]; + __ctrl2 ctrlSetPosition [safeZoneX + 0.001, safeZoneY - 0.001 - 0.1074 * (-0.86 max ((ACE_player weaponDirection currentWeapon ACE_player) select 2) min 0.86), 0.2, 0.2 * 4/3]; __ctrl2 ctrlCommit 0; __ctrl2 ctrlSetText QPATHTOF(UI\protractor_marker.paa); __ctrl2 ctrlSetTextColor [1, 1, 1, 1]; diff --git a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf index e9180cb1c44..9c359bf833e 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: Glowbal, Ruthberg, joko // Jonas + * Author: Glowbal, Ruthberg, joko // Jonas, Brett Mayson * Handle the PFH for Bullets * * Arguments: @@ -17,7 +17,7 @@ private _deleted = false; { - _x params ["_bullet","_caliber","_bulletTraceVisible","_index"]; + _y params ["_bullet","_caliber","_bulletTraceVisible"]; if (alive _bullet) then { private _bulletVelocity = velocity _bullet; @@ -27,13 +27,21 @@ private _deleted = false; drop ["\A3\data_f\ParticleEffects\Universal\Refract","","Billboard",1,0.1,getPos _bullet,[0,0,0],0,1.275,1,0,[0.02*_caliber,0.01*_caliber],[[0,0,0,0.65],[0,0,0,0.2]],[1,0],0,0,"","",""]; }; - _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]))); + ( + "ace" callExtension ["ballistics:bullet:simulate", [ + _x, + _bulletVelocity, + _bulletPosition, + wind, + ASLToATL(_bulletPosition) select 2, + CBA_missionTime toFixed 6 + ]] + ) params ["_data", "_code"]; + if (_code == 0) then { + _bullet setVelocity (_bulletVelocity vectorAdd (parseSimpleArray (_data))); + }; } else { - GVAR(allBullets) set [_forEachIndex, objNull]; - _deleted = true; + GVAR(allBullets) deleteAt _x; + "ace" callExtension ["ballistics:bullet:delete", [_x]]; }; -} forEach GVAR(allBullets); - -if (_deleted) then { - GVAR(allBullets) = GVAR(allBullets) - [objNull]; -}; +} forEach GVAR(allBullets) diff --git a/addons/advanced_ballistics/functions/fnc_handleFired.sqf b/addons/advanced_ballistics/functions/fnc_handleFired.sqf index 3c1edb77c3b..d8dc62bed22 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFired.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFired.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: Glowbal, Ruthberg + * Author: Glowbal, Ruthberg, Brett Mayson * * Handles advanced ballistics for (BulletBase) projectiles. Called from the unified fired EH only for players. * @@ -19,7 +19,7 @@ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); -if (!(_ammo isKindOf "BulletBase")) exitWith {}; +if !(_ammo isKindOf "BulletBase") exitWith {}; if (!alive _projectile) exitWith {}; if (underwater _unit) exitWith {}; @@ -59,11 +59,11 @@ if (_abort) exitWith {}; // Get Weapon and Ammo Configurations private _AmmoCacheEntry = uiNamespace getVariable format[QGVAR(%1), _ammo]; if (isNil "_AmmoCacheEntry") then { - _AmmoCacheEntry = _ammo call FUNC(readAmmoDataFromConfig); + _AmmoCacheEntry = _ammo call FUNC(readAmmoDataFromConfig); }; private _WeaponCacheEntry = uiNamespace getVariable format[QGVAR(%1), _weapon]; if (isNil "_WeaponCacheEntry") then { - _WeaponCacheEntry = _weapon call FUNC(readWeaponDataFromConfig); + _WeaponCacheEntry = _weapon call FUNC(readWeaponDataFromConfig); }; _AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleVelocityVariationSD"]; @@ -117,8 +117,26 @@ if (_caliber * _bulletLength * _bulletMass * _barrelTwist > 0) then { _stabilityFactor = [_caliber, _bulletLength, _bulletMass, _barrelTwist, _muzzleVelocity, _temperature, _barometricPressure] call FUNC(calculateStabilityFactor); }; -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)]; +("ace" callExtension [ + "ballistics:bullet:new", [ + _ammoCount, + _airFriction, + _ballisticCoefficients, + _velocityBoundaries, + _atmosphereModel, + _dragModel, + _stabilityFactor, + _twistDirection, + _transonicStabilityCoef, + _bulletVelocity, + EGVAR(common,mapLatitude), + EGVAR(weather,currentTemperature), + EGVAR(common,mapAltitude), + EGVAR(weather,currentHumidity), + EGVAR(weather,currentOvercast), + CBA_missionTime toFixed 6 + ] +]) params ["_id", "_code"]; +if (_code == 0) then { + GVAR(allBullets) set [_id, [_projectile, _caliber, _bulletTraceVisible]]; +}; diff --git a/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf b/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf index 89e89b9f7ea..8c908639c30 100644 --- a/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf +++ b/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf @@ -21,7 +21,14 @@ if (!GVAR(enabled)) exitWith {}; private _initStartTime = diag_tickTime; private _mapSize = worldSize; -if (("ace_advanced_ballistics" callExtension format["init:%1:%2", worldName, _mapSize]) == "Terrain already initialized") exitWith { +( + "ace" callExtension ["ballistics:map:init", [worldName, _mapSize]] +) params ["_data", "_code"]; +if (_code != 0) exitWith { + ERROR("Error initializing map") +}; + +if (_data == "true") exitWith { INFO_1("Terrain already initialized [world: %1]",worldName); #ifdef DEBUG_MODE_FULL systemChat "AdvancedBallistics: Terrain already initialized"; @@ -53,8 +60,7 @@ INFO_2("Starting Terrain Extension [cells: %1] [world: %2]",_gridCells,worldName private _gridCenter = [_x + 25, _y + 25]; private _gridHeight = round(getTerrainHeightASL _gridCenter); private _gridNumObjects = count (_gridCenter nearObjects ["Building", 50]); - private _gridSurfaceIsWater = parseNumber (surfaceIsWater _gridCenter); - "ace_advanced_ballistics" callExtension format["set:%1:%2:%3", _gridHeight, _gridNumObjects, _gridSurfaceIsWater]; + "ace" callExtension ["ballistics:map:set", [GVAR(currentGrid), _gridHeight, _gridNumObjects, surfaceIsWater _gridCenter]]; 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 d6081e6f9ef..51907869241 100644 --- a/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf +++ b/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf @@ -40,10 +40,13 @@ if (_transonicStabilityCoef == 0) then { _transonicStabilityCoef = 0.5; }; private _dragModel = getNumber(_ammoConfig >> "ACE_dragModel"); -if (!(_dragModel in [1, 2, 5, 6, 7, 8])) then { +if !(_dragModel in [1, 2, 5, 6, 7, 8]) then { _dragModel = 1; }; private _ballisticCoefficients = getArray(_ammoConfig >> "ACE_ballisticCoefficients"); +if (_ballisticCoefficients isEqualTo []) then { + _ballisticCoefficients = [0.5]; +}; private _velocityBoundaries = getArray(_ammoConfig >> "ACE_velocityBoundaries"); private _atmosphereModel = getText(_ammoConfig >> "ACE_standardAtmosphere"); if (_atmosphereModel isEqualTo "") then { diff --git a/addons/advanced_ballistics/initSettings.inc.sqf b/addons/advanced_ballistics/initSettings.inc.sqf index 957044f343a..28a1d6d8262 100644 --- a/addons/advanced_ballistics/initSettings.inc.sqf +++ b/addons/advanced_ballistics/initSettings.inc.sqf @@ -5,7 +5,9 @@ private _category = format ["ACE %1", localize LSTRING(DisplayName)]; [LSTRING(enabled_DisplayName), LSTRING(enabled_Description)], _category, false, - 1 + 1, + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -45,5 +47,7 @@ private _category = format ["ACE %1", localize LSTRING(DisplayName)]; [LSTRING(simulationInterval_DisplayName), LSTRING(simulationInterval_Description)], _category, [0, 0.2, 0.05, 2], - 1 + 1, + {[QGVAR(simulationInterval), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; diff --git a/addons/advanced_ballistics/stringtable.xml b/addons/advanced_ballistics/stringtable.xml index b077f53b6ae..67022f7deba 100644 --- a/addons/advanced_ballistics/stringtable.xml +++ b/addons/advanced_ballistics/stringtable.xml @@ -46,7 +46,7 @@ Fejlett ballisztika Продвинутая баллистика Balistica Avanzata - アドバンスド弾道計算 + 高度な弾道計算 고급 탄도학 先進彈道系統 进阶弹道系统 @@ -63,7 +63,7 @@ Fejlett ballisztika Продвинутая баллистика Balistica Avanzata - アドバンスド弾道計算を有効化 + 高度な弾道計算を有効化 고급 탄도학 先進彈道系統 进阶弹道系统 @@ -80,7 +80,7 @@ Engedélyezi a fejlett ballisztikát Включает продвинутую баллистику Abilita Balistica Avanzata - アドバンスド弾道計算は高度な弾道計算処理を有効化します。 + 高度な弾道計算を有効化します。 고급 탄도학을 적용합니다 啟用先進彈道系統 启用进阶弹道系统 @@ -280,7 +280,7 @@ 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) entro il quale la Balistica Avanzata è applicata ai proiettili - アドバンスド弾道計算の適用半径範囲 (プレイヤー中心、メートル単位) を定義します。 + 高度な弾道計算が飛翔体に適用される半径距離 (プレイヤー中心、メートル単位) を定義します。 플레이어 주위의 발사체를 고급 탄도학으로 정의하는 범위를 정합니다(미터) 以玩家的半徑距離(公尺)定義先進彈道系統啟用範圍 定义玩家周围的半径(米),在这个半径内,进阶弹道系统会被启用 @@ -297,7 +297,7 @@ Этот модуль включает симуляцию продвинутой баллистики - при этом на траекторию полета снаряда влияют различные параметры, такие как температура воздуха, атмосферное давление, влажность, гравитация, тип боеприпаса и оружия, из которого произвели выстрел. 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 - essa comporta che la traiettoria dei proiettili è influenzata da variabili come la temperatura dell'aria, pressione atmosferica, umidità, gravità, il tipo di munizione e l'arma da cui è sparata. - アドバンスド弾道計算のシミュレーションを有効化します。 弾道は気温・気圧・湿度・重力・弾薬の種類・発射する武器などの変化による影響を受けるようになります。 + 高度な弾道計算のシミュレーションを有効化します。 弾道は気温・気圧・湿度・重力・弾薬の種類・発射する武器などの変化による影響を受けるようになります。 이 모듈은 고급 탄도학을 적용시킵니다 - 이는 발사체의 궤적이 기온, 대기압, 습도, 중력, 탄환의 종류와 어느 무기에서 발사되는지에 따라 영향을 받습니다. 該模塊實現先進的彈道仿真 - 這意味著子彈的軌跡是由空氣溫度、大氣壓力、濕度、重力、彈藥類型以及射擊的武器所影響 该模块实现增强的弹道模拟—子弹的轨迹由空气温度、大气压力、湿度、重力、弹药类型和射击的武器等变量所影响 diff --git a/addons/advanced_fatigue/CfgEden.hpp b/addons/advanced_fatigue/CfgEden.hpp index 8307c8a2a57..50147c8e8c6 100644 --- a/addons/advanced_fatigue/CfgEden.hpp +++ b/addons/advanced_fatigue/CfgEden.hpp @@ -2,9 +2,35 @@ 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 ([_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, 2]; _slider ctrlAddEventHandler [""SliderPosChanged"", { params [""_slider""]; private _edit = (ctrlParentControlsGroup _slider) controlsGroupCtrl 101; private _value = sliderPosition _slider; _edit ctrlSetText ([_value, 1, 1] call CBA_fnc_formatNumber); }]; _edit ctrlAddEventHandler [""KillFocus"", { params [""_edit""]; private _slider = (ctrlParentControlsGroup _edit) controlsGroupCtrl 100; private _value = ((parseNumber ctrlText _edit) min 2) max 0; _slider sliderSetPosition _value; _edit ctrlSetText str _value; }];"; + #pragma hemtt suppress pw3_padded_arg + attributeLoad = QUOTE(\ + params ['_ctrlGroup']; \ + private _slider = _ctrlGroup controlsGroupCtrl 100; \ + private _edit = _ctrlGroup controlsGroupCtrl 101; \ + _slider sliderSetPosition _value; \ + _edit ctrlSetText ([ARR_3(_value,1,1)] call CBA_fnc_formatNumber); \ + ); + attributeSave = QUOTE(params ['_ctrlGroup']; sliderPosition (_ctrlGroup controlsGroupCtrl 100)); + #pragma hemtt suppress pw3_padded_arg + onLoad = QUOTE(\ + params ['_ctrlGroup']; \ + private _slider = _ctrlGroup controlsGroupCtrl 100; \ + private _edit = _ctrlGroup controlsGroupCtrl 101; \ + _slider sliderSetRange [ARR_2(0,MAX_PERFORMANCE_FACTOR)]; \ + _slider ctrlAddEventHandler [ARR_2('SliderPosChanged',{ \ + params ['_slider']; \ + private _edit = (ctrlParentControlsGroup _slider) controlsGroupCtrl 101; \ + private _value = sliderPosition _slider; \ + _edit ctrlSetText ([ARR_3(_value,1,1)] call CBA_fnc_formatNumber); \ + })]; \ + _edit ctrlAddEventHandler [ARR_2('KillFocus',{ \ + params ['_edit']; \ + private _slider = (ctrlParentControlsGroup _edit) controlsGroupCtrl 100; \ + private _value = ((parseNumber ctrlText _edit) min MAX_PERFORMANCE_FACTOR) max 0; \ + _slider sliderSetPosition _value; \ + _edit ctrlSetText str _value; \ + })]; \ + ); }; }; class Object { diff --git a/addons/advanced_fatigue/Dialog.hpp b/addons/advanced_fatigue/Dialog.hpp index df019f3800c..7b57e00ced9 100644 --- a/addons/advanced_fatigue/Dialog.hpp +++ b/addons/advanced_fatigue/Dialog.hpp @@ -2,18 +2,18 @@ class RscControlsGroupNoScrollbars; class RscPicture; class GVAR(StaminaBarContainer): RscControlsGroupNoScrollbars { - x = "(profilenamespace getvariable [""IGUI_GRID_STAMINA_X"", ((safezoneX + safezoneW) - (10 * (((safezoneW / safezoneH) min 1.2) / 40)) - 4.3 * (((safezoneW / safezoneH) min 1.2) / 40))])"; - y = "(profilenamespace getvariable [""IGUI_GRID_STAMINA_Y"", (safezoneY + 4.05 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))])"; - w = "10 * (((safezoneW / safezoneH) min 1.2) / 40)"; - h = "0.15 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + x = "(profilenamespace getvariable [""IGUI_GRID_STAMINA_X"", ((safeZoneX + safeZoneW) - (10 * (((safeZoneW / safeZoneH) min 1.2) / 40)) - 4.3 * (((safeZoneW / safeZoneH) min 1.2) / 40))])"; + y = "(profilenamespace getvariable [""IGUI_GRID_STAMINA_Y"", (safeZoneY + 4.05 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25))])"; + w = "10 * (((safeZoneW / safeZoneH) min 1.2) / 40)"; + h = "0.15 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; class Controls { class StaminaBar: RscPicture { idc = 10; x = 0; y = 0; - w = "10 * (((safezoneW / safezoneH) min 1.2) / 40)"; - h = "0.15 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + w = "10 * (((safeZoneW / safeZoneH) min 1.2) / 40)"; + h = "0.15 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; text = "\A3\Ui_f\data\IGUI\RscIngameUI\RscUnitInfo\stamina_ca.paa"; }; }; diff --git a/addons/advanced_fatigue/XEH_PREP.hpp b/addons/advanced_fatigue/XEH_PREP.hpp index 4ee00e3ce45..509c85e3755 100644 --- a/addons/advanced_fatigue/XEH_PREP.hpp +++ b/addons/advanced_fatigue/XEH_PREP.hpp @@ -9,3 +9,5 @@ PREP(handleStaminaBar); PREP(mainLoop); PREP(moduleSettings); PREP(removeDutyFactor); +PREP(renderDebugLines); +PREP(updateStaminaBar); diff --git a/addons/advanced_fatigue/XEH_postInit.sqf b/addons/advanced_fatigue/XEH_postInit.sqf index db4a9d9c5e1..e3b75a64a61 100644 --- a/addons/advanced_fatigue/XEH_postInit.sqf +++ b/addons/advanced_fatigue/XEH_postInit.sqf @@ -2,34 +2,9 @@ if (!hasInterface) exitWith {}; -["baseline", { - private _fatigue = ACE_player getVariable [QGVAR(aimFatigue), 0]; - switch (stance ACE_player) do { - case ("CROUCH"): { - (1.0 + _fatigue ^ 2 * 0.1) - }; - case ("PRONE"): { - (1.0 + _fatigue ^ 2 * 2.0) - }; - default { - (1.5 + _fatigue ^ 2 * 3.0) - }; - }; -}, QUOTE(ADDON)] call EFUNC(common,addSwayFactor); - -["multiplier", { - switch (true) do { - case (isWeaponRested ACE_player): { - GVAR(swayFactor) * GVAR(restedSwayFactor) - }; - case (isWeaponDeployed ACE_player): { - GVAR(swayFactor) * GVAR(deployedSwayFactor) - }; - default { - GVAR(swayFactor) - }; - }; -}, QUOTE(ADDON)] call EFUNC(common,addSwayFactor); +#ifdef DEBUG_MODE_FULL +call FUNC(renderDebugLines); +#endif // recheck weapon inertia after weapon swap, change of attachments or switching unit ["weapon", {[ACE_player] call FUNC(getWeaponInertia)}, true] call CBA_fnc_addPlayerEventHandler; @@ -39,6 +14,23 @@ if (!hasInterface) exitWith {}; ["CBA_settingsInitialized", { if (!GVAR(enabled)) exitWith {}; + [QEGVAR(ui,hideHud), LINKFUNC(updateStaminaBar)] call CBA_fnc_addEventHandler; + + ["baseline", { + private _fatigue = ACE_player getVariable [QGVAR(aimFatigue), 0]; + switch (stance ACE_player) do { + case ("CROUCH"): { + (1.0 + _fatigue ^ 2 * 0.1) + }; + case ("PRONE"): { + (1.0 + _fatigue ^ 2 * 2.0) + }; + default { + (1.5 + _fatigue ^ 2 * 3.0) + }; + }; + }, QUOTE(ADDON)] call EFUNC(common,addSwayFactor); + // - Post process effect ------------------------------------------------------ GVAR(ppeBlackout) = ppEffectCreate ["ColorCorrections", 4220]; GVAR(ppeBlackout) ppEffectEnable true; @@ -47,25 +39,23 @@ if (!hasInterface) exitWith {}; GVAR(ppeBlackout) ppEffectCommit 0.4; // - GVAR updating and initialization ----------------------------------------- - ["unit", LINKFUNC(handlePlayerChanged), true] call CBA_fnc_addPlayerEventHandler; + ["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; ["visibleMap", { params ["", "_visibleMap"]; // command visibleMap is updated one frame later - private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; - _staminaBarContainer ctrlShow ((!_visibleMap) && {(vehicle ACE_player) == ACE_player}); + (uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]) ctrlShow (!_visibleMap && isNull objectParent ACE_player); }, true] call CBA_fnc_addPlayerEventHandler; ["vehicle", { - private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; - _staminaBarContainer ctrlShow ((!visibleMap) && {(vehicle ACE_player) == ACE_player}); + (uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]) ctrlShow (!visibleMap && isNull objectParent ACE_player); }, true] call CBA_fnc_addPlayerEventHandler; // - Duty factors ------------------------------------------------------------- - if (GVAR(medicalLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [QEGVAR(medical,pain), { // 0->1.0, 0.5->1.05, 1->1.1 - linearConversion [0, 1, (_this getVariable [QEGVAR(medical,pain), 0]), 1, 1.1, true]; + linearConversion [0, 1, _this getVariable [QEGVAR(medical,pain), 0], 1, 1.1, true]; }] call FUNC(addDutyFactor); [QEGVAR(medical,bloodVolume), { // 6->1.0, 5->1.167, 4->1.33 - linearConversion [6, 0, (_this getVariable [QEGVAR(medical,bloodVolume), 6]), 1, 2, true]; + linearConversion [6, 0, _this getVariable [QEGVAR(medical,bloodVolume), 6], 1, 2, true]; }] call FUNC(addDutyFactor); }; if (["ace_dragging"] call EFUNC(common,isModLoaded)) then { @@ -76,7 +66,7 @@ if (!hasInterface) exitWith {}; // Weather has an off switch, Dragging & Medical don't. if (missionNamespace getVariable [QEGVAR(weather,enabled), false]) then { [QEGVAR(weather,temperature), { // 35->1, 45->2 - linearConversion [35, 45, (missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25]), 1, 2, true]; + linearConversion [35, 45, missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25], 1, 2, true]; }] call FUNC(addDutyFactor); }; diff --git a/addons/advanced_fatigue/XEH_preInit.sqf b/addons/advanced_fatigue/XEH_preInit.sqf index 9f58e44fdf2..ed1bd966229 100644 --- a/addons/advanced_fatigue/XEH_preInit.sqf +++ b/addons/advanced_fatigue/XEH_preInit.sqf @@ -8,11 +8,10 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" -GVAR(staminaBarWidth) = 10 * (((safezoneW / safezoneH) min 1.2) / 40); +GVAR(staminaBarWidth) = 10 * (((safeZoneW / safeZoneH) min 1.2) / 40); GVAR(dutyList) = createHashMap; GVAR(setAnimExclusions) = []; GVAR(inertia) = 0; GVAR(inertiaCache) = createHashMap; -GVAR(medicalLoaded) = ["ace_medical"] call EFUNC(common,isModLoaded); ADDON = true; diff --git a/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf b/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf index e992816e9b6..50e052d5f85 100644 --- a/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf +++ b/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: BaerMitUmlaut - * Calculates the duty of the current animation. + * Calculates the duty ('postureWeight') of the current animation. * * Arguments: * 0: Unit diff --git a/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf b/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf index cc07d9e004f..36048cee049 100644 --- a/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf +++ b/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf @@ -1,54 +1,74 @@ #include "..\script_component.hpp" /* - * Author: BaerMitUmlaut - * Calculates the current metabolic costs for a unit. + * Author: BaerMitUmlaut, ulteq + * Calculates the current metabolic costs. * Calculation is done according to the Pandolf/Wojtowicz formulas. * * Arguments: - * 0: Unit - * 1: Speed + * 0: Duty of animation + * 1: Mass of unit + * 2: Terrain gradient + * 3: Terrain factor + * 4: Speed * * Return Value: * Metabolic cost * * Example: - * [player, 3.3] call ace_advanced_fatigue_fnc_getMetabolicCosts + * [1, 840, 20, 1, 4] call ace_advanced_fatigue_fnc_getMetabolicCosts * * Public: No */ -params ["_unit", "_velocity"]; -private _gearMass = ((_unit getVariable [QEGVAR(movement,totalLoad), loadAbs _unit]) / 22.046) * GVAR(loadFactor); - -private _terrainAngle = asin (1 - ((surfaceNormal getPosASL _unit) select 2)); -private _terrainGradient = (_terrainAngle / 45 min 1) * 5 * GVAR(terrainGradientFactor); -private _duty = GVAR(animDuty); - -{ - if (_x isEqualType 0) then { - _duty = _duty * _x; - } else { - _duty = _duty * (_unit call _x); - }; -} forEach (values GVAR(dutyList)); - -if (GVAR(isSwimming)) then { - _terrainGradient = 0; -}; +params ["_duty", "_gearMass", "_terrainGradient", "_terrainFactor", "_speed"]; // Metabolic cost for walking and running is different -if (_velocity > 2) then { +if (_speed > 2) then { // Running + #ifdef DEBUG_MODE_FULL + private _baseline = 2.1 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + (SIM_BODYMASS + _gearMass) * 0.9 * (_speed ^ 2); + private _graded = 2.1 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.9 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient); + private _terrainImpact = abs ((_graded / _baseline) - 1); + hintSilent format ["FwdAngle: %1 | SideAngle: %2 \n TerrainFactor: %3 | TerrainGradient: %4 \n TerrainImpact: %5 \n Speed: %6 | CarriedLoad: %7 \n Duty: %8 | Work: %9", + _fwdAngle toFixed 1, + _sideAngle toFixed 1, + _terrainFactor toFixed 2, + _terrainGradient toFixed 1, + _terrainImpact toFixed 2, + _speed toFixed 2, + _gearMass toFixed 1, + _duty toFixed 2, + round (_graded * BIOMECH_EFFICIENCY * _duty) + ]; + #endif + ( - 2.10 * SIM_BODYMASS + 2.1 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) - + (SIM_BODYMASS + _gearMass) * (0.9 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient) - ) * 0.23 * _duty + + _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.9 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient) + ) * BIOMECH_EFFICIENCY * _duty } else { // Walking + #ifdef DEBUG_MODE_FULL + private _baseline = 1.05 * SIM_BODYMASS + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + (SIM_BODYMASS + _gearMass) * 1.15 * (_speed ^ 2); + private _graded = 1.05 * SIM_BODYMASS + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient); + private _terrainImpact = abs ((_graded / _baseline) - 1); + hintSilent format ["FwdAngle: %1 | SideAngle: %2 \n TerrainFactor: %3 | TerrainGradient: %4 \n TerrainImpact: %5 \n Speed: %6 | CarriedLoad: %7 \n Duty: %8 | Work: %9", + _fwdAngle toFixed 1, + _sideAngle toFixed 1, + _terrainFactor toFixed 2, + _terrainGradient toFixed 1, + _terrainImpact toFixed 2, + _speed toFixed 2, + _gearMass toFixed 1, + _duty toFixed 2, + round (_graded * BIOMECH_EFFICIENCY * _duty) + ]; + #endif + ( 1.05 * SIM_BODYMASS + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) - + (SIM_BODYMASS + _gearMass) * (1.15 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient) - ) * 0.23 * _duty + + _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient) + ) * BIOMECH_EFFICIENCY * _duty }; diff --git a/addons/advanced_fatigue/functions/fnc_handleEffects.sqf b/addons/advanced_fatigue/functions/fnc_handleEffects.sqf index 13c1fefc622..d9488233547 100644 --- a/addons/advanced_fatigue/functions/fnc_handleEffects.sqf +++ b/addons/advanced_fatigue/functions/fnc_handleEffects.sqf @@ -1,44 +1,44 @@ #include "..\script_component.hpp" /* - * Author: BaerMitUmlaut + * Author: BaerMitUmlaut, ulteq * Handles any audible, visual and physical effects of fatigue. * * Arguments: * 0: Unit * 1: Fatigue - * 2: Speed - * 3: Overexhausted + * 2: Overexhausted + * 3: Forward Angle + * 4: Side Angle * * Return Value: * None * * Example: - * [_player, 0.5, 3.3, true] call ace_advanced_fatigue_fnc_handleEffects + * [_player, 0.5, 3.3, true, 0, 0] call ace_advanced_fatigue_fnc_handleEffects * * Public: No */ -params ["_unit", "_fatigue", "_speed", "_overexhausted"]; -#ifdef DEBUG_MODE_FULL - systemChat str _fatigue; - systemChat str vectorMagnitude velocity _unit; -#endif +params ["_unit", "_fatigue", "_overexhausted", "_fwdAngle", "_sideAngle"]; // - Audible effects ---------------------------------------------------------- GVAR(lastBreath) = GVAR(lastBreath) + 1; + if (_fatigue > 0.4 && {GVAR(lastBreath) > (_fatigue * -10 + 9)} && {!underwater _unit}) then { if (!isGameFocused) exitWith {}; + switch (true) do { case (_fatigue < 0.6): { - playSound (QGVAR(breathLow) + str(floor random 6)); + playSound (QGVAR(breathLow) + str (floor random 6)); }; case (_fatigue < 0.85): { - playSound (QGVAR(breathMid) + str(floor random 6)); + playSound (QGVAR(breathMid) + str (floor random 6)); }; default { - playSound (QGVAR(breathMax) + str(floor random 6)); + playSound (QGVAR(breathMax) + str (floor random 6)); }; }; + GVAR(lastBreath) = 0; }; @@ -62,31 +62,35 @@ if (GVAR(isSwimming)) exitWith { if (GVAR(setAnimExclusions) isEqualTo []) then { _unit setAnimSpeedCoef linearConversion [0.7, 0.9, _fatigue, 1, 0.5, true]; }; - if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then { + + if (isSprintAllowed _unit && _fatigue > 0.7) then { // small checks like these are faster without lazy eval [_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); } else { - if ((!isSprintAllowed _unit) && {_fatigue < 0.7}) then { + if (!isSprintAllowed _unit && _fatigue < 0.7) then { [_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); }; }; }; -if ((getAnimSpeedCoef _unit) != 1) then { - if (GVAR(setAnimExclusions) isEqualTo []) then { - TRACE_1("reset",getAnimSpeedCoef _unit); - _unit setAnimSpeedCoef 1; - }; + +// If other components are setting setAnimSpeedCoef, do not change animSpeedCoef +if (getAnimSpeedCoef _unit != 1 && {GVAR(setAnimExclusions) isEqualTo []}) then { + TRACE_1("reset",getAnimSpeedCoef _unit); + _unit setAnimSpeedCoef 1; }; -if (_overexhausted) then { +if (!isForcedWalk _unit && _fatigue >= 1) then { // small checks like these are faster without lazy eval [_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + [_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); } else { - if (isForcedWalk _unit && {_fatigue < 0.7}) then { + if (isForcedWalk _unit && _fatigue < 0.7) then { [_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); + [_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); } else { - if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then { + // Forward angle is the slope of the terrain, side angle simulates the unevenness/roughness of the terrain + if (isSprintAllowed _unit && {_fatigue > 0.7 || abs _fwdAngle > 20 || abs _sideAngle > 20}) then { [_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); } else { - if ((!isSprintAllowed _unit) && {_fatigue < 0.6}) then { + if (!isSprintAllowed _unit && _fatigue < 0.6 && abs _fwdAngle < 20 && abs _sideAngle < 20) then { [_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); }; }; diff --git a/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf b/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf index a119b358629..82c9c90a564 100644 --- a/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf +++ b/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Author: BaerMitUmlaut - * Handles switching units (once on init and afterwards via Zeus). + * Author: BaerMitUmlaut, ulteq + * Handles switching units (once on init and afterwards via Zeus). Also handles CBA setting change for performance factor. * * Arguments: * 0: New Unit @@ -15,20 +15,24 @@ * * Public: No */ + params ["_newUnit", "_oldUnit"]; + TRACE_2("unit changed",_newUnit,_oldUnit); -if !(isNull _oldUnit) then { +if (!isNull _oldUnit) then { + TRACE_1("remove old",_oldUnit getVariable QGVAR(animHandler)); + _oldUnit enableStamina true; _oldUnit removeEventHandler ["AnimChanged", _oldUnit getVariable [QGVAR(animHandler), -1]]; _oldUnit setVariable [QGVAR(animHandler), nil]; - TRACE_1("remove old",_oldUnit getVariable QGVAR(animHandler)); _oldUnit setVariable [QGVAR(ae1Reserve), GVAR(ae1Reserve)]; _oldUnit setVariable [QGVAR(ae2Reserve), GVAR(ae2Reserve)]; _oldUnit setVariable [QGVAR(anReserve), GVAR(anReserve)]; _oldUnit setVariable [QGVAR(anFatigue), GVAR(anFatigue)]; _oldUnit setVariable [QGVAR(muscleDamage), GVAR(muscleDamage)]; + _oldUnit setVariable [QGVAR(respiratoryRate), GVAR(respiratoryRate)]; }; _newUnit enableStamina false; @@ -38,6 +42,7 @@ if (_newUnit getVariable [QGVAR(animHandler), -1] == -1) then { private _animHandler = _newUnit addEventHandler ["AnimChanged", { GVAR(animDuty) = _this call FUNC(getAnimDuty); }]; + TRACE_1("add new",_animHandler); _newUnit setVariable [QGVAR(animHandler), _animHandler]; }; @@ -47,18 +52,27 @@ GVAR(ae2Reserve) = _newUnit getVariable [QGVAR(ae2Reserve), AE2_MAXRESERVE] GVAR(anReserve) = _newUnit getVariable [QGVAR(anReserve), AN_MAXRESERVE]; GVAR(anFatigue) = _newUnit getVariable [QGVAR(anFatigue), 0]; GVAR(muscleDamage) = _newUnit getVariable [QGVAR(muscleDamage), 0]; +GVAR(respiratoryRate) = _newUnit getVariable [QGVAR(respiratoryRate), 0]; // Clean variables for respawning units { _newUnit setVariable [_x, nil]; -} forEach [QGVAR(ae1Reserve), QGVAR(ae2Reserve), QGVAR(anReserve), QGVAR(anFatigue), QGVAR(muscleDamage)]; +} forEach [QGVAR(ae1Reserve), QGVAR(ae2Reserve), QGVAR(anReserve), QGVAR(anFatigue), QGVAR(muscleDamage), QGVAR(respiratoryRate)]; GVAR(VO2Max) = 35 + 20 * (_newUnit getVariable [QGVAR(performanceFactor), GVAR(performanceFactor)]); -GVAR(VO2MaxPower) = GVAR(VO2Max) * SIM_BODYMASS * 0.23 * JOULES_PER_ML_O2 / 60; +GVAR(VO2MaxPower) = GVAR(VO2Max) * SIM_BODYMASS * BIOMECH_EFFICIENCY * JOULES_PER_ML_O2 / 60; GVAR(peakPower) = VO2MAX_STRENGTH * GVAR(VO2MaxPower); -GVAR(ae1PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 13.3 * ANTPERCENT ^ 1.28 * 1.362; -GVAR(ae2PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 16.7 * ANTPERCENT ^ 1.28 * 1.362; +GVAR(ae1PathwayPower) = GVAR(peakPower) / (AE1_ATP_RELEASE_RATE + AE2_ATP_RELEASE_RATE + AN_ATP_RELEASE_RATE) * AE1_ATP_RELEASE_RATE * ANTPERCENT ^ 1.28 * 1.362; +GVAR(ae2PathwayPower) = GVAR(peakPower) / (AE1_ATP_RELEASE_RATE + AE2_ATP_RELEASE_RATE + AN_ATP_RELEASE_RATE) * AE2_ATP_RELEASE_RATE * ANTPERCENT ^ 1.28 * 1.362; +GVAR(aePathwayPower) = GVAR(ae1PathwayPower) + GVAR(ae2PathwayPower); +GVAR(anPathwayPower) = GVAR(peakPower) - GVAR(aePathwayPower); + +GVAR(aeWattsPerATP) = GVAR(ae1PathwayPower) / AE1_ATP_RELEASE_RATE; +GVAR(anWattsPerATP) = GVAR(anPathwayPower) / AN_ATP_RELEASE_RATE; + +GVAR(respiratoryBufferDivisor) = (RESPIRATORY_BUFFER - 1) / RESPIRATORY_BUFFER; +GVAR(maxPowerFatigueRatio) = 0.057 / GVAR(peakPower); GVAR(ppeBlackoutLast) = 100; GVAR(lastBreath) = 0; diff --git a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf index da469b6d218..2955e9d6ee0 100644 --- a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf +++ b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: BaerMitUmlaut + * Author: BaerMitUmlaut, ulteq * Main looping function that updates fatigue values. * * Arguments: @@ -17,73 +17,141 @@ // Dead people don't breathe, will also handle null (map intros) if (!alive ACE_player) exitWith { - [FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; + [LINKFUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; + private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; _staminaBarContainer ctrlSetFade 1; _staminaBarContainer ctrlCommit 1; }; - -private _oxygen = 0.9; // Default AF oxygen saturation -if (GVAR(medicalLoaded) && {EGVAR(medical_vitals,simulateSpo2)}) then { - _oxygen = (ACE_player getVariable [QEGVAR(medical,spo2), 97]) / 100; +private _velocity = velocity ACE_player; +private _normal = surfaceNormal (getPosWorld ACE_player); +private _movementVector = vectorNormalized _velocity; +private _fwdAngle = asin (_movementVector select 2); +private _sideAngle = if ((getPosATL ACE_player) select 2 > 0.01) then { + 0 // ignore terrain normal if not touching it +} else { + private _sideVector = vectorNormalized (_movementVector vectorCrossProduct _normal); + asin (_sideVector select 2); +}; +if (GVAR(isSwimming)) then { // ignore when floating + _fwdAngle = 0; + _sideAngle = 0; }; + 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 (_sideAngle != 0) then { + private _sideGradient = abs (_sideAngle / 45) min 1; + + _terrainFactor = 1 + _sideGradient ^ 4; + }; + }; + + // Add a scaling factor of 0.1 to reduce excessive stamina consumption on default settings (see #10361) + _currentWork = [_duty, _gearMass, _terrainGradient * GVAR(terrainGradientFactor) * 0.1, _terrainFactor, _currentSpeed] call FUNC(getMetabolicCosts); _currentWork = _currentWork max REE; }; +// Oxygen calculation +private _oxygen = if (GETEGVAR(medical,enabled,false) && {EGVAR(medical_vitals,simulateSpo2)}) then { // Defer to medical + (ACE_player getVariable [QEGVAR(medical,spo2), 97]) / 100 +} else { + 1 - 0.131 * GVAR(respiratoryRate) ^ 2 // Default AF oxygen saturation +}; // Calculate muscle damage increase -// Note: Muscle damage recovery is ignored as it takes multiple days -GVAR(muscleDamage) = (GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3.2 * 0.00004) min 1; -private _muscleIntegritySqrt = sqrt (1 - GVAR(muscleDamage)); +GVAR(muscleDamage) = GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3.2 * MUSCLE_TEAR_RATE; + +// Calculate muscle damage recovery +GVAR(muscleDamage) = 0 max (GVAR(muscleDamage) - MUSCLE_RECOVERY * GVAR(recoveryFactor)) min 1; +private _muscleIntegrity = 1 - GVAR(muscleDamage); +private _muscleFactor = sqrt _muscleIntegrity; // Calculate available power -private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * _oxygen * _muscleIntegritySqrt; -private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * _oxygen * _muscleIntegritySqrt; +private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * _oxygen * _muscleFactor; +private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * _oxygen * _muscleFactor; +private _aePathwayPowerFatigued = _ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued; +private _anPathwayPowerFatigued = GVAR(anPathwayPower) * sqrt (GVAR(anReserve) / AN_MAXRESERVE) * _oxygen * _muscleIntegrity; // Calculate how much power is consumed from each reserve private _ae1Power = _currentWork min _ae1PathwayPowerFatigued; -private _ae2Power = ((_currentWork - _ae1Power) max 0) min _ae2PathwayPowerFatigued; -private _anPower = (_currentWork - _ae1Power - _ae2Power) max 0; +private _ae2Power = (_currentWork - _ae1Power) min _ae2PathwayPowerFatigued; +private _anPower = 0 max (_currentWork - _ae1Power - _ae2Power); // Remove ATP from reserves for current work -GVAR(ae1Reserve) = GVAR(ae1Reserve) - _ae1Power / WATTSPERATP; -GVAR(ae2Reserve) = GVAR(ae2Reserve) - _ae2Power / WATTSPERATP; -GVAR(anReserve) = GVAR(anReserve) - _anPower / WATTSPERATP; -// Increase anearobic fatigue -GVAR(anFatigue) = GVAR(anFatigue) + _anPower * (0.057 / GVAR(peakPower)) * 1.1; +GVAR(ae1Reserve) = 0 max (GVAR(ae1Reserve) - _ae1Power / GVAR(aeWattsPerATP)); +GVAR(ae2Reserve) = 0 max (GVAR(ae2Reserve) - _ae2Power / GVAR(aeWattsPerATP)); +GVAR(anReserve) = 0 max (GVAR(anReserve) - _anPower / GVAR(anWattsPerATP)); + +// Acidosis accumulation +GVAR(anFatigue) = GVAR(anFatigue) + _anPower * GVAR(maxPowerFatigueRatio) * 1.1; // Aerobic ATP reserve recovery -GVAR(ae1Reserve) = ((GVAR(ae1Reserve) + _oxygen * 6.60 * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower) * GVAR(recoveryFactor)) min AE1_MAXRESERVE) max 0; -GVAR(ae2Reserve) = ((GVAR(ae2Reserve) + _oxygen * 5.83 * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower) * GVAR(recoveryFactor)) min AE2_MAXRESERVE) max 0; +GVAR(ae1Reserve) = (GVAR(ae1Reserve) + _oxygen * GVAR(recoveryFactor) * AE1_ATP_RECOVERY * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower)) min AE1_MAXRESERVE; +GVAR(ae2Reserve) = (GVAR(ae2Reserve) + _oxygen * GVAR(recoveryFactor) * AE2_ATP_RECOVERY * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower)) min AE2_MAXRESERVE; + +private _aeSurplus = _ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power; -// 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; +// 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; -GVAR(anFatigue) = ((GVAR(anFatigue) - - (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) * (0.057 / GVAR(peakPower)) * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor) -) min 1) max 0; +// Respiratory rate decrease +GVAR(respiratoryRate) = GVAR(respiratoryRate) * GVAR(respiratoryBufferDivisor); +// Respiratory rate increase +private _aePowerRatio = (GVAR(aePathwayPower) / _aePathwayPowerFatigued) min 2; +private _respiratorySampleDivisor = 1 / (RESPIRATORY_BUFFER * 4.72 * GVAR(VO2Max)); +GVAR(respiratoryRate) = (GVAR(respiratoryRate) + _currentWork * _respiratorySampleDivisor * _aePowerRatio) min 1; + +// Calculate a pseudo-perceived fatigue, which is used for effects GVAR(aeReservePercentage) = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2; GVAR(anReservePercentage) = GVAR(anReserve) / AN_MAXRESERVE; private _perceivedFatigue = 1 - (GVAR(anReservePercentage) min GVAR(aeReservePercentage)); -[ACE_player, _perceivedFatigue, _currentSpeed, GVAR(anReserve) == 0] call FUNC(handleEffects); +#ifdef DEBUG_MODE_FULL +systemChat format ["---- muscleDamage: %1 ----", GVAR(muscleDamage) toFixed 8]; +systemChat format ["---- ae2: %1 - an: %2 ----", (GVAR(ae2Reserve) / AE2_MAXRESERVE) toFixed 2, (GVAR(anReserve) / AN_MAXRESERVE) toFixed 2]; +systemChat format ["---- anFatigue: %1 - perceivedFatigue: %2 ----", GVAR(anFatigue) toFixed 2, _perceivedFatigue toFixed 2]; +systemChat format ["---- velocity %1 - respiratoryRate: %2 ----", (vectorMagnitude _velocity) toFixed 2, GVAR(respiratoryRate) toFixed 2]; +// systemChat format ["---- aePower: %1 ----", _aePathwayPowerFatigued toFixed 1]; +#endif + +[ACE_player, _perceivedFatigue, GVAR(anReserve) == 0, _fwdAngle, _sideAngle] call FUNC(handleEffects); -if (GVAR(enableStaminaBar)) then { +if (GVAR(enableStaminaBarRealized)) then { [GVAR(anReserve) / AN_MAXRESERVE] call FUNC(handleStaminaBar); }; -[FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; +[LINKFUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; diff --git a/addons/advanced_fatigue/functions/fnc_renderDebugLines.sqf b/addons/advanced_fatigue/functions/fnc_renderDebugLines.sqf new file mode 100644 index 00000000000..3826637b9ea --- /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/fnc_updateStaminaBar.sqf b/addons/advanced_fatigue/functions/fnc_updateStaminaBar.sqf new file mode 100644 index 00000000000..627430c8201 --- /dev/null +++ b/addons/advanced_fatigue/functions/fnc_updateStaminaBar.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Updates the stamina bar state + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_advanced_fatigue_fnc_updateStaminaBar + * + * Public: No + */ + +GVAR(enableStaminaBarRealized) = GVAR(enabled) && GVAR(enableStaminaBar) && {!(missionNamespace getVariable [QEGVAR(ui,hideHud), false])}; +TRACE_1("updateStaminaBar",GVAR(enableStaminaBarRealized)); + +private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; +if (isNull _staminaBarContainer) exitWith {}; + +_staminaBarContainer ctrlSetFade ([1, 0] select GVAR(enableStaminaBarRealized)); +_staminaBarContainer ctrlCommit 0; diff --git a/addons/advanced_fatigue/initSettings.inc.sqf b/addons/advanced_fatigue/initSettings.inc.sqf index e2d797bf91b..bd8bd7d9281 100644 --- a/addons/advanced_fatigue/initSettings.inc.sqf +++ b/addons/advanced_fatigue/initSettings.inc.sqf @@ -4,12 +4,9 @@ [LSTRING(Enabled), LSTRING(Enabled_Description)], LSTRING(DisplayName), true, - true, { - if (!_this) then { - private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; - _staminaBarContainer ctrlSetFade 1; - _staminaBarContainer ctrlCommit 0; - }; + 1, + { + call FUNC(updateStaminaBar); [QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged) }, true // Needs mission restart @@ -21,13 +18,8 @@ [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; - }; - } + 1, + {call FUNC(updateStaminaBar)} ] call CBA_fnc_addSetting; [ @@ -36,7 +28,8 @@ [LSTRING(FadeStaminaBar), LSTRING(FadeStaminaBar_Description)], LSTRING(DisplayName), true, - false, { + 0, + { if (!_this && GVAR(enabled) && GVAR(enableStaminaBar)) then { private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; _staminaBarContainer ctrlSetFade 0; @@ -50,8 +43,14 @@ "SLIDER", [LSTRING(PerformanceFactor), LSTRING(PerformanceFactor_Description)], LSTRING(DisplayName), - [0, 5, 1, 1], - true + [0, MAX_PERFORMANCE_FACTOR, 1, 2], + 1, + { + // Recalculate values if the setting is changed mid-mission + if (GVAR(enabled) && hasInterface && !isNull ACE_player) then { + [ACE_player, ACE_player] call FUNC(handlePlayerChanged); + }; + } ] call CBA_fnc_addSetting; [ @@ -59,8 +58,8 @@ "SLIDER", [LSTRING(RecoveryFactor), LSTRING(RecoveryFactor_Description)], LSTRING(DisplayName), - [0, 5, 1, 1], - true + [0, 10, 1, 2], + 1 ] call CBA_fnc_addSetting; [ @@ -68,8 +67,8 @@ "SLIDER", [LSTRING(LoadFactor), LSTRING(LoadFactor_Description)], LSTRING(DisplayName), - [0, 5, 1, 1], - true + [0, 5, 1, 2], + 1 ] call CBA_fnc_addSetting; [ @@ -77,33 +76,6 @@ "SLIDER", [LSTRING(TerrainGradientFactor), LSTRING(TerrainGradientFactor_Description)], LSTRING(DisplayName), - [0, 5, 1, 1], - true -] call CBA_fnc_addSetting; - -[ - QGVAR(swayFactor), - "SLIDER", - [LSTRING(SwayFactor), LSTRING(SwayFactor_Description)], - LSTRING(DisplayName), - [0, 5, 1, 1], - true -] call CBA_fnc_addSetting; - -[ - QGVAR(restedSwayFactor), - "SLIDER", - [LSTRING(RestedSwayFactor), LSTRING(RestedSwayFactor_Description)], - LSTRING(DisplayName), - [0, 5, 1, 2], - true -] call CBA_fnc_addSetting; - -[ - QGVAR(deployedSwayFactor), - "SLIDER", - [LSTRING(DeployedSwayFactor), LSTRING(DeployedSwayFactor_Description)], - LSTRING(DisplayName), [0, 5, 1, 2], - true + 1 ] call CBA_fnc_addSetting; diff --git a/addons/advanced_fatigue/script_component.hpp b/addons/advanced_fatigue/script_component.hpp index fcc8abd3c06..11228ff3f25 100644 --- a/addons/advanced_fatigue/script_component.hpp +++ b/addons/advanced_fatigue/script_component.hpp @@ -16,14 +16,30 @@ #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 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 -#define AE1_MAXRESERVE 4000000 -#define AE2_MAXRESERVE 84000 -#define AN_MAXRESERVE 2300 +#define MAX_PERFORMANCE_FACTOR 10 diff --git a/addons/advanced_fatigue/stringtable.xml b/addons/advanced_fatigue/stringtable.xml index af25a7c181d..76e33a64e5f 100644 --- a/addons/advanced_fatigue/stringtable.xml +++ b/addons/advanced_fatigue/stringtable.xml @@ -7,7 +7,7 @@ ACE Erweiterte Ausdauer ACE 進階疲勞 ACE 进阶体力 - ACE アドバンスド疲労 + ACE 高度な疲労 ACE Fatica Avanzata ACE 고급 피로도 ACE Fatigue avancée @@ -44,7 +44,7 @@ Influenza la prestazione generale di tutti i giocatori smuniti di un fattore personalizzato. Maggiore significa migliore. 影響所有玩家的體力表現,值越高代表體力越好 影响所有玩家的体力表现,值越高代表体力越好 - Влияет на общую производительность игроков, у которых не задано персональное значение. + Влияет на общую производительность игроков, у которых не задано персональное значение. Чем выше, тем лучше. Influencia na performance geral de todos os jogadores sem nenhum fator personalizado. Quanto maior, melhor. Ovlivňuje celkový výkon všech hráčů bez vlastního faktoru. Vyšší znamená lépe. @@ -59,7 +59,7 @@ Influenza la prestazione personalizzata di questa unità. Maggiore significa migliore. 影響這個單位的體力表現,值越高代表體力越好 影响这个单位的体力表现,值越高代表体力越好 - Влияет на общую производительность юнита. + Влияет на общую производительность юнита.Чем выше, тем лучше. Influencia na performance geral dessa unidade. Quanto maior, melhor. Ovlivňuje celkový výkon této jednotky. Vyšší znamená lépe. @@ -154,76 +154,6 @@ Define o quanto que um terreno íngrime aumenta na perda de estamina. Quanto maior, maior a perda de estamina. Nastavuje, o kolik strmý terén zvyšuje ztrátu výdrže. Vyšší znamená vyšší ztrátu výdrže. - - Sway factor - Factor de balanceo de mira - Verwacklungsfaktor - 手ぶれ因数 - 抖动系数 - 抖動因素 - Facteur de tremblement - Fattore di Oscillazione - Czynnik kołysania - Фактор колебания прицела - Fator de Balanço de Mira - Faktor kývání - 손떨림 정도 - - - Influences the amount of weapon sway. Higher means more sway. - Afecta al la estabilidad de la mira. Más alto significa más balanceo - Beeinflusst, wie ruhig man eine Waffe halten kann. Ein höherer Wert bedeutet weniger Stabilisierung. - 武器の手ぶれの量に影響します。値が高いほど、手ぶれが強くなります。 - 影响手持武器的晃动程度,数值越高,抖动的越厉害。 - 影響手持武器晃動程度,數值越高抖動越厲害 - Influe sur l'amplitude du tremblement de l'arme. Une valeur plus élevée signifie plus de tremblement. - Influenza l'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 - 静止時の手ぶれ係数 - Коэффициент колебания в состоянии покоя - - - 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. - 静止している時の武器の手ぶれの量に影響します。 - Влияет на величину колебания оружия в состоянии покоя. - - - 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 - 展開時の手ぶれ係数 - Коэффициент колебания при развертывании - - - 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. - 武器の展開(Cキー)時の武器の手ぶれの量に影響します。 - Влияет на величину колебания оружия при его развертывании. - Enabled Activada @@ -243,14 +173,14 @@ Enables/disables Advanced Fatigue. Activa/desactiva la fatiga avanzada Aktiviert/deaktiviert Advanced Fatigue. - アドバンスド疲労は高度な疲労管理システムを有効化します。 + 高度な疲労を有効/無効化します。 Włącza/wyłącza zaawansowaną wytrzymałość 고급 피로도 활성화/비활성화 Active/Désactive la fatigue avancée. Abilita/Disabilita la Fatica Avanzata. 啟用/關閉進階體力. 启用/关闭进阶体力。 - Включает / Отключает Продвинутую усталость + Включает/отключает Продвинутую усталость Ativa/Desativa Fadiga Avançada. Aktivuje / deaktivuje Pokročilou únavu. diff --git a/addons/advanced_throwing/XEH_postInit.sqf b/addons/advanced_throwing/XEH_postInit.sqf index 96b0fbb09b4..d91129b0250 100644 --- a/addons/advanced_throwing/XEH_postInit.sqf +++ b/addons/advanced_throwing/XEH_postInit.sqf @@ -2,26 +2,18 @@ // Fired XEH GVAR(ammoEventHandlers) = createHashMap; -[QGVAR(throwFiredXEH), FUNC(throwFiredXEH)] call CBA_fnc_addEventHandler; +[QGVAR(throwFiredXEH), LINKFUNC(throwFiredXEH)] call CBA_fnc_addEventHandler; // Exit on HC if (!hasInterface) exitWith {}; -// Ammo/Magazines look-up hash for correctness of initSpeed -GVAR(ammoMagLookup) = call CBA_fnc_createNamespace; -{ - { - private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); - if (_ammo != "") then { GVAR(ammoMagLookup) setVariable [_ammo, _x]; }; - } count (getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")); - nil -} count getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); - +// Temporary Wind Info indication +GVAR(tempWindInfo) = false; // Add keybinds ["ACE3 Weapons", QGVAR(prepare), localize LSTRING(Prepare), { // Condition - if (!([ACE_player] call FUNC(canPrepare))) exitWith {false}; + if !([ACE_player] call FUNC(canPrepare)) exitWith {false}; if (EGVAR(common,isReloading)) exitWith {true}; // Statement diff --git a/addons/advanced_throwing/XEH_preStart.sqf b/addons/advanced_throwing/XEH_preStart.sqf index 022888575ed..efd2ca1f7eb 100644 --- a/addons/advanced_throwing/XEH_preStart.sqf +++ b/addons/advanced_throwing/XEH_preStart.sqf @@ -1,3 +1,21 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +// Ammo/Magazines look-up hash for correctness of initSpeed +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgAmmo = configFile >> "CfgAmmo"; +private _cfgThrow = configFile >> "CfgWeapons" >> "Throw"; + +private _ammoMagLookup = createHashMap; + +{ + { + private _ammo = getText (_cfgMagazines >> _x >> "ammo"); + if (_ammo != "") then { + _ammoMagLookup set [configName (_cfgAmmo >> _ammo), _x]; + }; + } forEach (getArray (_cfgThrow >> _x >> "magazines")); +} forEach (getArray (_cfgThrow >> "muzzles")); + +uiNamespace setVariable [QGVAR(ammoMagLookup), compileFinal _ammoMagLookup]; diff --git a/addons/advanced_throwing/functions/fnc_canThrow.sqf b/addons/advanced_throwing/functions/fnc_canThrow.sqf index 06cf166f88a..8b2987eafac 100644 --- a/addons/advanced_throwing/functions/fnc_canThrow.sqf +++ b/addons/advanced_throwing/functions/fnc_canThrow.sqf @@ -19,7 +19,7 @@ params ["_unit"]; if !(_unit getVariable [QGVAR(inHand), false]) exitWith {false}; -if (vehicle _unit != _unit) exitWith { +if (!isNull objectParent _unit) exitWith { private _startPos = eyePos _unit; private _aimLinePos = AGLToASL (positionCameraToWorld [0, 0, 1]); private _intersections = lineIntersectsSurfaces [_startPos, _aimLinePos, _unit, objNull, false]; diff --git a/addons/advanced_throwing/functions/fnc_drawThrowable.sqf b/addons/advanced_throwing/functions/fnc_drawThrowable.sqf index 5bc3f22b571..f85c33dbde2 100644 --- a/addons/advanced_throwing/functions/fnc_drawThrowable.sqf +++ b/addons/advanced_throwing/functions/fnc_drawThrowable.sqf @@ -43,13 +43,10 @@ if ((!_primed) && {!((_throwableMag in (uniformItems ACE_player)) || {_throwable // Get correct throw power for primed grenade if (_primed) then { - private _ammoType = typeOf _activeThrowable; - _throwableMag = GVAR(ammoMagLookup) getVariable _ammoType; - if (isNil "_throwableMag") then { - // What we're trying to throw must not be a normal throwable because it is not in our lookup hash (e.g. 40mm smoke) - // Just use HandGrenade as it has an average initSpeed value - _throwableMag = "HandGrenade"; - }; + // If ammo type is not found: + // What we're trying to throw must not be a normal throwable because it is not in our lookup hash (e.g. 40mm smoke) + // Just use HandGrenade as it has an average initSpeed value + _throwableMag = (uiNamespace getVariable QGVAR(ammoMagLookup)) getOrDefault [typeOf _activeThrowable, "HandGrenade"]; }; // Some throwables have different classname for magazine and ammo diff --git a/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf b/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf index 744a6d7aae3..3b88564eaee 100644 --- a/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf +++ b/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf @@ -53,6 +53,12 @@ _unit setVariable [QGVAR(dropDistance), DROP_DISTANCE_DEFAULT]; // Remove controls hint (check if ever enabled is inside the function) call EFUNC(interaction,hideMouseHint); +// Hide wind info after throw, if it was temporarily enabled for the throw +if (GVAR(tempWindInfo)) then { + EGVAR(weather,WindInfo) = false; + GVAR(tempWindInfo) = false; +}; + // Remove throw action [_unit, "DefaultAction", _unit getVariable [QGVAR(throwAction), -1]] call EFUNC(common,removeActionEventHandler); diff --git a/addons/advanced_throwing/functions/fnc_getMuzzle.sqf b/addons/advanced_throwing/functions/fnc_getMuzzle.sqf index e0c55daba62..eab95825e4a 100644 --- a/addons/advanced_throwing/functions/fnc_getMuzzle.sqf +++ b/addons/advanced_throwing/functions/fnc_getMuzzle.sqf @@ -17,9 +17,9 @@ params ["_magazineClassname"]; -_magazineClassname = toLower _magazineClassname; +_magazineClassname = toLowerANSI _magazineClassname; private _throwMuzzles = getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); -_throwMuzzles = _throwMuzzles select {_magazineClassname in ((getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")) apply {toLower _x})}; +_throwMuzzles = _throwMuzzles select {_magazineClassname in ((getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")) apply {toLowerANSI _x})}; [_throwMuzzles select 0, ""] select (_throwMuzzles isEqualTo []) diff --git a/addons/advanced_throwing/functions/fnc_prepare.sqf b/addons/advanced_throwing/functions/fnc_prepare.sqf index 070870879b1..c158ad51502 100644 --- a/addons/advanced_throwing/functions/fnc_prepare.sqf +++ b/addons/advanced_throwing/functions/fnc_prepare.sqf @@ -21,7 +21,7 @@ TRACE_1("params",_unit); // Select next throwable if one already in hand if (_unit getVariable [QGVAR(inHand), false]) exitWith { TRACE_1("inHand",_unit); - if (!(_unit getVariable [QGVAR(primed), false])) then { + if !(_unit getVariable [QGVAR(primed), false]) then { TRACE_1("not primed",_unit); // Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory) // selectNextGrenade relies on muzzles array (setAmmo 0 removes the muzzle from the array and current can't be found, cycles between 0 and 1 muzzles) @@ -35,6 +35,11 @@ if (isNull (_unit getVariable [QGVAR(activeThrowable), objNull]) && {(currentThr TRACE_1("no throwables",_unit); }; +// Temporarily enable wind info, to aid in throwing smoke grenades effectively +if (GVAR(enableTempWindInfo) && {!(missionNamespace getVariable [QEGVAR(weather,WindInfo), false])}) then { + [] call EFUNC(weather,displayWindInfo); + GVAR(tempWindInfo) = true; +}; _unit setVariable [QGVAR(inHand), true]; diff --git a/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf b/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf index 15cae41585e..d45f2add934 100644 --- a/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf +++ b/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf @@ -44,8 +44,7 @@ _addedPickUpHelpers pushBack _pickUpHelper; _throwablesHelped pushBack _x; }; - nil - } count _nearThrowables; + } forEach _nearThrowables; _args set [0, getPosASL ACE_player]; _args set [3, _nearThrowables]; @@ -56,11 +55,10 @@ { // Only handling with attachTo works nicely _x attachTo [_x getVariable [QGVAR(throwable), objNull], [0, 0, 0]]; - nil - } count _addedPickUpHelpers; + } forEach _addedPickUpHelpers; } else { TRACE_1("Cleaning Pick Up Helpers",count _addedPickUpHelpers); - {deleteVehicle _x} count _addedPickUpHelpers; + {deleteVehicle _x} forEach _addedPickUpHelpers; [_idPFH] call CBA_fnc_removePerFrameHandler; }; }, 0, [(getPosASL ACE_player) vectorAdd [-100, 0, 0], [], [], []]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/advanced_throwing/functions/fnc_throw.sqf b/addons/advanced_throwing/functions/fnc_throw.sqf index 0380d3d896e..d1773373411 100644 --- a/addons/advanced_throwing/functions/fnc_throw.sqf +++ b/addons/advanced_throwing/functions/fnc_throw.sqf @@ -20,7 +20,7 @@ TRACE_1("params",_unit); // Prime the throwable if it hasn't been cooking already // Next to proper simulation this also has to happen before delay for orientation of the throwable to be set -if (!(_unit getVariable [QGVAR(primed), false])) then { +if !(_unit getVariable [QGVAR(primed), false]) then { [_unit] call FUNC(prime); }; @@ -45,7 +45,7 @@ if (!(_unit getVariable [QGVAR(primed), false])) then { private _newVelocity = (_p1 vectorFromTo _p2) vectorMultiply _velocity; // Adjust for throwing from inside vehicles, where we have a vehicle-based velocity that can't be compensated for by a human - if (vehicle _unit != _unit) then { + if (!isNull objectParent _unit) then { _newVelocity = _newVelocity vectorAdd (velocity (vehicle _unit)); }; @@ -89,7 +89,7 @@ GVAR(flightPath) = []; GVAR(flightRotation) = []; (_unit getVariable QGVAR(activeThrowable)) spawn { while {!isNull _this && {(getPosATL _this) select 2 > 0.05}} do { - GVAR(flightPath) pushBack [ASLtoAGL (getPosASL _this), vectorUp _this]; + GVAR(flightPath) pushBack [ASLToAGL (getPosASL _this), vectorUp _this]; sleep 0.05; }; }; diff --git a/addons/advanced_throwing/initSettings.inc.sqf b/addons/advanced_throwing/initSettings.inc.sqf index d4ebe149185..d8396637c57 100644 --- a/addons/advanced_throwing/initSettings.inc.sqf +++ b/addons/advanced_throwing/initSettings.inc.sqf @@ -40,3 +40,11 @@ private _category = format ["ACE %1", localize LSTRING(Category)]; true, 1 ] call CBA_fnc_addSetting; + +[ + QGVAR(enableTempWindInfo), "CHECKBOX", + [LSTRING(EnableTempWindInfo_DisplayName), LSTRING(EnableTempWindInfo_Description)], + _category, + true, + 0 +] call CBA_fnc_addSetting; diff --git a/addons/advanced_throwing/stringtable.xml b/addons/advanced_throwing/stringtable.xml index ec2354a2c03..99fba866305 100644 --- a/addons/advanced_throwing/stringtable.xml +++ b/addons/advanced_throwing/stringtable.xml @@ -5,7 +5,7 @@ Advanced Throwing Lanzamiento Avanzado Улучшенный бросок гранат - アドバンスド投擲 + 高度な投擲 Zaawansowane rzucanie Erweitertes Wurfsystem 고급 투척 @@ -21,7 +21,7 @@ Allows changing advanced throwing behaviour. Permite modificar el comportamiento del lanzamiento avanzado Позволяет настраивать поведение улучшенного броска гранат. - アドバンスド投擲は投擲の高度な動作挙動を変更可能にします。 + 高度な投擲挙動への変更を可能にします。 Zezwala na zmianę zachowania zaawansowanego trybu rzucania. Erlaubt es, das Verhalten des erweiterten Wurfsystems zu ändern. 고급 투척 행위를 허가합니다 @@ -36,7 +36,7 @@ Enable Advanced Throwing Activar Lanzamiento Avanzado Вкл. улучшенный бросок - アドバンスド投擲を有効化 + 高度な投擲を有効化 Aktywuj zaawansowane rzucanie Aktiviere erweitertes Wurfsystem 고급 투척 활성화 @@ -52,7 +52,7 @@ Enables advanced throwing system. Activa el Lanzamiento Avanzado Включает систему улучшенного броска. - アドバンスド投擲は高度な投擲システムを有効化します。 + 高度な投擲システムを有効化します。 Aktywuje system zaawansowanego rzucania. Aktiviert das erweiterte Wurfsystem. 고급 투척을 활성화 합니다 @@ -144,7 +144,7 @@ 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. 땅에 떨어진 투척물을 주울 수 있게 해줍니다. @@ -174,7 +174,7 @@ 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. 부착된 투척물을 주울 수 있게 해줍니다. @@ -185,6 +185,26 @@ 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 @@ -234,7 +254,7 @@ Primed Preparado Подготовлена - 点火 + を点火した Odbezpieczony Scharf gemacht 뇌관 작동 diff --git a/addons/ai/XEH_postInit.sqf b/addons/ai/XEH_postInit.sqf index fce5152e3d0..7c4f79f8fb3 100644 --- a/addons/ai/XEH_postInit.sqf +++ b/addons/ai/XEH_postInit.sqf @@ -16,7 +16,7 @@ } forEach _sections; }] call CBA_fnc_addEventHandler; -[QGVAR(unGarrison), FUNC(unGarrison)] call CBA_fnc_addEventHandler; +[QGVAR(unGarrison), LINKFUNC(unGarrison)] call CBA_fnc_addEventHandler; [QGVAR(doMove), { params ["_unitsArray"]; @@ -73,6 +73,6 @@ if (isServer) then { ["CAManBase", "init", { // wait for HMD to be assigned so `hmd _unit` works - [FUNC(assignNVG), _this, 1] call CBA_fnc_waitAndExecute; + [LINKFUNC(assignNVG), _this, 1] call CBA_fnc_waitAndExecute; }] call CBA_fnc_addClassEventHandler; }; diff --git a/addons/ai/functions/fnc_drawCuratorGarrisonPathing.sqf b/addons/ai/functions/fnc_drawCuratorGarrisonPathing.sqf index 561c8748a65..8a312d95cc5 100644 --- a/addons/ai/functions/fnc_drawCuratorGarrisonPathing.sqf +++ b/addons/ai/functions/fnc_drawCuratorGarrisonPathing.sqf @@ -16,10 +16,11 @@ */ if (isNull findDisplay 312) exitWith { + //IGNORE_PRIVATE_WARNING ["_thisEventHandler"]; removeMissionEventHandler ["Draw3D", _thisEventHandler]; }; -private _unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; +private _unitMoveList = missionNamespace getVariable [QGVAR(garrison_unitMoveList), []]; { _x params ["_unit", "_pos"]; @@ -27,9 +28,9 @@ private _unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveLis 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]]; + 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]; + 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}) : { @@ -43,7 +44,7 @@ private _unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveLis 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]; + 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}) : { diff --git a/addons/ai/functions/fnc_garrison.sqf b/addons/ai/functions/fnc_garrison.sqf index 0f9613dd9fe..042c4fde3cb 100644 --- a/addons/ai/functions/fnc_garrison.sqf +++ b/addons/ai/functions/fnc_garrison.sqf @@ -26,14 +26,14 @@ params [["_startingPos",[0,0,0], [[]], 3], ["_buildingTypes", ["Building"], [[]] TRACE_6("fnc_garrison: Start",_startingPos,_buldingTypes,count _unitsArray,_fillingRadius,_fillingTYpe,_topDownFilling); _unitsArray = _unitsArray select {alive _x && {!isPlayer _x}}; -private _currentUnitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; +private _currentUnitMoveList = missionNamespace getVariable [QGVAR(garrison_unitMoveList), []]; if (_startingPos isEqualTo [0,0,0]) exitWith { TRACE_1("fnc_garrison: StartingPos error",_startingPos); [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); }; @@ -57,38 +57,38 @@ if (_topDownFilling) then { // Those reverse are necessary, as dumb as it is there's no better way to sort those subarrays in sqf { reverse _x; - } foreach _buildingPos; + } forEach _buildingPos; _buildingPos sort false; { reverse _x; - } foreach _buildingPos; + } forEach _buildingPos; _buildingsIndex pushBack _buildingPos; - } foreach _buildings; + } forEach _buildings; } else { { _buildingsIndex pushBack (_x buildingPos -1); - } foreach _buildings; + } forEach _buildings; }; // Remove buildings without positions { _buildingsIndex deleteAt (_buildingsIndex find _x); -} foreach (_buildingsIndex select {count _x == 0}); +} forEach (_buildingsIndex select {count _x == 0}); //Remove positions units are already pathing to _buildingsIndex = _buildingsIndex apply { _x select { private _testedPos = _x; - ({(_x select 1) isEqualTo _testedPos} count (missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []])) == 0 + ({(_x select 1) isEqualTo _testedPos} count (missionNamespace getVariable [QGVAR(garrison_unitMoveList), []])) == 0 } }; // Warn the user that there's not enough positions to place all units private _count = 0; -{_count = _count + count _x} foreach _buildingsIndex; +{_count = _count + count _x} forEach _buildingsIndex; if ( (count _unitsArray) - _count > 0) then { TRACE_4("fnc_garrison: Not enough spots to place all units",_unitsArray,count _unitsArray,_count,((count _unitsArray) - _count > 0)); [LSTRING(GarrisonNotEnoughPos)] call EFUNC(common,displayTextStructured); @@ -104,7 +104,7 @@ private _fnc_comparePos = { params ["_nearestUnits", "_pos"]; ({ if (surfaceIsWater getPos _x) then { - floor ((getPosASL _x) select 2) == floor ((AGLtoASL _pos) select 2) + floor ((getPosASL _x) select 2) == floor ((AGLToASL _pos) select 2) } else { floor ((getPosATL _x) select 2) == floor (_pos select 2) }; @@ -141,7 +141,7 @@ switch (_fillingType) do { if (_teleport) then { doStop _unit; if (_posSurface) then { - _unit setPosASL (AGLtoASL _pos); + _unit setPosASL (AGLToASL _pos); } else { _unit setPosATL _pos; }; @@ -190,7 +190,7 @@ switch (_fillingType) do { if (_teleport) then { doStop _unit; if (_posSurface) then { - _unit setPosASL (AGLtoASL _pos); + _unit setPosASL (AGLToASL _pos); } else { _unit setPosATL _pos; }; @@ -237,7 +237,7 @@ switch (_fillingType) do { if (_teleport) then { doStop _unit; if (_posSurface) then { - _unit setPosASL (AGLtoASL _pos); + _unit setPosASL (AGLToASL _pos); } else { _unit setPosATL _pos; }; @@ -261,7 +261,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); // Update the unit list and remove duplicate positions and units -private _garrison_unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; +private _garrison_unitMoveList = missionNamespace getVariable [QGVAR(garrison_unitMoveList), []]; _garrison_unitMoveList = _garrison_unitMoveList select { _x params ["_testedUnit", "_testedPos"]; @@ -270,7 +270,7 @@ _garrison_unitMoveList = _garrison_unitMoveList select { _garrison_unitMoveList append _unitMoveList; -missionNameSpace setVariable [QGVAR(garrison_unitMoveList), _garrison_unitMoveList, true]; +missionNamespace setVariable [QGVAR(garrison_unitMoveList), _garrison_unitMoveList, true]; if (_teleport) then { [QGVAR(AISection), [_placedUnits, ["PATH"], false], _placedUnits] call CBA_fnc_targetEvent; diff --git a/addons/ai/functions/fnc_garrisonMove.sqf b/addons/ai/functions/fnc_garrisonMove.sqf index 4d1c471a0ea..46313f12e38 100644 --- a/addons/ai/functions/fnc_garrisonMove.sqf +++ b/addons/ai/functions/fnc_garrisonMove.sqf @@ -31,21 +31,21 @@ private _unitMoveListUnits = (_unitMoveList apply {_x select 0}); { _x setVariable [QGVAR(garrisonMove_failSafe), nil, true]; _x setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true]; -} foreach _unitMoveListUnits; +} forEach _unitMoveListUnits; // Avoid duplicate PFHs if (isNil QGVAR(garrison_moveUnitPFH)) then { - missionNameSpace setVariable [QGVAR(garrison_moveUnitPFH), true, true]; + missionNamespace setVariable [QGVAR(garrison_moveUnitPFH), true, true]; // PFH checking if the units have reached their destination [{ params ["_args", "_pfhID"]; - private _unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; + private _unitMoveList = missionNamespace getVariable [QGVAR(garrison_unitMoveList), []]; // End PFH if all units are placed / unable to reach position if (_unitMoveList isEqualTo []) then { - missionNameSpace setVariable [QGVAR(garrison_moveUnitPFH), nil, true]; + missionNamespace setVariable [QGVAR(garrison_moveUnitPFH), nil, true]; LOG("garrisonMove PFH: PFH finished it's job | deleting PFH"); _pfhID call CBA_fnc_removePerFrameHandler; @@ -91,7 +91,7 @@ if (isNil QGVAR(garrison_moveUnitPFH)) then { } else { private _unitPos = getPos _unit; - if (surfaceisWater _unitPos) then { + if (surfaceIsWater _unitPos) then { _unitPos = getPosASL _unit; } else { _unitPos = getPosATL _unit; @@ -131,9 +131,9 @@ if (isNil QGVAR(garrison_moveUnitPFH)) then { }; }; }; - } foreach _unitMoveList; + } forEach _unitMoveList; - missionNameSpace setVariable [QGVAR(garrison_unitMoveList), _unitMoveList, true]; + missionNamespace setVariable [QGVAR(garrison_unitMoveList), _unitMoveList, true]; }; }, 0.5, []] call CBA_fnc_addPerFrameHandler; }; diff --git a/addons/ai/functions/fnc_unGarrison.sqf b/addons/ai/functions/fnc_unGarrison.sqf index 09ebc3e63da..f17d9aa4ab7 100644 --- a/addons/ai/functions/fnc_unGarrison.sqf +++ b/addons/ai/functions/fnc_unGarrison.sqf @@ -32,7 +32,7 @@ _units = _units select {local _x}; _unit setVariable [QGVAR(garrisonned), false, true]; - private _unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; + private _unitMoveList = missionNamespace getVariable [QGVAR(garrison_unitMoveList), []]; _unitMoveList deleteAt (_unitMoveList findIf {_x select 0 == _unit}); if (_leader != _unit) then { @@ -43,9 +43,9 @@ _units = _units select {local _x}; _unit doMove ((nearestBuilding (getPos _unit)) buildingExit 0); }; - if ((units _unit) findif {(_x getVariable [QGVAR(garrisonned), false]) && !isPlayer _x} == -1) then { + if ((units _unit) findIf {(_x getVariable [QGVAR(garrisonned), false]) && !isPlayer _x} == -1) then { LOG("fnc_ungarrison: enableAttack true"); (group _unit) enableAttack true; }; }; -} foreach _units; +} forEach _units; diff --git a/addons/ai/stringtable.xml b/addons/ai/stringtable.xml index 821d42fd271..b9df8bb35a1 100644 --- a/addons/ai/stringtable.xml +++ b/addons/ai/stringtable.xml @@ -91,6 +91,7 @@ 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! @@ -101,7 +102,8 @@ 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Не добавляет ПНВ в инвентарь! + Экипирует ПНВ в ночное время и отключает его в дневное время.\nНе добавляет ПНВ в инвентарь! + Equipa las gafas de visión nocturna en el inventario cuando es de noche, y las desequipa cuando es de día.\nNo añade las gafas al inventario! diff --git a/addons/aircraft/functions/fnc_canShowEject.sqf b/addons/aircraft/functions/fnc_canShowEject.sqf index 08c55eb781c..9239c413a73 100644 --- a/addons/aircraft/functions/fnc_canShowEject.sqf +++ b/addons/aircraft/functions/fnc_canShowEject.sqf @@ -30,6 +30,6 @@ _vehicle == vehicle _unit if (_unit == _x select FULLCREW_UNIT) exitWith { _ejectVarName = format [QGVAR(ejectAction_%1_%2), _x select FULLCREW_ROLE, _x select FULLCREW_TURRETPATH]; }; - } count fullCrew _vehicle; + } forEach fullCrew _vehicle; _vehicle getVariable [_ejectVarName, false] } diff --git a/addons/aircraft/functions/fnc_droneAddActions.sqf b/addons/aircraft/functions/fnc_droneAddActions.sqf index 38ca53e4c64..895004f0e96 100644 --- a/addons/aircraft/functions/fnc_droneAddActions.sqf +++ b/addons/aircraft/functions/fnc_droneAddActions.sqf @@ -22,7 +22,7 @@ if (!alive _vehicle) exitWith {}; if (_vehicle getVariable [QGVAR(droneActionsAdded), false]) exitWith {}; _vehicle setVariable [QGVAR(droneActionsAdded), true]; -// move to location +// Move to location private _condition = { params ["_vehicle"]; (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} @@ -37,14 +37,63 @@ private _action = [QGVAR(droneSetWaypointMove), localize "$STR_AC_MOVE", "\a3\3DEN\Data\CfgWaypoints\Move_ca.paa", _statement, _condition] call EFUNC(interact_menu,createAction); [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); +// Follow unit/vehicle at turret location +_condition = { + params ["_vehicle"]; + private _target = cursorTarget; + (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} && {!isNull _target} && {["CAManBase", "LandVehicle", "Ship"] findIf {_target isKindOf _x} != -1} +}; +_statement = { + params ["_vehicle"]; + private _group = group driver _vehicle; + private _pos = ([_vehicle, [0]] call FUNC(droneGetTurretTargetPos)) select 0; + [QGVAR(droneSetWaypoint), [_vehicle, _group, _pos, "FOLLOW", cursorTarget], _group] call CBA_fnc_targetEvent; + private _followDistance = _vehicle getVariable [QGVAR(wpFollowDistance), 0]; + [[LLSTRING(DroneFollowHint), _followDistance], 3] call EFUNC(common,displayTextStructured); +}; +_action = [QGVAR(droneSetWaypointFollow), localize "$STR_AC_FOLLOW", "\a3\3DEN\Data\CfgWaypoints\Follow_ca.paa", _statement, _condition] call EFUNC(interact_menu,createAction); +[_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); + +// Set drone follow distance +_condition = { + params ["_vehicle"]; + private _group = group driver _vehicle; + private _index = (currentWaypoint _group) min count waypoints _group; + private _waypoint = [_group, _index]; + (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} && {(waypointType _waypoint) == "HOLD"} +}; +_statement = { + params ["_vehicle", "", "_value"]; + _vehicle setVariable [QGVAR(wpFollowDistance), _value]; + [[LLSTRING(DroneFollowHint), _value], 3] call EFUNC(common,displayTextStructured); +}; +_action = [QGVAR(droneSetFollowDistance), LLSTRING(DroneFollowDistance), "", {}, _condition] call EFUNC(interact_menu,createAction); +private _base = [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); +private _followDistances = if (_vehicle isKindOf "Car_F") then { + [0, 25, 50, 100, 200] +} else { + [0, 100, 200, 300, 400, 500] +}; +{ + _action = [ + QGVAR(droneSetFollowDistance_) + str _x, + str _x, + "", + _statement, + {true}, + {}, + _x + ] call EFUNC(interact_menu,createAction); + [_vehicle, 1, _base, _action] call EFUNC(interact_menu,addActionToObject); +} forEach _followDistances; if (_vehicle isKindOf "Air") then { - // loiter at location + // Loiter at location _condition = { params ["_vehicle"]; (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} }; - _statement = { + _statement = { params ["_vehicle"]; private _group = group driver _vehicle; private _pos = ([_vehicle, [0]] call FUNC(droneGetTurretTargetPos)) select 0; @@ -55,7 +104,7 @@ if (_vehicle isKindOf "Air") then { [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); - // set height + // Set height _condition = { params ["_vehicle"]; (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} @@ -74,7 +123,7 @@ if (_vehicle isKindOf "Air") then { } forEach [20, 50, 200, 500, 2000]; - // set loiter radius + // Set loiter radius _condition = { params ["_vehicle"]; private _group = group driver _vehicle; @@ -97,7 +146,7 @@ if (_vehicle isKindOf "Air") then { } forEach [500, 750, 1000, 1250, 1500]; - // set loiter direction + // Set loiter direction _condition = { params ["_vehicle", "", "_args"]; private _group = group driver _vehicle; diff --git a/addons/aircraft/functions/fnc_droneModifyWaypoint.sqf b/addons/aircraft/functions/fnc_droneModifyWaypoint.sqf index 868a0d0f8b3..b85e5565871 100644 --- a/addons/aircraft/functions/fnc_droneModifyWaypoint.sqf +++ b/addons/aircraft/functions/fnc_droneModifyWaypoint.sqf @@ -17,13 +17,13 @@ * * Public: No */ - + params ["_vehicle", "_group", "_type", "_value"]; TRACE_4("droneModifyWaypoint",_vehicle,_group,_type,_value); private _index = (currentWaypoint _group) min count waypoints _group; private _waypoint = [_group, _index]; -switch (toLower _type) do { +switch (toLowerANSI _type) do { case ("height"): { private _pos = waypointPosition _waypoint; _pos set [2, _value]; diff --git a/addons/aircraft/functions/fnc_droneSetWaypoint.sqf b/addons/aircraft/functions/fnc_droneSetWaypoint.sqf index 5ffbbae825f..45c18c63da2 100644 --- a/addons/aircraft/functions/fnc_droneSetWaypoint.sqf +++ b/addons/aircraft/functions/fnc_droneSetWaypoint.sqf @@ -8,6 +8,7 @@ * 1: Group * 2: Pos 2D * 3: Type + * 4: Target to follow (default: objNull) * * Return Value: * None @@ -18,7 +19,7 @@ * Public: No */ -params ["_vehicle", "_group", "_pos", "_type"]; +params ["_vehicle", "_group", "_pos", "_type", ["_target", objNull]]; TRACE_4("droneSetWaypoint",_vehicle,_group,_pos,_type); private _index = (currentWaypoint _group) min count waypoints _group; @@ -34,9 +35,36 @@ _pos set [ [0, _currentHeight] select (_currentHeight >= 50) ]; -// [_group] call CBA_fnc_clearWaypoints; _waypoint = _group addWaypoint [_pos, 0]; -_waypoint setWaypointType _type; +// The Vanilla "FOLLOW"-type waypoint is not used directly, due to 2 main issues (as of v2.16): +// - It does not work at all for UGVs, which is a known issue https://feedback.bistudio.com/T126283; +// - No clear scripting way was found to mimic the UAV Terminal's "Follow Distance" functionality; +// Instead, the solution for both UAV and UGV following consists of a CBA PFH that moves a "HOLD"-type Waypoint every 3 seconds. +// Either on the target itself, or on the Drone's current position if the target is within the desired follow distance. +if (_type == "FOLLOW" && {["CAManBase", "LandVehicle", "Ship"] findIf {_target isKindOf _x} != -1}) then { + _waypoint setWaypointType "HOLD"; + [{ + params ["_args", "_handle"]; + _args params ["_vehicle", "_group", "_waypoint", "_target"]; + + if ( // Abort PFH if a new waypoint is created via UAV Terminal or ACE Interaction + _waypoint select 1 != currentWaypoint _group || + {!alive _vehicle} || {isNull _target} + ) exitWith { + deleteWaypoint _waypoint; + [_handle] call CBA_fnc_removePerFrameHandler; + }; + + private _followDistance = _vehicle getVariable [QGVAR(wpFollowDistance), 0]; + if ((_vehicle distance2D _target) < _followDistance) then { + _waypoint setWaypointPosition [getPosASL _vehicle, -1]; + } else { + _waypoint setWaypointPosition [getPosASL _target, -1]; + }; + }, 3, [_vehicle, _group, _waypoint, _target]] call CBA_fnc_addPerFrameHandler; +} else { + _waypoint setWaypointType _type; +}; TRACE_3("",_currentHeight,_currentLoiterRadius,_currentLoiterType); if (_currentHeight > 1) then { _vehicle flyInHeight _currentHeight; }; diff --git a/addons/aircraft/stringtable.xml b/addons/aircraft/stringtable.xml index c0cef87756f..9cddd7ec1ad 100644 --- a/addons/aircraft/stringtable.xml +++ b/addons/aircraft/stringtable.xml @@ -129,7 +129,7 @@ 30mm コンバット ミックス 4:1 劣化ウラン徹甲弾:焼夷榴弾 30mm Bojový Mix 4:1 DU:HEI 30мм Смешанное боепитание 4:1 ОУ:ОФЗ - 30mm 4:1 열화:고폭소이 + 30mm 열화우라늄:고폭소이 4:1 혼합 30mm Mix de Combate 4:1 DU:AEI @@ -145,7 +145,7 @@ 30mm CM 4:1 30mm BM 4:1 30мм СБ 4:1 - 30mm CM 4:1 + 30mm 4:1 혼합 30mm Combat Mix 5:1 DU:HEI @@ -160,7 +160,7 @@ 30mm コンバット ミックス 5:1 劣化ウラン徹甲弾:焼夷榴弾 30mm Bojový Mix 5:1 DU:HEI 30мм Смешанное боепитание 5:1 ОУ:ОФЗ - 30mm 5:1 열화:고폭소이 + 30mm 열화우라늄:고폭소이 5:1 혼합 30mm CM 5:1 @@ -175,7 +175,27 @@ 30mm CM 5:1 30mm BM 5:1 30мм СБ 5:1 - 30mm CM 5:1 + 30mm 5:1 혼합 + + + Follow Distance + Distanza di seguimento + Folge-Entfernung + 따라가는 거리 + Distance de suivi + 追跡距離 + Расстояние отслеживания + Distancia de Seguimiento + + + Following unit within %1m + Seguendo unità entro %1m + Folgt Einheit bis zu %1m + %1m 이내로 유닛을 따라갑니다 + Suivre l'unité jusqu'à %1m + %1m 間隔で 目標を追跡します + Отслеживание в пределах %1m + Seguir unidad a %1m diff --git a/addons/arsenal/ACE_Arsenal_Stats.hpp b/addons/arsenal/ACE_Arsenal_Stats.hpp index 7748d1bdc56..08566854478 100644 --- a/addons/arsenal/ACE_Arsenal_Stats.hpp +++ b/addons/arsenal/ACE_Arsenal_Stats.hpp @@ -123,7 +123,9 @@ class GVAR(stats) { stats[] = {"maximumLoad"}; displayName = "$STR_a3_rscdisplayarsenal_stat_load"; showBar = 1; + showText = 1; barStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_3([ARR_2(0,500)],[ARR_2(0.01,1)],false)])] call FUNC(statBarStatement_default)); + textStatement = QUOTE(call FUNC(statTextStatement_load)); tabs[] = {{3,4,5}, {}}; }; class ACE_smokeChemTTL: statBase { diff --git a/addons/arsenal/XEH_PREP.hpp b/addons/arsenal/XEH_PREP.hpp index 61b713fe9fd..d0819056f25 100644 --- a/addons/arsenal/XEH_PREP.hpp +++ b/addons/arsenal/XEH_PREP.hpp @@ -78,6 +78,7 @@ PREP(removeStat); PREP(removeVirtualItems); PREP(renameDefaultLoadout); PREP(replaceUniqueItemsLoadout); +PREP(saveLoadout); PREP(scanConfig); PREP(showItem); PREP(sortPanel); @@ -98,6 +99,7 @@ PREP(statBarStatement_rateOfFIre); PREP(statTextStatement_accuracy); PREP(statTextStatement_explosionTime); PREP(statTextStatement_illuminators); +PREP(statTextStatement_load); PREP(statTextStatement_magCount); PREP(statTextStatement_mass); PREP(statTextStatement_rateOfFire); diff --git a/addons/arsenal/XEH_preInit.sqf b/addons/arsenal/XEH_preInit.sqf index 10cc3989e94..248fc16db2c 100644 --- a/addons/arsenal/XEH_preInit.sqf +++ b/addons/arsenal/XEH_preInit.sqf @@ -85,10 +85,10 @@ private _insigniaCondition = toString { // Ref fnc_addListBoxItem, 0/nil = configFile, 1 = campaignConfigFile, 2 = missionConfigFile { - GVAR(insigniaCache) set [_x, 1]; + GVAR(insigniaCache) set [configName _x, 1]; } forEach (_insigniaCondition configClasses (campaignConfigFile >> "CfgUnitInsignia")); { - GVAR(insigniaCache) set [_x, 2]; + GVAR(insigniaCache) set [configName _x, 2]; } forEach (_insigniaCondition configClasses (missionConfigFile >> "CfgUnitInsignia")); ADDON = true; diff --git a/addons/arsenal/defines.hpp b/addons/arsenal/defines.hpp index cd6d937426a..10a599af0d4 100644 --- a/addons/arsenal/defines.hpp +++ b/addons/arsenal/defines.hpp @@ -3,17 +3,23 @@ #define GRID_W (pixelW * pixelGridNoUIScale * pixelScale) #define GRID_H (pixelH * pixelGridNoUIScale * pixelScale) -#define WIDTH_TOTAL (safezoneW - 2 * (93 * GRID_W)) +#define WIDTH_TOTAL (safeZoneW - 2 * (93 * GRID_W)) #define WIDTH_GAP (WIDTH_TOTAL / 100) #define WIDTH_SINGLE ((WIDTH_TOTAL - 7 * WIDTH_GAP) / 6) // IDDs +#ifndef IDD_MISSION #define IDD_MISSION 46 +#endif #define IDD_RSCDISPLAYCURATOR 312 #define IDD_DISPLAY3DEN 313 +#ifndef IDC_OK #define IDC_OK 1 // emulate "OK" button +#endif +#ifndef IDC_CANCEL #define IDC_CANCEL 2 // emulate "Cancel" button +#endif // Sorting #define ASCENDING 0 @@ -154,6 +160,8 @@ #define IDC_statsPreviousPage 52 #define IDC_statsNextPage 53 #define IDC_statsCurrentPage 54 +#define IDC_statsBoxTitleBackground 55 +#define IDC_statsBoxBackground 56 #define IDC_actionsBox 90 #define IDC_actionsBackground1 90010 #define IDC_actionsBackground2 90011 @@ -360,10 +368,10 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ {\ _x = _display displayCtrl _x;\ _x ctrlSetPosition [\ - safezoneX + safezoneW - 93 * GRID_W,\ - safezoneY + 14 * GRID_H,\ + safeZoneX + safeZoneW - 93 * GRID_W,\ + safeZoneY + 14 * GRID_H,\ 80 * GRID_W,\ - safezoneH - 28 * GRID_H\ + safeZoneH - 28 * GRID_H\ ];\ _x ctrlCommit 0;\ } forEach [\ @@ -406,10 +414,10 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ {\ _x = _display displayCtrl _x;\ _x ctrlSetPosition [\ - safezoneX + safezoneW - 93 * GRID_W,\ - safezoneY + 14 * GRID_H,\ + safeZoneX + safeZoneW - 93 * GRID_W,\ + safeZoneY + 14 * GRID_H,\ 80 * GRID_W,\ - safezoneH - 34 * GRID_H\ + safeZoneH - 34 * GRID_H\ ];\ _x ctrlCommit 0;\ } forEach [\ @@ -426,16 +434,16 @@ if (!isNil QGVAR(customRightPanelButtons)) then {\ 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\ + 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];\ + private _ctrl = _display ctrlCreate [QGVAR(customArsenalButton_Button), 61 + _plusId];\ _ctrl ctrlSetPosition [\ - safezoneW + safezoneX - 10 * GRID_W,\ - safezoneY + (88 + (10 * _forEachIndex)) * GRID_H\ + safeZoneW + safeZoneX - 10 * GRID_W,\ + safeZoneY + (88 + (10 * _forEachIndex)) * GRID_H\ ];\ _ctrl ctrlSetText _picture;\ _ctrl ctrlSetTooltip _tooltip;\ @@ -446,8 +454,8 @@ if (!isNil QGVAR(customRightPanelButtons)) then {\ {\ _x = _display displayCtrl _x;\ _x ctrlSetPosition [\ - safezoneW + safezoneX - (10 + (3 * _forEachIndex)) * GRID_W,\ - safezoneY + (88 + (10 * _miscOffset)) * GRID_H\ + safeZoneW + safeZoneX - (10 + (3 * _forEachIndex)) * GRID_W,\ + safeZoneY + (88 + (10 * _miscOffset)) * GRID_H\ ];\ _x ctrlCommit 0;\ } forEach [IDC_buttonMisc, IDC_iconBackgroundMisc];\ diff --git a/addons/arsenal/functions/fnc_addListBoxItem.sqf b/addons/arsenal/functions/fnc_addListBoxItem.sqf index 4368eb6ea1a..777b1efe875 100644 --- a/addons/arsenal/functions/fnc_addListBoxItem.sqf +++ b/addons/arsenal/functions/fnc_addListBoxItem.sqf @@ -22,7 +22,7 @@ params ["_configCategory", "_className", "_ctrlPanel", ["_pictureEntryName", "picture", [""]], ["_configRoot", 0, [0]]]; -private _skip = GVAR(favoritesOnly) && {!(_className in GVAR(currentItems))} && {!((toLower _className) in GVAR(favorites))}; +private _skip = GVAR(favoritesOnly) && {!(_className in GVAR(currentItems))} && {!((toLowerANSI _className) in GVAR(favorites))}; if (_skip) then { switch (GVAR(currentLeftPanel)) do { case IDC_buttonPrimaryWeapon: { @@ -58,7 +58,7 @@ _ctrlPanel lbSetPicture [_lbAdd, _itemPicture]; _ctrlPanel lbSetPictureRight [_lbAdd, ["", _modPicture] select GVAR(enableModIcons)]; _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _className]]; -if ((toLower _className) in GVAR(favorites)) then { +if ((toLowerANSI _className) in GVAR(favorites)) then { _ctrlPanel lbSetColor [_lbAdd, FAVORITES_COLOR]; _ctrlPanel lbSetSelectColor [_lbAdd, FAVORITES_COLOR]; }; diff --git a/addons/arsenal/functions/fnc_addRightPanelButton.sqf b/addons/arsenal/functions/fnc_addRightPanelButton.sqf index 6e1035a86a6..a1bdb09d1d1 100644 --- a/addons/arsenal/functions/fnc_addRightPanelButton.sqf +++ b/addons/arsenal/functions/fnc_addRightPanelButton.sqf @@ -66,7 +66,8 @@ _items = _items select { _x isKindOf ["CBA_MiscItem", _cfgWeapons] && {getNumber (_configItemInfo >> "type") in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD]} || {getNumber (_configItemInfo >> "type") in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || {getText (_cfgWeapons >> _x >> "simulation") == "ItemMineDetector"} || - {getNumber (_cfgMagazines >> _x >> "ACE_isUnique") == 1} + {getNumber (_cfgMagazines >> _x >> "ACE_isUnique") == 1} || + {getNumber (_cfgMagazines >> _x >> "ACE_asItem") == 1} }; GVAR(customRightPanelButtons) set [_position, [_items apply {_x call EFUNC(common,getConfigName)}, _picture, _tooltip, _moveOnOverwrite]]; diff --git a/addons/arsenal/functions/fnc_baseAttachment.sqf b/addons/arsenal/functions/fnc_baseAttachment.sqf index 2cee699ba68..1d6155c9ee2 100644 --- a/addons/arsenal/functions/fnc_baseAttachment.sqf +++ b/addons/arsenal/functions/fnc_baseAttachment.sqf @@ -22,10 +22,18 @@ TRACE_1("looking up base attachment",_item); private _switchableClasses = []; -private _cfgWeapons = configfile >> "CfgWeapons"; +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} diff --git a/addons/arsenal/functions/fnc_baseWeapon.sqf b/addons/arsenal/functions/fnc_baseWeapon.sqf index abeb0e0ab9b..2b1b219e65c 100644 --- a/addons/arsenal/functions/fnc_baseWeapon.sqf +++ b/addons/arsenal/functions/fnc_baseWeapon.sqf @@ -20,7 +20,7 @@ params [["_weapon", "", [""]]]; // Check if item is cached (uiNamespace getVariable QGVAR(baseWeaponNameCache)) getOrDefaultCall [toLowerANSI _weapon, { - private _cfgWeapons = configfile >> "CfgWeapons"; + private _cfgWeapons = configFile >> "CfgWeapons"; private _config = _cfgWeapons >> _weapon; // If class doesn't exist, exit diff --git a/addons/arsenal/functions/fnc_buttonExport.sqf b/addons/arsenal/functions/fnc_buttonExport.sqf index 3e5039a5040..abf7c7d6fcb 100644 --- a/addons/arsenal/functions/fnc_buttonExport.sqf +++ b/addons/arsenal/functions/fnc_buttonExport.sqf @@ -26,28 +26,27 @@ if (GVAR(shiftState)) then { switch (true) do { // Beginning case (_index == -1): { - "ace_clipboard" callExtension (format ["[%1", endl]); + "ace" callExtension ["clipboard:append", [format ["[%1", endl]]]; }; // End case (_index == _listLength): { - "ace_clipboard" callExtension "];"; + "ace" callExtension ["clipboard:append", ["];"]]; }; // Rest default { - "ace_clipboard" callExtension ([" ", str (GVAR(defaultLoadoutsList) select _index), [",", ""] select (_index == _listLength - 1), endl] joinString ""); + "ace" callExtension ["clipboard:append", [[" ", str (GVAR(defaultLoadoutsList) select _index), [",", ""] select (_index == _listLength - 1), endl] joinString ""]]; }; }; }; - "ace_clipboard" callExtension "--COMPLETE--"; + "ace" callExtension ["clipboard:complete", []]; [_display, LLSTRING(exportDefault)] call FUNC(message); } else { // Export singular loadout private _export = str (GVAR(center) call CBA_fnc_getLoadout); - - "ace_clipboard" callExtension (_export + ";"); - "ace_clipboard" callExtension "--COMPLETE--"; + "ace" callExtension ["clipboard:append", [_export]]; + "ace" callExtension ["clipboard:complete", []]; [_display, LLSTRING(exportCurrent)] call FUNC(message); }; diff --git a/addons/arsenal/functions/fnc_buttonImport.sqf b/addons/arsenal/functions/fnc_buttonImport.sqf index 8a83fe3ff0c..494bf159daa 100644 --- a/addons/arsenal/functions/fnc_buttonImport.sqf +++ b/addons/arsenal/functions/fnc_buttonImport.sqf @@ -16,7 +16,13 @@ params ["_display"]; // Can be either a singular loadout or an array of loadouts -private _extendedLoadout = call compile copyFromClipboard; +private _extendedLoadout = if (isMultiplayer) then { + ("ace" callExtension ["clipboard:loadout", []]) params ["_loadout", "_code"]; + if (_code != 0) exitWith {}; + parseSimpleArray _loadout +} else { + call compile copyFromClipboard +}; // If error, exit if (isNil "_extendedLoadout" || {!(_extendedLoadout isEqualType [])}) exitWith { diff --git a/addons/arsenal/functions/fnc_fillRightPanel.sqf b/addons/arsenal/functions/fnc_fillRightPanel.sqf index 09f986708d0..d8dc7e24031 100644 --- a/addons/arsenal/functions/fnc_fillRightPanel.sqf +++ b/addons/arsenal/functions/fnc_fillRightPanel.sqf @@ -53,7 +53,7 @@ if (GVAR(favoritesOnly)) then { private _fnc_fillRightContainer = { params ["_configCategory", "_className", ["_isUnique", false, [false]], ["_unknownOrigin", false, [false]]]; - if (GVAR(favoritesOnly) && {!(_className in _currentCargo)} && {!((toLower _className) in GVAR(favorites))}) exitWith {}; + if (GVAR(favoritesOnly) && {!(_className in _currentCargo)} && {!((toLowerANSI _className) in GVAR(favorites))}) exitWith {}; // If item is not in the arsenal, it must be unique if (!_isUnique && {!(_className in GVAR(virtualItemsFlat))}) then { @@ -89,7 +89,7 @@ private _fnc_fillRightContainer = { _ctrlPanel lnbSetPicture [[_lbAdd, 0], _picture]; _ctrlPanel lnbSetValue [[_lbAdd, 2], parseNumber _isUnique]; _ctrlPanel lnbSetTooltip [[_lbAdd, 0], format ["%1\n%2", _displayName, _className]]; - if ((toLower _className) in GVAR(favorites)) then { + if ((toLowerANSI _className) in GVAR(favorites)) then { _ctrlPanel lnbSetColor [[_lbAdd, 1], FAVORITES_COLOR]; _ctrlPanel lnbSetColorRight [[_lbAdd, 1], FAVORITES_COLOR]; }; diff --git a/addons/arsenal/functions/fnc_handleStats.sqf b/addons/arsenal/functions/fnc_handleStats.sqf index b5d435a101e..0511c05a25a 100644 --- a/addons/arsenal/functions/fnc_handleStats.sqf +++ b/addons/arsenal/functions/fnc_handleStats.sqf @@ -19,6 +19,8 @@ params ["_display", "_control", "_curSel", ["_itemCfg", configNull]]; private _statsBoxCtrl = _display displayCtrl IDC_statsBox; +private _statsBoxTitleBackgroundCtrl = _display displayCtrl IDC_statsBoxTitleBackground; +private _statsBoxBackgroundCtrl = _display displayCtrl IDC_statsBoxBackground; private _statsPreviousPageCtrl = _display displayCtrl IDC_statsPreviousPage; private _statsNextPageCtrl = _display displayCtrl IDC_statsNextPage; private _statsCurrentPageCtrl = _display displayCtrl IDC_statsCurrentPage; @@ -53,7 +55,7 @@ private _fnc_hideEverything = { // Hide the stats box _statsBoxCtrl ctrlSetPosition [ (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, - safezoneY + 1.8 * GRID_H, + safeZoneY + 1.8 * GRID_H, 0, 0 ]; @@ -62,7 +64,7 @@ private _fnc_hideEverything = { // Move action display private _ctrl = _display displayCtrl IDC_actionsBox; private _pos = ctrlPosition _ctrl; - _pos set [1, safezoneY + 1.8 * GRID_H]; + _pos set [1, safeZoneY + 1.8 * GRID_H]; _ctrl ctrlSetPosition _pos; _ctrl ctrlCommit 0; @@ -111,6 +113,7 @@ private _fnc_handleStats = { private _statsBarCtrl = controlNull; private _statsTextCtrl = controlNull; private _textStatementResult = ""; + private _lastCtrl = _statsBoxTitleBackgroundCtrl; { _x params ["", "_configEntry", "_title", "_bools", "_statements"]; @@ -127,6 +130,17 @@ private _fnc_handleStats = { _statsTitleCtrl ctrlSetText _title; _statsTitleCtrl ctrlSetFade 0; + // Vertical Position + ctrlPosition _lastCtrl params ["", "_lastPosY", "", "_lastPosH"]; + _statsTitleCtrl ctrlSetPositionY (_lastPosY + _lastPosH + GRID_H); + { + _x ctrlSetPositionY (_lastPosY + _lastPosH + GRID_H + (5 * GRID_H)); + } forEach [ + _statsBackgroundCtrl, + _statsBarCtrl, + _statsTextCtrl + ]; + // Handle bars if (_showBar) then { _statsBarCtrl progressSetPosition ([_configEntry, _itemCfg] call _barStatement); @@ -140,18 +154,39 @@ private _fnc_handleStats = { // Handle text entries if (_showText) then { _textStatementResult = [_configEntry, _itemCfg] call _textStatement; - - if !(_textStatementResult isEqualtype "") then { - _textStatementResult = str _textStatementResult; + if (_textStatementResult isEqualType []) then { + _textStatementResult = _textStatementResult joinString endl; + } else { + if !(_textStatementResult isEqualType "") then { + _textStatementResult = str _textStatementResult; + }; }; _statsTextCtrl ctrlSetText _textStatementResult; _statsTextCtrl ctrlSetTextColor ([[1, 1, 1, 1], [0, 0, 0, 1]] select (_showBar)); + + //Height based on Text lines + { + _x ctrlSetPositionH (ctrlTextHeight _statsTextCtrl); + } forEach [ + _statsBackgroundCtrl, + _statsBarCtrl, + _statsTextCtrl + ]; + _statsTextCtrl ctrlSetFade 0; } else { _statsTextCtrl ctrlSetFade 1; + //Ensure default height + { + _x ctrlSetPositionH (5 * GRID_H); + } forEach [ + _statsBackgroundCtrl, + _statsBarCtrl, + _statsTextCtrl + ]; }; - + { _x ctrlCommit 0; } forEach [ @@ -160,24 +195,29 @@ private _fnc_handleStats = { _statsBarCtrl, _statsTextCtrl ]; + + _lastCtrl = _statsTextCtrl; + } forEach _statsToDisplay; // Resize the window (5 - _statsCount) call _fnc_hideUnused; - private _height = 10 * _statsCount + 5; + ctrlPosition _lastCtrl params ["", "_lastPosY", "", "_lastPosH"]; _statsBoxCtrl ctrlSetPosition [ (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, - safezoneY + 1.8 * GRID_H, + safeZoneY + 1.8 * GRID_H, 47 * GRID_W, - _height * GRID_H + _lastPosY + _lastPosH + GRID_H ]; + _statsBoxBackgroundCtrl ctrlSetPositionH (_lastPosY + _lastPosH + GRID_H); + _statsBoxBackgroundCtrl ctrlCommit 0; _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]; + _pos set [1, safeZoneY + (_lastPosY + _lastPosH + GRID_H + (3.6 * GRID_H))]; _ctrl ctrlSetPosition _pos; _ctrl ctrlCommit 0; diff --git a/addons/arsenal/functions/fnc_itemInfo.sqf b/addons/arsenal/functions/fnc_itemInfo.sqf index 676783a8b54..f99de009053 100644 --- a/addons/arsenal/functions/fnc_itemInfo.sqf +++ b/addons/arsenal/functions/fnc_itemInfo.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" -#include "..\defines.hpp" #include "\a3\ui_f\hpp\defineResincl.inc" +#include "..\defines.hpp" /* * Author: Alganthe, johnb43 * Update arsenal's info box. @@ -32,11 +32,11 @@ if (isClass _itemCfg) then { (_display displayCtrl IDC_infoName) ctrlSetText ([_control lbText _curSel, _control lnbText [_curSel, 1]] select (ctrlType _control == CT_LISTNBOX)); private _itemAuthor = getText (_itemCfg >> "author"); - (_display displayctrl IDC_infoAuthor) 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 _ctrlDLC = _display displayCtrl IDC_DLCIcon; + private _ctrlDLCBackground = _display displayCtrl IDC_DLCBackground; private _dlc = _itemCfg call EFUNC(common,getAddon); if (_dlc != "") then { @@ -48,7 +48,7 @@ if (isClass _itemCfg) then { _ctrlDLC ctrlSetFade 0; // 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 { + 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 [ diff --git a/addons/arsenal/functions/fnc_message.sqf b/addons/arsenal/functions/fnc_message.sqf index b20689f6b9c..5d2846bafc6 100644 --- a/addons/arsenal/functions/fnc_message.sqf +++ b/addons/arsenal/functions/fnc_message.sqf @@ -25,6 +25,7 @@ if (!isNil "_handle") then { }; _handle = [_display, _messageBoxCtrl, time + 5, _message, FADE_DELAY] spawn { + //IGNORE_PRIVATE_WARNING ["_thisScript"]; disableSerialization; params ["_display", "_control", "_timer", "_message", "_delay"]; diff --git a/addons/arsenal/functions/fnc_onArsenalClose.sqf b/addons/arsenal/functions/fnc_onArsenalClose.sqf index 2cce9b13eed..6803d2d5de5 100644 --- a/addons/arsenal/functions/fnc_onArsenalClose.sqf +++ b/addons/arsenal/functions/fnc_onArsenalClose.sqf @@ -18,7 +18,7 @@ (_this select 1) params ["", "_exitCode"]; [QGVAR(displayClosed), []] call CBA_fnc_localEvent; -removeMissionEventHandler ["draw3D", GVAR(camPosUpdateHandle)]; +removeMissionEventHandler ["Draw3D", GVAR(camPosUpdateHandle)]; if (is3DEN) then { private _centerOriginParent = objectParent GVAR(centerOrigin); @@ -78,10 +78,10 @@ if (!isNull curatorCamera) then { // Make face and voice selection JIP compatible; 3DEN doesn't need this though if (isMultiplayer && {!is3DEN}) then { - private _id = [QGVAR(broadcastFace), [GVAR(center), GVAR(currentFace)], QGVAR(centerFace_) + netId GVAR(center)] call CBA_fnc_globalEventJIP; + private _id = [QGVAR(broadcastFace), [GVAR(center), GVAR(currentFace)], QGVAR(centerFace_) + hashValue GVAR(center)] call CBA_fnc_globalEventJIP; [_id, GVAR(center)] call CBA_fnc_removeGlobalEventJIP; - _id = [QGVAR(broadcastVoice), [GVAR(center), GVAR(currentVoice)], QGVAR(centerVoice_) + netId GVAR(center)] call CBA_fnc_globalEventJIP; + _id = [QGVAR(broadcastVoice), [GVAR(center), GVAR(currentVoice)], QGVAR(centerVoice_) + hashValue GVAR(center)] call CBA_fnc_globalEventJIP; [_id, GVAR(center)] call CBA_fnc_removeGlobalEventJIP; }; diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf index f307c932b13..2a2d8716c84 100644 --- a/addons/arsenal/functions/fnc_onArsenalOpen.sqf +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -121,7 +121,7 @@ _mouseBlockCtrl ctrlEnable false; private _statsBoxCtrl = _display displayCtrl IDC_statsBox; _statsBoxCtrl ctrlSetPosition [ (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, - safezoneY + 1.8 * GRID_H, + safeZoneY + 1.8 * GRID_H, 47 * GRID_W, 11 * GRID_H ]; @@ -132,20 +132,12 @@ _statsBoxCtrl ctrlCommit 0; private _actionsBoxCtrl = _display displayCtrl IDC_actionsBox; _actionsBoxCtrl ctrlSetPosition [ (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, - safezoneY + 58.6 * GRID_H, + safeZoneY + 58.6 * GRID_H, 47 * GRID_W, 11 * GRID_H ]; _actionsBoxCtrl ctrlCommit 0; -// Disable import in MP -if (isMultiplayer) then { - private _importButtonCtrl = _display displayCtrl IDC_buttonImport; - _importButtonCtrl ctrlEnable false; - _importButtonCtrl ctrlSetFade 0.6; - _importButtonCtrl ctrlCommit 0; -}; - //--------------- Camera prep cutText ["", "PLAIN"]; showCommandingMenu ""; @@ -278,4 +270,4 @@ showCinemaBorder false; //--------------- Reset camera pos [nil, [controlNull, 0, 0]] call FUNC(handleMouse); -GVAR(camPosUpdateHandle) = addMissionEventHandler ["draw3D", {call FUNC(updateCamPos)}]; +GVAR(camPosUpdateHandle) = addMissionEventHandler ["Draw3D", {call FUNC(updateCamPos)}]; diff --git a/addons/arsenal/functions/fnc_onKeyDown.sqf b/addons/arsenal/functions/fnc_onKeyDown.sqf index 4d62075f78f..fe69bb3486d 100644 --- a/addons/arsenal/functions/fnc_onKeyDown.sqf +++ b/addons/arsenal/functions/fnc_onKeyDown.sqf @@ -94,8 +94,8 @@ if (!isNull _loadoutsDisplay) then { }; } params ["_className"]; - "ace_clipboard" callExtension (_className + ";"); - "ace_clipboard" callExtension "--COMPLETE--"; + "ace" callExtension ["clipboard:append", [_className]]; + "ace" callExtension ["clipboard:complete", []]; [_display, LLSTRING(exportedClassnameText)] call FUNC(message); } else { diff --git a/addons/arsenal/functions/fnc_onPanelDblClick.sqf b/addons/arsenal/functions/fnc_onPanelDblClick.sqf index 032d87534bb..e9e639ecaeb 100644 --- a/addons/arsenal/functions/fnc_onPanelDblClick.sqf +++ b/addons/arsenal/functions/fnc_onPanelDblClick.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" -#include "..\defines.hpp" #include "\a3\ui_f\hpp\defineResincl.inc" +#include "..\defines.hpp" /* * Author: LinkIsGrim * Add or remove item(s) to favorites when LShift is pressed @@ -27,9 +27,9 @@ private _favorited = false; // Favorites/blacklist will always be lowercase to handle configCase changes private _item = ""; if (_isLnB) then { - _item = toLower (_control lnbData [_curSel, 0]); + _item = toLowerANSI (_control lnbData [_curSel, 0]); } else { - _item = toLower (_control lbData _curSel); + _item = toLowerANSI (_control lbData _curSel); }; if (_item in GVAR(favorites)) then { diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index 5bf08245c88..05b86358f80 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" -#include "..\defines.hpp" #include "\a3\ui_f\hpp\defineResincl.inc" +#include "..\defines.hpp" /* * Author: Alganthe, johnb43 * Handles selection changes on the left panel. @@ -17,7 +17,7 @@ params ["_control", "_curSel"]; -if (_curSel < 0) exitwith {}; +if (_curSel < 0) exitWith {}; private _display = ctrlParent _control; private _item = [_control lbData _curSel, _control lnbData [_curSel, 0]] select (ctrlType _control == CT_LISTNBOX); @@ -33,6 +33,7 @@ private _fnc_clearCurrentWeaponMags = { // If nothing was selected, remove all magazines from the current weapon if (_item != "") then { + //IGNORE_PRIVATE_WARNING ["_compatibleMags"]; _compatibleMagsCurrentWeapon = _compatibleMagsCurrentWeapon - _compatibleMags; }; @@ -382,6 +383,9 @@ switch (GVAR(currentLeftPanel)) do { }; GVAR(currentItems) set [IDX_CURR_VEST, _item]; + + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; }; TOGGLE_RIGHT_PANEL_CONTAINER @@ -420,6 +424,9 @@ switch (GVAR(currentLeftPanel)) do { }; GVAR(currentItems) set [IDX_CURR_BACKPACK, _item]; + + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; }; TOGGLE_RIGHT_PANEL_CONTAINER diff --git a/addons/arsenal/functions/fnc_onSelChangedRight.sqf b/addons/arsenal/functions/fnc_onSelChangedRight.sqf index ccb29887651..66315f7dc79 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRight.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRight.sqf @@ -16,7 +16,7 @@ params ["_control", "_curSel"]; -if (_curSel < 0) exitwith {}; +if (_curSel < 0) exitWith {}; private _display = ctrlParent _control; private _item = _control lbData _curSel; @@ -69,7 +69,14 @@ switch (_currentItemsIndex) do { // Secondary weapon case IDX_CURR_SECONDARY_WEAPON_ITEMS: { private _currentItemInSlot = (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select _itemIndex; - private _isDisposable = CBA_disposable_replaceDisposableLauncher && {!isNil {CBA_disposable_loadedLaunchers getVariable (secondaryWeapon GVAR(center))}}; + private _isDisposable = CBA_disposable_replaceDisposableLauncher && {!isNil "CBA_disposable_loadedLaunchers"} && + { + if (CBA_disposable_loadedLaunchers isEqualType createHashMap) then { // after CBA 3.18 + (secondaryWeapon GVAR(center)) in CBA_disposable_loadedLaunchers + } else { + !isNil {CBA_disposable_loadedLaunchers getVariable (secondaryWeapon player)} + } + }; // If removal if (_item == "") then { diff --git a/addons/arsenal/functions/fnc_removeSort.sqf b/addons/arsenal/functions/fnc_removeSort.sqf index 3957257a6d5..a5e9fb1d777 100644 --- a/addons/arsenal/functions/fnc_removeSort.sqf +++ b/addons/arsenal/functions/fnc_removeSort.sqf @@ -31,7 +31,7 @@ private _tabToChange = []; _stringCount = count _currentID; // Make sure to keep at least 1 sort per category, so make default sort not deletable - if ("ace_alphabetically" in toLower (_currentID select [0, _stringCount - 3])) then { + if ("ace_alphabetically" in toLowerANSI (_currentID select [0, _stringCount - 3])) then { continue; }; diff --git a/addons/arsenal/functions/fnc_saveLoadout.sqf b/addons/arsenal/functions/fnc_saveLoadout.sqf new file mode 100644 index 00000000000..05e712e45f6 --- /dev/null +++ b/addons/arsenal/functions/fnc_saveLoadout.sqf @@ -0,0 +1,37 @@ +#include "..\script_component.hpp" +/* + * Author: DartRuffian + * Saves a given loadout to the client's profile. + * + * Arguments: + * 0: Name of loadout + * 1: CBA extended loadout or getUnitLoadout array + * 2: Replace existing loadout (default: false) + * + * Return Value: + * True if loadout was saved, otherwise false + * + * Example: + * ["Current Loadout", getUnitLoadout ACE_player] call ace_arsenal_fnc_saveLoadout + * + * Public: Yes + */ + +params [["_name", "", [""]], ["_loadout", [], [[]]], ["_replaceExisting", false, [false]]]; + +if (_name == "" || {_loadout isEqualTo []}) exitWith { false }; + +private _loadouts = profileNamespace getVariable [QGVAR(saved_loadouts), []]; +private _loadoutIndex = _loadouts findIf {(_x#0) == _name}; + +// If a loadout with same name already exists and no overwriting enabled, quit +if (!_replaceExisting && {_loadoutIndex != -1}) exitWith { false }; + +if (_loadoutIndex == -1) then { + _loadouts pushBack [_name, _loadout]; +} else { + _loadouts set [_loadoutIndex, [_name, _loadout]]; +}; + +profileNamespace setVariable [QGVAR(saved_loadouts), _loadouts]; +true diff --git a/addons/arsenal/functions/fnc_scanConfig.sqf b/addons/arsenal/functions/fnc_scanConfig.sqf index 105eb3479a4..b5c6627cc7a 100644 --- a/addons/arsenal/functions/fnc_scanConfig.sqf +++ b/addons/arsenal/functions/fnc_scanConfig.sqf @@ -160,7 +160,7 @@ private _magazineMiscItems = createHashMap; { _magazineMiscItems set [configName _x, nil]; -} forEach ((toString {getNumber (_x >> "ACE_isUnique") == 1}) configClasses _cfgMagazines); +} forEach ((toString {getNumber (_x >> "ACE_isUnique") == 1 || getNumber (_x >> "ACE_asItem") == 1}) configClasses _cfgMagazines); // Remove invalid/non-existent entries _grenadeList deleteAt ""; @@ -228,10 +228,10 @@ private _faceCategory = ""; _faceCache set [configName _x, [getText (_x >> "displayName"), _modPicture, _faceCategory]]; }; } forEach ("true" configClasses _x); -} forEach ("true" configClasses (configfile >> "CfgFaces")); +} forEach ("true" configClasses (configFile >> "CfgFaces")); // Get all voices -private _voiceCache = (configProperties [configFile >> "CfgVoice", "isClass _x && {getNumber (_x >> 'scope') == 2}", true]) - [configfile >> "CfgVoice" >> "NoVoice"]; +private _voiceCache = (configProperties [configFile >> "CfgVoice", "isClass _x && {getNumber (_x >> 'scope') == 2}", true]) - [configFile >> "CfgVoice" >> "NoVoice"]; _voiceCache = _voiceCache apply {configName _x}; // Get all insignia diff --git a/addons/arsenal/functions/fnc_showItem.sqf b/addons/arsenal/functions/fnc_showItem.sqf index 7ceda5f0d54..f47f12d2bf4 100644 --- a/addons/arsenal/functions/fnc_showItem.sqf +++ b/addons/arsenal/functions/fnc_showItem.sqf @@ -72,6 +72,6 @@ if (_nextAction != GVAR(currentAction)) then { GVAR(currentAction) = _nextAction; }; -if (!(GVAR(currentAction) in ["Civil", "Salute"])) then { +if !(GVAR(currentAction) in ["Civil", "Salute"]) then { GVAR(center) selectWeapon ([primaryWeapon GVAR(center), secondaryWeapon GVAR(center), handgunWeapon GVAR(center), binocular GVAR(center)] select GVAR(selectedWeaponType)); // select correct weapon, prevents floating weapons }; diff --git a/addons/arsenal/functions/fnc_sortPanel.sqf b/addons/arsenal/functions/fnc_sortPanel.sqf index 7a8a8978eba..e47ece9d17b 100644 --- a/addons/arsenal/functions/fnc_sortPanel.sqf +++ b/addons/arsenal/functions/fnc_sortPanel.sqf @@ -155,6 +155,7 @@ private _for = if (_right) then { for "_i" from 0 to (lbSize _panel) - 1 }; +//IGNORE_PRIVATE_WARNING ["_i"]; _for do { // Get item _item = if (_right) then { @@ -244,7 +245,7 @@ _for do { // Sort alphabetically, find the previously selected item and select it again if (_right) then { - [_panel, 1] lnbSortBy ["TEXT", _sortDirection == ASCENDING, false, true, false]; + [_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 @@ -258,7 +259,7 @@ if (_right) then { }; }; } else { - _panel lbSortBy ["TEXT", _sortDirection == ASCENDING, false, true, false]; + _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; diff --git a/addons/arsenal/functions/fnc_sortStatement_mod.sqf b/addons/arsenal/functions/fnc_sortStatement_mod.sqf index ab945202171..063aba0dbc4 100644 --- a/addons/arsenal/functions/fnc_sortStatement_mod.sqf +++ b/addons/arsenal/functions/fnc_sortStatement_mod.sqf @@ -14,4 +14,9 @@ params ["_config"]; -(modParams [_config call EFUNC(common,getAddon), ["name"]]) param [0, ""] +private _addon = _config call EFUNC(common,getAddon); + +// Calling modParams with "" prints 'ModParams - Undefined or empty mod directory' in RPT +if (_addon == "") exitWith {""}; + +(modParams [_addon, ["name"]]) param [0, ""] diff --git a/addons/arsenal/functions/fnc_statTextStatement_binoVisionMode.sqf b/addons/arsenal/functions/fnc_statTextStatement_binoVisionMode.sqf index 6da45345f41..df4260ba1ae 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_binoVisionMode.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_binoVisionMode.sqf @@ -17,7 +17,7 @@ params ["", "_config"]; TRACE_1("statTextStatement_binoVisionMode",_config); private _text = []; -private _visionModes = getArray (_config >> "visionMode") apply {toLower _x}; +private _visionModes = getArray (_config >> "visionMode") apply {toLowerANSI _x}; { if (_x in _visionModes) then { _text pushBack (localize ([LSTRING(VisionNormal), LSTRING(VisionNight), LSTRING(VisionThermal)] select _forEachIndex)); diff --git a/addons/arsenal/functions/fnc_statTextStatement_load.sqf b/addons/arsenal/functions/fnc_statTextStatement_load.sqf new file mode 100644 index 00000000000..a7a132b1844 --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_load.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Text statement for the load stat. + * + * Arguments: + * 0: Stats + * 1: Item config path + * + * Return Value: + * Stat Text + * + * Public: No +*/ + +params ["_stats", "_config"]; +TRACE_2("statTextStatement_load",_stats,_config); + +if (!isNull (_config >> "ItemInfo" >> "containerClass")) then { // Uniform/Vest + _config = configFile >> "CfgVehicles" >> getText (_config >> "ItemInfo" >> "containerClass"); +}; + +private _load = getNumber (_config >> (_stats # 0)); + +if (_load <= 0) exitWith { LELSTRING(common,none) }; +format ["%1kg (%2lb)", (_load * 0.1 * (1 / 2.2046)) toFixed 2, (_load * 0.1) toFixed 2] diff --git a/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf b/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf index b4de06e7721..7348be5bc36 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf @@ -17,7 +17,7 @@ params ["", "_config"]; TRACE_1("statTextStatement_scopeVisionMode",_config); private _opticsModes = ("true" configClasses (_config >> "ItemInfo" >> "OpticsModes")) apply { - private _visionMode = getArray (_x >> "visionMode") apply {toLower _x}; + private _visionMode = getArray (_x >> "visionMode") apply {toLowerANSI _x}; [ getNumber (_x >> "useModelOptics") == 1, // Is in optics _visionMode isEqualTo [], // Optional NVG diff --git a/addons/arsenal/functions/fnc_verifyLoadout.sqf b/addons/arsenal/functions/fnc_verifyLoadout.sqf index 53e7221e3a8..10cd9a25539 100644 --- a/addons/arsenal/functions/fnc_verifyLoadout.sqf +++ b/addons/arsenal/functions/fnc_verifyLoadout.sqf @@ -22,6 +22,10 @@ private _extendedInfo = createHashMap; // 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; }; diff --git a/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf b/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf index a93611d3291..502f7b888dc 100644 --- a/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf +++ b/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf @@ -63,7 +63,7 @@ _target switchMove "amovpercmstpslowwrfldnon"; _target setVariable ["origin", _position]; // When killed, respawn AI -_target addEventHandler ["killed", { +_target addEventHandler ["Killed", { params ["_target"]; // Killed may fire twice, 2nd will be null - https://github.com/acemod/ACE3/pull/7561 diff --git a/addons/arsenal/stringtable.xml b/addons/arsenal/stringtable.xml index 081f5cecf47..38f41ef4a61 100644 --- a/addons/arsenal/stringtable.xml +++ b/addons/arsenal/stringtable.xml @@ -23,7 +23,7 @@ Masque l'interface Oberfläche verstecken Ukryj interfejs - インターフェースを隠す + インタフェースを隠す Nascondi interfaccia 인터페이스 숨기기 隱藏介面 @@ -1191,7 +1191,7 @@ 支持夜视仪 Podpora nočního vidění Gece Görüş Desteği - 야간투시 지원여부 + 야간투시 지원 Primary supported @@ -1206,7 +1206,7 @@ 主武器支援 主镜支持 Hlavní část hledí podporuje - 주무기 지원여부 + 주무기 지원 Secondary supported @@ -1221,7 +1221,7 @@ 次要武器支援 副镜支持 Vedlejší část hledí podporuje - 보조무기 지원여부 + 보조무기 지원 Primary integrated @@ -1236,17 +1236,27 @@ 整合主武器 主镜内置 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 @@ -1603,6 +1613,7 @@ Décroissant Decrescente Нисходящий + Descendiente Ascending @@ -1614,6 +1625,7 @@ Croissant Crescente Восходящий + Ascendiente Tools @@ -1641,6 +1653,7 @@ Nombre de munitions Quantidade de munição Количество боеприпасов + Cantidad de munición Illuminators @@ -1651,6 +1664,7 @@ Iluminadores イルミネーター Осветители + Iluminadores Default to Favorites @@ -1662,6 +1676,7 @@ Favoris par défaut Favoritos por padrão По умолчанию - Избранное + Favoritos por defecto Controls whether the ACE Arsenal defaults to showing all items or favorites. @@ -1673,6 +1688,7 @@ 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 @@ -1684,6 +1700,7 @@ Couleurs favorites Cor dos favoritos Избранный цвет + Color de Favoritos Highlight color for favorited items. @@ -1695,6 +1712,7 @@ 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. @@ -1706,6 +1724,7 @@ 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 @@ -1714,6 +1733,8 @@ 検索\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 dc70caa0c27..b487cffd617 100644 --- a/addons/arsenal/ui/RscAttributes.hpp +++ b/addons/arsenal/ui/RscAttributes.hpp @@ -15,14 +15,14 @@ class GVAR(display) { class ControlsBackground { class blackLeft: ctrlStatic { colorBackground[] = {0,0,0,1}; - x = QUOTE(safezoneXAbs); - y = QUOTE(safezoneY); - w = QUOTE(safezoneXAbs - safezoneX); - h = QUOTE(safezoneH); + x = QUOTE(safeZoneXAbs); + y = QUOTE(safeZoneY); + w = QUOTE(safeZoneXAbs - safeZoneX); + h = QUOTE(safeZoneH); }; class blackRight: blackLeft { - x = QUOTE(safezoneX + safezoneW); + x = QUOTE(safeZoneX + safeZoneW); }; class mouseArea: ctrlStatic { @@ -31,10 +31,10 @@ class GVAR(display) { 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); - h = QUOTE(safezoneH); + x = QUOTE(safeZoneX); + y = QUOTE(safeZoneY); + w = QUOTE(safeZoneW); + h = QUOTE(safeZoneH); }; }; class controls { @@ -58,34 +58,34 @@ class GVAR(display) { }; class blockLeftFrame: RscFrame { idc = IDC_blockLeftFrame; - x = QUOTE(safezoneX + 13 * GRID_W); - y = QUOTE(safezoneY + 14 * GRID_H); + x = QUOTE(safeZoneX + 13 * GRID_W); + y = QUOTE(safeZoneY + 14 * GRID_H); w = QUOTE(80 * GRID_W); - h = QUOTE(safezoneH - 24 * GRID_H); + h = QUOTE(safeZoneH - 24 * GRID_H); colorText[] = {0,0,0,1}; }; class blockLeftBackground: ctrlStaticBackground { idc = IDC_blockLeftBackground; - x = QUOTE(safezoneX + 13 * GRID_W); - y = QUOTE(safezoneY + 14 * GRID_H); + x = QUOTE(safeZoneX + 13 * GRID_W); + y = QUOTE(safeZoneY + 14 * GRID_H); w = QUOTE(80 * GRID_W); - h = QUOTE(safezoneH - 24 * GRID_H); + h = QUOTE(safeZoneH - 24 * GRID_H); colorBackground[] = {0,0,0,0.5}; }; class blockRightFrame: blockLeftFrame { idc = IDC_blockRightFrame; - x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); - h = QUOTE(safezoneH - 34 * GRID_H); + x = QUOTE(safeZoneX + safeZoneW - 93 * GRID_W); + h = QUOTE(safeZoneH - 34 * GRID_H); }; class blockRighttBackground: blockLeftBackground { idc = IDC_blockRighttBackground; - x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); - h = QUOTE(safezoneH - 34 * GRID_H); + x = QUOTE(safeZoneX + safeZoneW - 93 * GRID_W); + h = QUOTE(safeZoneH - 34 * GRID_H); }; class loadIndicator: RscControlsGroupNoScrollbars { idc = IDC_loadIndicator; - x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); - y = QUOTE(safeZoneH + safezoneY - 20 * GRID_H); + x = QUOTE(safeZoneX + safeZoneW - 93 * GRID_W); + y = QUOTE(safeZoneH + safeZoneY - 20 * GRID_H); w = QUOTE(80 * GRID_W); h = QUOTE(6 * GRID_H); class controls { @@ -112,8 +112,8 @@ class GVAR(display) { }; class totalWeight: RscControlsGroupNoScrollbars { idc = IDC_totalWeight; - x = QUOTE(safezoneX + 13 * GRID_W); - y = QUOTE(safeZoneH + safezoneY - 10 * GRID_H); + x = QUOTE(safeZoneX + 13 * GRID_W); + y = QUOTE(safeZoneH + safeZoneY - 10 * GRID_H); w = QUOTE(80 * GRID_W); h = QUOTE(8 * GRID_H); class controls { @@ -154,7 +154,7 @@ class GVAR(display) { colorBackground[] = {0,0,0,0.69999999}; text = ""; x = QUOTE(0.5 - WIDTH_TOTAL / 2); - y = QUOTE(safeZoneH + safezoneY - 25 * GRID_H); + y = QUOTE(safeZoneH + safeZoneY - 25 * GRID_H); w = QUOTE(WIDTH_TOTAL); h = QUOTE(10 * GRID_H); sizeEx = QUOTE(5 * GRID_H); @@ -162,7 +162,7 @@ class GVAR(display) { class menuBar: RscControlsGroupNoScrollbars { idc = IDC_menuBar; x = QUOTE(0.5 - WIDTH_TOTAL / 2); - y = QUOTE(safezoneH + safezoneY - 9 * GRID_H); + y = QUOTE(safeZoneH + safeZoneY - 9 * GRID_H); w = QUOTE(WIDTH_TOTAL); h = QUOTE(7 * GRID_H); class controls { @@ -223,8 +223,8 @@ class GVAR(display) { class infoBox: RscControlsGroupNoScrollbars { idc = IDC_infoBox; fade = 1; - x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); - y = QUOTE(safeZoneH + safezoneY - 14 * GRID_H); + x = QUOTE(safeZoneX + safeZoneW - 93 * GRID_W); + y = QUOTE(safeZoneH + safeZoneY - 14 * GRID_H); w = QUOTE(92 * GRID_W); h = QUOTE(12 * GRID_H); class controls { @@ -278,12 +278,12 @@ class GVAR(display) { class statsBox: RscControlsGroupNoScrollbars { idc = IDC_statsBox; x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP); - y = QUOTE(safezoneY + 1.8 * GRID_H); + y = QUOTE(safeZoneY + 1.8 * GRID_H); w = QUOTE(47 * GRID_W); h = QUOTE(55 * GRID_H); class controls { class statsStaticBackground1: ctrlStaticBackground { - idc = -1; + idc = IDC_statsBoxBackground; x = QUOTE(0); y = QUOTE(0); w = QUOTE(47 * GRID_W); @@ -291,7 +291,7 @@ class GVAR(display) { colorBackground[] = {0.1,0.1,0.1,0.5}; }; class statsStaticBackground2: ctrlStaticBackground { - idc = -1; + idc = IDC_statsBoxTitleBackground; x = QUOTE(0); y = QUOTE(0); w = QUOTE(47 * GRID_W); @@ -316,7 +316,7 @@ class GVAR(display) { x = QUOTE(1 * GRID_W); y = QUOTE(10 * GRID_H); w = QUOTE(45 * GRID_W); - h = QUOTE(4 * GRID_H); + h = QUOTE(5 * GRID_H); colorBackground[] = {1,1,1,0.15}; }; class statsBar1: ctrlProgress { @@ -329,9 +329,9 @@ class GVAR(display) { x = QUOTE(1 * GRID_W); y = QUOTE(10 * GRID_H); w = QUOTE(45 * GRID_W); - h = QUOTE(4 * GRID_H); + h = QUOTE(5 * GRID_H); }; - class statsText1: RscText { + class statsText1: RscTextMulti { idc = IDC_statsText1; shadow = 0; fade = 1; @@ -340,7 +340,7 @@ class GVAR(display) { x = QUOTE(0 * GRID_W); y = QUOTE(10 * GRID_H); w = QUOTE(45 * GRID_W); - h = QUOTE(4 * GRID_H); + h = QUOTE(5 * GRID_H); sizeEx = QUOTE(5 * GRID_H); text = ""; }; @@ -419,7 +419,7 @@ class GVAR(display) { 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); + y = QUOTE(safeZoneY + 1.8 * GRID_H); w = QUOTE(5 * GRID_W); h = QUOTE(5 * GRID_H); sizeEx = QUOTE(5.5 * GRID_H); @@ -434,7 +434,7 @@ class GVAR(display) { 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); + y = QUOTE(safeZoneY + 1.8 * GRID_H); w = QUOTE(37 * GRID_W); h = QUOTE(5 * GRID_H); colorBackground[] = {0,0,0,0}; @@ -445,7 +445,7 @@ class GVAR(display) { class actionsBox: RscControlsGroupNoScrollbars { idc = IDC_actionsBox; x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP); - y = QUOTE(safezoneY + 58.6 * GRID_H); + y = QUOTE(safeZoneY + 58.6 * GRID_H); w = QUOTE(47 * GRID_W); h = QUOTE(55 * GRID_H); class controls { @@ -482,7 +482,7 @@ class GVAR(display) { x = QUOTE(1 * GRID_W); y = QUOTE(6 * GRID_H); w = QUOTE(45 * GRID_W); - h = QUOTE(4 * GRID_H); + h = QUOTE(5 * GRID_H); }; class actionsText2: actionsText1 { idc = IDC_actionsText2; @@ -550,10 +550,10 @@ class GVAR(display) { class mouseBlock: RscText { idc = IDC_mouseBlock; style = 16; - x = QUOTE(safezoneX); - y = QUOTE(safezoneY); - w = QUOTE(safezoneW); - h = QUOTE(safezoneH); + x = QUOTE(safeZoneX); + y = QUOTE(safeZoneY); + w = QUOTE(safeZoneW); + h = QUOTE(safeZoneH); }; class leftTabContent: RscListBox { idc = IDC_leftTabContent; @@ -569,10 +569,10 @@ class GVAR(display) { onLBDblClick = QUOTE(_this call FUNC(onPanelDblClick)); onSetFocus = QUOTE(GVAR(leftTabFocus) = true); onKillFocus = QUOTE(GVAR(leftTabFocus) = false); - x = QUOTE(safezoneX + 13 * GRID_W); - y = QUOTE(safezoneY + 14 * GRID_H); + x = QUOTE(safeZoneX + 13 * GRID_W); + y = QUOTE(safeZoneY + 14 * GRID_H); w = QUOTE(80 * GRID_W); - h = QUOTE(safezoneH - 24.5 * GRID_H); + h = QUOTE(safeZoneH - 24.5 * GRID_H); sizeEx = QUOTE(7 * GRID_H); }; class rightTabContent: leftTabContent { @@ -583,8 +583,8 @@ class GVAR(display) { 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); + x = QUOTE(safeZoneX + safeZoneW - 93 * GRID_W); + h = QUOTE(safeZoneH - 28 * GRID_H); }; class rightTabContentListnBox: RscListNBox { idc = IDC_rightTabContentListnBox; @@ -605,16 +605,16 @@ class GVAR(display) { onLBDblClick = QUOTE(_this call FUNC(onPanelDblClick)); onSetFocus = QUOTE(GVAR(rightTabLnBFocus) = true); onKillFocus = QUOTE(GVAR(rightTabLnBFocus) = false); - x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); - y = QUOTE(safezoneY + 14 * GRID_H); + x = QUOTE(safeZoneX + safeZoneW - 93 * GRID_W); + y = QUOTE(safeZoneY + 14 * GRID_H); w = QUOTE(80 * GRID_W); - h = QUOTE(safezoneH - 34 * GRID_H); + h = QUOTE(safeZoneH - 34 * GRID_H); sizeEx = QUOTE(7 * GRID_H); }; class sortLeftTab: RscCombo { idc = IDC_sortLeftTab; - x = QUOTE(safezoneX + 13 * GRID_W); - y = QUOTE(safezoneY + 8 * GRID_H); + x = QUOTE(safeZoneX + 13 * GRID_W); + y = QUOTE(safeZoneY + 8 * GRID_H); w = QUOTE(40 * GRID_W); h = QUOTE(6 * GRID_H); onLBSelChanged = QUOTE(_this call FUNC(sortPanel)); @@ -622,16 +622,16 @@ class GVAR(display) { }; class sortLeftTabDirection: sortLeftTab { idc = IDC_sortLeftTabDirection; - x = QUOTE(safezoneX + 53 * GRID_W); + x = QUOTE(safeZoneX + 53 * GRID_W); w = QUOTE(40 * GRID_W); }; class sortRightTab: sortLeftTab { idc = IDC_sortRightTab; - x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); + x = QUOTE(safeZoneX + safeZoneW - 93 * GRID_W); }; class sortRightTabDirection: sortLeftTabDirection { idc = IDC_sortRightTabDirection; - x = QUOTE(safezoneX + safezoneW - 53 * GRID_W); + x = QUOTE(safeZoneX + safeZoneW - 53 * GRID_W); }; class leftSearchbar: ctrlEdit { idc = IDC_leftSearchbar; @@ -639,8 +639,8 @@ class GVAR(display) { onKillFocus = QUOTE(GVAR(leftSearchbarFocus) = false); 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); + x = QUOTE(safeZoneX + 13 * GRID_W); + y = QUOTE(safeZoneY + 1.8 * GRID_H); w = QUOTE(74 * GRID_W); h = QUOTE(6 * GRID_H); sizeEx = QUOTE(6 * GRID_H); @@ -652,8 +652,8 @@ class GVAR(display) { 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); + x = QUOTE(safeZoneX + 87 * GRID_W); + y = QUOTE(safeZoneY + 1.8 * GRID_H); w = QUOTE(6 * GRID_W); h = QUOTE(6 * GRID_H); }; @@ -661,17 +661,17 @@ class GVAR(display) { idc = IDC_rightSearchbar; onSetFocus = QUOTE(GVAR(rightSearchbarFocus) = true); onKillFocus = QUOTE(GVAR(rightSearchbarFocus) = false); - x = QUOTE(safezoneX + safezoneW - 87 * GRID_W); + x = QUOTE(safeZoneX + safeZoneW - 87 * GRID_W); }; class rightSearchbarButton: leftSearchbarButton { idc = IDC_rightSearchbarButton; 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); + x = QUOTE(safeZoneX + safeZoneW - 93 * GRID_W); }; class tabLeft: RscControlsGroupNoScrollbars { idc = IDC_tabLeft; - x = QUOTE(safezoneX + 1 * GRID_W); - y = QUOTE(safezoneY + 8 * GRID_H); + x = QUOTE(safeZoneX + 1 * GRID_W); + y = QUOTE(safeZoneY + 8 * GRID_H); w = QUOTE(12 * GRID_W); h = QUOTE(200 * GRID_H); class controls { @@ -873,8 +873,8 @@ class GVAR(display) { colorBackground[] = {0,0,0,1}; fade = 1; enable = 0; - x = QUOTE(safezoneW + safezoneX - 13 * GRID_W); - y = QUOTE(safezoneY + 8 * GRID_H); + x = QUOTE(safeZoneW + safeZoneX - 13 * GRID_W); + y = QUOTE(safeZoneY + 8 * GRID_H); w = QUOTE(12 * GRID_W); h = QUOTE(9 * GRID_H); }; @@ -884,110 +884,110 @@ class GVAR(display) { 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); + x = QUOTE(safeZoneW + safeZoneX - 10 * GRID_W); + y = QUOTE(safeZoneY + 8 * GRID_H); w = QUOTE(9 * GRID_W); h = QUOTE(9 * GRID_H); }; class iconBackgroundItemAcc: iconBackgroundOptic { idc = IDC_iconBackgroundItemAcc; - y = QUOTE(safezoneY + 18 * GRID_H); + y = QUOTE(safeZoneY + 18 * GRID_H); }; class buttonItemAcc: buttonOptic { idc = IDC_buttonItemAcc; text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemAcc_ca.paa"; tooltip = "$STR_A3_RscDisplayArsenal_tab_ItemAcc"; - y = QUOTE(safezoneY + 18 * GRID_H); + y = QUOTE(safeZoneY + 18 * GRID_H); }; class iconBackgroundMuzzle: iconBackgroundOptic { idc = IDC_iconBackgroundMuzzle; - y = QUOTE(safezoneY + 28 * GRID_H); + y = QUOTE(safeZoneY + 28 * GRID_H); }; class buttonMuzzle: buttonOptic { idc = IDC_buttonMuzzle; text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemMuzzle_ca.paa"; tooltip = "$STR_A3_RscDisplayArsenal_tab_ItemMuzzle"; - y = QUOTE(safezoneY + 28 * GRID_H); + y = QUOTE(safeZoneY + 28 * GRID_H); }; class iconBackgroundBipod: iconBackgroundOptic { idc = IDC_iconBackgroundBipod; - y = QUOTE(safezoneY + 38 * GRID_H); + y = QUOTE(safeZoneY + 38 * GRID_H); }; class buttonBipod: buttonOptic { idc = IDC_buttonBipod; text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemBipod_ca.paa"; tooltip = "$STR_A3_RscDisplayArsenal_tab_ItemBipod"; - y = QUOTE(safezoneY + 38 * GRID_H); + y = QUOTE(safeZoneY + 38 * GRID_H); }; class iconBackgroundCurrentMag: iconBackgroundOptic { idc = IDC_iconBackgroundCurrentMag; - y = QUOTE(safezoneY + 48 * GRID_H); + y = QUOTE(safeZoneY + 48 * GRID_H); }; class buttonCurrentMag: buttonOptic { idc = IDC_buttonCurrentMag; text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMag_ca.paa"; tooltip = CSTRING(buttonCurrentMagTooltip); - y = QUOTE(safezoneY + 48 * GRID_H); + y = QUOTE(safeZoneY + 48 * GRID_H); }; class iconBackgroundCurrentMag2: iconBackgroundOptic { idc = IDC_iconBackgroundCurrentMag2; - y = QUOTE(safezoneY + 58 * GRID_H); + y = QUOTE(safeZoneY + 58 * GRID_H); }; class buttonCurrentMag2: buttonOptic { idc = IDC_buttonCurrentMag2; text = QPATHTOF(data\iconSecondaryMuzzle); tooltip = CSTRING(buttonCurrentMag2Tooltip); - y = QUOTE(safezoneY + 58 * GRID_H); + y = QUOTE(safeZoneY + 58 * GRID_H); }; class iconBackgroundMag: iconBackgroundOptic { idc = IDC_iconBackgroundMag; - y = QUOTE(safezoneY + 48 * GRID_H); + y = QUOTE(safeZoneY + 48 * GRID_H); }; class buttonMag: buttonOptic { idc = IDC_buttonMag; text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMag_ca.paa"; tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoMag"; - y = QUOTE(safezoneY + 48 * GRID_H); + y = QUOTE(safeZoneY + 48 * GRID_H); }; class iconBackgroundMagALL: iconBackgroundOptic { idc = IDC_iconBackgroundMagALL; - y = QUOTE(safezoneY + 58 * GRID_H); + y = QUOTE(safeZoneY + 58 * GRID_H); }; class buttonMagALL: buttonOptic { idc = IDC_buttonMagALL; text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMagAll_ca.paa"; tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoMagAll"; - y = QUOTE(safezoneY + 58 * GRID_H); + y = QUOTE(safeZoneY + 58 * GRID_H); }; class iconBackgroundThrow: iconBackgroundOptic { idc = IDC_iconBackgroundThrow; - y = QUOTE(safezoneY + 68 * GRID_H); + y = QUOTE(safeZoneY + 68 * GRID_H); }; class buttonThrow: buttonOptic { idc = IDC_buttonThrow; text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoThrow_ca.paa"; tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoThrow"; - y = QUOTE(safezoneY + 68 * GRID_H); + y = QUOTE(safeZoneY + 68 * GRID_H); }; class iconBackgroundPut: iconBackgroundOptic { idc = IDC_iconBackgroundPut; - y = QUOTE(safezoneY + 78 * GRID_H); + y = QUOTE(safeZoneY + 78 * GRID_H); }; class buttonPut: buttonOptic { idc = IDC_buttonPut; text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoPut_ca.paa"; tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoPut"; - y = QUOTE(safezoneY + 78 * GRID_H); + y = QUOTE(safeZoneY + 78 * GRID_H); }; class iconBackgroundMisc: iconBackgroundOptic { idc = IDC_iconBackgroundMisc; - y = QUOTE(safezoneY + 88 * GRID_H); + y = QUOTE(safeZoneY + 88 * GRID_H); }; class buttonMisc: buttonOptic { idc = IDC_buttonMisc; text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMisc_ca.paa"; tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoMisc"; - y = QUOTE(safezoneY + 88 * GRID_H); + y = QUOTE(safeZoneY + 88 * GRID_H); }; class buttonRemoveAll: ctrlButtonPicture { @@ -998,8 +998,8 @@ class GVAR(display) { onButtonClick = QUOTE(ctrlParent (_this select 0) call FUNC(buttonClearAll)); fade = 1; enable = 0; - x = QUOTE(safezoneW + safezoneX - 11 * GRID_W); - y = QUOTE(safeZoneH + safezoneY - 29 * GRID_H); + x = QUOTE(safeZoneW + safeZoneX - 11 * GRID_W); + y = QUOTE(safeZoneH + safeZoneY - 29 * GRID_H); w = QUOTE(9 * GRID_W); h = QUOTE(9 * GRID_H); }; @@ -1013,17 +1013,17 @@ class GVAR(loadoutsDisplay) { class controls { class centerBox: ctrlControlsGroupNoScrollbars { idc = IDC_centerBox; - x = QUOTE(safezoneW + safezoneX - (180 * GRID_W)); - y = QUOTE(safezoneY + (5 * GRID_H)); + x = QUOTE(safeZoneW + safeZoneX - (180 * GRID_W)); + y = QUOTE(safeZoneY + (5 * GRID_H)); w = QUOTE(160 * GRID_W); - h = QUOTE(safezoneH - (34 * GRID_H)); + h = QUOTE(safeZoneH - (34 * GRID_H)); class controls { class centerFrame: RscFrame { idc = -1; x = QUOTE(0 * GRID_W); y = QUOTE(0 * GRID_H); w = QUOTE(160 * GRID_W); - h = QUOTE(safezoneH - (45 * GRID_H)); + h = QUOTE(safeZoneH - (45 * GRID_H)); colorText[] = {0,0,0,1}; }; class centerBackground: ctrlStaticBackground { @@ -1031,7 +1031,7 @@ class GVAR(loadoutsDisplay) { x = QUOTE(0); y = QUOTE(0); w = QUOTE(160 * GRID_W); - h = QUOTE(safezoneH - (45 * GRID_H)); + h = QUOTE(safeZoneH - (45 * GRID_H)); colorBackground[] = {0.13,0.13,0.13,0.9}; }; class centerTitle: ctrlStaticTitle { @@ -1056,14 +1056,14 @@ class GVAR(loadoutsDisplay) { x = QUOTE(0); y = QUOTE(5 * GRID_H); w = QUOTE(160 * GRID_W); - h = QUOTE(safezoneH - (57 * GRID_H)); + h = QUOTE(safeZoneH - (57 * GRID_H)); sizeEx = QUOTE(7 * GRID_H); }; class textTitle: RscText { idc = -1; text = "$STR_DISP_GAME_NAME"; x = QUOTE(0 * GRID_W); - y = QUOTE(safezoneH - (51 * GRID_H)); + y = QUOTE(safeZoneH - (51 * GRID_H)); w = QUOTE(15 * GRID_W); h = QUOTE(5 * GRID_H); sizeEx = QUOTE(5 * GRID_H); @@ -1072,7 +1072,7 @@ class GVAR(loadoutsDisplay) { class textEditBox: ctrlEdit { idc = IDC_textEditBox; x = QUOTE(15 * GRID_W); - y = QUOTE(safezoneH - (51 * GRID_H)); + y = QUOTE(safeZoneH - (51 * GRID_H)); w = QUOTE(65 * GRID_W); h = QUOTE(5 * GRID_H); sizeEx = QUOTE(6 * GRID_H); @@ -1083,7 +1083,7 @@ class GVAR(loadoutsDisplay) { onKillFocus = QUOTE(GVAR(loadoutsSearchbarFocus) = false); 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)); + y = QUOTE(safeZoneH - (51 * GRID_H)); w = QUOTE(72 * GRID_W); h = QUOTE(5 * GRID_H); sizeEx = QUOTE(6 * GRID_H); @@ -1094,14 +1094,14 @@ class GVAR(loadoutsDisplay) { 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)); + y = QUOTE(safeZoneH - (51 * GRID_H)); w = QUOTE(5 * GRID_W); h = QUOTE(5 * GRID_H); }; class buttonSave: ctrlButton { idc = IDC_buttonSave; x = QUOTE(0 * GRID_W); - y = QUOTE(safezoneH - (44 * GRID_H)); + y = QUOTE(safeZoneH - (44 * GRID_H)); w = QUOTE(30 * GRID_W); h = QUOTE(10 * GRID_H); text = CSTRING(buttonSaveText); @@ -1143,8 +1143,8 @@ class GVAR(loadoutsDisplay) { }; class buttonClose: ctrlButton { idc = -1; - x = QUOTE(safezoneW + safezoneX - 32 * GRID_W); - y = QUOTE(safezoneH + safezoneY - 9 * GRID_H); + 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); @@ -1154,8 +1154,8 @@ class GVAR(loadoutsDisplay) { }; class buttonBar: ctrlControlsGroupNoScrollbars { idc = -1; - x = QUOTE((safezoneW * 0.5) + safezoneX - (80.5 * GRID_W)); - y = QUOTE(safezoneH + safezoneY - 9 * GRID_H); + x = QUOTE((safeZoneW * 0.5) + safeZoneX - (80.5 * GRID_W)); + y = QUOTE(safeZoneH + safeZoneY - 9 * GRID_H); w = QUOTE(161 * GRID_W); h = QUOTE(7 * GRID_H); class controls { diff --git a/addons/arsenal/ui/RscCommon.hpp b/addons/arsenal/ui/RscCommon.hpp index f74326bcfb7..cb36a67aed3 100644 --- a/addons/arsenal/ui/RscCommon.hpp +++ b/addons/arsenal/ui/RscCommon.hpp @@ -86,12 +86,12 @@ #define TR_AUTOCOLLAPSE 2 // Default grid -#define GUI_GRID_WAbs ((safezoneW / safezoneH) min 1.2) +#define GUI_GRID_WAbs ((safeZoneW / safeZoneH) min 1.2) #define GUI_GRID_HAbs (GUI_GRID_WAbs / 1.2) #define GUI_GRID_W (GUI_GRID_WAbs / 40) #define GUI_GRID_H (GUI_GRID_HAbs / 25) -#define GUI_GRID_X (safezoneX) -#define GUI_GRID_Y (safezoneY + safezoneH - GUI_GRID_HAbs) +#define GUI_GRID_X (safeZoneX) +#define GUI_GRID_Y (safeZoneY + safeZoneH - GUI_GRID_HAbs) // Default text sizes #define GUI_TEXT_SIZE_SMALL (GUI_GRID_H * 0.8) diff --git a/addons/arsenal/ui/RscCustomArsenalButton.hpp b/addons/arsenal/ui/RscCustomArsenalButton.hpp index 0aa077f424c..e745203e7ea 100644 --- a/addons/arsenal/ui/RscCustomArsenalButton.hpp +++ b/addons/arsenal/ui/RscCustomArsenalButton.hpp @@ -1,6 +1,6 @@ class GVAR(customArsenalButton_Button): RscButtonArsenal { - x = QUOTE(safezoneW + safezoneX - 10 * GRID_W); - y = QUOTE(safezoneY + 88 * GRID_H); + x = QUOTE(safeZoneW + safeZoneX - 10 * GRID_W); + y = QUOTE(safeZoneY + 88 * GRID_H); w = QUOTE(9 * GRID_W); h = QUOTE(9 * GRID_H); @@ -11,8 +11,8 @@ class GVAR(customArsenalButton_Button): RscButtonArsenal { }; class GVAR(customArsenalButton_Background): ctrlStaticBackground { - x = QUOTE(safezoneW + safezoneX - 13 * GRID_W); - y = QUOTE(safezoneY + 88 * GRID_H); + x = QUOTE(safeZoneW + safeZoneX - 13 * GRID_W); + y = QUOTE(safeZoneY + 88 * GRID_H); w = QUOTE(12 * GRID_W); h = QUOTE(9 * GRID_H); diff --git a/addons/artillerytables/RscRangeTable.hpp b/addons/artillerytables/RscRangeTable.hpp index ef11d7eac82..a24aa503cb5 100644 --- a/addons/artillerytables/RscRangeTable.hpp +++ b/addons/artillerytables/RscRangeTable.hpp @@ -8,16 +8,16 @@ class GVAR(rangeTableDialog) { 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)"; + 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)"; + 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}; @@ -26,8 +26,8 @@ class GVAR(rangeTableDialog) { 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)"; + 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"}; @@ -48,8 +48,8 @@ class GVAR(rangeTableDialog) { }; 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)"; + 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)); @@ -58,8 +58,8 @@ class GVAR(rangeTableDialog) { 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)"; + 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)"; }; @@ -67,12 +67,12 @@ class GVAR(rangeTableDialog) { idc = IDC_BUTTON_ELEV_LOW; text = "Low"; onButtonClick = QUOTE([false] call FUNC(rangeTableUpdate)); - x = "15.6 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH) / 2)"; + 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)"; + 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}; @@ -82,8 +82,8 @@ class GVAR(rangeTableDialog) { 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)"; + 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}; diff --git a/addons/artillerytables/RscTitles.hpp b/addons/artillerytables/RscTitles.hpp index c26f302a00f..e0c4cc34495 100644 --- a/addons/artillerytables/RscTitles.hpp +++ b/addons/artillerytables/RscTitles.hpp @@ -9,10 +9,10 @@ class RscTitles { 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)"; + 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 { @@ -21,18 +21,18 @@ class RscTitles { 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)"; + 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)"; + 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)"; + x = "(5) * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; }; }; }; diff --git a/addons/artillerytables/XEH_PREP.hpp b/addons/artillerytables/XEH_PREP.hpp index 7ef48b61dd8..7f977dd6b32 100644 --- a/addons/artillerytables/XEH_PREP.hpp +++ b/addons/artillerytables/XEH_PREP.hpp @@ -1,8 +1,14 @@ TRACE_1("prep",_this); +PREP(adjustFire); +PREP(calculateElevation); +PREP(calculateMaxAngle); +PREP(calculateMuzzleVelocity); +PREP(calculateSolution); PREP(firedEH); PREP(interactMenuOpened); PREP(rangeTableOpen); PREP(rangeTableUpdate); +PREP(simulateShot); PREP(turretChanged); PREP(turretPFEH); diff --git a/addons/artillerytables/XEH_postInit.sqf b/addons/artillerytables/XEH_postInit.sqf index 4f0e2032088..0696302ea9b 100644 --- a/addons/artillerytables/XEH_postInit.sqf +++ b/addons/artillerytables/XEH_postInit.sqf @@ -4,10 +4,13 @@ TRACE_2("CBA_settingsInitialized",GVAR(advancedCorrections),GVAR(disableArtilleryComputer)); if (hasInterface) then { - // Add hud overlay for actuall azimuth and elevation: + // Add hud overlay for actual azimuth and elevation: GVAR(pfID) = -1; ["turret", LINKFUNC(turretChanged), true] call CBA_fnc_addPlayerEventHandler; + // Handles being teleported from one vehicle to another + ["vehicle", {[_this select 0, (_this select 1) unitTurret (_this select 0)] call FUNC(turretChanged)}] call CBA_fnc_addPlayerEventHandler; + // Add ability to dynamically open rangetables: ["ace_interactMenuOpened", LINKFUNC(interactMenuOpened)] call CBA_fnc_addEventHandler; }; @@ -30,6 +33,33 @@ }; }] call CBA_fnc_addEventHandler; +addMissionEventHandler ["ExtensionCallback", { + params ["_name", "_function", "_data"]; + if (_name == "ace:artillery" && {_function == "calculate_table"}) then { + (parseSimpleArray _data) params ["_line", "_data"]; + if (_data isEqualType []) then { + GVAR(tableData) set [_line, _data]; + }; + GVAR(tableSizeReceived) = GVAR(tableSizeReceived) + 1; + if (GVAR(tableSizeReceived) == GVAR(tableSizeActual)) then { + private _dialog = uiNamespace getVariable [QGVAR(rangeTableDialog), displayNull]; + private _ctrlRangeTable = _dialog displayCtrl IDC_TABLE; + if (isNull _dialog) exitWith {true}; + for "_i" from 0 to GVAR(tableSizeActual) do { + private _row = GVAR(tableData) getOrDefault [_i, []]; + if (count _row == 12) then { + _ctrlRangeTable lnbAddRow _row; + }; + }; + 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); + }; + }; +}]; + #ifdef DEBUG_MODE_FULL #include "dev\showShotInfo.inc.sqf" #include "dev\checkConfigs.inc.sqf" diff --git a/addons/artillerytables/config.cpp b/addons/artillerytables/config.cpp index 1f6fa9f74e7..5aafdfb9b2e 100644 --- a/addons/artillerytables/config.cpp +++ b/addons/artillerytables/config.cpp @@ -14,13 +14,6 @@ class CfgPatches { }; }; -class ACE_Extensions { - class ace_artillerytables { - windows = 1; - client = 1; - }; -}; - #include "CfgEventHandlers.hpp" #include "CfgMagazines.hpp" #include "CfgVehicles.hpp" diff --git a/addons/artillerytables/dev/showShotInfo.inc.sqf b/addons/artillerytables/dev/showShotInfo.inc.sqf index ac99acbdc16..6945e95ba0b 100644 --- a/addons/artillerytables/dev/showShotInfo.inc.sqf +++ b/addons/artillerytables/dev/showShotInfo.inc.sqf @@ -35,7 +35,7 @@ INFO("showing shot info"); private _diff = _lastPos vectorDiff _shootPos; _mkrB setMarkerText format ["%1", _diff apply {round _x}]; - private _dist2d = _shootPos distance2d _lastPos; + 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]; diff --git a/addons/artillerytables/functions/fnc_adjustFire.sqf b/addons/artillerytables/functions/fnc_adjustFire.sqf new file mode 100644 index 00000000000..1e07c5ca212 --- /dev/null +++ b/addons/artillerytables/functions/fnc_adjustFire.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke + * Adjusts a target point north and east, and recalculates a solution in air based on atmospheric conditions + * + * Arguments: + * 0: Gun Position ASL + * 1: Target Position ASL + * 2: Adjustment to the East (negative is West); meters + * 3: Adjustment to the North (negative is South); meters + * 4: Adjustment vertically (negative is Down); meters + * 5: Muzzle velocity; meters/second + * 6: Air Friction; meters^-1 (m/s^2)/(m^2/s^2) + * 7: High angle boolean (true is high angle) + * 8: Temperature; degrees Celsius + * 9: Atmospheric Density; kg/(meters^3) + * 10: Direction of wind; degrees clockwise from north + * 11: Speed of wind; meters/second + * + * Return Value: + * Array of returns + * 0: Angle of shot; Milliradians + * 1: Angle adjust left or right; Milliradians + * 2: Time of flight; seconds + * + * Example: + * [getposASL vehicle player, targetPos, 20, 50, 0, 200, -0.0001, true, 15, 1.225, 225, 5] call ace_artilleryTables_fnc_adjustFire + * + * Public: No + */ + +params ["_gunPos", "_targetPos", "_adjustEast", "_adjustNorth", "_adjustUp", "_muzzleVelocity", "_airFriction", ["_highAngle", true], ["_temperature", 15], ["_airDensity", 1.225], ["_windDir", 0], ["_windSpeed", 0]]; + +//DEFAULT_AIR_FRICTION == -0.00006 +//MK6_82mm_AIR_FRICTION == -0.0001 + +private _resultPos = [_adjustEast + _targetPos select 0, _adjustNorth + _targetPos select 1, _adjustUp + _targetPos select 2]; + +private _returns = [_gunPos, _resultPos, _muzzleVelocity, _highAngle, _airFriction, _temperature, _airDensity, _windDir, _windSpeed] call FUNC(calculateSolution); + +_returns diff --git a/addons/artillerytables/functions/fnc_calculateElevation.sqf b/addons/artillerytables/functions/fnc_calculateElevation.sqf new file mode 100644 index 00000000000..977253eff93 --- /dev/null +++ b/addons/artillerytables/functions/fnc_calculateElevation.sqf @@ -0,0 +1,71 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke + * Adjusts a target point north and east, and recalculates a solution in air based on atmospheric conditions + * + * Arguments: + * 0: Distance to Target; meters + * 1: Height of target; meters, relative to gun altitude (positive means target higher than gun) + * 2: Muzzle velocity; meters/second + * 3: High angle boolean (true is high angle) + * 4: Air Friction; meters^-1 [(m/s^2)/(m^2/s^2)] + * 5: Temperature; degrees Celsius + * 6: Atmospheric Density; kg/(meters^3) + * 7: Cross wind; meters/second (negative is Right to Left) + * 8: Tail wind; meters/second (negative is flying against the wind) + * + * Return Value: + * Array of returns + * 0: Angle of shot; Milliradians + * 1: Angle adjust left or right; Milliradians + * 2: Time of flight; seconds + * + * Example: + * [myPos, 0, 200, true, -0.0001, 15, 1.225, 5, -10] call ace_artilleryTables_fnc_calculateElevation + * + * Public: No + */ + +params ["_targetDistance", "_targetHeight", "_muzzleVelocity", ["_highArc", true], ["_airFriction", 0], ["_temperature", 15], ["_airDensity", 1.225], ["_crossWind", 0], ["_tailWind", 0]]; + +//DEFAULT_AIR_FRICTION == -0.00006 +//MK6_82mm_AIR_FRICTION == -0.0001 + +if (_airFriction != 0) then { + _muzzleVelocity = [_muzzleVelocity, _temperature, _airDensity] call FUNC(calculateMuzzleVelocity); +}; +private _maxResults = [_muzzleVelocity, _airFriction] call FUNC(calculateMaxAngle); + +private _testShot = [_maxResults select 0, _targetHeight, _muzzleVelocity, _airFriction, _crossWind, _tailWind, _temperature, _airDensity] call FUNC(simulateShot); +if (_testShot select 1 < _targetDistance) exitWith { + //No way we can hit it so don't bother; + [-1, -1, -1] +}; + +private _useDistance = _targetDistance; +private _useAngle = 0; +private _resultDistance = 0; +private _xDeviation = 0; +private _tof = 0; + +while {abs(_resultDistance - _targetDistance) > 0.5} do { + TRACE_7("callExtension:artillery:simulate_find_solution",_useDistance,_targetHeight,_muzzleVelocity,_airFriction,_higharc,DEFAULT_MIN_ELEV,DEFAULT_MAX_ELEV); + ( + "ace" callExtension ["artillery:simulate_find_solution", [_useDistance, _targetHeight, _muzzleVelocity, _airFriction, _higharc, DEFAULT_MIN_ELEV, DEFAULT_MAX_ELEV]] + ) params ["_data", "_code"]; + TRACE_1("",_code); + (parseSimpleArray _data) params ["", "_useAngleRad", ""]; + _useAngle = deg(_useAngleRad) * DEGTOMILS; + + private _shotResults = [_useAngle, _targetHeight, _muzzleVelocity, _airFriction, _crossWind, _tailWind, _temperature, _airDensity] call FUNC(simulateShot); + + _xDeviation = _shotResults select 0; + _resultDistance = _shotResults select 1; + _tof = _shotResults select 2; + _useDistance = (2 * _targetDistance) - _resultDistance; +}; + +private _angleOffsetDeg = _xDeviation atan2 _resultDistance; +private _angleOffset = _angleOffsetDeg * DEGTOMILS; + +[_useAngle, -_angleOffset, _tof] diff --git a/addons/artillerytables/functions/fnc_calculateMaxAngle.sqf b/addons/artillerytables/functions/fnc_calculateMaxAngle.sqf new file mode 100644 index 00000000000..9866ec4b28e --- /dev/null +++ b/addons/artillerytables/functions/fnc_calculateMaxAngle.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke + * Calculates the best possible angle to shoot farthest based on muzzle velocity and air friction. + * + * Arguments: + * 0: Initial Muzzle Velocity; meters/second + * 1: Air Friction; meters^-1 (m/s^2)/(m^2/s^2) + * + * Return Values: + * 1: Best Angle; Milliradians + * 2: Furthest Distance; Meters + * + * Example: + * [200, -0.00006] call ace_artilleryTables_fnc_calculateMaxAngle + * + * Public: No + */ + +params ["_muzzleVelocity", "_airFriction"]; + +TRACE_2("callExtension:artillery:find_max_angle",_muzzleVelocity,_airFriction); +( + "ace" callExtension ["artillery:find_max_angle", [_muzzleVelocity, _airFriction]] +) params ["_data", "_code"]; +TRACE_1("",_code); +(parseSimpleArray _data) params ["_bestAngle", "_bestDistance"]; +[deg _bestAngle * 6400 / 360, _bestDistance] // return diff --git a/addons/artillerytables/functions/fnc_calculateMuzzleVelocity.sqf b/addons/artillerytables/functions/fnc_calculateMuzzleVelocity.sqf new file mode 100644 index 00000000000..6f00f74c148 --- /dev/null +++ b/addons/artillerytables/functions/fnc_calculateMuzzleVelocity.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke + * Calculates the muzzleVelocity change with advanced calculations. + * + * Arguments: + * 0: Initial Muzzle velocity; meters/second + * 1: Temperature; degrees Celsius + * 2: Atmospheric Density; kg/(meters^3) + * + * Return Value: + * Adjusted Muzzle Velocity; Meters + * + * Example: + * [200, 15, 1.225] call ace_artilleryTables_fnc_calculateMuzzleVelocity + * + * Public: No + */ + +params ["_muzzleVelocity", "_temperature", "_airDensity"]; + +// Calculate air density +private _relativeDensity = _airDensity / 1.225; +private _newMuzzleVelocityCoefficient = (((_temperature + 273.13) / 288.13 - 1) / 40 + 1); + +private _newMuzzleVelocity = _muzzleVelocity * _newMuzzleVelocityCoefficient; + +_newMuzzleVelocity diff --git a/addons/artillerytables/functions/fnc_calculateSolution.sqf b/addons/artillerytables/functions/fnc_calculateSolution.sqf new file mode 100644 index 00000000000..13e798568c4 --- /dev/null +++ b/addons/artillerytables/functions/fnc_calculateSolution.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke + * Provides fire angle and deflection solutions on a target of set distance and height, including accounting for drag and atmospheric wind conditions. + * + * Arguments: + * 0: Gun Position ASL; + * 1: Target Position ASL; + * 2: Muzzle Velocity; meters/second + * 3: High angle boolean (true is high angle) + * 4: Air Friction; meters^-1 [(m/s^2)/(m^2/s^2)] + * 5: Temperature; degrees Celsius + * 6: Atmospheric Density; kg/(meters^3) + * 7: Direction of wind; degrees clockwise from north + * 8: Speed of wind; meters/second + * + * Return Value: + * array of returns + * 0: Angle of shot; Milliradians + * 1: Angle adjust left or right; Milliradians + * 2: Time of flight; seconds + * + * Example: + * [myPos, targetPos, 200, true, -0.0001, 15, 1.225, 225, 5] call ace_artilleryTables_fnc_calculateSolution + * + * Public: No + */ + +params ["_ownPos", "_targetPos", "_muzzleVelocity", ["_highAngle", true], ["_airFriction", 0], ["_temperature", 15], ["_airDensity", 1.225], ["_windDir", 0], ["_windSpeed", 0]]; + +//DEFAULT_AIR_FRICTION == -0.00006 +//MK6_82mm_AIR_FRICTION == -0.0001 + +private _relPos = _targetPos vectorDiff _ownPos; + +private _targetDir = (_relpos select 0) atan2 (_relPos select 1); +private _targetDist = sqrt( (_relPos select 0)^2 + (_relpos select 1)^2 ); +private _heightDif = _relPos select 2; +private _crossWind = sin(_targetDir - _windDir) * _windSpeed; +private _tailWind = -cos(_targetDir - _windDir) * _windSpeed; + +private _solutionReturns = [_targetDist, _heightDif, _muzzleVelocity, _highAngle, _airFriction, _crossWind, _tailWind, _temperature, _airDensity] call FUNC(calculateElevation); + +_solutionReturns diff --git a/addons/artillerytables/functions/fnc_firedEH.sqf b/addons/artillerytables/functions/fnc_firedEH.sqf index 01947b4ebe0..5aa46c69690 100644 --- a/addons/artillerytables/functions/fnc_firedEH.sqf +++ b/addons/artillerytables/functions/fnc_firedEH.sqf @@ -25,7 +25,7 @@ params ["_vehicle", "", "", "", "", "_magazine", "_projectile", "_gunner"]; TRACE_4("firedEH",_vehicle,_magazine,_projectile,_gunner); -if (!([_gunner] call EFUNC(common,isPlayer))) exitWith {}; // AI don't know how to use (this does give them more range than a player) +if !([_gunner] call EFUNC(common,isPlayer)) exitWith {}; // AI don't know how to use (this does give them more range than a player) if ((gunner _vehicle) != _gunner) exitWith {}; // check if primaryGunner @@ -35,7 +35,7 @@ if (isNumber (configFile >> "CfgMagazines" >> _magazine >> QGVAR(airFriction))) _airFriction = getNumber (configFile >> "CfgMagazines" >> _magazine >> QGVAR(airFriction)); }; TRACE_1("",_airFriction); -if (_airFriction >= 0) exitWith {}; // 0 disables everything, >0 makes no sense +if (_airFriction == 0) exitWith {}; // 0 disables everything BEGIN_COUNTER(adjustmentsCalc); @@ -60,6 +60,7 @@ if (_newMuzzleVelocityCoefficent != 1) then { _projectile setVelocity _bulletVelocity; }; +if (_airFriction > 0) exitWith {}; // positive value indicates it has vanilla airFriction, so we can just exit [{ params ["_projectile", "_kFactor", "_time"]; diff --git a/addons/artillerytables/functions/fnc_interactMenuOpened.sqf b/addons/artillerytables/functions/fnc_interactMenuOpened.sqf index b7d6371339e..4ba6342fc83 100644 --- a/addons/artillerytables/functions/fnc_interactMenuOpened.sqf +++ b/addons/artillerytables/functions/fnc_interactMenuOpened.sqf @@ -19,7 +19,7 @@ params ["_menuType"]; TRACE_1("interactMenuOpened",_menuType); if (_menuType != 1) exitWith {}; -if (!("ACE_artilleryTable" in (ace_player call EFUNC(common,uniqueItems)))) exitWith {}; +if !("ACE_artilleryTable" in (ace_player call EFUNC(common,uniqueItems))) exitWith {}; private _vehicleAdded = ace_player getVariable [QGVAR(vehiclesAdded), []]; private _rangeTablesShown = ace_player getVariable [QGVAR(rangeTablesShown), []]; diff --git a/addons/artillerytables/functions/fnc_rangeTableOpen.sqf b/addons/artillerytables/functions/fnc_rangeTableOpen.sqf index 327a2903a05..3984e4dacb9 100644 --- a/addons/artillerytables/functions/fnc_rangeTableOpen.sqf +++ b/addons/artillerytables/functions/fnc_rangeTableOpen.sqf @@ -34,15 +34,22 @@ TRACE_2("created dialog",_dialog,_ctrlChargeList); // Get Mags: private _mags = [_weaponName] call CBA_fnc_compatibleMagazines; -if (_mags isEqualTo []) exitWith {WARNING_1("No Mags",_weaponName);}; +if (_mags isEqualTo []) exitWith {WARNING_1("No Mags %1",_weaponName);}; private _magCfg = configFile >> "CfgMagazines"; private _magParamsArray = []; _mags = _mags apply { private _initSpeed = getNumber (_magCfg >> _x >> "initSpeed"); _magParamsArray pushBackUnique _initSpeed; private _airFriction = 0; - if (_advCorrection) then { - _airFriction = if (isNumber (_magCfg >> _x >> QGVAR(airFriction))) then { getNumber (_magCfg >> _x >> QGVAR(airFriction)) } else { DEFAULT_AIR_FRICTION }; + private _magAirFriction = getNumber (_magCfg >> _x >> QGVAR(airFriction)); + if (_magAirFriction <= 0) then { + if (_advCorrection) then { + _airFriction = [DEFAULT_AIR_FRICTION, _magAirFriction] select (isNumber (_magCfg >> _x >> QGVAR(airFriction))); + }; + } else { + // positive value, use ammo's airFriction (regardless of setting) + private _ammo = getText (_magCfg >> _x >> "ammo"); + _airFriction = getNumber (configFile >> "CfgAmmo" >> _ammo >> "airFriction"); }; _magParamsArray pushBackUnique _airFriction; [getText (_magCfg >> _x >> "displayNameShort"), getText (_magCfg >> _x >> "displayName"), _initSpeed, _airFriction] diff --git a/addons/artillerytables/functions/fnc_rangeTableUpdate.sqf b/addons/artillerytables/functions/fnc_rangeTableUpdate.sqf index 56135025aeb..4cce2499cf4 100644 --- a/addons/artillerytables/functions/fnc_rangeTableUpdate.sqf +++ b/addons/artillerytables/functions/fnc_rangeTableUpdate.sqf @@ -22,10 +22,10 @@ private _ctrlElevationHigh = _dialog displayCtrl IDC_BUTTON_ELEV_HIGH; private _ctrlElevationLow = _dialog displayCtrl IDC_BUTTON_ELEV_LOW; GVAR(lastElevationMode) = param [0, GVAR(lastElevationMode)]; // update if passed a new value -GVAR(lastCharge) = lbCurSel _ctrlChargeList; +GVAR(lastTablePage) = lbCurSel _ctrlChargeList; // get data for currently selected mag/mode combo: -(GVAR(magModeData) select GVAR(lastCharge)) params [["_muzzleVelocity", -1], ["_airFriction", 0]]; +(GVAR(magModeData) select GVAR(lastTablePage)) params [["_muzzleVelocity", -1], ["_airFriction", 0]]; private _elevMin = _dialog getVariable [QGVAR(elevMin), 0]; private _elevMax = _dialog getVariable [QGVAR(elevMax), 0]; _ctrlElevationHigh ctrlSetTextColor ([[0.25,0.25,0.25,1],[1,1,1,1]] select GVAR(lastElevationMode)); @@ -34,31 +34,12 @@ _ctrlElevationLow ctrlSetTextColor ([[1,1,1,1],[0.25,0.25,0.25,1]] select GVAR(l 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; +TRACE_5("callExtension:artillery:calculate_table",_muzzleVelocity,_airFriction,_elevMin,_elevMax,GVAR(lastElevationMode)); +( + "ace" callExtension ["artillery:calculate_table", [_muzzleVelocity, _airFriction, _elevMin, _elevMax, GVAR(lastElevationMode)]] +) params ["_data", "_code"]; +TRACE_1("",_code); + +GVAR(tableData) = createHashMap; +GVAR(tableSizeActual) = (parseSimpleArray _data) select 1; +GVAR(tableSizeReceived) = 0; diff --git a/addons/artillerytables/functions/fnc_simulateShot.sqf b/addons/artillerytables/functions/fnc_simulateShot.sqf new file mode 100644 index 00000000000..be747e862ae --- /dev/null +++ b/addons/artillerytables/functions/fnc_simulateShot.sqf @@ -0,0 +1,47 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke + * Simulates an indirect shot on a target of known height with given drag, wind, and atmospheric conditions + * + * Arguments: + * 0: Gun Elevation Angle; milliradians + * 1: Relative Target Height; meters, relative to gun altitude (positive means target higher than gun) + * 2: Muzzle Velocity; meters/second + * 3: Air Friction; meters^-1 [(m/s^2)/(m^2/s^2)] + * 4: Cross wind; meters/second (negative is Right to Left) + * 5: Tail wind; meters/second (negative is flying against the wind) + * 6: Temperature; degrees Celsius + * 7: Atmospheric Density; kg/(meters^3) + * + * Return Value: + * array of returns + * 0: Deflection Adjustment To Hit; Milliradians (negative is Left) + * 1: Distance of Shot; meters + * 2: Time of Flight; seconds + * + * Example: + * [900, 10, 200, -0.0001, 4, 0, 15, 1.225] call ace_artilleryTables_fnc_simulateShot + * + * Public: No + */ + +params ["_angle", "_targetHeight", "_muzzleVelocity", ["_airFriction", 0], ["_crossWind", 0], ["_tailWind", 0], ["_temperature", 15], ["_atmosphericDensity", 1.225]]; + +//DEFAULT_AIR_FRICTION == -0.00006 +//MK6_82mm_AIR_FRICTION == -0.0001 + +if (_airFriction != 0) then { + _muzzleVelocity = [_muzzleVelocity, _temperature, _atmosphericDensity] call FUNC(calculateMuzzleVelocity); +}; + +private _atmosphericDensityRatio = _atmosphericDensity / 1.225; +private _radAngle = rad(_angle / DEGTOMILS); + +TRACE_8("callExtension:artillery:simulate_shot",_radAngle,_targetHeight,_muzzleVelocity,_airFriction,_crossWind,_tailWind,_temperature,_atmosphericDensityRatio); +( + "ace" callExtension ["artillery:simulate_shot", [_radAngle, _targetHeight, _muzzleVelocity, _airFriction, _crossWind, _tailWind, _temperature, _atmosphericDensityRatio]] +) params ["_data", "_code"]; +TRACE_1("",_code); + +//[xDeviation, yDistance, timeOfFlight] +parseSimpleArray _data diff --git a/addons/artillerytables/functions/fnc_turretPFEH.sqf b/addons/artillerytables/functions/fnc_turretPFEH.sqf index 9ad10de1aa8..5e4e6c94657 100644 --- a/addons/artillerytables/functions/fnc_turretPFEH.sqf +++ b/addons/artillerytables/functions/fnc_turretPFEH.sqf @@ -30,7 +30,10 @@ if (isNull (uiNamespace getVariable [QGVAR(display), displayNull])) then { }; 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 + +// Need to be in gunner mode, so we can check where the optics are aiming at +// However, if there are no optics, ignore the above +if (!_invalidGunnerMem && {cameraView != "GUNNER"}) exitWith { _ctrlGroup ctrlShow false; }; _ctrlGroup ctrlShow true; @@ -40,7 +43,7 @@ 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 _lookVector = (AGLToASL (positionCameraToWorld [0,0,0])) vectorFromTo (AGLToASL (positionCameraToWorld [0,0,1])); private _weaponDir = _vehicle weaponDirection (currentWeapon _vehicle); // Calc real azimuth/elevation @@ -48,7 +51,7 @@ private _weaponDir = _vehicle weaponDirection (currentWeapon _vehicle); 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 _testSeekerPosASL = AGLToASL (positionCameraToWorld [0,0,0]); private _testPoint = _testSeekerPosASL vectorAdd (_lookVector vectorMultiply viewDistance); !((terrainIntersectASL [_testSeekerPosASL, _testPoint]) || {lineIntersects [_testSeekerPosASL, _testPoint, _vehicle]}); } else { @@ -81,8 +84,8 @@ private _ctrlCharge = (uiNamespace getVariable [QGVAR(display), displayNull]) di 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]; +_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) diff --git a/addons/artillerytables/initSettings.inc.sqf b/addons/artillerytables/initSettings.inc.sqf index 762010b2caa..f34190f910a 100644 --- a/addons/artillerytables/initSettings.inc.sqf +++ b/addons/artillerytables/initSettings.inc.sqf @@ -15,7 +15,5 @@ private _categoryName = [format ["ACE %1", localize "str_a3_cfgmarkers_nato_art" [LSTRING(disableArtilleryComputer_displayName), LSTRING(disableArtilleryComputer_description)], _categoryName, false, // default value - true, // isGlobal - {[QGVAR(disableArtilleryComputer), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/artillerytables/script_component.hpp b/addons/artillerytables/script_component.hpp index 128c3c17ff1..a2303b2a762 100644 --- a/addons/artillerytables/script_component.hpp +++ b/addons/artillerytables/script_component.hpp @@ -12,6 +12,10 @@ // This is a good fit for most large artillery, but a little low for lighter mortars #define DEFAULT_AIR_FRICTION -0.00006 +#define DEFAULT_MIN_ELEV 0 +// 90 degrees in radians +#define DEFAULT_MAX_ELEV 1.5708 + #define DEGTOMILS 17.7777778 #define IDC_MODECONTROLGROUP 1000 diff --git a/addons/atragmx/RscTitles.hpp b/addons/atragmx/RscTitles.hpp index 6196346c575..33b8c8036a0 100644 --- a/addons/atragmx/RscTitles.hpp +++ b/addons/atragmx/RscTitles.hpp @@ -157,8 +157,8 @@ class ATragMX_Display { SizeEX="0.025"; idc=720000; style=48; - x="0.55*safezoneW+safezoneX-0.256"; - y="0.265*safezoneH+safezoneY-0.1"; + 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}; @@ -167,8 +167,8 @@ class ATragMX_Display { }; class POWER: ATragMX_RscButton { idc=-1; - x="0.55*safezoneW+safezoneX+0.145"; - y="0.265*safezoneH+safezoneY+0.94"; + 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}; @@ -177,26 +177,26 @@ class ATragMX_Display { class BACK: POWER { idc=-1; w="0.06"; - x="0.55*safezoneW+safezoneX+0.3122"; + 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"; + 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"; + 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}; @@ -204,13 +204,13 @@ class ATragMX_Display { }; 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"; + 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}; @@ -218,50 +218,50 @@ class ATragMX_Display { }; 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"; + 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"; + 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"; + 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"; + x="0.550*safeZoneW+safeZoneX+0.11"; + y="0.265*safeZoneH+safeZoneY+0.20"; w="0.18"; h="0.03"; style=ST_LEFT; @@ -271,8 +271,8 @@ class ATragMX_Display { class TEXT_D: ATragMX_RscButton { idc=600; w="0.0231"; - x="0.550*safezoneW+safezoneX+0.29"; - y="0.265*safezoneH+safezoneY+0.20"; + 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"; + 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"; @@ -305,8 +305,8 @@ 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"; + 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"; + 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"; + 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"; + 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"; + 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,103 +429,103 @@ 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"; + 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"; + 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"; 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 { @@ -534,67 +534,67 @@ class ATragMX_Display { sizeEx="0.025"; w="0.065"; h="0.032"; - x="0.550*safezoneW+safezoneX+0.17"; - y="0.265*safezoneH+safezoneY+0.50"; + 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"; + 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"; 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)); }; @@ -602,7 +602,7 @@ class ATragMX_Display { idc=2000; style=ST_CENTER; w="0.06"; - x="0.550*safezoneW+safezoneX+0.205"; + x="0.550*safeZoneW+safeZoneX+0.205"; colorBackground[]={0,0,0,0}; text="TMOA"; action=QUOTE(call FUNC(cycle_scope_unit)); @@ -611,14 +611,14 @@ class ATragMX_Display { idc=2001; style=ST_CENTER; w="0.025"; - x="0.550*safezoneW+safezoneX+0.27"; + 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,8 +627,8 @@ 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"; + x="0.550*safeZoneW+safeZoneX+0.105"; + y="0.265*safeZoneH+safeZoneY+0.17"; w="0.3"; h="0.535"; offsetPressedX="0.0"; @@ -640,8 +640,8 @@ class ATragMX_Display { style=0; w="0.17"; h="0.28"; - x="0.550*safezoneW+safezoneX+0.225"; - y="0.265*safezoneH+safezoneY+0.355"; + 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)); }; @@ -653,8 +653,8 @@ 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"; + 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,7 +662,7 @@ 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)); }; @@ -670,24 +670,24 @@ class ATragMX_Display { idc=5003; style=ST_LEFT; w="0.07"; - x="0.550*safezoneW+safezoneX+0.11"; - y="0.265*safezoneH+safezoneY+0.24"; + 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)); }; @@ -698,8 +698,8 @@ class ATragMX_Display { idcRight=50062; w="0.285"; h="0.42"; - x="0.550*safezoneW+safezoneX+0.11"; - y="0.265*safezoneH+safezoneY+0.27"; + x="0.550*safeZoneW+safeZoneX+0.11"; + y="0.265*safeZoneH+safeZoneY+0.27"; }; class TEXT_GUN_LIST_OUTPUT: ATragMX_RscListNBox { @@ -707,8 +707,8 @@ class ATragMX_Display { columns[]={-0.05}; w="0.16"; h="0.45"; - x="0.550*safezoneW+safezoneX+0.11"; - y="0.265*safezoneH+safezoneY+0.24"; + 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}; @@ -724,8 +724,8 @@ class ATragMX_Display { idc=6002; style=ST_RIGHT; w="0.115"; - x="0.550*safezoneW+safezoneX+0.28"; - y="0.265*safezoneH+safezoneY+0.20"; + 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"; @@ -734,30 +734,30 @@ class ATragMX_Display { }; 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)); }; @@ -766,8 +766,8 @@ class ATragMX_Display { idc=7000; style="16+0x200"; lineSpacing=1.0; - x="0.550*safezoneW+safezoneX+0.11"; - y="0.265*safezoneH+safezoneY+0.24"; + x="0.550*safeZoneW+safeZoneX+0.11"; + y="0.265*safeZoneH+safeZoneY+0.24"; w="0.29"; h="0.10"; sizeEx="0.022"; @@ -776,8 +776,8 @@ class ATragMX_Display { 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"; + x="0.550*safeZoneW+safeZoneX+0.115"; + y="0.265*safeZoneH+safeZoneY+0.35"; w="0.12"; h="0.03"; sizeEx="0.027"; @@ -786,8 +786,8 @@ class ATragMX_Display { 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"; + 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,73 +795,73 @@ 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"; + 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"; + 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"; + 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"; + 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)); }; @@ -869,15 +869,15 @@ class ATragMX_Display { idc=7016; style=ST_LEFT; w="0.07"; - x="0.550*safezoneW+safezoneX+0.32"; + 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"; + 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 { @@ -937,14 +937,14 @@ 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"; + 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)); }; @@ -981,16 +981,16 @@ class ATragMX_Display { idc=9000; w="0.285"; h="0.49"; - x="0.550*safezoneW+safezoneX+0.11"; - y="0.265*safezoneH+safezoneY+0.2"; + 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"; + x="0.550*safeZoneW+safeZoneX+0.22"; + y="0.265*safeZoneH+safeZoneY+0.51"; w="0.08"; h="0.09"; style=ST_CENTER; @@ -1002,8 +1002,8 @@ class ATragMX_Display { style=ST_CENTER; w="0.07"; h="0.04"; - x="0.550*safezoneW+safezoneX+0.225"; - y="0.265*safezoneH+safezoneY+0.60"; + 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 { @@ -1057,8 +1057,8 @@ class ATragMX_Display { style=ST_LEFT; w="0.25"; h="0.04"; - x="0.550*safezoneW+safezoneX+0.12"; - y="0.265*safezoneH+safezoneY+0.24"; + x="0.550*safeZoneW+safeZoneX+0.12"; + y="0.265*safeZoneH+safeZoneY+0.24"; sizeEx="0.025"; text="New Gun Name"; }; @@ -1067,8 +1067,8 @@ class ATragMX_Display { style=ST_LEFT; w="0.225"; h="0.04"; - x="0.550*safezoneW+safezoneX+0.12"; - y="0.265*safezoneH+safezoneY+0.28"; + 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)); @@ -1078,8 +1078,8 @@ class ATragMX_Display { style=ST_CENTER; w="0.1"; h="0.04"; - x="0.550*safezoneW+safezoneX+0.12"; - y="0.265*safezoneH+safezoneY+0.33"; + 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,7 +1087,7 @@ 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)); }; @@ -1095,74 +1095,74 @@ class ATragMX_Display { class TEXT_GUN_AMMO_DATA_BORE_HEIGHT: TEXT_BORE_HEIGHT { idc=12000; w="0.22"; - y="0.265*safezoneH+safezoneY+0.28"; + 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"; + 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"; + 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 { @@ -1183,62 +1183,62 @@ 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"; + 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"; + 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; @@ -1259,36 +1259,36 @@ class ATragMX_Display { style=64; w="0.14"; h="0.07"; - x="0.550*safezoneW+safezoneX+0.235"; - y="0.265*safezoneH+safezoneY+0.29"; + 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"; + 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"; + 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"; + y="0.265*safeZoneH+safeZoneY+0.360"; text="Wind Speed (m/s)"; }; class TEXT_TARGET_DATA_WIND_SPEED_1: TEXT_TARGET_DATA_LATITUDE { @@ -1297,40 +1297,40 @@ class ATragMX_Display { w="0.05"; h="0.03"; sizeEx="0.025"; - x="0.550*safezoneW+safezoneX+0.270"; - y="0.265*safezoneH+safezoneY+0.357"; + 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"; + 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"; + 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"; + y="0.265*safeZoneH+safeZoneY+0.440"; text="Inclination Angle"; }; class TEXT_TARGET_DATA_INCLINATION_ANGLE_COSINE: TEXT_TARGET_DATA_LATITUDE { @@ -1339,62 +1339,62 @@ class ATragMX_Display { w="0.05"; h="0.03"; sizeEx="0.025"; - x="0.550*safezoneW+safezoneX+0.270"; - y="0.265*safezoneH+safezoneY+0.437"; + 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"; + 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"; + 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"; + 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"; + 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 { @@ -1417,45 +1417,45 @@ class ATragMX_Display { style=64; w="0.25"; h="0.07"; - x="0.550*safezoneW+safezoneX+0.13"; - y="0.265*safezoneH+safezoneY+0.32"; + 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"; + 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)); }; @@ -1464,53 +1464,53 @@ class ATragMX_Display { style=64; w="0.25"; h="0.07"; - x="0.550*safezoneW+safezoneX+0.13"; - y="0.265*safezoneH+safezoneY+0.42"; + 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"; + 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"; + 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"; + x="0.550*safeZoneW+safeZoneX+0.215"; sizeEx="0.022"; text="Muzzle velocity"; }; @@ -1518,73 +1518,73 @@ class ATragMX_Display { idc=160021; w="0.082"; h="0.035"; - x="0.550*safezoneW+safezoneX+0.128"; - y="0.265*safezoneH+safezoneY+0.29"; + 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"; + 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=""; }; @@ -1606,14 +1606,14 @@ 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"; + 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"; + x="0.550*safeZoneW+safeZoneX+0.235"; sizeEx="0.022"; text="BC-Coef"; }; @@ -1621,75 +1621,75 @@ class ATragMX_Display { idc=170021; w="0.082"; h="0.035"; - x="0.550*safezoneW+safezoneX+0.128"; - y="0.265*safezoneH+safezoneY+0.29"; + 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"; + 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"; + y="0.265*safeZoneH+safeZoneY+0.4175"; text="Clear"; action=QUOTE(call FUNC(clear_c1_ballistic_coefficient_data)); }; @@ -1711,8 +1711,8 @@ 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"; + x="0.550*safeZoneW+safeZoneX+0.115"; + y="0.265*safeZoneH+safeZoneY+0.220"; w="0.135"; h="0.03"; sizeEx="0.025"; @@ -1721,29 +1721,29 @@ class ATragMX_Display { 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"; + 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"; + 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 { @@ -1752,31 +1752,31 @@ class ATragMX_Display { 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"; + 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"; + 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)); }; @@ -1785,56 +1785,56 @@ class ATragMX_Display { 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"; + 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"; + 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"; + 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 62d45555b10..01eb14d9281 100644 --- a/addons/atragmx/XEH_postInit.sqf +++ b/addons/atragmx/XEH_postInit.sqf @@ -1,8 +1,10 @@ #include "script_component.hpp" +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/config.cpp b/addons/atragmx/config.cpp index 125d4a488e0..9b02aba4919 100644 --- a/addons/atragmx/config.cpp +++ b/addons/atragmx/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {"ACE_Item_ATragMX"}; weapons[] = {"ACE_ATragMX"}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ACE_Advanced_Ballistics", "ACE_common", "ACE_weather"}; + requiredAddons[] = {"ace_advanced_ballistics", "ace_common", "ace_weather"}; author = ECSTRING(common,ACETeam); authors[] = {"Ruthberg"}; url = ECSTRING(main,URL); diff --git a/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf b/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf index 9fe18a258d6..e667d22e75e 100644 --- a/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf +++ b/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf @@ -30,9 +30,16 @@ while {_velocity > _thresholdVelocity} do { private _bc = GVAR(targetSolutionInput) select 14; private _dragModel = GVAR(targetSolutionInput) select 15; private _temperature = GVAR(targetSolutionInput) select 5; - private _drag = parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3:%4", _dragModel, _bc, _velocity, _temperature])); _distance = _distance + _velocity * __DELTA_T; - _velocity = _velocity - (_drag * __DELTA_T); + private _data = ( + "ace" callExtension ["ballistics:retard", [ + _dragModel, + _bc, + _velocity, + _temperature + ]] + ) select 0; + _velocity = _velocity - ((parseNumber _data) * __DELTA_T); }; _distance diff --git a/addons/atragmx/functions/fnc_calculate_solution.sqf b/addons/atragmx/functions/fnc_calculate_solution.sqf index 7efc25ebbf4..e910017f2fc 100644 --- a/addons/atragmx/functions/fnc_calculate_solution.sqf +++ b/addons/atragmx/functions/fnc_calculate_solution.sqf @@ -90,7 +90,14 @@ private _wind1 = [cos(270 - _windDirection * 30) * _windSpeed1, sin(270 - _windD private _wind2 = [cos(270 - _windDirection * 30) * _windSpeed2, sin(270 - _windDirection * 30) * _windSpeed2, 0]; private _windDrift = 0; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { - _bc = parseNumber(("ace_advanced_ballistics" callExtension format["atmosphericCorrection:%1:%2:%3:%4:%5", _bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel])); + _bc = parseNumber (("ace" callExtension ["ballistics:atmospheric_correction", [ + _bc, + _temperature, + _barometricPressure, + _relativeHumidity, + _atmosphereModel + ]] + ) select 0); }; private _eoetvoesMultiplier = 0; @@ -103,8 +110,8 @@ _bulletPos set [1, 0]; _bulletPos set [2, -(_boreHeight / 100)]; _bulletVelocity set [0, 0]; -_bulletVelocity set [1, Cos(_scopeBaseAngle) * _muzzleVelocity]; -_bulletVelocity set [2, Sin(_scopeBaseAngle) * _muzzleVelocity]; +_bulletVelocity set [1, cos(_scopeBaseAngle) * _muzzleVelocity]; +_bulletVelocity set [2, sin(_scopeBaseAngle) * _muzzleVelocity]; while {_TOF < 15 && (_bulletPos select 1) < _targetRange} do { _bulletSpeed = vectorMagnitude _bulletVelocity; @@ -113,8 +120,15 @@ while {_TOF < 15 && (_bulletPos select 1) < _targetRange} do { _trueSpeed = vectorMagnitude _trueVelocity; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { - private _drag = parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3:%4", _dragModel, _bc, _trueSpeed, _temperature])); - _bulletAccel = (vectorNormalized _trueVelocity) vectorMultiply (-1 * _drag); + private _data = ( + "ace" callExtension ["ballistics:retard", [ + _dragModel, + _bc, + _trueSpeed, + _temperature + ]] + ) select 0; + _bulletAccel = (vectorNormalized _trueVelocity) vectorMultiply (-1 * (parseNumber _data)); } else { _bulletAccel = _trueVelocity vectorMultiply (_trueSpeed * _airFriction); }; @@ -139,9 +153,9 @@ while {_TOF < 15 && (_bulletPos select 1) < _targetRange} do { _windage1 = - atan(_tx / _trueRange); _windDrift = (_wind2 select 0) * (_TOF - _trueRange / _muzzleVelocity); _windage2 = - atan(_windDrift / _trueRange); - _lead = (_targetSpeed * _TOF) / (Tan(MRAD_TO_DEG(1)) * _trueRange); + _lead = (_targetSpeed * _TOF) / (tan(MRAD_TO_DEG(1)) * _trueRange); }; - _kineticEnergy = 0.5 * (_bulletMass / 1000 * (_bulletSpeed ^ 2)); + private _kineticEnergy = 0.5 * (_bulletMass / 1000 * (_bulletSpeed ^ 2)); _kineticEnergy = _kineticEnergy * 0.737562149; if ((missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) && (_bulletPos select 1) > 0) then { @@ -174,10 +188,10 @@ if (_targetRange != 0) then { _windage1 = - atan(_tx / _targetRange); _windDrift = (_wind2 select 0) * (_TOF - _targetRange / _muzzleVelocity); _windage2 = - atan(_windDrift / _targetRange); - _lead = (_targetSpeed * _TOF) / (Tan(MRAD_TO_DEG(1)) * _targetRange); + _lead = (_targetSpeed * _TOF) / (tan(MRAD_TO_DEG(1)) * _targetRange); }; -_kineticEnergy = 0.5 * (_bulletMass / 1000 * (_bulletSpeed ^ 2)); +private _kineticEnergy = 0.5 * (_bulletMass / 1000 * (_bulletSpeed ^ 2)); _kineticEnergy = _kineticEnergy * 0.737562149; if ((missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) && (_bulletPos select 1) > 0) then { diff --git a/addons/atragmx/functions/fnc_calculate_target_range_assist.sqf b/addons/atragmx/functions/fnc_calculate_target_range_assist.sqf index dc9c62c3fc5..5ad543ccc94 100644 --- a/addons/atragmx/functions/fnc_calculate_target_range_assist.sqf +++ b/addons/atragmx/functions/fnc_calculate_target_range_assist.sqf @@ -68,7 +68,7 @@ switch (_this) do { }; }; - ctrlSetText [7010, Str(Round(_targetSize * 100) / 100)]; + ctrlSetText [7010, str(round(_targetSize * 100) / 100)]; }; case 1: { if (_estRange > 0) then { @@ -87,13 +87,13 @@ switch (_this) do { }; }; - ctrlSetText [7011, Str(Round(_imageSize * 100) / 100)]; + ctrlSetText [7011, str(round(_imageSize * 100) / 100)]; }; case 2: { if (tan(_imageSize) != 0) then { _estRange = _targetSize / tan(_imageSize); }; - ctrlSetText [7013, Str(Round(_estRange))]; + ctrlSetText [7013, str(round(_estRange))]; }; }; diff --git a/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf b/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf index 69af9eba165..25106c794e9 100644 --- a/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf +++ b/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf @@ -44,4 +44,4 @@ if (GVAR(currentUnit) != 2) then { _estSpeed = _estSpeed * 2.23693629; }; -ctrlSetText [8007, Str(Round(_estSpeed * 10) / 10)]; +ctrlSetText [8007, str(round(_estSpeed * 10) / 10)]; diff --git a/addons/atragmx/functions/fnc_calculate_truing_drop.sqf b/addons/atragmx/functions/fnc_calculate_truing_drop.sqf index 5191848d050..5f7adee2838 100644 --- a/addons/atragmx/functions/fnc_calculate_truing_drop.sqf +++ b/addons/atragmx/functions/fnc_calculate_truing_drop.sqf @@ -29,8 +29,8 @@ if (_parseInput) then { _transonicRange = _transonicRange * 0.9144; _subsonicRange = _subsonicRange * 0.9144; }; - _transonicRange = Round(_transonicRange); - _subsonicRange = Round(_subsonicRange); + _transonicRange = round(_transonicRange); + _subsonicRange = round(_subsonicRange); _subsonicRange = _transonicRange max _subsonicRange; @@ -54,8 +54,8 @@ if (_parseInput) then { _subsonicDrop = _subsonicDrop / 1.047; }; }; - _transonicDrop = Round(_transonicDrop * 100) / 100; - _subsonicDrop = Round(_subsonicDrop * 100) / 100; + _transonicDrop = round(_transonicDrop * 100) / 100; + _subsonicDrop = round(_subsonicDrop * 100) / 100; _subsonicDrop = _transonicDrop max _subsonicDrop; }; @@ -67,11 +67,11 @@ if ((GVAR(truingDropDropData) select 0) == 0 || {[_transonicRange, _subsonicRang private _solutionInput = +GVAR(targetSolutionInput); if (_transonicRange == 0) then { - _transonicRange = Round(403 call FUNC(calculate_distance_at_velocity)); + _transonicRange = round(403 call FUNC(calculate_distance_at_velocity)); }; _solutionInput set [13, _transonicRange]; private _result1 = _solutionInput call FUNC(calculate_solution); - _transonicDrop = Round((_result1 select 0) * 100) / 100; + _transonicDrop = round((_result1 select 0) * 100) / 100; GVAR(truingDropRangeData) set [0, _transonicRange]; GVAR(truingDropDropData) set [1, _transonicDrop]; GVAR(truingDropReferenceDropData) set [0, _transonicDrop]; @@ -84,11 +84,11 @@ if ((GVAR(truingDropDropData) select 0) == 0 || {[_transonicRange, _subsonicRang } else { _subsonicRange = _subsonicRange + 200 * 1.0936133; }; - _subsonicRange = Round(_subsonicRange); + _subsonicRange = round(_subsonicRange); }; _solutionInput set [13, _subsonicRange]; private _result2 = _solutionInput call FUNC(calculate_solution); - _subsonicDrop = Round((_result2 select 0) * 100) / 100; + _subsonicDrop = round((_result2 select 0) * 100) / 100; GVAR(truingDropRangeData) set [1, _subsonicRange]; GVAR(truingDropDropData) set [2, _subsonicDrop]; GVAR(truingDropReferenceDropData) set [1, _subsonicDrop]; diff --git a/addons/atragmx/functions/fnc_initGunList.sqf b/addons/atragmx/functions/fnc_initGunList.sqf index 2ae67bb78df..515bc9013eb 100644 --- a/addons/atragmx/functions/fnc_initGunList.sqf +++ b/addons/atragmx/functions/fnc_initGunList.sqf @@ -23,7 +23,7 @@ if ((profileNamespace getVariable ["ACE_ATragMX_profileNamespaceVersion", 0]) == _resetGunList = false; { // Verify each gun has correct param type - if (!(_x isEqualTypeArray ["", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [], [], false])) exitWith { + if !(_x isEqualTypeArray ["", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [], [], false]) exitWith { _resetGunList = true; }; } forEach GVAR(gunList); diff --git a/addons/atragmx/functions/fnc_parse_input.sqf b/addons/atragmx/functions/fnc_parse_input.sqf index 1c3ea3398a5..4f62f301160 100644 --- a/addons/atragmx/functions/fnc_parse_input.sqf +++ b/addons/atragmx/functions/fnc_parse_input.sqf @@ -100,11 +100,11 @@ if (GVAR(currentUnit) == 1) then { _targetRange = 25 max _targetRange min 3700; }; GVAR(targetRangeDirtyFlag) = GVAR(targetRangeDirtyFlag) || {_targetRange != GVAR(targetRange) select GVAR(currentTarget)}; -GVAR(latitude) set [GVAR(currentTarget), -90 max Round(parseNumber(ctrlText 140000)) min 90]; -GVAR(directionOfFire) set [GVAR(currentTarget), 0 max abs(Round(parseNumber(ctrlText 140010))) min 359]; +GVAR(latitude) set [GVAR(currentTarget), -90 max round(parseNumber(ctrlText 140000)) min 90]; +GVAR(directionOfFire) set [GVAR(currentTarget), 0 max abs(round(parseNumber(ctrlText 140010))) min 359]; GVAR(windSpeed1) set [GVAR(currentTarget), _windSpeed1]; GVAR(windSpeed2) set [GVAR(currentTarget), _windSpeed2]; -GVAR(windDirection) set [GVAR(currentTarget), 1 max Round(parseNumber(ctrlText 140030)) min 12]; +GVAR(windDirection) set [GVAR(currentTarget), 1 max round(parseNumber(ctrlText 140030)) min 12]; GVAR(targetSpeed) set [GVAR(currentTarget), _targetSpeed]; GVAR(targetRange) set [GVAR(currentTarget), _targetRange]; private _inclinationAngleCosine = 0.5 max parseNumber(ctrlText 140041) min 1; @@ -112,7 +112,7 @@ private _inclinationAngleDegree = -60 max round(parseNumber(ctrlText 140040)) mi if (_inclinationAngleDegree != GVAR(inclinationAngle) select GVAR(currentTarget)) then { GVAR(inclinationAngle) set [GVAR(currentTarget), _inclinationAngleDegree]; } else { - if (_inclinationAngleCosine != Round(cos(GVAR(inclinationAngle) select GVAR(currentTarget)) * 100) / 100) then { + if (_inclinationAngleCosine != round(cos(GVAR(inclinationAngle) select GVAR(currentTarget)) * 100) / 100) then { GVAR(inclinationAngle) set [GVAR(currentTarget), round(acos(_inclinationAngleCosine))]; }; }; 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 31451c7ff81..cbbb4603e34 100644 --- a/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf +++ b/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf @@ -74,7 +74,7 @@ private _validate_preset = { ERROR(_errorMsg); _valid = false; }; - if (!((_this select 17) in ["ASM", "ICAO"])) then { + if !((_this select 17) in ["ASM", "ICAO"]) then { private _errorMsg = format ["Invalid atmosphere model: %1", _this select 17]; ERROR(_errorMsg); _valid = false; diff --git a/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf b/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf index f7e4709cc11..0d5c83ae01c 100644 --- a/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf +++ b/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf @@ -45,7 +45,7 @@ for "_index" from 1 to (_lookupTableSize - 1) do { (_lookupTable select _lowerIndex) params ["_lowerDistance", "_lowerMuzzleVelocity"]; (_lookupTable select _upperIndex) params ["_upperDistance", "_upperMuzzleVelocity"]; -_muzzleVelocity = 100 max (linearConversion [_lowerDistance, _upperDistance, GVAR(temperature), _lowerMuzzleVelocity, _upperMuzzleVelocity]) min 1400; +private _muzzleVelocity = 100 max (linearConversion [_lowerDistance, _upperDistance, GVAR(temperature), _lowerMuzzleVelocity, _upperMuzzleVelocity]) min 1400; if (_muzzleVelocity != GVAR(workingMemory) select 1) then { GVAR(workingMemory) set [1, _muzzleVelocity]; diff --git a/addons/atragmx/functions/fnc_show_range_card_setup.sqf b/addons/atragmx/functions/fnc_show_range_card_setup.sqf index 15558ceb983..a4301f5b761 100644 --- a/addons/atragmx/functions/fnc_show_range_card_setup.sqf +++ b/addons/atragmx/functions/fnc_show_range_card_setup.sqf @@ -22,7 +22,7 @@ GVAR(showRangeCardSetup) = _this; if (_this) then { ctrlSetFocus ((uiNamespace getVariable "ATragMX_Display") displayCtrl 10006); - ctrlSetText [10003, Str(Round(GVAR(rangeCardStartRange)))]; - ctrlSetText [10004, Str(Round(GVAR(rangeCardEndRange)))]; - ctrlSetText [10005, Str(Round(GVAR(rangeCardIncrement)))]; + ctrlSetText [10003, str(round(GVAR(rangeCardStartRange)))]; + ctrlSetText [10004, str(round(GVAR(rangeCardEndRange)))]; + ctrlSetText [10005, str(round(GVAR(rangeCardIncrement)))]; }; diff --git a/addons/atragmx/functions/fnc_show_target_range_assist.sqf b/addons/atragmx/functions/fnc_show_target_range_assist.sqf index 83516ef5c6a..b13352d22f9 100644 --- a/addons/atragmx/functions/fnc_show_target_range_assist.sqf +++ b/addons/atragmx/functions/fnc_show_target_range_assist.sqf @@ -21,8 +21,8 @@ GVAR(showTargetRangeAssist) = _this; if (_this) then { ctrlSetFocus ((uiNamespace getVariable "ATragMX_Display") displayCtrl 7018); - ctrlSetText [7012, Str(parseNumber(ctrlText 320))]; - ctrlSetText [7013, Str(parseNumber(ctrlText 340))]; + ctrlSetText [7012, str(parseNumber(ctrlText 320))]; + ctrlSetText [7013, str(parseNumber(ctrlText 340))]; if (GVAR(currentUnit) == 1) then { ctrlSetText [7016, "Yards"]; diff --git a/addons/atragmx/functions/fnc_show_target_speed_assist.sqf b/addons/atragmx/functions/fnc_show_target_speed_assist.sqf index 3efa6ed6d43..c2b34bd9081 100644 --- a/addons/atragmx/functions/fnc_show_target_speed_assist.sqf +++ b/addons/atragmx/functions/fnc_show_target_speed_assist.sqf @@ -22,7 +22,7 @@ GVAR(showTargetSpeedAssist) = _this; if (_this) then { ctrlSetFocus ((uiNamespace getVariable "ATragMX_Display") displayCtrl 8012); - ctrlSetText [8004, Str(Round((GVAR(targetRange) select GVAR(currentTarget))))]; + ctrlSetText [8004, str(round((GVAR(targetRange) select GVAR(currentTarget))))]; if (GVAR(currentUnit) == 1) then { ctrlSetText [8008, "Yards"]; diff --git a/addons/atragmx/functions/fnc_show_truing_drop.sqf b/addons/atragmx/functions/fnc_show_truing_drop.sqf index 5e7f60f4d4e..f75d3f7758c 100644 --- a/addons/atragmx/functions/fnc_show_truing_drop.sqf +++ b/addons/atragmx/functions/fnc_show_truing_drop.sqf @@ -21,9 +21,9 @@ GVAR(showTruingDrop) = _this; if (_this) then { if (GVAR(currentUnit) == 2) then { - ctrlSetText [18000, format["ZR=%1meters", Round(GVAR(workingMemory) select 2)]]; + ctrlSetText [18000, format["ZR=%1meters", round(GVAR(workingMemory) select 2)]]; } else { - ctrlSetText [18000, format["ZR=%1yards", Round((GVAR(workingMemory) select 2) * 1.0936133)]]; + ctrlSetText [18000, format["ZR=%1yards", round((GVAR(workingMemory) select 2) * 1.0936133)]]; }; private _dropUnit = GVAR(currentScopeUnit); if (_dropUnit == 3) then { diff --git a/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf b/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf index b34dd666f22..40c0ac7cd8f 100644 --- a/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf +++ b/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf @@ -26,10 +26,10 @@ 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)]; + ctrlSetText [8006, str(round((CBA_missionTime - _startTime) * 10) / 10)]; [] call FUNC(calculate_target_speed_assist); @@ -39,7 +39,7 @@ if !(ctrlVisible 9000) then { [_this select 1] call CBA_fnc_removePerFrameHandler; }; - ctrlSetText [9001, Str(Round((CBA_missionTime - _startTime) * 10) / 10)]; + ctrlSetText [9001, str(round((CBA_missionTime - _startTime) * 10) / 10)]; }, 0.1, [CBA_missionTime]] call CBA_fnc_addPerFrameHandler; }; 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 bb581ad6ea7..a8cd7ce52ae 100644 --- a/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 17000) then { false call FUNC(show_c1_ballistic_coefficient_data); diff --git a/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf index 562ef305537..34326b251da 100644 --- a/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 16000) then { false call FUNC(show_muzzle_velocity_data); diff --git a/addons/atragmx/functions/fnc_toggle_range_card_setup.sqf b/addons/atragmx/functions/fnc_toggle_range_card_setup.sqf index 5c499b8b826..29c856013b4 100644 --- a/addons/atragmx/functions/fnc_toggle_range_card_setup.sqf +++ b/addons/atragmx/functions/fnc_toggle_range_card_setup.sqf @@ -20,9 +20,9 @@ if (ctrlVisible 10000) then { true call FUNC(show_range_card); if (_this == 1) then { - GVAR(rangeCardStartRange) = 0 max Round(parseNumber(ctrlText 10003)) min 3000; - GVAR(rangeCardEndRange) = 0 max Round(parseNumber(ctrlText 10004)) min 3000; - GVAR(rangeCardIncrement) = 1 max Round(parseNumber(ctrlText 10005)) min 3000; + GVAR(rangeCardStartRange) = 0 max round(parseNumber(ctrlText 10003)) min 3000; + GVAR(rangeCardEndRange) = 0 max round(parseNumber(ctrlText 10004)) min 3000; + GVAR(rangeCardIncrement) = 1 max round(parseNumber(ctrlText 10005)) min 3000; [] call FUNC(calculate_range_card); [] call FUNC(update_range_card); diff --git a/addons/atragmx/functions/fnc_toggle_target_range_assist.sqf b/addons/atragmx/functions/fnc_toggle_target_range_assist.sqf index 1e6c485e995..dd14f2ddcd0 100644 --- a/addons/atragmx/functions/fnc_toggle_target_range_assist.sqf +++ b/addons/atragmx/functions/fnc_toggle_target_range_assist.sqf @@ -20,10 +20,10 @@ if (ctrlVisible 7000) then { true call FUNC(show_main_page); if (_this == 1) then { - ctrlSetText [320, Str(parseNumber(ctrlText 7012))]; - ctrlSetText [140040, Str(parseNumber(ctrlText 7012))]; - ctrlSetText [340, Str(parseNumber(ctrlText 7013))]; - ctrlSetText [140060, Str(parseNumber(ctrlText 7013))]; + ctrlSetText [320, str(parseNumber(ctrlText 7012))]; + ctrlSetText [140040, str(parseNumber(ctrlText 7012))]; + ctrlSetText [340, str(parseNumber(ctrlText 7013))]; + ctrlSetText [140060, str(parseNumber(ctrlText 7013))]; [] call FUNC(calculate_target_solution); }; } else { diff --git a/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf b/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf index 009074105e8..fec9e528e57 100644 --- a/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf +++ b/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf @@ -23,8 +23,8 @@ if (ctrlVisible 8000) then { [] call FUNC(calculate_target_speed_assist); private _targetSpeed = parseNumber(ctrlText 8007); if (_targetSpeed != 0) then { - ctrlSetText [330, Str(_targetSpeed)]; - ctrlSetText [140050, Str(_targetSpeed)]; + ctrlSetText [330, str(_targetSpeed)]; + ctrlSetText [140050, str(_targetSpeed)]; [] call FUNC(calculate_target_solution); }; }; diff --git a/addons/atragmx/functions/fnc_toggle_truing_drop.sqf b/addons/atragmx/functions/fnc_toggle_truing_drop.sqf index 2c61b1776ba..2d13619de08 100644 --- a/addons/atragmx/functions/fnc_toggle_truing_drop.sqf +++ b/addons/atragmx/functions/fnc_toggle_truing_drop.sqf @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 18000) then { false call FUNC(show_truing_drop); diff --git a/addons/atragmx/functions/fnc_true_c1_ballistic_coefficient.sqf b/addons/atragmx/functions/fnc_true_c1_ballistic_coefficient.sqf index 84371ca8527..06824cc7a20 100644 --- a/addons/atragmx/functions/fnc_true_c1_ballistic_coefficient.sqf +++ b/addons/atragmx/functions/fnc_true_c1_ballistic_coefficient.sqf @@ -18,7 +18,7 @@ private _referenceDrop = GVAR(truingDropDropData) select 0; private _actualDrop = GVAR(truingDropDropData) select 2; -if (Round(_actualDrop * 10) / 10 == Round(_referenceDrop * 10) / 10) exitWith {}; +if (round(_actualDrop * 10) / 10 == round(_referenceDrop * 10) / 10) exitWith {}; private _step = 0.01; if (_actualDrop > _referenceDrop) then { diff --git a/addons/atragmx/functions/fnc_true_muzzle_velocity.sqf b/addons/atragmx/functions/fnc_true_muzzle_velocity.sqf index f8fb9e621c4..75e1fbdc78d 100644 --- a/addons/atragmx/functions/fnc_true_muzzle_velocity.sqf +++ b/addons/atragmx/functions/fnc_true_muzzle_velocity.sqf @@ -18,7 +18,7 @@ private _referenceDrop = GVAR(truingDropDropData) select 0; private _actualDrop = GVAR(truingDropDropData) select 1; -if (Round(_actualDrop * 10) / 10 == Round(_referenceDrop * 10) / 10) exitWith {}; +if (round(_actualDrop * 10) / 10 == round(_referenceDrop * 10) / 10) exitWith {}; private _step = 10; if (_actualDrop > _referenceDrop) then { diff --git a/addons/atragmx/functions/fnc_update_atmo_env_data.sqf b/addons/atragmx/functions/fnc_update_atmo_env_data.sqf index 340924b5aa7..3118bee2233 100644 --- a/addons/atragmx/functions/fnc_update_atmo_env_data.sqf +++ b/addons/atragmx/functions/fnc_update_atmo_env_data.sqf @@ -18,20 +18,20 @@ ctrlSetFocus ((uiNamespace getVariable "ATragMX_Display") displayCtrl 13007); if (GVAR(currentUnit) == 2) then { - ctrlSetText [130040, Str(Round(GVAR(temperature) * 10) / 10)]; + ctrlSetText [130040, str(round(GVAR(temperature) * 10) / 10)]; } else { - ctrlSetText [130040, Str(Round((GVAR(temperature) * 1.8 + 32) * 10) / 10)]; + ctrlSetText [130040, str(round((GVAR(temperature) * 1.8 + 32) * 10) / 10)]; }; if (GVAR(currentUnit) == 2) then { - ctrlSetText [130050, Str(Round(GVAR(barometricPressure)))]; + ctrlSetText [130050, str(round(GVAR(barometricPressure)))]; } else { - ctrlSetText [130050, Str(Round(GVAR(barometricPressure) / 33.8638866667 * 100) / 100)]; + ctrlSetText [130050, str(round(GVAR(barometricPressure) / 33.8638866667 * 100) / 100)]; }; -ctrlSetText [130060, Str(Round(GVAR(relativeHumidity) * 100 * 10) / 10)]; +ctrlSetText [130060, str(round(GVAR(relativeHumidity) * 100 * 10) / 10)]; if (GVAR(currentUnit) == 2) then { - ctrlSetText [130030, Str(Round(GVAR(altitude)))]; + ctrlSetText [130030, str(round(GVAR(altitude)))]; } else { - ctrlSetText [130030, Str(Round(GVAR(altitude) * 3.2808399))]; + ctrlSetText [130030, str(round(GVAR(altitude) * 3.2808399))]; }; if (GVAR(currentUnit) == 2) then { diff --git a/addons/atragmx/functions/fnc_update_atmosphere.sqf b/addons/atragmx/functions/fnc_update_atmosphere.sqf index 7d523158925..ac04d19ba9a 100644 --- a/addons/atragmx/functions/fnc_update_atmosphere.sqf +++ b/addons/atragmx/functions/fnc_update_atmosphere.sqf @@ -16,18 +16,18 @@ */ if (GVAR(currentUnit) == 2) then { - ctrlSetText [200, Str(Round(GVAR(temperature) * 10) / 10)]; + ctrlSetText [200, str(round(GVAR(temperature) * 10) / 10)]; } else { - ctrlSetText [200, Str(Round((GVAR(temperature) * 1.8 + 32) * 10) / 10)]; + ctrlSetText [200, str(round((GVAR(temperature) * 1.8 + 32) * 10) / 10)]; }; if (GVAR(currentUnit) == 2) then { - ctrlSetText [210, Str(Round(GVAR(barometricPressure)))]; + ctrlSetText [210, str(round(GVAR(barometricPressure)))]; } else { - ctrlSetText [210, Str(Round(GVAR(barometricPressure) / 33.8638866667 * 100) / 100)]; + ctrlSetText [210, str(round(GVAR(barometricPressure) / 33.8638866667 * 100) / 100)]; }; -ctrlSetText [220, Str(Round(GVAR(relativeHumidity) * 100 * 10) / 10)]; +ctrlSetText [220, str(round(GVAR(relativeHumidity) * 100 * 10) / 10)]; if (GVAR(currentUnit) == 2) then { - ctrlSetText [230, Str(Round(GVAR(altitude)))]; + ctrlSetText [230, str(round(GVAR(altitude)))]; } else { - ctrlSetText [230, Str(Round(GVAR(altitude) * 3.2808399))]; + ctrlSetText [230, str(round(GVAR(altitude) * 3.2808399))]; }; 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 4c0c6d7175b..886ad33ba97 100644 --- a/addons/atragmx/functions/fnc_update_c1_ballistic_coefficient_data.sqf +++ b/addons/atragmx/functions/fnc_update_c1_ballistic_coefficient_data.sqf @@ -17,9 +17,9 @@ // Distances if (GVAR(currentUnit) != 1) then { - {ctrlSetText [_x, Str(Round(((GVAR(workingMemory) select 19) select _forEachIndex) select 0))]} forEach [170021, 170022, 170023, 170024, 170025, 170026, 170027]; + {ctrlSetText [_x, str(round(((GVAR(workingMemory) select 19) select _forEachIndex) select 0))]} forEach [170021, 170022, 170023, 170024, 170025, 170026, 170027]; } else { - {ctrlSetText [_x, Str(Round((((GVAR(workingMemory) select 19) select _forEachIndex) select 0) * 1.0936133))]} forEach [170021, 170022, 170023, 170024, 170025, 170026, 170027]; + {ctrlSetText [_x, str(round((((GVAR(workingMemory) select 19) select _forEachIndex) select 0) * 1.0936133))]} forEach [170021, 170022, 170023, 170024, 170025, 170026, 170027]; }; // Ballistic coefficients -{ctrlSetText [_x, Str(Round((((GVAR(workingMemory) select 19) select _forEachIndex) select 1) * 1000) / 1000)]} forEach [170031, 170032, 170033, 170034, 170035, 170036, 170037]; +{ctrlSetText [_x, str(round((((GVAR(workingMemory) select 19) select _forEachIndex) select 1) * 1000) / 1000)]} forEach [170031, 170032, 170033, 170034, 170035, 170036, 170037]; diff --git a/addons/atragmx/functions/fnc_update_gun.sqf b/addons/atragmx/functions/fnc_update_gun.sqf index 5a5dab00fa8..67f726e92e6 100644 --- a/addons/atragmx/functions/fnc_update_gun.sqf +++ b/addons/atragmx/functions/fnc_update_gun.sqf @@ -17,34 +17,34 @@ ctrlSetText [1000, GVAR(workingMemory) select 0]; if (GVAR(currentUnit) != 2) then { - ctrlSetText [100, Str(Round((GVAR(workingMemory) select 5) / 2.54 * 100) / 100)]; + ctrlSetText [100, str(round((GVAR(workingMemory) select 5) / 2.54 * 100) / 100)]; } else { - ctrlSetText [100, Str(Round((GVAR(workingMemory) select 5) * 100) / 100)]; + ctrlSetText [100, str(round((GVAR(workingMemory) select 5) * 100) / 100)]; }; if (GVAR(currentUnit) != 2) then { - ctrlSetText [110, Str(Round((GVAR(workingMemory) select 12) * 15.4323584))]; + ctrlSetText [110, str(round((GVAR(workingMemory) select 12) * 15.4323584))]; } else { - ctrlSetText [110, Str(Round((GVAR(workingMemory) select 12) * 10) / 10)]; + ctrlSetText [110, str(round((GVAR(workingMemory) select 12) * 10) / 10)]; }; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { - ctrlSetText [120, Str(Round((GVAR(workingMemory) select 15) * 1000) / 1000)]; + ctrlSetText [120, str(round((GVAR(workingMemory) select 15) * 1000) / 1000)]; } else { - ctrlSetText [120, Str(Round((GVAR(workingMemory) select 4) * -1000 * 1000) / 1000)]; + ctrlSetText [120, str(round((GVAR(workingMemory) select 4) * -1000 * 1000) / 1000)]; }; if (GVAR(currentUnit) != 2) then { - ctrlSetText [130, Str(Round((GVAR(workingMemory) select 1) * 3.2808399))]; + ctrlSetText [130, str(round((GVAR(workingMemory) select 1) * 3.2808399))]; } else { - ctrlSetText [130, Str(Round(GVAR(workingMemory) select 1))]; + ctrlSetText [130, str(round(GVAR(workingMemory) select 1))]; }; switch (GVAR(currentUnit)) do { case 0: { - ctrlSetText [140, format["*%1", Round(GVAR(workingMemory) select 2)]]; + ctrlSetText [140, format["*%1", round(GVAR(workingMemory) select 2)]]; }; case 1: { - ctrlSetText [140, Str(Round((GVAR(workingMemory) select 2) * 1.0936133))]; + ctrlSetText [140, str(round((GVAR(workingMemory) select 2) * 1.0936133))]; }; case 2: { - ctrlSetText [140, Str(Round(GVAR(workingMemory) select 2))]; + ctrlSetText [140, str(round(GVAR(workingMemory) select 2))]; }; }; [] call FUNC(update_scope_unit); diff --git a/addons/atragmx/functions/fnc_update_gun_ammo_data.sqf b/addons/atragmx/functions/fnc_update_gun_ammo_data.sqf index 59bd0149733..56347ac6db6 100644 --- a/addons/atragmx/functions/fnc_update_gun_ammo_data.sqf +++ b/addons/atragmx/functions/fnc_update_gun_ammo_data.sqf @@ -18,39 +18,39 @@ ctrlSetFocus ((uiNamespace getVariable "ATragMX_Display") displayCtrl 12008); if (GVAR(currentUnit) != 2) then { - ctrlSetText [120000, Str(Round((GVAR(workingMemory) select 5) / 2.54 * 100) / 100)]; + ctrlSetText [120000, str(round((GVAR(workingMemory) select 5) / 2.54 * 100) / 100)]; } else { - ctrlSetText [120000, Str(Round((GVAR(workingMemory) select 5) * 100) / 100)]; + ctrlSetText [120000, str(round((GVAR(workingMemory) select 5) * 100) / 100)]; }; if (GVAR(currentUnit) != 2) then { - ctrlSetText [120010, Str(Round((GVAR(workingMemory) select 12) * 15.4323584))]; + ctrlSetText [120010, str(round((GVAR(workingMemory) select 12) * 15.4323584))]; } else { - ctrlSetText [120010, Str(Round((GVAR(workingMemory) select 12) * 10) / 10)]; + ctrlSetText [120010, str(round((GVAR(workingMemory) select 12) * 10) / 10)]; }; if (GVAR(currentUnit) != 2) then { - ctrlSetText [120020, Str(Round((GVAR(workingMemory) select 13) / 10 / 2.54 * 1000) / 1000)]; + ctrlSetText [120020, str(round((GVAR(workingMemory) select 13) / 10 / 2.54 * 1000) / 1000)]; } else { - ctrlSetText [120020, Str(Round((GVAR(workingMemory) select 13) / 10 * 1000) / 1000)]; + ctrlSetText [120020, str(round((GVAR(workingMemory) select 13) / 10 * 1000) / 1000)]; }; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { - ctrlSetText [120030, Str(Round((GVAR(workingMemory) select 15) * 1000) / 1000)]; + ctrlSetText [120030, str(round((GVAR(workingMemory) select 15) * 1000) / 1000)]; } else { - ctrlSetText [120030, Str(Round((GVAR(workingMemory) select 4) * -1000 * 1000) / 1000)]; + ctrlSetText [120030, str(round((GVAR(workingMemory) select 4) * -1000 * 1000) / 1000)]; }; if (GVAR(currentUnit) != 2) then { - ctrlSetText [120040, Str(Round((GVAR(workingMemory) select 14) / 2.54 * 10) / 10)]; + ctrlSetText [120040, str(round((GVAR(workingMemory) select 14) / 2.54 * 10) / 10)]; } else { - ctrlSetText [120040, Str(Round((GVAR(workingMemory) select 14) * 100) / 100)]; + ctrlSetText [120040, str(round((GVAR(workingMemory) select 14) * 100) / 100)]; }; if (GVAR(currentUnit) != 2) then { - ctrlSetText [120050, Str(Round((GVAR(workingMemory) select 1) * 3.2808399))]; + ctrlSetText [120050, str(round((GVAR(workingMemory) select 1) * 3.2808399))]; } else { - ctrlSetText [120050, Str(Round(GVAR(workingMemory) select 1))]; + ctrlSetText [120050, str(round(GVAR(workingMemory) select 1))]; }; if (GVAR(currentUnit) == 1) then { - ctrlSetText [120060, Str(Round((GVAR(workingMemory) select 2) * 1.0936133))]; + ctrlSetText [120060, str(round((GVAR(workingMemory) select 2) * 1.0936133))]; } else { - ctrlSetText [120060, Str(Round(GVAR(workingMemory) select 2))]; + ctrlSetText [120060, str(round(GVAR(workingMemory) select 2))]; }; if (GVAR(currentUnit) == 0) then { ctrlSetText [120061, "*"]; diff --git a/addons/atragmx/functions/fnc_update_inclination_angle.sqf b/addons/atragmx/functions/fnc_update_inclination_angle.sqf index 532b3d94e8f..b7ae40160c6 100644 --- a/addons/atragmx/functions/fnc_update_inclination_angle.sqf +++ b/addons/atragmx/functions/fnc_update_inclination_angle.sqf @@ -19,7 +19,7 @@ private _inclinationAngleCosine = 0.5 max parseNumber(ctrlText 140041) min 1; private _inclinationAngleDegree = -60 max parseNumber(ctrlText 140040) min 60; if (_this == 0) then { - ctrlSetText [140040, Str(round(acos(_inclinationAngleCosine)))]; + ctrlSetText [140040, str(round(acos(_inclinationAngleCosine)))]; } else { - ctrlSetText [140041, Str(round(cos(_inclinationAngleDegree) * 100) / 100)]; + ctrlSetText [140041, str(round(cos(_inclinationAngleDegree) * 100) / 100)]; }; diff --git a/addons/atragmx/functions/fnc_update_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_update_muzzle_velocity_data.sqf index 23193aa9036..36af09d6427 100644 --- a/addons/atragmx/functions/fnc_update_muzzle_velocity_data.sqf +++ b/addons/atragmx/functions/fnc_update_muzzle_velocity_data.sqf @@ -17,12 +17,12 @@ if (GVAR(currentUnit) == 2) then { // Temperatures - {ctrlSetText [_x, Str(Round((((GVAR(workingMemory) select 18) select _forEachIndex) select 0) * 10) / 10)]} forEach [160021, 160022, 160023, 160024, 160025, 160026, 160027]; + {ctrlSetText [_x, str(round((((GVAR(workingMemory) select 18) select _forEachIndex) select 0) * 10) / 10)]} forEach [160021, 160022, 160023, 160024, 160025, 160026, 160027]; // Muzzle velocities - {ctrlSetText [_x, Str(Round(((GVAR(workingMemory) select 18) select _forEachIndex) select 1))]} forEach [160031, 160032, 160033, 160034, 160035, 160036, 160037]; + {ctrlSetText [_x, str(round(((GVAR(workingMemory) select 18) select _forEachIndex) select 1))]} forEach [160031, 160032, 160033, 160034, 160035, 160036, 160037]; } else { // Temperatures - {ctrlSetText [_x, Str(Round(((((GVAR(workingMemory) select 18) select _forEachIndex) select 0) * 1.8 + 32) * 10) / 10)]} forEach [160021, 160022, 160023, 160024, 160025, 160026, 160027]; + {ctrlSetText [_x, str(round(((((GVAR(workingMemory) select 18) select _forEachIndex) select 0) * 1.8 + 32) * 10) / 10)]} forEach [160021, 160022, 160023, 160024, 160025, 160026, 160027]; // Muzzle velocities - {ctrlSetText [_x, Str(Round((((GVAR(workingMemory) select 18) select _forEachIndex) select 1) * 3.2808399))]} forEach [160031, 160032, 160033, 160034, 160035, 160036, 160037]; + {ctrlSetText [_x, str(round((((GVAR(workingMemory) select 18) select _forEachIndex) select 1) * 3.2808399))]} forEach [160031, 160032, 160033, 160034, 160035, 160036, 160037]; }; diff --git a/addons/atragmx/functions/fnc_update_range_card.sqf b/addons/atragmx/functions/fnc_update_range_card.sqf index 066bd651746..e280c7d137a 100644 --- a/addons/atragmx/functions/fnc_update_range_card.sqf +++ b/addons/atragmx/functions/fnc_update_range_card.sqf @@ -59,16 +59,16 @@ private _speedOfSound = GVAR(temperature) call EFUNC(weather,calculateSpeedOfSou private _clickNumber = GVAR(workingMemory) select 8; private _clickInterval = _clickSize / _clickNumber; - _elevation = Round(_elevation / _clickInterval); - _windage1 = Round(_windage1 / _clickInterval); - _windage2 = Round(_windage2 / _clickInterval); + _elevation = round(_elevation / _clickInterval); + _windage1 = round(_windage1 / _clickInterval); + _windage2 = round(_windage2 / _clickInterval); }; }; - private _elevationOutput = Str(Round(_elevation * 100) / 100); - private _windageOutput = Str(Round(_windage1 * 100) / 100); + private _elevationOutput = str(round(_elevation * 100) / 100); + private _windageOutput = str(round(_windage1 * 100) / 100); - private _rangeOutput = Str(_range); + private _rangeOutput = str(_range); if (_velocity < _speedOfSound) then { _rangeOutput = _rangeOutput + "*"; }; @@ -80,19 +80,19 @@ private _speedOfSound = GVAR(temperature) call EFUNC(weather,calculateSpeedOfSou switch (GVAR(rangeCardCurrentColumn)) do { case 0: { if (GVAR(showWind2)) then { - _lastColumnOutput = Str(Round(_windage2 * 100) / 100); + _lastColumnOutput = str(round(_windage2 * 100) / 100); } else { - _lastColumnOutput = Str(Round(_lead * 100) / 100); + _lastColumnOutput = str(round(_lead * 100) / 100); }; }; case 1: { - _lastColumnOutput = Str(Round(_velocity)); + _lastColumnOutput = str(round(_velocity)); }; case 2: { - _lastColumnOutput = Str(Round(_kineticEnergy)); + _lastColumnOutput = str(round(_kineticEnergy)); }; case 3: { - _lastColumnOutput = Str(Round(_TOF * 100) / 100); + _lastColumnOutput = str(round(_TOF * 100) / 100); } }; diff --git a/addons/atragmx/functions/fnc_update_result.sqf b/addons/atragmx/functions/fnc_update_result.sqf index cfd8f460a93..3e8d4ef9bd3 100644 --- a/addons/atragmx/functions/fnc_update_result.sqf +++ b/addons/atragmx/functions/fnc_update_result.sqf @@ -69,16 +69,16 @@ switch (GVAR(currentScopeUnit)) do { private _clickNumber = GVAR(workingMemory) select 8; private _clickInterval = _clickSize / _clickNumber; - _elevationAbs = Round(_elevationAbs / _clickInterval); - _windageAbs = Round(_windageAbs / _clickInterval); + _elevationAbs = round(_elevationAbs / _clickInterval); + _windageAbs = round(_windageAbs / _clickInterval); - _wind2 = Round(_wind2 / _clickInterval); + _wind2 = round(_wind2 / _clickInterval); - _elevationRel = Round(_elevationRel / _clickInterval); - _windageRel = Round(_windageRel / _clickInterval); + _elevationRel = round(_elevationRel / _clickInterval); + _windageRel = round(_windageRel / _clickInterval); - _elevationCur = Round(_elevationCur / _clickInterval); - _windageCur = Round(_windageCur / _clickInterval); + _elevationCur = round(_elevationCur / _clickInterval); + _windageCur = round(_windageCur / _clickInterval); }; }; @@ -88,7 +88,7 @@ if (GVAR(showWind2)) then { ctrlSetText [42, "Lead"]; }; -_elevationAbs = Round(_elevationAbs * 100) / 100; +_elevationAbs = round(_elevationAbs * 100) / 100; if (_elevationAbs > 0) then { ctrlSetText [400, str abs _elevationAbs]; } else { @@ -98,7 +98,7 @@ if (_elevationAbs > 0) then { ctrlSetText [400, "0.0"]; }; }; -_elevationRel = Round(_elevationRel * 100) / 100; +_elevationRel = round(_elevationRel * 100) / 100; if (_elevationRel > 0) then { ctrlSetText [401, str abs _elevationRel]; } else { @@ -108,7 +108,7 @@ if (_elevationRel > 0) then { ctrlSetText [401, "0.0"]; }; }; -_elevationCur = Round(_elevationCur * 100) / 100; +_elevationCur = round(_elevationCur * 100) / 100; if (_elevationCur > 0) then { ctrlSetText [402, str abs _elevationCur]; } else { @@ -119,7 +119,7 @@ if (_elevationCur > 0) then { }; }; -_windageAbs = Round(_windageAbs * 100) / 100; +_windageAbs = round(_windageAbs * 100) / 100; if (_windageAbs > 0) then { ctrlSetText [410, format["%1R", abs(_windageAbs)]]; } else { @@ -129,7 +129,7 @@ if (_windageAbs > 0) then { ctrlSetText [410, "0.0"]; }; }; -_windageRel = Round(_windageRel * 100) / 100; +_windageRel = round(_windageRel * 100) / 100; if (_windageRel > 0) then { ctrlSetText [411, format["%1R", abs(_windageRel)]]; } else { @@ -139,7 +139,7 @@ if (_windageRel > 0) then { ctrlSetText [411, "0.0"]; }; }; -_windageCur = Round(_windageCur * 100) / 100; +_windageCur = round(_windageCur * 100) / 100; if (_windageCur > 0) then { ctrlSetText [412, format["%1R", abs(_windageCur)]]; } else { @@ -151,7 +151,7 @@ if (_windageCur > 0) then { }; if (GVAR(showWind2)) then { - _wind2 = Round(_wind2 * 100) / 100; + _wind2 = round(_wind2 * 100) / 100; if (_wind2 > 0) then { ctrlSetText [420, format["%1R", abs(_wind2)]]; } else { @@ -162,7 +162,7 @@ if (GVAR(showWind2)) then { }; }; } else { - _lead = Round(_lead * 100) / 100; + _lead = round(_lead * 100) / 100; if (_lead > 0) then { if ((GVAR(targetSpeedDirection) select GVAR(currentTarget)) == 1) then { ctrlSetText [420, format["%1R", abs(_lead)]]; diff --git a/addons/atragmx/functions/fnc_update_scope_unit.sqf b/addons/atragmx/functions/fnc_update_scope_unit.sqf index d1f0e9cf170..e72b490ef03 100644 --- a/addons/atragmx/functions/fnc_update_scope_unit.sqf +++ b/addons/atragmx/functions/fnc_update_scope_unit.sqf @@ -16,7 +16,7 @@ */ ctrlSetText [2000, GVAR(scopeUnits) select GVAR(currentScopeUnit)]; -ctrlSetText [2001, Str(GVAR(currentScopeClickNumber))]; +ctrlSetText [2001, str(GVAR(currentScopeClickNumber))]; if (GVAR(currentScopeUnit) == 3) then { ctrlSetText [5000, format["Clicks=%1", GVAR(currentScopeClickNumber)]]; diff --git a/addons/atragmx/functions/fnc_update_target.sqf b/addons/atragmx/functions/fnc_update_target.sqf index a87ba9ba54f..df37e7848e4 100644 --- a/addons/atragmx/functions/fnc_update_target.sqf +++ b/addons/atragmx/functions/fnc_update_target.sqf @@ -17,32 +17,32 @@ if (GVAR(showWind2)) then { if (GVAR(currentUnit) != 2) then { - ctrlSetText [300, format["%1/%2", Round((GVAR(windSpeed1) select GVAR(currentTarget)) * 2.23693629), Round((GVAR(windSpeed2) select GVAR(currentTarget)) * 2.23693629)]]; + ctrlSetText [300, format["%1/%2", round((GVAR(windSpeed1) select GVAR(currentTarget)) * 2.23693629), round((GVAR(windSpeed2) select GVAR(currentTarget)) * 2.23693629)]]; } else { - ctrlSetText [300, format["%1/%2", Round(GVAR(windSpeed1) select GVAR(currentTarget)), Round(GVAR(windSpeed2) select GVAR(currentTarget))]]; + ctrlSetText [300, format["%1/%2", round(GVAR(windSpeed1) select GVAR(currentTarget)), round(GVAR(windSpeed2) select GVAR(currentTarget))]]; }; } else { if (GVAR(currentUnit) != 2) then { - ctrlSetText [300, Str(Round((GVAR(windSpeed1) select GVAR(currentTarget)) * 2.23693629 * 100) / 100)]; + ctrlSetText [300, str(round((GVAR(windSpeed1) select GVAR(currentTarget)) * 2.23693629 * 100) / 100)]; } else { - ctrlSetText [300, Str(Round((GVAR(windSpeed1) select GVAR(currentTarget)) * 100) / 100)]; + ctrlSetText [300, str(round((GVAR(windSpeed1) select GVAR(currentTarget)) * 100) / 100)]; }; }; -ctrlSetText [310, Str(Round((GVAR(windDirection) select GVAR(currentTarget))))]; -ctrlSetText [320, Str(Round((GVAR(inclinationAngle) select GVAR(currentTarget))))]; +ctrlSetText [310, str(round((GVAR(windDirection) select GVAR(currentTarget))))]; +ctrlSetText [320, str(round((GVAR(inclinationAngle) select GVAR(currentTarget))))]; if (GVAR(currentUnit) != 2) then { - ctrlSetText [330, Str(Round((GVAR(targetSpeed) select GVAR(currentTarget)) * 2.23693629 * 100) / 100)]; + ctrlSetText [330, str(round((GVAR(targetSpeed) select GVAR(currentTarget)) * 2.23693629 * 100) / 100)]; } else { - ctrlSetText [330, Str(Round((GVAR(targetSpeed) select GVAR(currentTarget)) * 100) / 100)]; + ctrlSetText [330, str(round((GVAR(targetSpeed) select GVAR(currentTarget)) * 100) / 100)]; }; switch (GVAR(currentUnit)) do { case 0: { - ctrlSetText [340, format["*%1", Round((GVAR(targetRange) select GVAR(currentTarget)))]]; + ctrlSetText [340, format["*%1", round((GVAR(targetRange) select GVAR(currentTarget)))]]; }; case 1: { - ctrlSetText [340, Str(Round((GVAR(targetRange) select GVAR(currentTarget)) * 1.0936133))]; + ctrlSetText [340, str(round((GVAR(targetRange) select GVAR(currentTarget)) * 1.0936133))]; }; case 2: { - ctrlSetText [340, Str(Round((GVAR(targetRange) select GVAR(currentTarget))))]; + ctrlSetText [340, str(round((GVAR(targetRange) select GVAR(currentTarget))))]; }; }; diff --git a/addons/atragmx/functions/fnc_update_target_data.sqf b/addons/atragmx/functions/fnc_update_target_data.sqf index 92b5df50a06..f47d0401ddb 100644 --- a/addons/atragmx/functions/fnc_update_target_data.sqf +++ b/addons/atragmx/functions/fnc_update_target_data.sqf @@ -15,22 +15,22 @@ * Public: No */ -ctrlSetText [140000, Str(Round((GVAR(latitude) select GVAR(currentTarget)) * 100) / 100)]; -ctrlSetText [140010, Str(Round((GVAR(directionOfFire) select GVAR(currentTarget)) * 100) / 100)]; +ctrlSetText [140000, str(round((GVAR(latitude) select GVAR(currentTarget)) * 100) / 100)]; +ctrlSetText [140010, str(round((GVAR(directionOfFire) select GVAR(currentTarget)) * 100) / 100)]; if (GVAR(currentUnit) != 2) then { - ctrlSetText [140020, Str(Round((GVAR(windSpeed1) select GVAR(currentTarget)) * 2.23693629 * 100) / 100)]; - ctrlSetText [140021, Str(Round((GVAR(windSpeed2) select GVAR(currentTarget)) * 2.23693629 * 100) / 100)]; + ctrlSetText [140020, str(round((GVAR(windSpeed1) select GVAR(currentTarget)) * 2.23693629 * 100) / 100)]; + ctrlSetText [140021, str(round((GVAR(windSpeed2) select GVAR(currentTarget)) * 2.23693629 * 100) / 100)]; } else { - ctrlSetText [140020, Str(Round((GVAR(windSpeed1) select GVAR(currentTarget)) * 100) / 100)]; - ctrlSetText [140021, Str(Round((GVAR(windSpeed2) select GVAR(currentTarget)) * 100) / 100)]; + ctrlSetText [140020, str(round((GVAR(windSpeed1) select GVAR(currentTarget)) * 100) / 100)]; + ctrlSetText [140021, str(round((GVAR(windSpeed2) select GVAR(currentTarget)) * 100) / 100)]; }; -ctrlSetText [140030, Str(Round((GVAR(windDirection) select GVAR(currentTarget))))]; -ctrlSetText [140040, Str(Round((GVAR(inclinationAngle) select GVAR(currentTarget))))]; -ctrlSetText [140041, Str(Round(cos(GVAR(inclinationAngle) select GVAR(currentTarget)) * 100) / 100)]; +ctrlSetText [140030, str(round((GVAR(windDirection) select GVAR(currentTarget))))]; +ctrlSetText [140040, str(round((GVAR(inclinationAngle) select GVAR(currentTarget))))]; +ctrlSetText [140041, str(round(cos(GVAR(inclinationAngle) select GVAR(currentTarget)) * 100) / 100)]; if (GVAR(currentUnit) != 2) then { - ctrlSetText [140050, Str(Round((GVAR(targetSpeed) select GVAR(currentTarget)) * 2.23693629 * 100) / 100)]; + ctrlSetText [140050, str(round((GVAR(targetSpeed) select GVAR(currentTarget)) * 2.23693629 * 100) / 100)]; } else { - ctrlSetText [140050, Str(Round((GVAR(targetSpeed) select GVAR(currentTarget)) * 100) / 100)]; + ctrlSetText [140050, str(round((GVAR(targetSpeed) select GVAR(currentTarget)) * 100) / 100)]; }; if ((GVAR(targetSpeedDirection) select GVAR(currentTarget)) == 1) then { ctrlSetText [140051, ">"]; @@ -38,9 +38,9 @@ if ((GVAR(targetSpeedDirection) select GVAR(currentTarget)) == 1) then { ctrlSetText [140051, "<"]; }; if (GVAR(currentUnit) == 1) then { - ctrlSetText [140060, Str(Round((GVAR(targetRange) select GVAR(currentTarget)) * 1.0936133))]; + ctrlSetText [140060, str(round((GVAR(targetRange) select GVAR(currentTarget)) * 1.0936133))]; } else { - ctrlSetText [140060, Str(Round((GVAR(targetRange) select GVAR(currentTarget))))]; + ctrlSetText [140060, str(round((GVAR(targetRange) select GVAR(currentTarget))))]; }; if (GVAR(currentUnit) == 0) then { ctrlSetText [140061, "*"]; diff --git a/addons/atragmx/functions/fnc_update_truing_drop_data.sqf b/addons/atragmx/functions/fnc_update_truing_drop_data.sqf index ad0f0dda0e8..1180b689cd0 100644 --- a/addons/atragmx/functions/fnc_update_truing_drop_data.sqf +++ b/addons/atragmx/functions/fnc_update_truing_drop_data.sqf @@ -16,11 +16,11 @@ */ if (GVAR(currentUnit) == 2) then { - ctrlSetText [18011, Str(Round(GVAR(truingDropRangeData) select 0))]; - ctrlSetText [18012, Str(Round(GVAR(truingDropRangeData) select 1))]; + ctrlSetText [18011, str(round(GVAR(truingDropRangeData) select 0))]; + ctrlSetText [18012, str(round(GVAR(truingDropRangeData) select 1))]; } else { - ctrlSetText [18011, Str(Round((GVAR(truingDropRangeData) select 0) * 1.0936133))]; - ctrlSetText [18012, Str(Round((GVAR(truingDropRangeData) select 1) * 1.0936133))]; + ctrlSetText [18011, str(round((GVAR(truingDropRangeData) select 0) * 1.0936133))]; + ctrlSetText [18012, str(round((GVAR(truingDropRangeData) select 1) * 1.0936133))]; }; if (GVAR(truingDropMode) == 0) then { @@ -53,25 +53,25 @@ switch (_dropUnit) do { }; }; -ctrlSetText [18006, Str(Round((_dropData select 0) * 100) / 100)]; -ctrlSetText [18013, Str(Round((_dropData select 1) * 100) / 100)]; -ctrlSetText [18014, Str(Round((_dropData select 2) * 100) / 100)]; +ctrlSetText [18006, str(round((_dropData select 0) * 100) / 100)]; +ctrlSetText [18013, str(round((_dropData select 1) * 100) / 100)]; +ctrlSetText [18014, str(round((_dropData select 2) * 100) / 100)]; if (GVAR(currentUnit) != 2) then { - ctrlSetText [18007, Str(Round((GVAR(workingMemory) select 1) * 3.2808399))]; - ctrlSetText [18016, Str(Round((GVAR(workingMemory) select 1) * 3.2808399))]; + ctrlSetText [18007, str(round((GVAR(workingMemory) select 1) * 3.2808399))]; + ctrlSetText [18016, str(round((GVAR(workingMemory) select 1) * 3.2808399))]; if (GVAR(truingDropMuzzleVelocity) > 0) then { - ctrlSetText [18016, Str(Round(GVAR(truingDropMuzzleVelocity) * 3.2808399))]; + ctrlSetText [18016, str(round(GVAR(truingDropMuzzleVelocity) * 3.2808399))]; }; } else { - ctrlSetText [18007, Str(Round(GVAR(workingMemory) select 1))]; - ctrlSetText [18016, Str(Round(GVAR(workingMemory) select 1))]; + ctrlSetText [18007, str(round(GVAR(workingMemory) select 1))]; + ctrlSetText [18016, str(round(GVAR(workingMemory) select 1))]; if (GVAR(truingDropMuzzleVelocity) > 0) then { - ctrlSetText [18016, Str(Round(GVAR(truingDropMuzzleVelocity)))]; + ctrlSetText [18016, str(round(GVAR(truingDropMuzzleVelocity)))]; }; }; -ctrlSetText [18008, Str(Round((GVAR(workingMemory) select 15) * 1000) / 1000)]; -ctrlSetText [18017, Str(Round((GVAR(workingMemory) select 15) * 1000) / 1000)]; +ctrlSetText [18008, str(round((GVAR(workingMemory) select 15) * 1000) / 1000)]; +ctrlSetText [18017, str(round((GVAR(workingMemory) select 15) * 1000) / 1000)]; if (GVAR(truingDropC1) > 0) then { - ctrlSetText [18017, Str(Round(GVAR(truingDropC1) * 1000) / 1000)]; + ctrlSetText [18017, str(round(GVAR(truingDropC1) * 1000) / 1000)]; }; diff --git a/addons/atragmx/functions/fnc_update_zero_range.sqf b/addons/atragmx/functions/fnc_update_zero_range.sqf index 023a5a7ee29..d29ad18b688 100644 --- a/addons/atragmx/functions/fnc_update_zero_range.sqf +++ b/addons/atragmx/functions/fnc_update_zero_range.sqf @@ -35,12 +35,26 @@ if (!GVAR(atmosphereModeTBH)) then { _relativeHumidity = 0.5; }; -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) +private _scopeBaseAngle = if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { + parseNumber (("ace" callExtension ["ballistics:zero_vanilla", [ + _zeroRange, + _muzzleVelocity, + _airFriction, + _boreHeight + ]]) select 0) } else { - private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, _temperature, _barometricPressure, _relativeHumidity, _bc, _dragModel, _atmosphereModel]; - (parseNumber _zeroAngle) + parseNumber (("ace" callExtension ["ballistics:zero_advanced", [ + _zeroRange, + _muzzleVelocity, + _airFriction, + _boreHeight, + _temperature, + _barometricPressure, + _relativeHumidity, + _bc, + _dragModel, + _atmosphereModel + ]]) select 0) }; GVAR(workingMemory) set [2, _zeroRange]; diff --git a/addons/attach/functions/fnc_attach.sqf b/addons/attach/functions/fnc_attach.sqf index 6a0c4082711..d1e9f129875 100644 --- a/addons/attach/functions/fnc_attach.sqf +++ b/addons/attach/functions/fnc_attach.sqf @@ -50,8 +50,8 @@ if (_unit == _attachToVehicle) then { //Self Attachment } else { GVAR(placeAction) = PLACE_WAITING; - [_unit, "forceWalk", "ACE_Attach", true] call EFUNC(common,statusEffect_set); - [_unit, "blockThrow", "ACE_Attach", true] call EFUNC(common,statusEffect_set); + [_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + [_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); [{[localize LSTRING(PlaceAction), ""] call EFUNC(interaction,showMouseHint)}, []] call CBA_fnc_execNextFrame; _unit setVariable [QGVAR(placeActionEH), [_unit, "DefaultAction", {true}, {GVAR(placeAction) = PLACE_APPROVE;}] call EFUNC(common,AddActionEventHandler)]; @@ -88,8 +88,8 @@ if (_unit == _attachToVehicle) then { //Self Attachment {!([_attachToVehicle, _unit, _itemClassname] call FUNC(canAttach))}) then { [_idPFH] call CBA_fnc_removePerFrameHandler; - [_unit, "forceWalk", "ACE_Attach", false] call EFUNC(common,statusEffect_set); - [_unit, "blockThrow", "ACE_Attach", false] call EFUNC(common,statusEffect_set); + [_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); + [_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); [] call EFUNC(interaction,hideMouseHint); [_unit, "DefaultAction", (_unit getVariable [QGVAR(placeActionEH), -1])] call EFUNC(common,removeActionEventHandler); _unit removeAction _actionID; diff --git a/addons/attach/functions/fnc_canDetach.sqf b/addons/attach/functions/fnc_canDetach.sqf index 7202ba410fc..9b70d35ff4e 100644 --- a/addons/attach/functions/fnc_canDetach.sqf +++ b/addons/attach/functions/fnc_canDetach.sqf @@ -32,7 +32,7 @@ private _inRange = false; _attachedList deleteAt _forEachIndex; _attachToVehicle setVariable [QGVAR(attached), _attachedList, true]; }; - if (((getPos _unit) distance2d (getPos _xObject)) < 4) exitWith {_inRange = true}; + if (((getPos _unit) distance2D (getPos _xObject)) < 4) exitWith {_inRange = true}; } forEach _attachedList; _inRange && diff --git a/addons/attach/functions/fnc_detach.sqf b/addons/attach/functions/fnc_detach.sqf index ec87f96dd0f..8eab98e0720 100644 --- a/addons/attach/functions/fnc_detach.sqf +++ b/addons/attach/functions/fnc_detach.sqf @@ -31,8 +31,8 @@ private _minDistance = 1000; { _x params ["_xObject", "_xItemName"]; - if (((getPos _unit) distance2d (getPos _xObject)) < _minDistance) then { - _minDistance = ((getPos _unit) distance2d (getPos _xObject)); + if (((getPos _unit) distance2D (getPos _xObject)) < _minDistance) then { + _minDistance = ((getPos _unit) distance2D (getPos _xObject)); _attachedObject = _xObject; _itemName = _xItemName; _attachedIndex = _forEachIndex; @@ -57,7 +57,7 @@ if (!_isChemlight) then { _unit addItem _itemName; }; -if (toLower _itemName in ["b_ir_grenade", "o_ir_grenade", "i_ir_grenade"]) then { +if (toLowerANSI _itemName in ["b_ir_grenade", "o_ir_grenade", "i_ir_grenade"]) then { // Hack for dealing with X_IR_Grenade effect not dissapearing on deleteVehicle detach _attachedObject; _attachedObject setPos ((getPos _unit) vectorAdd [0, 0, -1000]); diff --git a/addons/attach/functions/fnc_handleKilled.sqf b/addons/attach/functions/fnc_handleKilled.sqf index ef08aff3058..2183b05b426 100644 --- a/addons/attach/functions/fnc_handleKilled.sqf +++ b/addons/attach/functions/fnc_handleKilled.sqf @@ -28,7 +28,7 @@ if (_attachedList isEqualTo []) exitWith {}; TRACE_2("detaching",_xObject,_deadUnit); detach _xObject; //If it's a vehicle, also delete the attached - if (!(_deadUnit isKindOf "CAManBase")) then { + if !(_deadUnit isKindOf "CAManBase") then { _xObject setPos ((getPos _deadUnit) vectorAdd [0, 0, -1000]); [{deleteVehicle (_this select 0)}, [_xObject], 2] call CBA_fnc_waitAndExecute; }; diff --git a/addons/attach/functions/fnc_placeApprove.sqf b/addons/attach/functions/fnc_placeApprove.sqf index 2f0c4d6b751..9e9f8effba4 100644 --- a/addons/attach/functions/fnc_placeApprove.sqf +++ b/addons/attach/functions/fnc_placeApprove.sqf @@ -48,10 +48,10 @@ while {(_closeInMax - _closeInMin) > 0.01} do { { if (_doesIntersect) exitWith {}; private _startingPosShifted = _startingPosition vectorAdd _x; - private _startASL = if (surfaceIsWater _startingPosShifted) then {_startingPosShifted} else {ATLtoASL _startingPosShifted}; + private _startASL = if (surfaceIsWater _startingPosShifted) then {_startingPosShifted} else {ATLToASL _startingPosShifted}; { private _endPosShifted = _endPosTest vectorAdd _x; - private _endASL = if (surfaceIsWater _startingPosShifted) then {_endPosShifted} else {ATLtoASL _endPosShifted}; + private _endASL = if (surfaceIsWater _startingPosShifted) then {_endPosShifted} else {ATLToASL _endPosShifted}; #ifdef DRAW_ATTACH_SCAN [{ diff --git a/addons/ballistics/stringtable.xml b/addons/ballistics/stringtable.xml index aa746e543ff..58d46f0d4f9 100644 --- a/addons/ballistics/stringtable.xml +++ b/addons/ballistics/stringtable.xml @@ -256,7 +256,7 @@ Chumbo Grosso #0 Calibre Doze 2 Tiros 12 Калибр 2 патр. #0 Картечь 12 kalibre 2 mermi #0 İrisaçma - 12 게이지 2발 #00 벅샷 + 12 게이지 2발 #0 벅샷 12 Gauge 2Rnd #1 Buckshot @@ -479,7 +479,7 @@ 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.5x47mm 20발 들이 탄창 (Scenar제 HPBT) 6.5x47毫米 20發 彈匣 (拉普 空尖艇尾狙擊專用彈) 6.5x47 mm 20发 弹匣(HPBT Scenar) 6.5x47 mm 20Rnd Mag (HPBT Scenar) @@ -513,7 +513,7 @@ 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.5x47mm (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 @@ -530,7 +530,7 @@ 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.5mm 크리드무어 20발 들이 탄창 6.5毫米 20發 彈匣 (克里德莫爾(CM) 狙擊專用彈) 6.5 mm 20发 弹匣(Creedmor) 6.5 mm Creedmor 20Rnd Mag @@ -581,7 +581,7 @@ 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.8mm 10발 들이 탄창 (DBP88) 5.8毫米 10發 彈匣 (DBP88) 5.8 mm 10发 弹匣(DBP88) 5.8 mm DBP88 10Rnd Mag @@ -633,7 +633,7 @@ Caricatore 6.5 mm 30cp Traccianti IR-DIM Магазин из 30-ти 6,5 мм ИК-трассирующих 6.5 mm 30Rnd IR-DIM トレーサー ケースレスマガジン - 30발 들이 6.5mm IR-DIM 예광탄 탄창 + 6.5mm 30발 들이 탄창 (IR-DIM 예광탄) 6.5毫米 30發 低視度紅外線曳光彈 彈匣 6.5 mm 30发 弹匣(红外曳光) 6.5 mm 30Rnd Tracer IR-DIM Mag @@ -667,7 +667,7 @@ Calibro: 6.5x39 mm Tracciante IR-DIM <br />Munizioni: 30<br />In uso su: MX/C/M/SW/3GL Калибр: 6,5x39 мм ИК-трассирующие<br />Патронов: 30<br />Используются с: MX/C/M/SW/3GL 口径: 6.5x39 mm IR-DIM トレーサー<br />装填数: 30<br />次で使用: MX/C/M/SW/3GL - 구경: 6.5x39mm 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 @@ -684,7 +684,7 @@ Caricatore 6.5 mm 30cp Sil. Магазин из 30-ти 6,5 мм дозвуковых 6.5 mm 30Rnd 亜音速弾 マガジン - 30발 들이 6.5mm 아음속탄 탄창 + 6.5mm 30발 들이 탄창 (아음속탄) 6.5毫米 30發 消音彈 彈匣 6.5 mm 30发 弹匣(亚音速) 6.5 mm 30Rnd SD Mag @@ -735,7 +735,7 @@ Caricatore 6.5 mm 30cp AP Магазин из 30-ти 6,5 мм бронебойных 6.5 mm 30Rnd 徹甲弾 マガジン - 30발 들이 6.5mm 철갑탄 탄창 + 6.5mm 30발 들이 탄창 (철갑탄) 6.5毫米30發 穿甲彈 彈匣 6.5 mm 30发 弹匣(穿甲) 6.5 mm 30Rnd AP Mag @@ -787,7 +787,7 @@ Caricatore 6.5 mm 30cp Traccianti IR-DIM Магазин из 30-ти 6,5 мм ИК-трассирующих 6.5 mm 30Rnd IR-DIM トレーサー マガジン - 30발 들이 6.5mm IR-DIM 예광탄 탄창 + 6.5mm 30발 들이 탄창 (IR-DIM 예광탄) 6.5毫米 30發 低視度紅外線曳光彈 彈匣 6.5 mm 30发 弹匣(红外曳光) 6.5 mm 30Rnd Tracer IR-DIM Mag @@ -821,7 +821,7 @@ Calibro: 6.5x39 mm Tracciant IR-DIM<br />Munizioni: 30<br />In uso su: Katiba Калибр: 6,5x39 мм ИК-трассирующие<br />Патронов: 30<br />Используются с: Katiba 口径: 6.5x39 mm IR-DIM トレーサー<br />装填数: 30<br />次で使用: Katiba - 구경: 6.5x39mm IR-DIM 예광탄<br/>장탄수: 30<br/>사용처: KH-2002 + 구경: 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 @@ -838,7 +838,7 @@ Caricatore 6.5 mm 30cp Sil. Магазин из 30-ти 6,5 мм дозвуковых 6.5 mm 30Rnd 亜音速弾 マガジン - 30발 들이 6.5mm 아음속탄 탄창 + 6.5mm 30발 들이 탄창 (아음속탄) 6.5毫米 30發 消音彈 彈匣 6.5 mm 30发 弹匣(亚音速) 6.5 mm 30Rnd SD Mag @@ -889,7 +889,7 @@ Caricatore 6.5 mm 30cp AP Магазин из 30-ти 6,5 мм бронебойных 6.5 mm 30Rnd 徹甲弾 マガジン - 30발 들이 6.5mm 철갑탄 탄창 + 6.5mm 30발 들이 탄창 (철갑탄) 6.5毫米 30發 穿甲彈 彈匣 6.5 mm 30发 弹匣(穿甲) 6.5 mm 30Rnd AP Mag @@ -941,7 +941,7 @@ Caricatore 5.56 mm 30cp Traccianti IR-DIM Магазин из 30-ти 5,56 мм ИК-трассирующих 5.56mm 30Rnd IR-DIM トレーサー マガジン - 30발 들이 5.56mm IR-DIM 예광탄 탄창 + 5.56mm 30발 들이 탄창 (IR-DIM 예광탄) 5.56毫米 30發 低視度紅外線曳光彈 彈匣 5.56 mm 30发 弹匣(红外曳光) 5.56 mm 30rnd Tracer IR-DIM Mag @@ -975,7 +975,7 @@ Calibro: 5.56x45 mm Tracciante IR-DIM<br />Munizioni: 30<br />In uso su: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR Калибр: 5,56x45 мм ИК-трассирующие<br />Патронов: 30<br />Используются с: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR 口径: 5.56x45 mm IR-DIM トレーサー<br />装填数: 30<br />次で使用: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - 구경: 5.56x45 mm IR-DIM 예광탄<br/>장탄수: 30<br/>사용처: CTAR-21, TAR-21/GTAR-21 EGLM, F2000/택티컬/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 @@ -993,7 +993,7 @@ Caricatore 7.62 mm 20cp Traccianti Магазин из 20-ти 7,62 мм трассирующих 7.62mm 20Rnd マガジン (トレーサー) - 20발 들이 7.62mm 예광탄 탄창 + 7.62mm 20발 들이 탄창 (예광탄) 7.62毫米 20發 曳光彈 彈匣 7.62 mm 20发 弹匣(曳光) 7.62 mm 20Rnd Mag (Tracer) @@ -1044,7 +1044,7 @@ Caricatore 7.62 mm 20cp Traccianti IR-DIM Магазин из 20-ти 7,62 мм ИК-трассирующих 7.62mm 20Rnd マガジン (IR-DIM) - 20발 들이 7.62mm IR-DIM 예광탄 탄창 + 7.62mm 20발 들이 탄창 (IR-DIM 예광탄) 7.62毫米 20發 低視度紅外線曳光彈 彈匣 7.62 mm 20发 弹匣(红外曳光) 7.62 mm 20Rnd Mag (IR-DIM) @@ -1095,7 +1095,7 @@ Caricatore 7.62 mm 20cp Sil. Магазин из 20-ти 7,62 мм дозвуковых 7.62mm 20Rnd マガジン (亜音速弾) - 20발 들이 7.62mm 아음속탄 탄창 + 7.62mm 20발 들이 탄창 (아음속탄) 7.62毫米 20發 消音彈 彈匣 7.62 mm 20发 弹匣(亚音速) 7.62 mm 20Rnd Mag (SD) @@ -1146,7 +1146,7 @@ Caricatore 7.62 mm 10cp Traccianti Магазин из 10-ти 7,62 мм трассирующих 7.62mm 10Rnd マガジン (トレーサー) - 10발 들이 7.62mm 예광탄 탄창 + 7.62mm 10발 들이 탄창 (예광탄) 7.62毫米 10發 曳光彈 彈匣 7.62 mm 10发 弹匣(曳光) 7.62 mm 10Rnd Mag (Tracer) @@ -1197,7 +1197,7 @@ Caricatore 7.62 mm 10cp Traccianti IR-DIM Магазин из 10-ти 7,62 мм ИК-трассирующих 7.62mm 10Rnd マガジン (IR-DIM) - 10발 들이 7.62mm IR-DIM 예광탄 탄창 + 7.62mm 10발 들이 탄창 (IR-DIM 예광탄) 7.62毫米 10發 低視度紅外線曳光彈 彈匣 7.62 mm 10发 弹匣(红外曳光) 7.62 mm 10Rnd Mag (IR-DIM) @@ -1231,7 +1231,7 @@ 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.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 @@ -1248,7 +1248,7 @@ Caricatore 7.62 mm 10cp Sil. Магазин из 10-ти 7,62 мм дозвуковых 7.62mm 10Rnd マガジン (亜音速弾) - 10발 들이 7.62mm 아음속탄 탄창 + 7.62mm 10발 들이 탄창 (아음속탄) 7.62毫米 10發 消音彈 彈匣 7.62 mm 10发 弹匣(亚音速) 7.62 mm 10Rnd Mag (SD) @@ -1300,7 +1300,7 @@ Cinto de munição .338 NM com 130 cartuchos .338 NM 130-lövedékes nyomkövető heveder .338 NM 130Rnd トレーサー ベルト - 130발 들이 .338구경 노르마 매그넘 예광탄 벨트 + .338구경 노르마 매그넘 130발 들이 벨트 (예광탄) .338 拉普麥格農(NM) 130發 曳光彈 彈鏈 .338 NM 130发 弹链(曳光) .338 NM 130Rnd Tracer Belt @@ -1351,7 +1351,7 @@ 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 130Rnd IR-DIM ベルト - 130발 들이 .338rnrud 노르마 매그넘 IR-DIM 예광탄 벨트 + .338구경 노르마 매그넘 130발 들이 벨트 (IR-DIM 예광탄) .338 拉普麥格農(NM) 130發 低視度紅外線曳光彈 彈鏈 .338 NM 130发 弹链(红外曳光) .338 NM 130Rnd IR-DIM Belt @@ -1385,7 +1385,7 @@ 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구경 노르마 매그넘 IR-DIM 예광탄<br/>장탄수: 130<br/>사용처: LWMMG + 구경: .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 @@ -1402,7 +1402,7 @@ Cinto de munição .338 NM com 130 cartuchos AP .338 NM 130-lövedékes páncéltörő heveder .338 NM 130Rnd 徹甲弾 ベルト - 130발 들이 .338구경 노르마 매그넘 철갑탄 벨트 + .338구경 노르마 매그넘 130발 들이 벨트 (철갑탄) .338 拉普麥格農(NM) 130發 穿甲彈 彈鏈 .338 NM 130发 弹链(穿甲) .338 NM 130Rnd AP Belt @@ -1454,7 +1454,7 @@ 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.3mm 10발 들이 탄창 (예광탄) 9.3毫米 10發 曳光彈 彈匣 9.3 mm 10发 弹匣(曳光) 9.3 mm 10Rnd Tracer Mag @@ -1505,7 +1505,7 @@ 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발 들이 탄창 (IR-DIM 예광탄) 9.3毫米 10發 低視度紅外線曳光彈 彈匣 9.3 mm 10发 弹匣(红外曳光) 9.3 mm 10Rnd Tracer IR-DIM Mag @@ -1539,7 +1539,7 @@ 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.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 @@ -1557,7 +1557,7 @@ 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.3mm 150발 들이 벨트 (예광탄) 9.3毫米 150發 曳光彈 彈鏈 9.3 mm 150发 弹链(曳光) 9.3 mm 150Rnd Tracer Belt @@ -1608,7 +1608,7 @@ 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발 들이 벨트 (IR-DIM 예광탄) 9.3毫米 150發 低視度紅外線曳光彈 彈鏈 9.3 mm 150发 弹链(红外曳光) 9.3 mm 150Rnd Tracer IR-DIM Belt @@ -1642,7 +1642,7 @@ 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.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 @@ -1659,7 +1659,7 @@ 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.3毫米 150發 穿甲彈 彈鏈 9.3 mm 150发 弹链(穿甲) 9.3 mm 150Rnd AP Belt @@ -1710,7 +1710,7 @@ Carregador de 16 cartuchos 9x19 mm 9x19 mm 16-lövedékes tár 9x19 mm 16Rnd マガジン - 17발들이 9x19mm 탄창 + 9x19mm 16발 들이 탄창 9x19毫米 16發 彈匣 9x19 mm 16发 弹匣 9x19 mm 16Rnd Mag @@ -1744,7 +1744,7 @@ Carregador de 16 cartuchos 9x19 mm 9x19 mm 16-lövedékes tár 9x19 mm 30Rnd マガジン - 30발 들이 9x19mm 탄창 + 9x19mm 30발 들이 탄창 9x19毫米 30發 彈匣 9x19 mm 30发 弹匣 9x19 mm 30Rnd Mag @@ -1761,7 +1761,7 @@ Carregador de 30 cartuchos 9x19 mm 9x19 mm 30-lövedékes tár 9x19 mm 30Rnd マガジン - 30발 들이 9x19mm 탄창 + 9x19mm 30발 들이 탄창 9x19毫米 30發 彈匣 9x19 mm 30发 弹匣 9x19 mm 30Rnd Mag @@ -1795,7 +1795,7 @@ Carregador de 30 cartuchos 9x19 mm 9x19 mm 30-lövedékes tár 9x19 mm 30Rnd マガジン - 30발 들이 9x19mm 탄창 + 9x19mm 30발 들이 탄창 9x19毫米 30發 彈匣 9x19 mm 30发 弹匣 9x19 mm 30Rnd Mag @@ -1812,7 +1812,7 @@ 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.62x54mmR 10발 들이 탄창 (예광탄) 7.62x54毫米 10發 曳光彈 彈匣 7.62x54 mm 10发 弹匣(曳光) 7.62x54 mm 10Rnd Tracer Mag @@ -1846,7 +1846,7 @@ 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.62x54mmR 10발 들이 탄창 (예광탄) 7.62x54毫米 10發 曳光彈 彈匣 7.62x54 mm 10发 弹匣(曳光) 7.62x54 mm 10Rnd Tracer Mag @@ -1863,7 +1863,7 @@ 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.5mm 100발 들이 탄창 (IR-DIM 예광탄) 6.5毫米 100發 低視度紅外線曳光彈 彈匣 6.5 mm 100发 弹匣(红外曳光) 6.5 mm 100Rnd Tracer IR-DIM Mag @@ -1897,7 +1897,7 @@ 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.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 @@ -1914,7 +1914,7 @@ 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.5mm 200발 들이 탄창 (IR-DIM 예광탄) 6.5毫米 200發 低視度紅外線曳光彈 彈鏈 6.5 mm 200发 弹链(红外曳光) 6.5 mm 200Rnd Belt Tracer (IR-DIM) @@ -1948,7 +1948,7 @@ 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.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 @@ -1965,7 +1965,7 @@ 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.56mm 30발 들이 탄창 (Mk.262) 5.56毫米 30發 彈匣 (Mk262 狙擊專用彈) 5.56 mm 30发 弹匣(Mk262) 5.56 mm 30Rnd Mag (Mk262) @@ -1999,7 +1999,7 @@ 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.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 @@ -2016,7 +2016,7 @@ 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.56mm 30발 들이 탄창 (Mk.318) 5.56毫米 30發 彈匣 (Mk318 特戰專用彈) 5.56 mm 30发 弹匣(Mk318) 5.56 mm 30Rnd Mag (Mk318) @@ -2067,7 +2067,7 @@ 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.56mm 30발 들이 탄창 (M995) 5.56毫米 30發 彈匣 (M995 穿甲彈) 5.56 mm 30发 弹匣(M995 穿甲) 5.56 mm 30Rnd Mag (M995 AP) @@ -2118,7 +2118,7 @@ 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.62mm 10발 들이 탄창 (M118LR) 7.62毫米 10發 彈匣 (M118LR 狙擊專用彈) 7.62 mm 10发 弹匣(M118LR) 7.62 mm 10Rnd Mag (M118LR) @@ -2152,7 +2152,7 @@ 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.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 @@ -2169,7 +2169,7 @@ 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.62mm 20발 들이 탄창 (M118LR) 7.62毫米 20發 彈匣 (M118LR 狙擊專用彈) 7.62 mm 20发 弹匣(M118LR) 7.62 mm 20Rnd Mag (M118LR) @@ -2203,7 +2203,7 @@ 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.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 @@ -2220,7 +2220,7 @@ 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.62mm 10발 들이 탄창 (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) @@ -2271,7 +2271,7 @@ 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.62mm 20발 들이 탄창 (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) @@ -2305,7 +2305,7 @@ 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.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 @@ -2322,7 +2322,7 @@ 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.62mm 10발 들이 탄창 (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) @@ -2356,7 +2356,7 @@ 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.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 @@ -2373,7 +2373,7 @@ 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.62mm 20발 들이 탄창 (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) @@ -2407,7 +2407,7 @@ 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.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 @@ -2424,7 +2424,7 @@ 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.62mm 10발 들이 탄창 (M993) 7.62毫米 10發 彈匣 (M993 穿甲專用彈) 7.62 mm 10发 弹匣(M993 穿甲) 7.62 mm 10Rnd Mag (M993 AP) @@ -2475,7 +2475,7 @@ 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.62mm 20발 들이 탄창 (M993) 7.62毫米 20發 彈匣 (M993 穿甲專用彈) 7.62 mm 20发 弹匣(M993 穿甲) 7.62 mm 20Rnd Mag (M993 AP) @@ -2526,7 +2526,7 @@ 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구경 윈체스터 매그넘 20발 들이 탄창 (Mk.248 Mod 0) .300 萬能(WM) 20發 彈匣 (Mk248 Mod 0 狙擊專用彈) .300 WM 20发 弹匣(Mk248 Mod 0) .300 WM 20Rnd Mag (Mk248 Mod 0) @@ -2560,7 +2560,7 @@ 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 윈체스터 매그넘 (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 @@ -2577,7 +2577,7 @@ 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발 들이 탄창 (Mk.248 Mod 1) .300 西米 20發 彈匣 (Mk248 Mod 1 狙擊專用彈) .300 WM 20发 弹匣(Mk248 Mod 1) .300 WM 20Rnd Mag (Mk248 Mod 1) @@ -2611,7 +2611,7 @@ 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구경 윈체스터 매그넘 (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 @@ -2628,7 +2628,7 @@ 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제 하이브리드 OTM) .300 西米 20發 彈匣 (Berger Hybrid 空尖比賽專用彈) .300 WM 20发 弹匣(Berger Hybrid 空尖) .300 WM 20Rnd Mag (Berger Hybrid OTM) @@ -2662,7 +2662,7 @@ 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구경 윈체스터 매그넘 (Berger제 하이브리드 오픈 팁 매치탄)<br/>장탄수: 20 口徑: .300 西米 NATO標準 (Berger Hybrid 空尖比賽專用彈)<br />發數: 20 口径:.300 WM 北约(Berger Hybrid 空尖)<br />发数:20 Kalibre: .300 WM NATO (Berger Hybrid OTM)<br />Mermi: 20 @@ -2679,7 +2679,7 @@ 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구경 윈체스터 매그넘 10발 들이 탄창 (Mk.248 Mod 0) .300 萬能(WM) 10發 彈匣 (Mk248 Mod 0 狙擊專用彈) .300 WM 10发 弹匣(Mk248 Mod 0) .300 WM 10Rnd Mag (Mk248 Mod 0) @@ -2713,7 +2713,7 @@ 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 윈체스터 매그넘 (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 @@ -2730,7 +2730,7 @@ 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발 들이 탄창 (Mk.248 Mod 1) .300 西米 10發 彈匣 (Mk248 Mod 1 狙擊專用彈) .300 WM 10发 弹匣(Mk248 Mod 1) .300 WM 10Rnd Mag (Mk248 Mod 1) @@ -2764,7 +2764,7 @@ 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구경 윈체스터 매그넘 (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 @@ -2781,7 +2781,7 @@ 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제 하이브리드 OTM) .300 西米 10發 彈匣 (Berger Hybrid 空尖比賽專用彈) .300 WM 10发 弹匣(Berger Hybrid 空尖) .300 WM 10Rnd Mag (Berger Hybrid OTM) @@ -2815,7 +2815,7 @@ 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구경 윈체스터 매그넘 (Berger제 하이브리드 오픈 팁 매치탄)<br/>장탄수: 10 口徑: .300 西米 NATO標準 (Berger Hybrid 空尖比賽專用彈)<br />發數: 10 口径:.300 WM 北约(Berger Hybrid 空尖)<br />发数:10 Kalibre: .300 WM NATO (Berger Hybrid OTM)<br />Mermi: 10 @@ -2828,7 +2828,7 @@ 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) + 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) @@ -2841,7 +2841,7 @@ 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) + 6.5x47mm 30발 들이 탄창/프로멧용 (Scenar제 HPBT) Магазин из 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) @@ -2854,7 +2854,7 @@ 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) + 6.5x47mm 30발 들이 탄창/검정 (Scenar제 HPBT) Магазин из 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) @@ -2867,7 +2867,7 @@ 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) + 6.5x47mm 30발 들이 탄창/카키 (Scenar제 HPBT) Магазин из 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) @@ -2901,7 +2901,7 @@ 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.5x47mm (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 @@ -2918,7 +2918,7 @@ 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.5x47mm (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 @@ -2931,7 +2931,7 @@ 6.5 mm Creedmor 30cp Car Sabbia Magazynek 6.5 mm Creedmor 30Rnd Piaskowy 6.5 mm 30发 沙色弹匣(Creedmor) - 6.5mm 크리드무어 30발 사막 탄창 + 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 @@ -2944,7 +2944,7 @@ 6.5 mm Creedmor 30cp Car Promet Magazynek 6.5 mm Creedmor 30Rnd Promet 6.5 mm 30发 Promet 弹匣(Creedmor) - 6.5mm 크리드무어 30발 프로멧 탄창 + 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 @@ -2957,7 +2957,7 @@ 6.5 mm Creedmor 30cp Car Nero Magazynek 6.5 mm Creedmor 30Rnd Czarny 6.5 mm 30发 黑色弹匣(Creedmor) - 6.5mm 크리드무어 30발 검정 탄창 + 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 @@ -2970,7 +2970,7 @@ 6.5 mm Creedmor 30cp Car Cachi Magazynek 6.5 mm Creedmor 30Rnd Khaki 6.5 mm 30发 卡其色弹匣(Creedmor) - 6.5mm 크리드무어 30발 카키 탄창 + 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 @@ -3038,7 +3038,7 @@ 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발 들이 탄창 (Scenar제 300그레인) .338 10發 彈匣 (300公克 Lapua Scenar) .338 LM 10发 弹匣(300gr Lapua Scenar) .338 LM 10Rnd Mag (300gr Lapua Scenar) @@ -3072,7 +3072,7 @@ 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 라푸아 매그넘 (300그레인 Scenar)<br/>장탄수: 10 + 구경: 8.6x70mm 라푸아 매그넘 (Scenar제 300그레인)<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 @@ -3089,7 +3089,7 @@ 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) @@ -3106,7 +3106,7 @@ .338 AP .338 páncéltörő .338 AP - .338구경 라푸아 매그넘 철갑탄 + .338구경 라푸아 매그넘 철갑소이탄 .338 API526 穿甲燃燒彈 .338 穿燃 .338 AP @@ -3123,7 +3123,7 @@ 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.6x70毫米 (API526 穿甲燃燒彈)<br />發數: 10 口径:8.6x70 mm(API526 穿燃)<br />发数:10 Kalibre: 8.6x70mm (API526)<br />Mermi: 10 @@ -3140,7 +3140,7 @@ Carregador .408 (305gr) com 7 cartuchos .408 7-lövedékes tár (305gr) .408 7Rnd マガジン (305gr) - 7발 들이 .408구경 샤이택 탄창 (305그레인) + .408구경 샤이택 7발 들이 탄창 (305그레인) .408 7發 彈匣 (305公克) .408 7发 弹匣(305gr) .408 7Rnd Mag (305gr) @@ -3191,7 +3191,7 @@ Carregador 12.7x99 mm com 5 cartuchos 12,7x99 mm 5-lövedékes tár 12.7x99mm 5Rnd マガジン - 5발 들이 12.7x99mm 탄창 + 12.7x99mm 5발 들이 탄창 12.7x99毫米 5發 彈匣 12.7x99 mm 5发 弹匣 12.7x99 mm 5Rnd Mag @@ -3225,7 +3225,7 @@ Carregador 12.7x99 mm com 10 cartuchos 12,7x99 mm 10-lövedékes tár 12.7x99mm 10Rnd マガジン - 10발 들이 12.7x99mm 탄창 + 12.7x99mm 10발 들이 탄창 12.7x99毫米 10發 彈匣 12.7x99 mm 10发 弹匣 12.7x99 mm 10Rnd Mag @@ -3276,7 +3276,7 @@ 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.7x99mm 5발 들이 탄창 (철갑소이탄) 12.7x99毫米 穿甲燃燒彈 5發 彈匣 12.7x99 mm 穿燃 5发 弹匣 12.7x99 mm API 5Rnd Mag @@ -3310,7 +3310,7 @@ 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.7x99mm 10발 들이 탄창 (철갑소이탄) 12.7x99毫米 穿甲燃燒彈 10發 彈匣 12.7x99 mm 穿燃 10发 弹匣 12.7x99 mm API 10Rnd Mag @@ -3344,7 +3344,7 @@ 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발 들이 탄창 (A-MAX) 12.7x99毫米 5發 彈匣 (AMAX 比賽專用彈) 12.7x99 mm 5发 弹匣(AMAX) 12.7x99 mm 5Rnd Şarjör (AMAX) @@ -3361,7 +3361,7 @@ 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.7x99mm (A-MAX 매치그레이드)<br/>장탄수: 5 口徑: 12.7x99毫米 (AMAX 比賽專用彈)<br />發數: 5 口径:12.7x99 mm(AMAX)<br />发数:5 Kalibre: 12.7x99 mm (AMAX)<br />Mermi: 5 @@ -3378,7 +3378,7 @@ 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.7x99mm 10발 들이 탄창 (A-MAX) 12.7x99毫米 10發 彈匣 (AMAX 比賽專用彈) 12.7x99 mm 10发 弹匣(AMAX) 12.7x99 mm 10Rnd Şarjör (AMAX) @@ -3395,7 +3395,7 @@ 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.7x99mm (A-MAX 매치그레이드)<br/>장탄수: 10 口徑: 12.7x99毫米 (AMAX 比賽專用彈)<br />發數: 10 口径:12.7x99 mm(AMAX)<br />发数:10 Kalibre: 12.7x99 mm (AMAX)<br />Mermi: 10 @@ -3412,7 +3412,7 @@ 12.7 mm AMAX 12,7 mm AMAX 12.7 mm AMAX - 12.7mm AMAX + 12.7mm A-MAX 12.7毫米 AMAX 比賽專用彈 12.7 mm AMAX 12.7 mm AMAX @@ -3540,6 +3540,7 @@ Utilisation de l'IA Utilização por IA Использование ИИ + Uso de la IA Illum @@ -3551,6 +3552,7 @@ Fusées éclairantes Sinalizadoras Осветители + Iluminación Smoke @@ -3562,6 +3564,7 @@ Fumigènes Fumígenas Дым + Humo Inf @@ -3573,6 +3576,7 @@ Infanterie Infantaria Пехота + Infantería Veh @@ -3584,6 +3588,7 @@ Véhicule Veículo Техника + Vehículo Armor @@ -3595,6 +3600,7 @@ Blindage Blindagem Бронетехника + Blindados Air @@ -3606,6 +3612,7 @@ Aviation Aeronaves Авиация + Aeronaves diff --git a/addons/captives/XEH_postInit.sqf b/addons/captives/XEH_postInit.sqf index 8d34c4fb403..2580e724633 100644 --- a/addons/captives/XEH_postInit.sqf +++ b/addons/captives/XEH_postInit.sqf @@ -24,15 +24,15 @@ if (isServer) then { }]; }; -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; -[QGVAR(moveInCaptive), FUNC(vehicleCaptiveMoveIn)] call CBA_fnc_addEventHandler; -[QGVAR(moveOutCaptive), FUNC(vehicleCaptiveMoveOut)] call CBA_fnc_addEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +[QGVAR(moveInCaptive), LINKFUNC(vehicleCaptiveMoveIn)] call CBA_fnc_addEventHandler; +[QGVAR(moveOutCaptive), LINKFUNC(vehicleCaptiveMoveOut)] call CBA_fnc_addEventHandler; -[QGVAR(setHandcuffed), FUNC(setHandcuffed)] call CBA_fnc_addEventHandler; -[QGVAR(setSurrendered), FUNC(setSurrendered)] call CBA_fnc_addEventHandler; +[QGVAR(setHandcuffed), LINKFUNC(setHandcuffed)] call CBA_fnc_addEventHandler; +[QGVAR(setSurrendered), LINKFUNC(setSurrendered)] call CBA_fnc_addEventHandler; //Medical Integration Events -["ace_unconscious", FUNC(handleOnUnconscious)] call CBA_fnc_addEventHandler; +["ace_unconscious", LINKFUNC(handleOnUnconscious)] call CBA_fnc_addEventHandler; if (!hasInterface) exitWith {}; diff --git a/addons/captives/functions/fnc_canEscortCaptive.sqf b/addons/captives/functions/fnc_canEscortCaptive.sqf index f39ff2ac5f2..204206e5069 100644 --- a/addons/captives/functions/fnc_canEscortCaptive.sqf +++ b/addons/captives/functions/fnc_canEscortCaptive.sqf @@ -21,7 +21,6 @@ params ["_unit", "_target"]; (_target getVariable [QGVAR(isHandcuffed), false]) && {isNull (attachedTo _target)} && -{alive _target} && -{!(_target getVariable ["ACE_isUnconscious", false])} && +{_target call EFUNC(common,isAwake)} && {(vehicle _unit) == _unit} && {(vehicle _target) == _target} diff --git a/addons/captives/functions/fnc_canLoadCaptive.sqf b/addons/captives/functions/fnc_canLoadCaptive.sqf index 982e4025a29..46da188238f 100644 --- a/addons/captives/functions/fnc_canLoadCaptive.sqf +++ b/addons/captives/functions/fnc_canLoadCaptive.sqf @@ -20,7 +20,7 @@ params ["_unit", "_target", "_vehicle"]; // Don't show "Load Captive" if unit is unconscious (already has "Load Patient") -if (_target getVariable ["ACE_isUnconscious", false]) exitWith {false}; +if !(_target call EFUNC(common,isAwake)) exitWith {false}; if ((isNull _target) && {_unit getVariable [QGVAR(isEscorting), false]}) then { //Looking at a vehicle while escorting, get target from attached objects: diff --git a/addons/captives/functions/fnc_doEscortCaptive.sqf b/addons/captives/functions/fnc_doEscortCaptive.sqf index 817745ece3b..86cc52cb9cd 100644 --- a/addons/captives/functions/fnc_doEscortCaptive.sqf +++ b/addons/captives/functions/fnc_doEscortCaptive.sqf @@ -39,12 +39,12 @@ if (_state) then { _args params ["_unit", "_target", "_actionID"]; if (_unit getVariable [QGVAR(isEscorting), false]) then { - if (!alive _target || {!alive _unit} || {!canStand _target} || {!canStand _unit} || {_target getVariable ["ACE_isUnconscious", false]} || {_unit getVariable ["ACE_isUnconscious", false]} || {!isNull (attachedTo _unit)}) then { + if (!canStand _target || {!canStand _unit} || {!(_target call EFUNC(common,isAwake))} || {!(_unit call EFUNC(common,isAwake))} || {!isNull (attachedTo _unit)}) then { _unit setVariable [QGVAR(isEscorting), false, true]; }; }; - if (!(_unit getVariable [QGVAR(isEscorting), false])) then { + if !(_unit getVariable [QGVAR(isEscorting), false]) then { [(_this select 1)] call CBA_fnc_removePerFrameHandler; [objNull, _target, false] call EFUNC(common,claim); detach _target; diff --git a/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf b/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf index 3363ca923e6..8ce4391783a 100644 --- a/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf +++ b/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf @@ -19,7 +19,7 @@ params ["_unit", "_newAnimation"]; TRACE_2("AnimChanged",_unit,_newAnimation); if (_unit == (vehicle _unit)) then { - if ((_newAnimation != "ACE_AmovPercMstpSsurWnonDnon") && {!(_unit getVariable ["ACE_isUnconscious", false])}) then { + if ((_newAnimation != "ACE_AmovPercMstpSsurWnonDnon") && {_unit call EFUNC(common,isAwake)}) then { TRACE_1("Handcuff animation interrupted",_newAnimation); [_unit, "ACE_AmovPercMstpScapWnonDnon", 1] call EFUNC(common,doAnimation); }; diff --git a/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf b/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf index b9164ddbe5f..7d69c8c7faa 100644 --- a/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf +++ b/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf @@ -19,7 +19,7 @@ params ["_unit", "_newAnimation"]; TRACE_2("AnimChanged",_unit,_newAnimation); -if ((_newAnimation != "ACE_AmovPercMstpSsurWnonDnon") && {!(_unit getVariable ["ACE_isUnconscious", false])}) then { +if ((_newAnimation != "ACE_AmovPercMstpSsurWnonDnon") && {_unit call EFUNC(common,isAwake)}) then { TRACE_1("Surrender animation interrupted",_newAnimation); [_unit, "ACE_AmovPercMstpSsurWnonDnon", 1] call EFUNC(common,doAnimation); }; diff --git a/addons/captives/functions/fnc_handleOnUnconscious.sqf b/addons/captives/functions/fnc_handleOnUnconscious.sqf index 1527038ce99..a43207fc848 100644 --- a/addons/captives/functions/fnc_handleOnUnconscious.sqf +++ b/addons/captives/functions/fnc_handleOnUnconscious.sqf @@ -27,7 +27,7 @@ if (_isUnconc) then { }; } else { //Woke up: if handcuffed, goto animation - if (_unit getVariable [QGVAR(isHandcuffed), false] && {vehicle _unit == _unit}) then { + if (_unit getVariable [QGVAR(isHandcuffed), false] && {isNull objectParent _unit}) then { [_unit] call EFUNC(common,fixLoweredRifleAnimation); [_unit, "ACE_AmovPercMstpScapWnonDnon", 1] call EFUNC(common,doAnimation); }; diff --git a/addons/captives/functions/fnc_handleRespawn.sqf b/addons/captives/functions/fnc_handleRespawn.sqf index 1dc6ca7bfa3..f3c728d0538 100644 --- a/addons/captives/functions/fnc_handleRespawn.sqf +++ b/addons/captives/functions/fnc_handleRespawn.sqf @@ -40,12 +40,12 @@ if (_respawn > 3) then { if (_unit getVariable [QGVAR(isHandcuffed), false]) then { [_unit, false] call FUNC(setHandcuffed); }; - [_unit, "setCaptive", QGVAR(Handcuffed), false] call EFUNC(common,statusEffect_set); + [_unit, "setCaptive", QGVAR(handcuffed), false] call EFUNC(common,statusEffect_set); if (_unit getVariable [QGVAR(isSurrendering), false]) then { [_unit, false] call FUNC(setSurrendered); }; - [_unit, "setCaptive", QGVAR(Surrendered), false] call EFUNC(common,statusEffect_set); + [_unit, "setCaptive", QGVAR(surrendered), false] call EFUNC(common,statusEffect_set); if (_unit getVariable [QGVAR(isEscorting), false]) then { _unit setVariable [QGVAR(isEscorting), false, true]; diff --git a/addons/captives/functions/fnc_setHandcuffed.sqf b/addons/captives/functions/fnc_setHandcuffed.sqf index c13da8f9274..2ccd36493c8 100644 --- a/addons/captives/functions/fnc_setHandcuffed.sqf +++ b/addons/captives/functions/fnc_setHandcuffed.sqf @@ -41,8 +41,8 @@ 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); + [_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); @@ -58,7 +58,7 @@ if (_state) then { // fix anim on mission start (should work on dedicated servers) [{ params ["_unit"]; - if (!(_unit getVariable [QGVAR(isHandcuffed), false])) exitWith {}; + if !(_unit getVariable [QGVAR(isHandcuffed), false]) exitWith {}; if ((vehicle _unit) == _unit) then { [_unit] call EFUNC(common,fixLoweredRifleAnimation); @@ -82,8 +82,8 @@ if (_state) then { }, [_unit], 0.01] call CBA_fnc_waitAndExecute; } 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); + [_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]; @@ -91,7 +91,7 @@ if (_state) then { _unit removeEventHandler ["AnimChanged", _animChangedEHID]; _unit setVariable [QGVAR(handcuffAnimEHID), -1]; - if (((vehicle _unit) == _unit) && {!(_unit getVariable ["ACE_isUnconscious", false])}) then { + if (((vehicle _unit) == _unit) && {_unit call EFUNC(common,isAwake)}) then { //Break out of hands up animation loop [_unit, "ACE_AmovPercMstpScapWnonDnon_AmovPercMstpSnonWnonDnon", 2] call EFUNC(common,doAnimation); }; diff --git a/addons/captives/functions/fnc_setSurrendered.sqf b/addons/captives/functions/fnc_setSurrendered.sqf index 393465e08eb..3a3724c94d2 100644 --- a/addons/captives/functions/fnc_setSurrendered.sqf +++ b/addons/captives/functions/fnc_setSurrendered.sqf @@ -44,8 +44,8 @@ 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); + [_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,8 +71,8 @@ if (_state) then { }, [_unit], 0.01] call CBA_fnc_waitAndExecute; } 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); + [_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]; @@ -81,13 +81,12 @@ if (_state) then { if (_unit == ACE_player) then { //only re-enable HUD if not handcuffed - if (!(_unit getVariable [QGVAR(isHandcuffed), false])) then { + if !(_unit getVariable [QGVAR(isHandcuffed), false]) then { ["captive", []] call EFUNC(common,showHud); //same as showHud true; }; }; - if (!alive _unit) exitWith {}; - if (_unit getVariable ["ACE_isUnconscious", false]) exitWith {}; //don't touch animations if unconscious + if !(_unit call EFUNC(common,isAwake)) exitWith {}; //don't touch animations if unconscious //if we are in "hands up" animationState, crack it now if (((vehicle _unit) == _unit) && {(animationState _unit) == "ACE_AmovPercMstpSsurWnonDnon"}) then { @@ -99,7 +98,7 @@ if (_state) then { params ["_args", "_pfID"]; _args params ["_unit", "_maxTime"]; //If waited long enough or they re-surrendered or they are unconscious, exit loop - if ((CBA_missionTime > _maxTime) || {_unit getVariable [QGVAR(isSurrendering), false]} || {_unit getVariable ["ACE_isUnconscious", false]}) exitWith { + if ((CBA_missionTime > _maxTime) || {_unit getVariable [QGVAR(isSurrendering), false]} || {!(_unit call EFUNC(common,isAwake))}) exitWith { [_pfID] call CBA_fnc_removePerFrameHandler; }; //Only break animation if they are actualy the "hands up" animation (because we are using switchmove there won't be an transition) diff --git a/addons/captives/stringtable.xml b/addons/captives/stringtable.xml index c2da8892e5b..dfc293028dc 100644 --- a/addons/captives/stringtable.xml +++ b/addons/captives/stringtable.xml @@ -146,6 +146,7 @@ 포로 눈 가리기 目隠しをする Завязать глаза пленному + Vendar ojos al prisionero Remove blindfold @@ -156,6 +157,8 @@ 눈가리개 풀기 目隠しを外す Снять повязку с глаз + Quitar vendas de los ojos + Remover a venda Cable Tie @@ -486,7 +489,7 @@ 设置在光标下的单位成俘虏状态。 커서의 병력을 포박합니다. Ustawia jednostkę pod kursorem jako jeniec. - Арестовывает указанный курсором юнит + Арестовывает указанный курсором юнит. Torna a unidade sob o cursor um prisioneiro Capture l'unité sous le curseur. Nastaví jednotku pod kurzorem jako zajatce. diff --git a/addons/cargo/CfgVehicles.hpp b/addons/cargo/CfgVehicles.hpp index 485a53d8f58..9b4e316a19a 100644 --- a/addons/cargo/CfgVehicles.hpp +++ b/addons/cargo/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CBA_Extended_EventHandlers; class CfgVehicles { @@ -48,22 +47,14 @@ 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 { GVAR(space) = 4; GVAR(hasCargo) = 1; }; - class Tank_F: Tank {}; + class Tank_F; class UGV_02_Base_F: Tank_F { GVAR(space) = 0; GVAR(hasCargo) = 0; @@ -75,7 +66,7 @@ class CfgVehicles { GVAR(hasCargo) = 1; }; - // HEMTTs - Default at 10, some variants are altered based on model size and/or expected level of free space inside. + // HEMTTs - Default at 30, some variants are altered based on model size and/or expected level of free space inside. class Truck_01_base_F: Truck_F { GVAR(space) = 30; }; @@ -245,8 +236,6 @@ class CfgVehicles { 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) = 10; GVAR(hasCargo) = 1; @@ -267,7 +256,7 @@ class CfgVehicles { GVAR(hasCargo) = 0; }; - class Plane_Base_F: Plane {}; + class Plane_Base_F; class Plane_Civil_01_base_F: Plane_Base_F { // Tanoa Civilian Prop Plane GVAR(space) = 2; GVAR(hasCargo) = 1; @@ -308,7 +297,7 @@ class CfgVehicles { GVAR(hasCargo) = 1; }; - class Boat_F: Ship_F {}; + class Boat_F; class Rubber_duck_base_F: Boat_F { GVAR(space) = 0; GVAR(hasCargo) = 0; @@ -364,7 +353,7 @@ class CfgVehicles { }; // Slingload pallets - class Slingload_base_F: ReammoBox_F {}; + class Slingload_base_F; class CargoNet_01_base_F: Slingload_base_F { GVAR(size) = 6; }; @@ -510,7 +499,7 @@ class CfgVehicles { }; GVAR(space) = 2; - GVAR(hasCargo) = 2; + GVAR(hasCargo) = 1; GVAR(size) = 3; GVAR(canLoad) = 1; @@ -520,11 +509,8 @@ class CfgVehicles { transportMaxWeapons = 12; }; class Land_WoodenCrate_01_F: ThingX { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; GVAR(space) = 3; - GVAR(hasCargo) = 3; + GVAR(hasCargo) = 1; GVAR(size) = 3; GVAR(canLoad) = 1; @@ -552,240 +538,141 @@ class CfgVehicles { }; }; class Cargo10_base_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 14; GVAR(size) = 15; }; - class Land_Cargo20_blue_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; + class Land_Cargo10_IDAP_F: ThingX { + GVAR(space) = 14; + GVAR(size) = 15; + }; + class Land_Cargo20_blue_F: Cargo_base_F { GVAR(space) = 49; GVAR(size) = 50; }; class Land_Cargo20_brick_red_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 49; GVAR(size) = 50; }; class Land_Cargo20_cyan_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 49; GVAR(size) = 50; }; class Land_Cargo20_grey_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 49; GVAR(size) = 50; }; class Land_Cargo20_light_blue_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 49; GVAR(size) = 50; }; class Land_Cargo20_light_green_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 49; GVAR(size) = 50; }; class Land_Cargo20_military_green_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 49; GVAR(size) = 50; }; class Land_Cargo20_orange_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 49; GVAR(size) = 50; }; class Land_Cargo20_red_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 49; GVAR(size) = 50; }; class Land_Cargo20_sand_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 49; GVAR(size) = 50; }; class Land_Cargo20_vr_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 49; GVAR(size) = 50; }; class Land_Cargo20_white_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 49; GVAR(size) = 50; }; class Land_Cargo20_yellow_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 49; GVAR(size) = 50; }; - class Cargo_IDAP_base_F: Cargo_base_F {}; + + class Cargo_IDAP_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 Cargo_EMP_base_F; + class Land_Cargo20_EMP_F: Cargo_EMP_base_F { + GVAR(space) = 49; + GVAR(size) = 50; + }; + class Land_Cargo20_EMP_Training_F: Cargo_EMP_base_F { GVAR(space) = 49; GVAR(size) = 50; }; class Land_Cargo40_blue_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 99; GVAR(size) = 100; }; class Land_Cargo40_brick_red_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 99; GVAR(size) = 100; }; class Land_Cargo40_cyan_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 99; GVAR(size) = 100; }; class Land_Cargo40_grey_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 99; GVAR(size) = 100; }; class Land_Cargo40_light_blue_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 99; GVAR(size) = 100; }; class Land_Cargo40_light_green_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 99; GVAR(size) = 100; }; class Land_Cargo40_military_green_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 99; GVAR(size) = 100; }; class Land_Cargo40_orange_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 99; GVAR(size) = 100; }; class Land_Cargo40_red_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 99; GVAR(size) = 100; }; class Land_Cargo40_sand_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 99; GVAR(size) = 100; }; - class Land_Cargo40_vr_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - + class Land_Cargo40_white_F: Cargo_base_F { GVAR(space) = 99; GVAR(size) = 100; }; - class Land_Cargo40_white_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - + class Land_Cargo40_yellow_F: Cargo_base_F { GVAR(space) = 99; GVAR(size) = 100; }; - class Land_Cargo40_yellow_F: Cargo_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; + class Land_Cargo40_IDAP_F: Cargo_IDAP_base_F { GVAR(space) = 99; GVAR(size) = 100; }; // Small class Land_CargoBox_V1_F: ThingX { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(space) = 7; GVAR(hasCargo) = 1; GVAR(size) = 7; diff --git a/addons/cargo/XEH_PREP.hpp b/addons/cargo/XEH_PREP.hpp index 10281e29674..4632a401f17 100644 --- a/addons/cargo/XEH_PREP.hpp +++ b/addons/cargo/XEH_PREP.hpp @@ -5,6 +5,7 @@ PREP(canUnloadItem); PREP(deployCancel); PREP(deployConfirm); PREP(getCargoSpaceLeft); +PREP(getDelayItem); PREP(getNameItem); PREP(getSelectedItem); PREP(getSizeItem); diff --git a/addons/cargo/XEH_postInit.sqf b/addons/cargo/XEH_postInit.sqf index 94cb2afc871..84597b1c216 100644 --- a/addons/cargo/XEH_postInit.sqf +++ b/addons/cargo/XEH_postInit.sqf @@ -51,7 +51,7 @@ params ["_item", "_emptyPosAGL"]; _item hideObjectGlobal false; - _item setPosASL (AGLtoASL _emptyPosAGL); + _item setPosASL (AGLToASL _emptyPosAGL); // Let objects remain invulernable for a short while after placement [EFUNC(common,statusEffect_set), [_item, "blockDamage", QUOTE(ADDON), false], 2] call CBA_fnc_waitAndExecute; @@ -86,7 +86,7 @@ GVAR(vehicleAction) = [ GVAR(enable) && {alive _target} && {locked _target < 2} && - {(_target getVariable [QGVAR(hasCargo), getNumber (configOf _target >> QGVAR(hasCargo)) == 1])} && + {_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} @@ -111,6 +111,20 @@ GVAR(objectActions) = [ {[_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew)} } ] call EFUNC(interact_menu,createAction), + [QGVAR(checkSize), LLSTRING(checkSize), "\a3\ui_f\data\igui\cfg\simpletasks\types\box_ca.paa", + { + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; + [format [LLSTRING(SizeMenu), _target call FUNC(getSizeItem)], 3] call EFUNC(common,displayTextStructured); + }, + { + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; + GVAR(enable) && + {alive _target} && + {_target getVariable [QGVAR(canLoad), getNumber (configOf _target >> QGVAR(canLoad)) == 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"]; diff --git a/addons/cargo/functions/fnc_addCargoItem.sqf b/addons/cargo/functions/fnc_addCargoItem.sqf index 38ccdc0dd94..d5c7925a6fa 100644 --- a/addons/cargo/functions/fnc_addCargoItem.sqf +++ b/addons/cargo/functions/fnc_addCargoItem.sqf @@ -7,9 +7,10 @@ * 0: Item to be loaded or * 1: Holder object (vehicle) * 2: Amount (default: 1) + * 3: Ignore interaction distance and stability checks (default: false) * * Return Value: - * None + * Objects loaded * * Example: * ["ACE_Wheel", cursorObject] call ace_cargo_fnc_addCargoItem @@ -17,21 +18,31 @@ * Public: No */ -params ["_item", "_vehicle", ["_amount", 1]]; -TRACE_3("params",_item,_vehicle,_amount); +params ["_item", "_vehicle", ["_amount", 1], ["_ignoreInteraction", false]]; +TRACE_4("params",_item,_vehicle,_amount,_ignoreInteraction); + +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 { - [_item, _vehicle] call FUNC(loadItem); + if !([_item, _vehicle, _ignoreInteraction] call FUNC(loadItem)) exitWith {}; + + _loaded = _loaded + 1; }; } else { - [_item, _vehicle] call FUNC(loadItem); + _loaded = parseNumber ([_item, _vehicle, _ignoreInteraction] call FUNC(loadItem)); _item = typeOf _item; }; +TRACE_1("loaded",_loaded); + // Invoke listenable event -["ace_cargoAdded", [_item, _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_deployConfirm.sqf b/addons/cargo/functions/fnc_deployConfirm.sqf index 27674b0515b..e4c87342f04 100644 --- a/addons/cargo/functions/fnc_deployConfirm.sqf +++ b/addons/cargo/functions/fnc_deployConfirm.sqf @@ -24,7 +24,7 @@ if (!isNull GVAR(itemPreviewObject) && {[GVAR(selectedItem), GVAR(interactionVeh // 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)); + private _duration = [GVAR(selectedItem), false] call FUNC(getDelayItem); // If unload time is 0, don't show a progress bar if (_duration <= 0) exitWith { diff --git a/addons/cargo/functions/fnc_getDelayItem.sqf b/addons/cargo/functions/fnc_getDelayItem.sqf new file mode 100644 index 00000000000..7f1d6b4d401 --- /dev/null +++ b/addons/cargo/functions/fnc_getDelayItem.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Gets the delay duration an item should take to load/unload. + * + * Arguments: + * 0: Item or + * 1: If delay is for paradrop context + * + * Return Value: + * Item load/unload duration + * + * Example: + * [cursorObject, false] call ace_cargo_fnc_getDelayItem + * + * Public: No + */ + +params ["_item", "_isParadrop"]; + +if ((_item isEqualType objNull) && {_item getVariable [QGVAR(delay), -1] >= 0}) exitWith { + _item getVariable QGVAR(delay) // return +}; + +([GVAR(loadTimeCoefficient), GVAR(paradropTimeCoefficent)] select _isParadrop) * (_item call FUNC(getSizeItem)) // return + diff --git a/addons/cargo/functions/fnc_handleScrollWheel.sqf b/addons/cargo/functions/fnc_handleScrollWheel.sqf index 9ec2c498e64..e6f3b23e76f 100644 --- a/addons/cargo/functions/fnc_handleScrollWheel.sqf +++ b/addons/cargo/functions/fnc_handleScrollWheel.sqf @@ -38,7 +38,7 @@ if (!CBA_events_control) then { // 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); + private _selectionPosition = _unit worldToModel (ASLToAGL getPosWorld _deployedItem); _selectionPosition = _selectionPosition vectorAdd _positionChange; _deployedItem attachTo [_unit, _selectionPosition]; diff --git a/addons/cargo/functions/fnc_initVehicle.sqf b/addons/cargo/functions/fnc_initVehicle.sqf index ec432ea91f7..25cebe5b130 100644 --- a/addons/cargo/functions/fnc_initVehicle.sqf +++ b/addons/cargo/functions/fnc_initVehicle.sqf @@ -22,11 +22,11 @@ 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 = _item getVariable QGVAR(hasCargo); -private _hasCargoPublicDefined = !isNil "_canLoadPublic"; +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",_item,_type,QGVAR(hasCargo),_hasCargoPublic); + WARNING_4("%1[%2] - Variable %3 is %4 - Should be bool",_vehicle,_type,QGVAR(hasCargo),_hasCargoPublic); }; private _hasCargoConfig = getNumber (_config >> QGVAR(hasCargo)) == 1; @@ -52,14 +52,21 @@ if (isServer) then { private _cargoClassname = ""; private _cargoCount = 0; + private _loaded = 0; { _cargoClassname = getText (_x >> "type"); _cargoCount = getNumber (_x >> "amount"); - TRACE_3("adding ACE_Cargo",configName _x,_cargoClassname,_cargoCount); + TRACE_3("adding ace_cargo",configName _x,_cargoClassname,_cargoCount); - ["ace_addCargo", [_cargoClassname, _vehicle, _cargoCount]] call CBA_fnc_localEvent; + // Ignore stability check (distance check is also ignored with this, but it's ignored by default if item is a string) + _loaded = [_cargoClassname, _vehicle, _cargoCount, true] call FUNC(addCargoItem); + + // Let loop continue until the end, so that it prints everything into the rpt (there might be smaller items that could still fit in cargo) + if (_loaded != _cargoCount) then { + WARNING_5("%1 (%2) could not fit %3 %4 inside its cargo, only %5 were loaded.",_vehicle,_type,_cargoCount,_cargoClassname,_loaded); + }; } forEach ("true" configClasses (_config >> QUOTE(ADDON) >> "cargo")); }; diff --git a/addons/cargo/functions/fnc_loadItem.sqf b/addons/cargo/functions/fnc_loadItem.sqf index 21ebc0d52ad..aa3117c7dde 100644 --- a/addons/cargo/functions/fnc_loadItem.sqf +++ b/addons/cargo/functions/fnc_loadItem.sqf @@ -62,6 +62,17 @@ if (_item isEqualType objNull) then { // Some objects below water will take damage over time, eventually becoming "water logged" and unfixable (because of negative z attach) [_item, "blockDamage", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + + // Prevent UAVs from firing + private _UAVCrew = _item call EFUNC(common,getVehicleUAVCrew); + + if (_UAVCrew isNotEqualTo []) then { + { + [_x, true] call EFUNC(common,disableAiUAV); + } forEach _UAVCrew; + + _item setVariable [QGVAR(isUAV), _UAVCrew, true]; + }; }; // Invoke listenable event diff --git a/addons/cargo/functions/fnc_paradropItem.sqf b/addons/cargo/functions/fnc_paradropItem.sqf index acd780f4635..934beb2aad2 100644 --- a/addons/cargo/functions/fnc_paradropItem.sqf +++ b/addons/cargo/functions/fnc_paradropItem.sqf @@ -63,7 +63,7 @@ if (_item isEqualType objNull) then { [QGVAR(serverUnload), [_object, _posBehindVehicleAGL]] call CBA_fnc_serverEvent; } else { _object = createVehicle [_item, _posBehindVehicleAGL, [], 0, "NONE"]; - _object setPosASL (AGLtoASL _posBehindVehicleAGL); + _object setPosASL (AGLToASL _posBehindVehicleAGL); }; [QEGVAR(common,setVelocity), [_object, (velocity _vehicle) vectorAdd ((vectorNormalized (vectorDir _vehicle)) vectorMultiply -5)], _object] call CBA_fnc_targetEvent; @@ -100,14 +100,26 @@ if (_item isEqualType objNull) then { // Create smoke effect when crate landed [{ - (_this select 0) params ["_object"]; + params ["_object", "_pfhID"]; if (isNull _object) exitWith { - [_this select 1] call CBA_fnc_removePerFrameHandler; + _pfhID call CBA_fnc_removePerFrameHandler; }; if (getPos _object select 2 < 1) exitWith { - [_this select 1] call CBA_fnc_removePerFrameHandler; + _pfhID call CBA_fnc_removePerFrameHandler; + + // Reenable UAV crew + private _UAVCrew = _object getVariable [QGVAR(isUAV), []]; + + if (_UAVCrew isNotEqualTo []) then { + // Reenable AI + { + [_x, false] call EFUNC(common,disableAiUAV); + } forEach _UAVCrew; + + _object setVariable [QGVAR(isUAV), nil, true]; + }; if ((GVAR(disableParadropEffectsClasstypes) findIf {_object isKindOf _x}) == -1) then { private _smoke = "SmokeshellYellow" createVehicle [0, 0, 0]; diff --git a/addons/cargo/functions/fnc_setSpace.sqf b/addons/cargo/functions/fnc_setSpace.sqf index 01c078496c2..514b84ea176 100644 --- a/addons/cargo/functions/fnc_setSpace.sqf +++ b/addons/cargo/functions/fnc_setSpace.sqf @@ -35,7 +35,7 @@ private _cargoSpace = _space; } forEach _loaded; // If the new value is the same as the old, do nothing -if (_cargoSpace == (_vehicle call FUNC(getCargoSpaceLeft))) exitwith {}; +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 diff --git a/addons/cargo/functions/fnc_startLoadIn.sqf b/addons/cargo/functions/fnc_startLoadIn.sqf index 7212d89c229..23d62c7c01b 100644 --- a/addons/cargo/functions/fnc_startLoadIn.sqf +++ b/addons/cargo/functions/fnc_startLoadIn.sqf @@ -36,7 +36,7 @@ if (isNull _vehicle) exitWith { // Start progress bar if ([_item, _vehicle] call FUNC(canLoadItemIn)) then { - private _duration = GVAR(loadTimeCoefficient) * (_item call FUNC(getSizeItem)); + private _duration = [_item, false] call FUNC(getDelayItem); // If load time is 0, don't show a progress bar if (_duration <= 0) exitWith { diff --git a/addons/cargo/functions/fnc_startUnload.sqf b/addons/cargo/functions/fnc_startUnload.sqf index 39dbf59f48a..e5eaab76dc7 100644 --- a/addons/cargo/functions/fnc_startUnload.sqf +++ b/addons/cargo/functions/fnc_startUnload.sqf @@ -26,7 +26,7 @@ if (GVAR(interactionParadrop)) exitWith { // Close the cargo menu closeDialog 0; - private _duration = GVAR(paradropTimeCoefficent) * (_item call FUNC(getSizeItem)); + private _duration = [_item, true] call FUNC(getDelayItem); // If drop time is 0, don't show a progress bar if (_duration <= 0) exitWith { @@ -81,7 +81,7 @@ if ([_item, GVAR(interactionVehicle), _unit] call FUNC(canUnloadItem)) then { // Close the cargo menu closeDialog 0; - private _duration = GVAR(loadTimeCoefficient) * (_item call FUNC(getSizeItem)); + private _duration = [_item, false] call FUNC(getDelayItem); // If unload time is 0, don't show a progress bar if (_duration <= 0) exitWith { diff --git a/addons/cargo/functions/fnc_unloadItem.sqf b/addons/cargo/functions/fnc_unloadItem.sqf index f32215fdd7d..e22d87a098b 100644 --- a/addons/cargo/functions/fnc_unloadItem.sqf +++ b/addons/cargo/functions/fnc_unloadItem.sqf @@ -96,6 +96,18 @@ if (_object isEqualType objNull) then { [QEGVAR(zeus,addObjects), [[_object], _objectCurators]] call CBA_fnc_serverEvent; }; + + // Reenable UAV crew + private _UAVCrew = _object getVariable [QGVAR(isUAV), []]; + + if (_UAVCrew isNotEqualTo []) then { + // Reenable AI + { + [_x, false] call EFUNC(common,disableAiUAV); + } forEach _UAVCrew; + + _object setVariable [QGVAR(isUAV), nil, true]; + }; } else { _object = createVehicle [_item, _emptyPosAGL, [], 0, "NONE"]; @@ -104,7 +116,7 @@ if (_object isEqualType objNull) then { _object setDir _direction; }; - _object setPosASL (AGLtoASL _emptyPosAGL); + _object setPosASL (AGLToASL _emptyPosAGL); [QEGVAR(common,fixCollision), _object] call CBA_fnc_localEvent; [QEGVAR(common,fixPosition), _object] call CBA_fnc_localEvent; diff --git a/addons/cargo/initSettings.inc.sqf b/addons/cargo/initSettings.inc.sqf index 029a845a254..4f92934d46a 100644 --- a/addons/cargo/initSettings.inc.sqf +++ b/addons/cargo/initSettings.inc.sqf @@ -6,8 +6,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(ModuleSettings_enable), LSTRING(ModuleSettings_enable_Description)], _category, true, - 1, - {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -16,8 +15,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(loadTimeCoefficient), LSTRING(loadTimeCoefficient_description)], _category, [0, 10, 5, 1], - 1, - {[QGVAR(loadTimeCoefficient), _this, true] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -26,8 +24,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(paradropTimeCoefficent), LSTRING(paradropTimeCoefficent_description)], _category, [0, 10, 2.5, 1], - 1, - {[QGVAR(paradropTimeCoefficent), _this, true] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -35,9 +32,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; "LIST", [LSTRING(openAfterUnload), LSTRING(openAfterUnload_description)], _category, - [[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0], - 0, - {[QGVAR(openAfterUnload), _this, true] call EFUNC(common,cbaSettings_settingChanged)} + [[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0] ] call CBA_fnc_addSetting; [ @@ -45,9 +40,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; "CHECKBOX", [LSTRING(carryAfterUnload), LSTRING(carryAfterUnload_description)], _category, - true, - 0, - {[QGVAR(carryAfterUnload), _this] call EFUNC(common,cbaSettings_settingChanged)} + true ] call CBA_fnc_addSetting; [ @@ -56,8 +49,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(enableDeploy), LSTRING(enableDeploy_description)], _category, true, - 1, - {[QGVAR(enableDeploy), _this] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -65,7 +57,5 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; "CHECKBOX", [LSTRING(ModuleSettings_enableRename), LSTRING(ModuleSettings_enableRename_Description)], _category, - true, - 0, - {[QGVAR(enableRename), _this, true] call EFUNC(common,cbaSettings_settingChanged)} + true ] call CBA_fnc_addSetting; diff --git a/addons/cargo/menu.hpp b/addons/cargo/menu.hpp index 1811369d7d5..51020335d45 100644 --- a/addons/cargo/menu.hpp +++ b/addons/cargo/menu.hpp @@ -8,16 +8,16 @@ class GVAR(menu) { 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)"; + 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 = "14.2 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + y = "2.1 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25) + (safeZoneY + (safeZoneH - (((safeZoneW / safeZoneH) min 1.2) / 1.2))/2)"; + 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])"}; @@ -28,36 +28,36 @@ class GVAR(menu) { 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)"; + 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)"; + 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(cargoMenu); }; class SubHeader: HeaderName { idc = 2; - x = "13 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; - y = "2.5 * ((((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)"; + x = "13 * (((safeZoneW / safeZoneH) min 1.2) / 40) + (safeZoneX + (safeZoneW - ((safeZoneW / safeZoneH) min 1.2))/2)"; + y = "2.5 * ((((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_CENTER; colorText[] = {1, 1, 1, 0.9}; colorBackground[] = {0, 0, 0, 0}; - SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1.2)"; + SizeEx = "(((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25) * 1.2)"; text = ""; }; class cargoList: ACE_gui_listBoxBase { idc = 100; - x = "13.1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; - y = "4 * ((((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 = "10 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.7)"; + x = "13.1 * (((safeZoneW / safeZoneH) min 1.2) / 40) + (safeZoneX + (safeZoneW - ((safeZoneW / safeZoneH) min 1.2))/2)"; + y = "4 * ((((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 = "10 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; + SizeEx = "(((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25) * 0.7)"; rowHeight = 0.03; colorBackground[] = {0, 0, 0, 0.2}; colorText[] = {1, 1, 1, 1.0}; @@ -70,12 +70,12 @@ class GVAR(menu) { 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 = "14.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; - 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)"; + 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 = "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)"; 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)"; @@ -96,13 +96,13 @@ class GVAR(menu) { class btnUnload: btnCancel { text = CSTRING(unloadObject); idc = 12; - x = "19.9 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; + x = "19.9 * (((safeZoneW / safeZoneH) min 1.2) / 40) + (safeZoneX + (safeZoneW - ((safeZoneW / safeZoneH) min 1.2))/2)"; action = QUOTE(ACE_player call FUNC(startUnload)); }; class btnPlace: btnUnload { text = CSTRING(deployObject); idc = 13; - y = "15.2 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; + y = "15.2 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25) + (safeZoneY + (safeZoneH - (((safeZoneW / safeZoneH) min 1.2) / 1.2))/2)"; action = QUOTE(ACE_player call FUNC(startDeploy)); colorDisabled[] = {0.25, 0.25, 0.25, 1}; }; diff --git a/addons/cargo/renameMenu.hpp b/addons/cargo/renameMenu.hpp index b6acc9ad4e3..a3cb845c6b7 100644 --- a/addons/cargo/renameMenu.hpp +++ b/addons/cargo/renameMenu.hpp @@ -8,16 +8,16 @@ class GVAR(renameMenu) { 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)"; + 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)"; + 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])"}; @@ -28,13 +28,13 @@ class GVAR(renameMenu) { 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)"; + 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)"; + 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); @@ -43,21 +43,21 @@ class GVAR(renameMenu) { 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)"; + 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)"; + 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)"; @@ -78,7 +78,7 @@ class GVAR(renameMenu) { 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)"; + 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/stringtable.xml b/addons/cargo/stringtable.xml index b45a27cd5b8..7a9cdf56a37 100644 --- a/addons/cargo/stringtable.xml +++ b/addons/cargo/stringtable.xml @@ -35,8 +35,13 @@ Deploy + Piazza Разместить 配置する + 배치하기 + Déployer + Aufstellen + Desplegar Raise/Lower | (Ctrl + Scroll) Rotate @@ -279,14 +284,22 @@ 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 %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 @@ -328,15 +341,23 @@ 荷降ろし不可能です 하역할 수가 없습니다 Не может быть выгружен + No puede ser descargado + + + Check Cargo Size + 화물 크기 확인 + 貨物としての大きさを確認 + Проверить размер груза Cargo Size: %1 Frachtgröße: %1 Dimensione Carico: %1 Encombrement fret: %1 - 貨物のサイズ: %1 + 貨物の大きさ: %1 화물 크기: %1 Размер груза: %1 + Tamaño de carga: %1 Custom Name @@ -399,7 +420,7 @@ Cargo Size Frachtgröße Dimensioni nel Carico - 貨物のサイズ + 貨物の大きさ 貨物的大小 货物的大小 Wielkość ładunku @@ -491,7 +512,7 @@ Ladezeitmultiplikator 積載の所要時間係数 Współczynnik czasu załadowania - Coefficente Tempo Caricamento + Coefficiente Tempo Caricamento Коэф. времени погрузки Fator de tempo para carregar Coefficient du temps de chargement @@ -504,10 +525,10 @@ Modifies how long it takes to load/unload items.\nTime, in seconds, is the size of the item multiplied by this value. Gibt an, wie lange das Laden / Entladen von Gegenständen dauern soll.\nZeit in Sekunden, die mit der Größe des Gegenstandes multipliziert wird. - 貨物の積み込み/積み下ろしに掛かる時間を変更します。\n時間 (秒) は、貨物のサイズにこの値を掛けたものです。 + 貨物の積み込み/積み下ろしに掛かる時間を変更します。\n時間 (秒単位) は、貨物の大きさにこの値を掛けたものです。 Modyfikuje, jak długo zajmuje załadowywanie/wyładowywanie przedmiotów. \nCzasem, w sekundach, jest wielkość przedmiotu razy jego wartość. Modifica il tempo impiegato per caricare o scaricare gli oggetti.\nIl tempo, in secondi, equivale alla dimensione dell'oggetto moltiplicata per questo valore - Изменяет время для загрузки/выгрузки предметов. \n Время (сек) - это размер предмета, умноженный на это значение. + Изменяет время для загрузки/выгрузки предметов. \nВремя (сек) - это размер предмета, умноженный на это значение. Coeficiente de quanto tempo leva para carregar/descarregar itens.\nTempo, em segundos, é o tamanho do objeto multiplicado por esse valor. Modifie le temps nécessaire pour charger/décharger des objets.\nLe temps, en secondes, est calculé en multipliant la taille de l'élément par ce coefficient. 修改要花多長時間來裝載/卸載物品。\n時間,以秒為單位,而物品的大小數值與這個係數成比。 @@ -570,13 +591,23 @@ Enable deploy + Abilita Piazzamento Включить размещение 配置機能を有効化 + 배치 활성화 + Permettre le placement + Aktiviere Aufbauen + Habilitar despliegue Controls whether cargo items can be unloaded via the deploy method. + Determina se oggetti in carico possono essere scaricati e piazzati direttamente. Определяет, можно ли выгружать грузы с помощью метода размещения. 配置機能を介して貨物アイテムを降ろすことが出来るかどうかを制御します。 + 배치 방법을 통해 화물 아이템을 내릴 수 있는지 여부를 제어합니다. + Contrôler si les éléments de cargaison peuvent être déchargés via la méthode de déploiement. + Steuert, ob Frachtgegenstände über die Aufbaumethode entladen werden können. + Controla si los objetos de la carga pueden ser descargados mediante el método de despliegue. diff --git a/addons/casings/CfgVehicles.hpp b/addons/casings/CfgVehicles.hpp new file mode 100644 index 00000000000..73d06bc0ac6 --- /dev/null +++ b/addons/casings/CfgVehicles.hpp @@ -0,0 +1,6 @@ +class CfgVehicles { + class FxCartridge; + class FxCartridge_65_caseless: FxCartridge { + GVAR(model) = ""; // note: the vanilla 6.5 caseless don't actually use this, just being safe + }; +}; diff --git a/addons/casings/XEH_postInit.sqf b/addons/casings/XEH_postInit.sqf index e91ab96c0d8..47737c4e04a 100644 --- a/addons/casings/XEH_postInit.sqf +++ b/addons/casings/XEH_postInit.sqf @@ -1,7 +1,12 @@ #include "script_component.hpp" -if (!hasInterface || !GVAR(enabled)) exitWith {}; +if (!hasInterface) exitWith {}; -GVAR(cachedCasings) = createHashMap; -GVAR(casings) = []; -["CAManBase", "FiredMan", {call FUNC(createCasing)}] call CBA_fnc_addClassEventHandler; +["CBA_settingsInitialized", { + if (!GVAR(enabled)) exitWith {}; + + GVAR(cachedCasings) = createHashMap; + GVAR(casings) = []; + + ["CAManBase", "FiredMan", LINKFUNC(createCasing)] call CBA_fnc_addClassEventHandler; +}] call CBA_fnc_addEventHandler; diff --git a/addons/casings/config.cpp b/addons/casings/config.cpp index 815048a0827..29d0b7cb89c 100644 --- a/addons/casings/config.cpp +++ b/addons/casings/config.cpp @@ -15,3 +15,4 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/casings/functions/fnc_createCasing.sqf b/addons/casings/functions/fnc_createCasing.sqf index 22347d36a72..428d940414a 100644 --- a/addons/casings/functions/fnc_createCasing.sqf +++ b/addons/casings/functions/fnc_createCasing.sqf @@ -20,35 +20,34 @@ params ["_unit", "", "", "", "_ammo"]; if (!isNull objectParent _unit) exitWith {}; -private _modelPath = GVAR(cachedCasings) get _ammo; -if (isNil "_modelPath") then { +private _modelPath = GVAR(cachedCasings) getOrDefaultCall [_ammo, { private _cartridge = getText (configFile >> "CfgAmmo" >> _ammo >> "cartridge"); - //Default cartridge is a 5.56mm model - _modelPath = switch (_cartridge) do { - case "FxCartridge_9mm": { "A3\Weapons_f\ammo\cartridge_small.p3d" }; - case "FxCartridge_65": { "A3\weapons_f\ammo\cartridge_65.p3d" }; - case "FxCartridge_762": { "A3\weapons_f\ammo\cartridge_762.p3d" }; - case "FxCartridge_762x39": { "A3\weapons_f_enoch\ammo\cartridge_762x39.p3d" }; - case "FxCartridge_93x64_Ball": { "A3\Weapons_F_Mark\Ammo\cartridge_93x64.p3d" }; - case "FxCartridge_338_Ball": { "A3\Weapons_F_Mark\Ammo\cartridge_338_LM.p3d" }; - case "FxCartridge_338_NM": { "A3\Weapons_F_Mark\Ammo\cartridge_338_NM.p3d" }; - case "FxCartridge_127": { "A3\weapons_f\ammo\cartridge_127.p3d" }; - case "FxCartridge_127x54": { "A3\Weapons_F_Mark\Ammo\cartridge_127x54.p3d" }; - case "FxCartridge_slug": { "A3\weapons_f\ammo\cartridge_slug.p3d" }; - case "FxCartridge_12Gauge_HE_lxWS": { "lxWS\weapons_1_f_lxws\Ammo\cartridge_he_lxws.p3d" }; - case "FxCartridge_12Gauge_Slug_lxWS": { "lxWS\weapons_1_f_lxws\Ammo\cartridge_slug_lxws.p3d" }; - case "FxCartridge_12Gauge_Smoke_lxWS": { "lxWS\weapons_1_f_lxws\Ammo\cartridge_smoke_lxws.p3d" }; - case "FxCartridge_12Gauge_Pellet_lxWS": { "lxWS\weapons_1_f_lxws\Ammo\cartridge_pellet_lxws.p3d" }; - case "": { "" }; - default { "A3\Weapons_f\ammo\cartridge.p3d" }; + if (_cartridge == "") then { // return (note: can't use exitWith) + "" + } else { + private _cartridgeConfig = configFile >> "CfgVehicles" >> _cartridge; + + // if explicitly defined, use ACE's config + if (isText (_cartridgeConfig >> QGVAR(model))) exitWith { + getText (_cartridgeConfig >> QGVAR(model)) + }; + // use casing's default model + private _model = getText (_cartridgeConfig >> "model"); + if ("a3\weapons_f\empty" in toLowerANSI _model) exitWith { "" }; + + // Add file extension if missing (fileExists needs file extension) + if ((_model select [count _model - 4]) != ".p3d") then { + _model = _model + ".p3d"; + }; + + ["", _model] select (fileExists _model) }; - GVAR(cachedCasings) set [_ammo, _modelPath]; -}; +}, true]; if (_modelPath isEqualTo "") exitWith {}; -private _unitPos = getposASL _unit; +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 {}; diff --git a/addons/chemlights/XEH_postInit.sqf b/addons/chemlights/XEH_postInit.sqf index 6b22de4a3c9..b40ffb764ed 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/config.cpp b/addons/chemlights/config.cpp index 263fcb1a575..7f30429e798 100644 --- a/addons/chemlights/config.cpp +++ b/addons/chemlights/config.cpp @@ -3,6 +3,7 @@ class CfgPatches { class ADDON { + name = COMPONENT_NAME; units[] = {"ACE_Box_Chemlights","ACE_Item_Chemlight_Shield","ACE_Item_Chemlight_Shield_Green","ACE_Item_Chemlight_Shield_Red","ACE_Item_Chemlight_Shield_Blue","ACE_Item_Chemlight_Shield_Yellow","ACE_Item_Chemlight_Shield_Orange","ACE_Item_Chemlight_Shield_White","ModuleChemlightOrange","ModuleChemlightWhite","ModuleChemlightHiRed","ModuleChemlightHiYellow","ModuleChemlightHiWhite","ModuleChemlightHiBlue","ModuleChemlightHiGreen","ModuleChemlightUltraHiOrange"}; weapons[] = {"ACE_Chemlight_Shield", "ACE_Chemlight_Shield_Green","ACE_Chemlight_Shield_Red","ACE_Chemlight_Shield_Blue","ACE_Chemlight_Shield_Yellow","ACE_Chemlight_Shield_Orange","ACE_Chemlight_Shield_White"}; requiredVersion = REQUIRED_VERSION; diff --git a/addons/chemlights/script_component.hpp b/addons/chemlights/script_component.hpp index 324af2c55c1..5095ebe6664 100644 --- a/addons/chemlights/script_component.hpp +++ b/addons/chemlights/script_component.hpp @@ -1,4 +1,5 @@ #define COMPONENT chemlights +#define COMPONENT_BEAUTIFIED Chemlights #include "\z\ace\addons\main\script_mod.hpp" // #define DEBUG_MODE_FULL diff --git a/addons/chemlights/stringtable.xml b/addons/chemlights/stringtable.xml index 2c4066e9b76..76f937df61a 100644 --- a/addons/chemlights/stringtable.xml +++ b/addons/chemlights/stringtable.xml @@ -355,7 +355,7 @@ Chemlight (Hi Green) - Cyalume HL (vert) + Cyalume HL (Vert) Knicklicht (Grün, Hell) ケミカルライト(高輝度 緑) Świetlik (jaskrawy zielony) @@ -533,9 +533,9 @@ Chemlight Shield (Green) ケミカルライト シールド(緑) Osłona na świetlik (zielona) - Knicklicht-Abschirmung (grün) + Knicklicht-Abschirmung (Grün) 화학조명 가림막 (초록) - Etui avec cyalume (vert) + Etui avec cyalume (Vert) Scudo Luce Chimica (Verde) 螢光棒保護殼 (綠色) 荧光棒保护壳(绿色) diff --git a/addons/common/CfgMoves.hpp b/addons/common/CfgMoves.hpp index 14686526e92..da83153b152 100644 --- a/addons/common/CfgMoves.hpp +++ b/addons/common/CfgMoves.hpp @@ -1,5 +1,6 @@ class CfgMovesBasic { class Default; + // From ACRE class ManActions { GVAR(stop) = QGVAR(stop); @@ -82,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/CfgUIGrids.hpp b/addons/common/CfgUIGrids.hpp index 1e8963e03e1..7c48886bafd 100644 --- a/addons/common/CfgUIGrids.hpp +++ b/addons/common/CfgUIGrids.hpp @@ -5,13 +5,13 @@ class CfgUIGrids { 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))" + "((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)" + "(((safeZoneW / safeZoneH) min 1.2) / 40)", + "((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)" }; }; }; diff --git a/addons/common/CompassControl.hpp b/addons/common/CompassControl.hpp index 627e18d2f8d..16b1b3cf43d 100644 --- a/addons/common/CompassControl.hpp +++ b/addons/common/CompassControl.hpp @@ -10,7 +10,7 @@ #define POINTER_WIDTH_FACTOR (1/128) #define LEFT (0.5 - 8 * GUI_GRID_W) -#define TOP (safezoneY + 1.6 * GUI_GRID_H) +#define TOP (safeZoneY + 1.6 * GUI_GRID_H) #define WIDTH (16 * GUI_GRID_W) #define HEIGHT (0.5 * GUI_GRID_H) diff --git a/addons/common/DisableMouseDialog.hpp b/addons/common/DisableMouseDialog.hpp index 75689cf6526..1d1d6cfaa74 100644 --- a/addons/common/DisableMouseDialog.hpp +++ b/addons/common/DisableMouseDialog.hpp @@ -8,10 +8,10 @@ class GVAR(DisableMouse_Dialog) { class Background: ctrlMapEmpty { idc = 101; fade = 1; - x = "safezoneXAbs"; - y = "safezoneY"; - w = "safezoneWAbs"; - h = "safezoneH"; + x = "safeZoneXAbs"; + y = "safeZoneY"; + w = "safeZoneWAbs"; + h = "safeZoneH"; }; }; }; diff --git a/addons/common/HintConfig.hpp b/addons/common/HintConfig.hpp index c299bee8dfb..c3eda57d6bb 100644 --- a/addons/common/HintConfig.hpp +++ b/addons/common/HintConfig.hpp @@ -39,11 +39,11 @@ class RscTitles { idc = 1; text = ""; //size = "1 / 40 / (getResolution select 5)"; - SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; + 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"; + 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"; @@ -63,11 +63,11 @@ class RscTitles { idc = 1; text = ""; //size = "1 / 40 / (getResolution select 5)"; - SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; + 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"; + 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 bef2994e7d9..c3026a9fe4f 100644 --- a/addons/common/ProgressScreen.hpp +++ b/addons/common/ProgressScreen.hpp @@ -18,28 +18,28 @@ class GVAR(ProgressBar_Dialog) { size = 1; colorBackground[] = {0, 0, 0, 0.0}; colorText[] = {0, 0, 0, 0}; - x = "safezoneX"; - y = "safezoneY"; - w = "safezoneW"; - h = "safezoneH"; + x = "safeZoneX"; + y = "safeZoneY"; + w = "safeZoneW"; + h = "safeZoneH"; }; class TitleBackground: ACE_gui_staticBase { idc = 1; style = ST_CENTER; - sizeEx = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + sizeEx = "1 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; colorBackground[] = {0, 0, 0, 0.5}; colorText[] = {1, 1, 1, 1}; - x = "1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; - y = "0 * ((((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 = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + x = "1 * (((safeZoneW / safeZoneH) min 1.2) / 40) + (safeZoneX + (safeZoneW - ((safeZoneW / safeZoneH) min 1.2))/2)"; + y = "0 * ((((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 = "1 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; }; class Progress: ACE_gui_RscProgress { idc = 2; - x = "1.2 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; - y = "0.1 * ((((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 = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + x = "1.2 * (((safeZoneW / safeZoneH) min 1.2) / 40) + (safeZoneX + (safeZoneW - ((safeZoneW / safeZoneH) min 1.2))/2)"; + y = "0.1 * ((((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 = "1 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; colorFrame[] = {1,1,1,0.5}; colorBar[] = {"(profilenamespace getVariable ['GUI_BCG_RGB_R',0.77])","(profilenamespace getVariable ['GUI_BCG_RGB_G',0.51])","(profilenamespace getVariable ['GUI_BCG_RGB_B',0.08])","(profilenamespace getVariable ['GUI_BCG_RGB_A',0.8])"}; texture = "#(argb,8,8,3)color(1,1,1,0.7)"; diff --git a/addons/common/RscInfoType.hpp b/addons/common/RscInfoType.hpp index 672d043276c..89d3c02ec1d 100644 --- a/addons/common/RscInfoType.hpp +++ b/addons/common/RscInfoType.hpp @@ -6,19 +6,19 @@ class RscInGameUI { }; 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 { @@ -30,11 +30,11 @@ class RscInGameUI { }; 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 { @@ -94,7 +94,7 @@ class RscInGameUI { }; 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 { @@ -106,10 +106,10 @@ class RscInGameUI { }; class RscStaminaBar { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscStaminaBar"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2(QUOTE(QGVAR(dlgStaminaBar)),_this select 0)]); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscStaminaBar"",'IGUI')] call (uiNamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2(QUOTE(QGVAR(dlgStaminaBar)),_this select 0)]); }; 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 ce6ac334eea..529da07da2b 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -13,6 +13,7 @@ PREP(addLineToDebugDraw); PREP(addSwayFactor); PREP(addToInventory); PREP(addWeapon); +PREP(adjustMagazineAmmo); PREP(assignedItemFix); PREP(assignObjectsInList); PREP(ambientBrightness); @@ -29,6 +30,7 @@ PREP(changeProjectileDirection); PREP(checkFiles); PREP(checkFiles_diagnoseACE); PREP(checkPBOs); +PREP(checkVersionNumber); PREP(claim); PREP(claimSafeServer); PREP(codeToString); @@ -41,6 +43,7 @@ PREP(deviceKeyFindValidIndex); PREP(deviceKeyRegisterNew); PREP(deprecateComponent); PREP(disableAI); +PREP(disableAiUAV); PREP(disableUserInput); PREP(displayIcon); PREP(displayText); @@ -102,6 +105,7 @@ PREP(getWeaponAzimuthAndInclination); PREP(getWeaponIndex); PREP(getWeaponState); PREP(getWeight); +PREP(getWheelHitPointsWithSelections); PREP(getWindDirection); PREP(getZoom); PREP(goKneeling); @@ -160,6 +164,7 @@ PREP(sendRequest); PREP(serverLog); PREP(setAimCoef); PREP(setApproximateVariablePublic); +PREP(setDead); PREP(setDefinedVariable); PREP(setDisableUserInputStatus); PREP(setHearingCapability); @@ -173,6 +178,7 @@ PREP(setupLocalUnitsHandler); PREP(setVariableJIP); PREP(setVariablePublic); PREP(setVolume); +PREP(setWeaponLightLaserState); PREP(showHud); PREP(statusEffect_addType); PREP(statusEffect_get); @@ -185,6 +191,7 @@ PREP(stopGesture); PREP(stringCompare); PREP(stringToColoredText); PREP(swayLoop); +PREP(switchAttachmentMode); PREP(switchPersistentLaser); PREP(switchToGroupSide); PREP(throttledPublicVariable); @@ -262,7 +269,9 @@ PREP(_handleRequestAllSyncedEvents); // other eventhandlers PREP(addActionEventHandler); PREP(addActionMenuEventHandler); +PREP(addExplosionEventHandler); PREP(addMapMarkerCreatedEventHandler); +PREP(addPlayerEH); PREP(removeActionEventHandler); PREP(removeActionMenuEventHandler); diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index af4b33d49b8..98520aef937 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -18,17 +18,17 @@ ////////////////////////////////////////////////// //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", "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); +[QGVAR(setStatusEffect), LINKFUNC(statusEffect_set)] call CBA_fnc_addEventHandler; +["forceWalk", false, ["ace_advanced_fatigue", "ace_attach", "ace_dragging", "ace_explosives", QEGVAR(medical,fracture), "ace_rearm", "ace_refuel", "ace_sandbag", "ace_switchunits", "ace_tacticalladder", "ace_trenches"]] call FUNC(statusEffect_addType); +["blockSprint", false, ["ace_advanced_fatigue", "ace_dragging", QEGVAR(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_rearm", "ace_refuel", "ace_sandbag", "ace_tacticalladder", "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); +["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); +["disableWeaponAssembly", false, ["ace_common", QGVAR(lockVehicle), "ace_csw"]] call FUNC(statusEffect_addType); ["lockInventory", true, [], true] call FUNC(statusEffect_addType); [QGVAR(forceWalk), { @@ -133,6 +133,30 @@ _object lockInventory (_set > 0); }] call CBA_fnc_addEventHandler; +[QGVAR(disableAiUAV), { + params ["_unit", "_disable"]; + + if (_disable) then { + private _features = ["AUTOTARGET", "TARGET", "WEAPONAIM"/*, "FIREWEAPON"*/, "RADIOPROTOCOL"]; // TODO: Uncomment in 2.18 + + // Save current status + _unit setVariable [QGVAR(featuresAiUAV), _features apply {[_x, _unit checkAIFeature _x]}]; + + { + _unit enableAIFeature [_x, false]; + } forEach _features; + } else { + // Restore previous status + private _features = _unit getVariable [QGVAR(featuresAiUAV), []]; + + { + _unit enableAIFeature [_x select 0, _x select 1]; + } forEach _features; + + _unit setVariable [QGVAR(featuresAiUAV), nil]; + }; +}] call CBA_fnc_addEventHandler; + //Add a fix for BIS's zeus remoteControl module not reseting variables on DC when RC a unit //This variable is used for isPlayer checks if (isServer) then { @@ -141,12 +165,11 @@ if (isServer) then { private _zeusLogic = getAssignedCuratorLogic _dcPlayer; if ((!isNil "_zeusLogic") && {!isNull _zeusLogic}) then { { - if ((_x getvariable ["bis_fnc_moduleRemoteControl_owner", objnull]) isEqualTo _dcPlayer) exitWith { + 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); _x setVariable ["bis_fnc_moduleRemoteControl_owner", nil, true]; }; - nil - } count (curatorEditableObjects _zeusLogic); + } forEach (curatorEditableObjects _zeusLogic); }; }]; }; @@ -157,9 +180,9 @@ if (isServer) then { INFO_2("Headbug Used: Name: %1, Animation: %2",_profileName,_animation); }] call CBA_fnc_addEventHandler; -[QGVAR(fixCollision), FUNC(fixCollision)] call CBA_fnc_addEventHandler; -[QGVAR(fixFloating), FUNC(fixFloating)] call CBA_fnc_addEventHandler; -[QGVAR(fixPosition), FUNC(fixPosition)] call CBA_fnc_addEventHandler; +[QGVAR(fixCollision), LINKFUNC(fixCollision)] call CBA_fnc_addEventHandler; +[QGVAR(fixFloating), LINKFUNC(fixFloating)] call CBA_fnc_addEventHandler; +[QGVAR(fixPosition), LINKFUNC(fixPosition)] call CBA_fnc_addEventHandler; ["ace_loadPersonEvent", LINKFUNC(loadPersonLocal)] call CBA_fnc_addEventHandler; ["ace_unloadPersonEvent", LINKFUNC(unloadPersonLocal)] call CBA_fnc_addEventHandler; @@ -174,7 +197,7 @@ if (isServer) then { [QGVAR(unlockVehicle), { _this lock (_this getVariable [QGVAR(lockStatus), locked _this]); - if ([] isNotEqualTo getArray (configOf _target >> "assembleInfo" >> "dissasembleTo")) then { + if ([] isNotEqualTo getArray (configOf _this >> "assembleInfo" >> "dissasembleTo")) then { [_this, "disableWeaponAssembly", QGVAR(lockVehicle), false] call FUNC(statusEffect_set); }; }] call CBA_fnc_addEventHandler; @@ -192,6 +215,9 @@ 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(addMagazineTurret), {(_this select 0) addMagazineTurret (_this select 1)}] call CBA_fnc_addEventHandler; +[QGVAR(removeMagazinesTurret), {(_this select 0) removeMagazinesTurret [_this select 1, _this select 2]}] call CBA_fnc_addEventHandler; +[QGVAR(triggerAmmo), {triggerAmmo _this}] call CBA_fnc_addEventHandler; [QGVAR(setVanillaHitPointDamage), { params ["_object", "_hitPointAnddamage"]; @@ -209,8 +235,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; @@ -219,10 +245,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 @@ -236,14 +265,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; }; @@ -361,7 +390,7 @@ addMissionEventHandler ["PlayerViewChanged", { private _position = [player] call FUNC(getUavControlPosition); private _seatAI = objNull; private _turret = []; - switch (toLower _position) do { + switch (toLowerANSI _position) do { case (""): { _UAV = objNull; // set to objNull if not actively controlling }; @@ -392,8 +421,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"]; @@ -403,7 +432,7 @@ addMissionEventHandler ["PlayerViewChanged", { }; }] call CBA_fnc_addEventHandler; -["ace_useItem", DFUNC(useItem)] call CBA_fnc_addEventHandler; +["ace_useItem", LINKFUNC(useItem)] call CBA_fnc_addEventHandler; ////////////////////////////////////////////////// @@ -467,10 +496,10 @@ GVAR(reloadMutex_lastMagazines) = []; private _isLauncher = _weapon isKindOf ["Launcher", configFile >> "CfgWeapons"]; private _duration = 0; if (_isLauncher) then { - _duration = getNumber (configfile >> "CfgMovesMaleSdr" >> "States" >> _gesture >> "speed"); + _duration = getNumber (configFile >> "CfgMovesMaleSdr" >> "States" >> _gesture >> "speed"); }; if (_duration == 0) then { - _duration = getNumber (configfile >> "CfgGesturesMale" >> "States" >> _gesture >> "speed"); + _duration = getNumber (configFile >> "CfgGesturesMale" >> "States" >> _gesture >> "speed"); }; if (_duration != 0) then { @@ -499,10 +528,24 @@ GVAR(reloadMutex_lastMagazines) = []; // Start the sway loop ////////////////////////////////////////////////// ["CBA_settingsInitialized", { + ["multiplier", { + switch (true) do { + case (isWeaponRested ACE_player): { + GVAR(swayFactor) * GVAR(restedSwayFactor) + }; + case (isWeaponDeployed ACE_player): { + GVAR(swayFactor) * GVAR(deployedSwayFactor) + }; + default { + GVAR(swayFactor) + }; + }; + }, QUOTE(ADDON)] call FUNC(addSwayFactor); + [{ // frame after settingsInitialized to ensure all other addons have added their factors - if ((GVAR(swayFactorsBaseline) + GVAR(swayFactorsMultiplier)) isNotEqualTo []) then { - call FUNC(swayLoop) + if (GVAR(enableSway)) then { + call FUNC(swayLoop); }; // check for pre-3.16 sway factors being added if (!isNil {missionNamespace getVariable "ACE_setCustomAimCoef"}) then { @@ -519,7 +562,7 @@ GVAR(reloadMutex_lastMagazines) = []; // Lastly, do JIP events // JIP Detection and event trigger. Run this at the very end, just in case anything uses it // Note: usage of player is most likely on purpose -if (didJip) then { +if (didJIP) then { // We are jipping! Get ready and wait, and throw the event [{ if(!isNull player && GVAR(settingsInitFinished)) then { diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf index 9b5d27d12ca..f2194deb64f 100644 --- a/addons/common/XEH_preInit.sqf +++ b/addons/common/XEH_preInit.sqf @@ -10,6 +10,9 @@ PREP_RECOMPILE_END; GVAR(syncedEvents) = createHashMap; GVAR(showHudHash) = createHashMap; GVAR(vehicleIconCache) = createHashMap; // for getVehicleIcon +GVAR(wheelSelections) = createHashMap; + +GVAR(InteractionConditions) = createHashMap; GVAR(blockItemReplacement) = false; diff --git a/addons/common/XEH_preStart.sqf b/addons/common/XEH_preStart.sqf index 208adea7b15..5e02fb26f17 100644 --- a/addons/common/XEH_preStart.sqf +++ b/addons/common/XEH_preStart.sqf @@ -3,7 +3,7 @@ #include "XEH_PREP.hpp" if (isFilePatchingEnabled) then { - private _notLoaded = configProperties [configfile >> "ace_notLoaded", "isText _x"]; + private _notLoaded = configProperties [configFile >> "ace_notLoaded", "isText _x"]; { INFO_2("%1 not loaded because %2",configName _x,getText _x); } forEach _notLoaded; @@ -15,3 +15,25 @@ uiNamespace setVariable [QGVAR(addonCache), createHashMap]; // Cache for FUNC(getConfigName) uiNamespace setVariable [QGVAR(configNames), createHashMap]; + +//Add warnings for missing compat PBOs +GVAR(isModLoadedCache) = createHashMap; +{ + _x params ["_modPBO", "_compatPBO"]; + if ([_modPBO] call FUNC(isModLoaded) && {!([_compatPBO] call FUNC(isModLoaded))}) then { + WARNING_2("Weapon Mod [%1] missing ace compat pbo [%2]",_modPBO,_compatPBO); + }; +} forEach [ + ["CUP_Creatures_People_LoadOrder","ace_compat_cup_units"], + ["CUP_Vehicles_LoadOrder","ace_compat_cup_vehicles"], + ["CUP_Weapons_LoadOrder","ace_compat_cup_weapons"], + ["r3f_armes_c","ace_compat_r3f"], + ["RF_Data_Loadorder","ace_compat_rf"], + ["RH_acc","ace_compat_rh_acc"], + ["RH_de_cfg","ace_compat_rh_de"], + ["RH_m4_cfg","ace_compat_rh_m4"], + ["RH_PDW","ace_compat_rh_pdw"], + ["RKSL_PMII","ace_compat_rksl_pm_ii"], + ["iansky_opt","ace_compat_sma3_iansky"], + ["R3F_Armes","ace_compat_r3f"] +]; diff --git a/addons/common/config.cpp b/addons/common/config.cpp index 144e7d96c61..f7b27ce3749 100644 --- a/addons/common/config.cpp +++ b/addons/common/config.cpp @@ -70,8 +70,6 @@ class ctrlMapEmpty; #include "CompassControl.hpp" #include "CfgUIGrids.hpp" -class ACE_Extensions {}; - class ACE_Tests { vehicleTransportInventory = QPATHTOF(dev\test_vehicleInventory.sqf); mapConfigs = QPATHTOF(dev\test_mapConfigs.sqf); diff --git a/addons/common/define.hpp b/addons/common/define.hpp index ce8765ec9f4..e27c369146b 100644 --- a/addons/common/define.hpp +++ b/addons/common/define.hpp @@ -107,7 +107,7 @@ class ACE_gui_editBase { style = "0x00 + 0x40"; font = "RobotoCondensed"; shadow = 2; - sizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; + sizeEx = "(((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25) * 1)"; colorDisabled[] = {1, 1, 1, 0.25}; }; @@ -187,10 +187,10 @@ class ACE_gui_RscProgress { 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)"; + 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 { @@ -384,9 +384,9 @@ class ACE_gui_comboBoxBase: RscCombo { class ACE_gui_mapBase { moveOnEdges = 1; x = "SafeZoneXAbs"; - y = "SafeZoneY + 1.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + 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)"; + h = "SafeZoneH - 1.5 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; type = 100; // Use 100 to hide markers style = 48; shadow = 0; @@ -440,15 +440,15 @@ class ACE_gui_mapBase { onMouseButtonDblClick = ""; fontLabel = "RobotoCondensed"; - sizeExLabel = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; + 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)"; + 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"; + 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)"; + 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)"; @@ -458,12 +458,12 @@ class ACE_gui_mapBase { 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)"; + 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)"; + sizeEx = "(((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25) * 0.8)"; colorBackground[] = {1, 1, 1, 0.5}; color[] = {0, 0, 0, 1}; }; diff --git a/addons/common/dev/test_cfgPatches.sqf b/addons/common/dev/test_cfgPatches.sqf index 281c16eca35..c5f3c81ef55 100644 --- a/addons/common/dev/test_cfgPatches.sqf +++ b/addons/common/dev/test_cfgPatches.sqf @@ -13,7 +13,7 @@ private _allPatches = "(configName _x) select [0,3] == 'ace'" configClasses (con // Get all units[] private _allUnits = []; { - _allUnits append ((getArray (_x >> "units")) apply { toLower _x }); + _allUnits append ((getArray (_x >> "units")) apply { toLowerANSI _x }); } forEach _allPatches; { private _class = configFile >> "CfgVehicles" >> _x; @@ -31,7 +31,7 @@ private _allUnits = []; // Get all weapons[] private _allWeapons = []; { - _allWeapons append ((getArray (_x >> "weapons")) apply { toLower _x }); + _allWeapons append ((getArray (_x >> "weapons")) apply { toLowerANSI _x }); } forEach _allPatches; { private _class = configFile >> "CfgWeapons" >> _x; @@ -50,7 +50,7 @@ private _allWeapons = []; private _vics = "(configName _x) select [0,3] == 'ace'" configClasses (configFile >> "CfgVehicles"); { if (((getNumber (_x >> "scope")) == 2) || {((getNumber (_x >> "scopeCurator")) == 2)}) then { - if (!((toLower configName _x) in _allUnits)) then { + if !((toLowerANSI configName _x) in _allUnits) then { WARNING_2("Not in any units[] - %1 from %2",configName _x,configSourceMod _x); _testPass = false; }; @@ -60,9 +60,9 @@ private _vics = "(configName _x) select [0,3] == 'ace'" configClasses (configFil // Check if all public weapons are defined in a cfgPatch private _weapons = "(configName _x) select [0,3] == 'ace'" configClasses (configFile >> "CfgWeapons"); { - private _type = toLower configName _x; + private _type = toLowerANSI configName _x; if (((getNumber (_x >> "scope")) == 2) || {((getNumber (_x >> "scopeCurator")) == 2)}) then { - if (!((toLower configName _x) in _allWeapons)) then { + if !((toLowerANSI configName _x) in _allWeapons) then { WARNING_2("Not in any weapons[] - %1 from %2",configName _x,configSourceMod _x); _testPass = false; }; diff --git a/addons/common/dev/test_mapConfigs.sqf b/addons/common/dev/test_mapConfigs.sqf index 369b2b18089..261dc0a9abd 100644 --- a/addons/common/dev/test_mapConfigs.sqf +++ b/addons/common/dev/test_mapConfigs.sqf @@ -28,7 +28,7 @@ private _maps = configProperties [configFile >> "CfgWorldList", "(isClass _x)", private _stepX = 1e10; private _stepY = 1e10; { - private _zoom = getnumber (_x >> "zoomMax"); + private _zoom = getNumber (_x >> "zoomMax"); if (_zoom < _zoomMax) then { _zoomMax = _zoom; _formatX = getText (_x >> "formatX"); diff --git a/addons/common/dev/test_vehicleInventory.sqf b/addons/common/dev/test_vehicleInventory.sqf index 7fdd0159c0a..9fb24fc1d67 100644 --- a/addons/common/dev/test_vehicleInventory.sqf +++ b/addons/common/dev/test_vehicleInventory.sqf @@ -14,7 +14,7 @@ private _vehicles = configProperties [configFile >> "CfgVehicles", "(isClass _x) private _glassesConfig = configFile >> "CfgGlasses" >> _name; if (((!isClass _weaponConfig) || {(getNumber (_weaponConfig >> "type")) in [1,2,4]}) && {!isClass _glassesConfig}) then { diag_log text format ["%1 -> TransportItems -> %2 = Bad", _vehType, _name]; - if ("ace" in toLower (_vehType + _name)) then { _testPass = false; }; + if ("ace" in toLowerANSI (_vehType + _name)) then { _testPass = false; }; }; }; } forEach (configProperties [_x >> "TransportItems", "isClass _x", true]); @@ -23,7 +23,7 @@ private _vehicles = configProperties [configFile >> "CfgVehicles", "(isClass _x) private _weaponConfig = configFile >> "CfgWeapons" >> _name; if ((!isClass _weaponConfig) || {!((getNumber (_weaponConfig >> "type")) in [1,2,4])}) then { diag_log text format ["%1 -> TransportWeapons -> %2 = Bad", _vehType, _name]; - if ("ace" in toLower (_vehType + _name)) then { _testPass = false; }; + if ("ace" in toLowerANSI (_vehType + _name)) then { _testPass = false; }; }; } forEach (configProperties [_x >> "TransportWeapons", "isClass _x", true]); { @@ -31,7 +31,7 @@ private _vehicles = configProperties [configFile >> "CfgVehicles", "(isClass _x) private _magConfig = configFile >> "CfgMagazines" >> _name; if ((!isClass _magConfig)) then { diag_log text format ["%1 -> TransportMagazines -> %2 = Bad", _vehType, _name]; - if ("ace" in toLower (_vehType + _name)) then { _testPass = false; }; + if ("ace" in toLowerANSI (_vehType + _name)) then { _testPass = false; }; }; } forEach (configProperties [_x >> "TransportMagazines", "isClass _x", true]); { @@ -39,7 +39,7 @@ private _vehicles = configProperties [configFile >> "CfgVehicles", "(isClass _x) private _vehConfig = configFile >> "CfgVehicles" >> _name; if ((!isClass _vehConfig)) then { diag_log text format ["%1 -> TransportBackpacks -> %2 = Bad", _vehType, _name]; - if ("ace" in toLower (_vehType + _name)) then { _testPass = false; }; + if ("ace" in toLowerANSI (_vehType + _name)) then { _testPass = false; }; }; } forEach (configProperties [_x >> "TransportBackpacks", "isClass _x", true]); } forEach _vehicles; diff --git a/addons/common/functions/fnc_ASLToPosition.sqf b/addons/common/functions/fnc_ASLToPosition.sqf index b99e9fb88a3..991e79c4331 100644 --- a/addons/common/functions/fnc_ASLToPosition.sqf +++ b/addons/common/functions/fnc_ASLToPosition.sqf @@ -20,5 +20,5 @@ if (surfaceIsWater _this) then { _this } else { - ASLtoATL _this + ASLToATL _this }; diff --git a/addons/common/functions/fnc__handleRequestSyncedEvent.sqf b/addons/common/functions/fnc__handleRequestSyncedEvent.sqf index 299dff83733..1924ed22ffd 100644 --- a/addons/common/functions/fnc__handleRequestSyncedEvent.sqf +++ b/addons/common/functions/fnc__handleRequestSyncedEvent.sqf @@ -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_actionKeysNamesConverted.sqf b/addons/common/functions/fnc_actionKeysNamesConverted.sqf index dd62fc87892..27c3597a9b3 100644 --- a/addons/common/functions/fnc_actionKeysNamesConverted.sqf +++ b/addons/common/functions/fnc_actionKeysNamesConverted.sqf @@ -43,10 +43,10 @@ if (isNil "_keyTable") then { }; }; -private _keyCache = uiNamespace getVariable [QGVAR(keyNameCache), locationNull]; +private _keyCache = uiNamespace getVariable QGVAR(keyNameCache); // @TODO: Move cache creation to preStart/somewhere else -if (isNull _keyCache) then { - _keyCache = call CBA_fnc_createNamespace; +if (isNil "_keyCache") then { + _keyCache = createHashMap; uiNamespace setVariable [QGVAR(keyNameCache), _keyCache]; }; @@ -54,7 +54,7 @@ params [["_action", "", [""]]]; private _keybinds = actionKeysNamesArray _action apply { private _keyName = _x; - private _keybind = _keyCache getVariable _keyName; + private _keybind = _keyCache get _keyName; if (isNil "_keybind") then { private _key = -1; @@ -101,7 +101,7 @@ private _keybinds = actionKeysNamesArray _action apply { // cache _keybind = [_key, _shift, _ctrl, _alt]; - _keyCache setVariable [_keyName, _keybind]; + _keyCache set [_keyName, _keybind]; }; _keybind diff --git a/addons/common/functions/fnc_addCanInteractWithCondition.sqf b/addons/common/functions/fnc_addCanInteractWithCondition.sqf index d9c4e3335d5..1d315f5aa53 100644 --- a/addons/common/functions/fnc_addCanInteractWithCondition.sqf +++ b/addons/common/functions/fnc_addCanInteractWithCondition.sqf @@ -18,18 +18,5 @@ params ["_conditionName", "_conditionFunc"]; -_conditionName = toLower _conditionName; - -private _conditions = missionNamespace getVariable [QGVAR(InteractionConditions), [[],[]]]; -_conditions params ["_conditionNames", "_conditionFuncs"]; - -private _index = _conditionNames find _conditionName; - -if (_index == -1) then { - _index = count _conditionNames; -}; - -_conditionNames set [_index, _conditionName]; -_conditionFuncs set [_index, _conditionFunc]; - -GVAR(InteractionConditions) = _conditions; +_conditionName = toLowerANSI _conditionName; +GVAR(InteractionConditions) set [_conditionName, _conditionFunc]; diff --git a/addons/common/functions/fnc_addExplosionEventHandler.sqf b/addons/common/functions/fnc_addExplosionEventHandler.sqf new file mode 100644 index 00000000000..9fb5ef80f24 --- /dev/null +++ b/addons/common/functions/fnc_addExplosionEventHandler.sqf @@ -0,0 +1,48 @@ +#include "..\script_component.hpp" +/* + * Author: johnb432, PabstMirror + * Adds event hander for explosions (for local projectiles) + * Warning: For shots that are tracers and explosive the event will trigger on all machines in range + * This function may be changed after 2.18! + * + * Arguments: + * 0: Code to execute + * + * Return Value: + * The CBA Event Handler Index + * + * Example: + * [{systemChat "boom"}] call ace_common_fnc_addExplosionEventHandler + * + * Public: No (maybe after 2.18) + */ + +params [["_code", {}, [{}]]]; + +if !(missionNamespace getVariable [QGVAR(addExplosionEventHandlerActive), false]) then { + GVAR(addExplosionEventHandlerActive) = true; + + // Add EH to existing projectiles and mines + { + TRACE_2("existing",typeOf _x,local _x); + // Rockets only explode on local clients + _x addEventHandler ["Explode", { + TRACE_1("exp (existing)",_this); + [QGVAR(explosion), _this] call CBA_fnc_localEvent; + }]; + } forEach ((8 allObjects 2) select {local _x}); + + addMissionEventHandler ["ProjectileCreated", { + params ["_projectile"]; + TRACE_2("pc",typeOf _projectile,local _projectile); + + if (!local _projectile) exitWith {}; // Rockets only explode on local clients + + _projectile addEventHandler ["Explode", { + TRACE_1("exp",_this); + [QGVAR(explosion), _this] call CBA_fnc_localEvent; + }]; + }]; +}; + +[QGVAR(explosion), _code] call CBA_fnc_addEventHandler diff --git a/addons/common/functions/fnc_addLineToDebugDraw.sqf b/addons/common/functions/fnc_addLineToDebugDraw.sqf index 016c99ddf48..3d6309fdd43 100644 --- a/addons/common/functions/fnc_addLineToDebugDraw.sqf +++ b/addons/common/functions/fnc_addLineToDebugDraw.sqf @@ -25,10 +25,10 @@ if (isNil QGVAR(debugLines)) then { }; if (count GVAR(debugLines) < 100) then { - GVAR(debugLines) pushBack [ASLtoAGL _startASL, ASLtoAGL _endASL, _color]; + GVAR(debugLines) pushBack [ASLToAGL _startASL, ASLToAGL _endASL, _color]; GVAR(debugLinesIndex) = 0; } else { - GVAR(debugLines) set [GVAR(debugLinesIndex), [ASLtoAGL _startASL, ASLtoAGL _endASL, _color]]; + GVAR(debugLines) set [GVAR(debugLinesIndex), [ASLToAGL _startASL, ASLToAGL _endASL, _color]]; GVAR(debugLinesIndex) = (GVAR(debugLinesIndex) + 1) mod 100; }; diff --git a/addons/common/functions/fnc_addPlayerEH.sqf b/addons/common/functions/fnc_addPlayerEH.sqf new file mode 100644 index 00000000000..c20fde9da17 --- /dev/null +++ b/addons/common/functions/fnc_addPlayerEH.sqf @@ -0,0 +1,63 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Adds event handler just to ACE_player + * Can be removed after cba 3.18 is released for CBA_fnc_addBISPlayerEventHandler + * This never was public in a release + * + * Arguments: + * 0: Key + * 1: Event Type + * 2: Event Code + * 3: Ignore Virtual Units (spectators, virtual zeus, uav RC) (default: true) + * + * Return Value: + * None + * + * Example: + * ["example", "FiredNear", {systemChat str _this}] call ace_common_fnc_addPlayerEH + * + * Public: No +*/ +params [["_key", "", [""]], ["_type", "", [""]], ["_code", {}, [{}]], ["_ignoreVirtual", true, [true]]]; +TRACE_3("addPlayerEH",_key,_type,_ignoreVirtual); + +if (isNil QGVAR(playerEventsHash)) then { // first-run init + GVAR(playerEventsHash) = createHashMap; + ["unit", { + params ["_newPlayer", "_oldPlayer"]; + // uav check only applies to direct controlling UAVs from zeus, no effect on normal UAV operation + private _isVirutal = (unitIsUAV _newPlayer) || {getNumber (configOf _newPlayer >> "isPlayableLogic") == 1}; + + TRACE_4("",_newPlayer,_oldPlayer,_isVirutal,count GVAR(playerEventsHash)); + { + _y params ["_type", "_code", "_ignoreVirtual"]; + + private _oldEH = _oldPlayer getVariable [_x, -1]; + if (_oldEH != -1) then { + _oldPlayer removeEventHandler [_type, _oldEH]; + _oldPlayer setVariable [_x, nil]; + }; + + _oldEH = _newPlayer getVariable [_x, -1]; + if (_oldEH != -1) then { continue }; // if respawned then var and EH already exists + if (_ignoreVirtual && _isVirutal) then { continue }; + + private _newEH = _newPlayer addEventHandler [_type, _code]; + _newPlayer setVariable [_x, _newEH]; + } forEach GVAR(playerEventsHash); + }, false] call CBA_fnc_addPlayerEventHandler; +}; + + +_key = format [QGVAR(playerEvents_%1), toLower _key]; +if (_key in GVAR(playerEventsHash)) exitWith { ERROR_1("bad key %1",_this); }; + +GVAR(playerEventsHash) set [_key, [_type, _code, _ignoreVirtual]]; + +if (isNull ACE_player) exitWith {}; +if (_ignoreVirtual && {(unitIsUAV ACE_player) || {getNumber (configOf ACE_player >> "isPlayableLogic") == 1}}) exitWith {}; + +// Add event now +private _newEH = ACE_player addEventHandler [_type, _code]; +ACE_player setVariable [_key, _newEH]; diff --git a/addons/common/functions/fnc_addSwayFactor.sqf b/addons/common/functions/fnc_addSwayFactor.sqf index 7a258bc12a2..1cdc6fb7215 100644 --- a/addons/common/functions/fnc_addSwayFactor.sqf +++ b/addons/common/functions/fnc_addSwayFactor.sqf @@ -18,7 +18,7 @@ */ params ["_type", "_code", "_id"]; -_type = toLower _type; +_type = toLowerANSI _type; if !(_type in ["baseline", "multiplier"]) exitWith { ERROR_2("%1-%2 type unsupported",_type,_id); false }; diff --git a/addons/common/functions/fnc_addSyncedEventHandler.sqf b/addons/common/functions/fnc_addSyncedEventHandler.sqf index dbe0612e954..616897842b2 100644 --- a/addons/common/functions/fnc_addSyncedEventHandler.sqf +++ b/addons/common/functions/fnc_addSyncedEventHandler.sqf @@ -24,7 +24,7 @@ if (_name in GVAR(syncedEvents)) exitWith { false }; -private _eventId = [_name, FUNC(_handleSyncedEvent)] call CBA_fnc_addEventHandler; +private _eventId = [_name, LINKFUNC(_handleSyncedEvent)] call CBA_fnc_addEventHandler; private _data = [_handler, [], _ttl, _eventId]; GVAR(syncedEvents) set [_name, _data]; diff --git a/addons/common/functions/fnc_addToInventory.sqf b/addons/common/functions/fnc_addToInventory.sqf index 39e69033907..38476ad5fc1 100644 --- a/addons/common/functions/fnc_addToInventory.sqf +++ b/addons/common/functions/fnc_addToInventory.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet - * Adds an item, weapon, or magazine to the unit's inventory or places it in a weaponHolder if no space. + * Adds an item, weapon, or magazine to the unit's inventory or places it in a weapon holder if no space. * * Arguments: * 0: Unit @@ -11,10 +11,10 @@ * * Return Value: * 0: Added to player - * 1: weaponholder + * 1: Weapon holder item was placed in * * Example: - * [bob, "classname", "", 5] call ace_common_fnc_addToInventory + * [player, "30Rnd_65x39_caseless_mag", "", 5] call ace_common_fnc_addToInventory * * Public: Yes */ @@ -26,6 +26,7 @@ private _type = _classname call FUNC(getItemType); private _canAdd = false; private _canFitWeaponSlot = false; private _addedToUnit = false; +private _weaponHolder = _unit; switch (_container) do { case "vest": { @@ -58,6 +59,21 @@ switch (_container) do { }; }; +if (_type select 0 == "magazine") then { + private _configAmmoCount = getNumber (configFile >> "CfgMagazines" >> _classname >> "count"); + + // https://feedback.bistudio.com/T74244 + // When adding throwables with the addXXXCargo(Global) commands, they don't show up in the throwables list + // If a throwable has more than 1 ammo count, adding it with addItem(XXX) commands also renders the throwable unusable + if (_configAmmoCount == 1 && {_ammoCount in [-1, 1]} && {_classname call BIS_fnc_isThrowable}) then { // TODO: replace with https://community.bistudio.com/wiki/isThrowable in 2.18 + _type set [0, "item"]; + }; + + if (_ammoCount == -1) then { + _ammoCount = _configAmmoCount; + }; +}; + switch (_type select 0) do { case "weapon": { if (_canAdd || {_canFitWeaponSlot}) then { @@ -94,31 +110,29 @@ switch (_type select 0) do { } else { _addedToUnit = false; - private _pos = _unit modelToWorldVisual [0,1,0.05]; + _weaponHolder = nearestObject [_unit, "WeaponHolder"]; + + if (isNull _weaponHolder || {_unit distance _weaponHolder > 2}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", _unit, [], 0, "CAN_COLLIDE"]; + }; - _unit = createVehicle ["WeaponHolder_Single_F", _pos, [], 0, "NONE"]; - _unit addWeaponCargoGlobal [_classname, 1]; - _unit setPosATL _pos; + _weaponHolder addWeaponCargoGlobal [_classname, 1]; }; }; case "magazine": { - if (_ammoCount == -1) then { - _ammoCount = getNumber (configFile >> "CfgMagazines" >> _classname >> "count"); - }; - if (_canAdd) then { _addedToUnit = true; switch (_container) do { case "vest": { - _unit addItemToVest _classname; //@todo Bug! A full magazine, ignoring ammo. No such command. + (vestContainer _unit) addMagazineAmmoCargo [_classname, 1, _ammoCount]; }; case "backpack": { - _unit addItemToBackpack _classname; //@todo Bug! A full magazine, ignoring ammo. No such command. + (backpackContainer _unit) addMagazineAmmoCargo [_classname, 1, _ammoCount]; }; case "uniform": { - _unit addItemToUniform _classname; //@todo Bug! A full magazine, ignoring ammo. No such command. + (uniformContainer _unit) addMagazineAmmoCargo [_classname, 1, _ammoCount]; }; default { _unit addMagazine [_classname, _ammoCount]; @@ -127,11 +141,13 @@ switch (_type select 0) do { } else { _addedToUnit = false; - private _pos = _unit modelToWorldVisual [0,1,0.05]; + _weaponHolder = nearestObject [_unit, "WeaponHolder"]; - _unit = createVehicle ["WeaponHolder_Single_F", _pos, [], 0, "NONE"]; - _unit addMagazineCargoGlobal [_classname, 1/*_ammoCount*/]; //@todo Bug! This isn't really the ammo, but magazine count. No such command. - _unit setPosATL _pos; + if (isNull _weaponHolder || {_unit distance _weaponHolder > 2}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", _unit, [], 0, "CAN_COLLIDE"]; + }; + + _weaponHolder addMagazineAmmoCargo [_classname, 1, _ammoCount]; }; }; @@ -156,11 +172,13 @@ switch (_type select 0) do { } else { _addedToUnit = false; - private _pos = _unit modelToWorldVisual [0,1,0.05]; + _weaponHolder = nearestObject [_unit, "WeaponHolder"]; + + if (isNull _weaponHolder || {_unit distance _weaponHolder > 2}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", _unit, [], 0, "CAN_COLLIDE"]; + }; - _unit = createVehicle ["WeaponHolder_Single_F", _pos, [], 0, "NONE"]; - _unit addItemCargoGlobal [_classname, 1]; - _unit setPosATL _pos; + _weaponHolder addItemCargoGlobal [_classname, 1]; }; }; @@ -170,4 +188,4 @@ switch (_type select 0) do { }; }; -[_addedToUnit, _unit] +[_addedToUnit, _weaponHolder] diff --git a/addons/common/functions/fnc_addWeapon.sqf b/addons/common/functions/fnc_addWeapon.sqf index 16ae92c4f5d..787c9fb24ad 100644 --- a/addons/common/functions/fnc_addWeapon.sqf +++ b/addons/common/functions/fnc_addWeapon.sqf @@ -2,22 +2,33 @@ /* * Author: commy2, johnb43 * Adds weapon to unit without taking a magazine. - * Same as CBA_fnc_addWeaponWithoutItems, but doesn't remove linked items. + * Same as CBA_fnc_addWeaponWithoutItems, but doesn't remove linked items by default. * * Arguments: - * 0: Unit to add the weapon to + * 0: Unit to add the weapon to * 1: Weapon to add + * 2: If linked items should be removed or not (default: false) + * 3: Magazines that should be added to the weapon (default: []) + * - 0: Magazine classname + * - 1: Ammo count * * Return Value: * None * * Example: - * [player, "arifle_AK12_F"] call ace_common_fnc_addWeapon + * [player, "arifle_MX_GL_F", true, [["30Rnd_65x39_caseless_mag", 30], ["1Rnd_HE_Grenade_shell", 1]]] call ace_common_fnc_addWeapon * * Public: Yes */ -params ["_unit", "_weapon"]; +params [ + ["_unit", objNull, [objNull]], + ["_weapon", "", [""]], + ["_removeLinkedItems", false, [false]], + ["_magazines", [], [[]]] +]; + +if (isNull _unit || {_weapon == ""}) exitWith {}; // Config case private _compatibleMagazines = compatibleMagazines _weapon; @@ -45,6 +56,35 @@ private _backpackMagazines = (magazinesAmmoCargo _backpack) select { // Add weapon _unit addWeapon _weapon; +// This doesn't remove magazines, but linked items can't be magazines, so it's fine +if (_removeLinkedItems) then { + switch (_weapon call FUNC(getConfigName)) do { + case (primaryWeapon _unit): { + removeAllPrimaryWeaponItems _unit; + }; + case (secondaryWeapon _unit): { + removeAllSecondaryWeaponItems _unit; + }; + case (handgunWeapon _unit): { + removeAllHandgunItems _unit; + }; + case (binocular _unit): { + removeAllBinocularItems _unit; + }; + }; +}; + +// Add magazines directly now, so that AI don't reload +if (_magazines isNotEqualTo []) then { + { + _x params [["_magazine", "", [""]], ["_ammoCount", -1, [0]]]; + + if (_magazine != "" && {_ammoCount > -1}) then { + _unit addWeaponItem [_weapon, [_magazine, _ammoCount], true]; + }; + } forEach _magazines; +}; + // Add all magazines back { _uniform addMagazineAmmoCargo [_x select 0, 1, _x select 1]; diff --git a/addons/common/functions/fnc_adjustMagazineAmmo.sqf b/addons/common/functions/fnc_adjustMagazineAmmo.sqf new file mode 100644 index 00000000000..87d5b9e899c --- /dev/null +++ b/addons/common/functions/fnc_adjustMagazineAmmo.sqf @@ -0,0 +1,107 @@ +#include "..\script_component.hpp" +/* + * Author: Katalam, Blue, Brett Mayson, johnb43 + * Handle adjusting a magazine's ammo + * + * Arguments: + * 0: Vehicle or Unit + * 1: Item + * 2: Ammo to adjust by (default: -1) + * + * Return Value: + * How much the ammo was adjusted by + * + * Example: + * [player, "30Rnd_556x45_Stanag", 1] call ace_common_fnc_adjustMagazineAmmo; + * + * Public: No + */ + +params ["_unit", "_magazine", ["_count", -1]]; + +if (_count == 0) exitWith {0}; + +private _containers = if (_unit isKindOf "CAManBase") then { + [uniformContainer _unit, vestContainer _unit, backpackContainer _unit] +} else { + [_unit] +}; + +scopeName "main"; + +private _originalCount = _count; +private _container = objNull; +private _magazinesContainer = []; +private _newAmmoCount = 0; +private _removeAmmo = _count < 0; +private _maxMagazineAmmo = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); + +{ + _container = _x; + + // Get all magazines of _magazine type + _magazinesContainer = (magazinesAmmoCargo _container) select {_x select 0 == _magazine}; + + // Get the ammo count, filter out magazines with 0 ammo + _magazinesContainer = (_magazinesContainer apply {_x select 1}) select {_x != 0}; + + // If there are none, skip to next container + if (_magazinesContainer isEqualTo []) then { + continue; + }; + + // Sort, smallest first when removing, largest first when adding + _magazinesContainer sort _removeAmmo; + + if (_removeAmmo) then { + { + _count = _x + _count; + + _container addMagazineAmmoCargo [_magazine, -1, _x]; + + if (_count >= 0) then { + // Only add magazine back if it's not empty + if (_count != 0) then { + _container addMagazineAmmoCargo [_magazine, 1, _count]; + }; + + _originalCount breakOut "main"; + }; + } forEach _magazinesContainer; + } else { + // This loop only fills up partially filled magazines + { + // Fill the magazine to either its max or until all ammo has been added + _newAmmoCount = (_x + _count) min _maxMagazineAmmo; + + if (_newAmmoCount <= _maxMagazineAmmo) then { + _container addMagazineAmmoCargo [_magazine, -1, _x]; + _container addMagazineAmmoCargo [_magazine, 1, _newAmmoCount]; + }; + + // Remove the ammo that was added + _count = _count - (_newAmmoCount - _x); + + if (_count <= 0) then { + _originalCount breakOut "main"; + }; + } forEach (_magazinesContainer select {_x < _maxMagazineAmmo}); + }; +} forEach _containers; + +// If there is still remaining ammo to add, try add it after having iterated through all containers +if (!_removeAmmo && _count > 0) then { + { + while {_count > 0 && {_x canAdd [_magazine, 1/* 2.18 , true*/]}} do { + _x addMagazineAmmoCargo [_magazine, 1, _count]; + + _count = _count - _maxMagazineAmmo; + }; + } forEach _containers; + + if (_count <= 0) then { + _originalCount breakOut "main"; + }; +}; + +_originalCount - _count diff --git a/addons/common/functions/fnc_assignObjectsInList.sqf b/addons/common/functions/fnc_assignObjectsInList.sqf index 23d373c310f..0928812cd43 100644 --- a/addons/common/functions/fnc_assignObjectsInList.sqf +++ b/addons/common/functions/fnc_assignObjectsInList.sqf @@ -28,18 +28,13 @@ if (_list isEqualType "") then { }; { - if (!isNil "_x") then { - if (_x isEqualType objNull) then { - if (local _x) then { - if (_vehicle) then { - (vehicle _x) setVariable [_variable, _setting, _global]; - TRACE_6("Set variable vehicle",_x,vehicle _x,typeOf (vehicle _x),_variable,_setting,_global); - } else { - _x setVariable [_variable, _setting, _global]; - TRACE_5("Set variable",_x,typeOf _x,_variable,_setting,_global); - }; - }; + if (!isNil "_x" && {_x isEqualType objNull} && {local _x}) then { + if (_vehicle) then { + (vehicle _x) setVariable [_variable, _setting, _global]; + TRACE_6("Set variable vehicle",_x,vehicle _x,typeOf (vehicle _x),_variable,_setting,_global); + } else { + _x setVariable [_variable, _setting, _global]; + TRACE_5("Set variable",_x,typeOf _x,_variable,_setting,_global); }; }; - false -} count _list; +} forEach _list; diff --git a/addons/common/functions/fnc_canGetInPosition.sqf b/addons/common/functions/fnc_canGetInPosition.sqf index d78e623d7bd..777f3103a5a 100644 --- a/addons/common/functions/fnc_canGetInPosition.sqf +++ b/addons/common/functions/fnc_canGetInPosition.sqf @@ -24,7 +24,7 @@ params ["_unit", "_vehicle", "_position", ["_checkDistance", false], ["_index", -1]]; -_position = toLower _position; +_position = toLowerANSI _position; // general if (!alive _vehicle || {locked _vehicle > 1}) exitWith {false}; diff --git a/addons/common/functions/fnc_canInteractWith.sqf b/addons/common/functions/fnc_canInteractWith.sqf index 4cbcb1c19dc..134a3101e4b 100644 --- a/addons/common/functions/fnc_canInteractWith.sqf +++ b/addons/common/functions/fnc_canInteractWith.sqf @@ -19,7 +19,7 @@ params ["_unit", "_target", ["_exceptions", []]]; -_exceptions = _exceptions apply {toLower _x}; +_exceptions = _exceptions apply {toLowerANSI _x}; private _owner = _target getVariable [QGVAR(owner), objNull]; @@ -27,15 +27,11 @@ private _owner = _target getVariable [QGVAR(owner), objNull]; if (!isNull _owner && {_unit != _owner}) exitWith {false}; // check general conditions -private _conditions = missionNamespace getVariable [QGVAR(InteractionConditions), [[],[]]]; -_conditions params ["_conditionNames", "_conditionFuncs"]; - private _canInteract = true; - { - if (!(_x in _exceptions) && {!([_unit, _target] call (_conditionFuncs select _forEachIndex))}) exitWith { + if (!(_x in _exceptions) && {!([_unit, _target] call _y)}) exitWith { _canInteract = false; }; -} forEach _conditionNames; +} forEach GVAR(InteractionConditions); _canInteract diff --git a/addons/common/functions/fnc_cbaSettings.sqf b/addons/common/functions/fnc_cbaSettings.sqf index 3e6f66fa42e..bd23fef6976 100644 --- a/addons/common/functions/fnc_cbaSettings.sqf +++ b/addons/common/functions/fnc_cbaSettings.sqf @@ -66,8 +66,7 @@ GVAR(settingsMovedToSQF) = []; INFO_1("%1 delayed functions running.",count GVAR(runAtSettingsInitialized)); { (_x select 1) call (_x select 0); - false - } count GVAR(runAtSettingsInitialized); + } forEach GVAR(runAtSettingsInitialized); GVAR(runAtSettingsInitialized) = nil; //cleanup #ifdef DEBUG_MODE_FULL @@ -89,7 +88,7 @@ for "_index" from 0 to (_countOptions - 1) do { if (isNil (configName _optionEntry)) then { [_optionEntry] call FUNC(cbaSettings_loadFromConfig); } else { - WARNING_1("Setting [%1] - Already defined from somewhere else??",_varName); + WARNING_1("Setting [%1] - Already defined from somewhere else??",configName _optionEntry); }; #ifdef DEBUG_MODE_FULL } else { @@ -104,8 +103,8 @@ 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 { - WARNING_1("Setting [%1] - Already Forced - ignoring missionConfig",_varName); + if ((toLowerANSI _settingName) in GVAR(cbaSettings_forcedSettings)) then { + WARNING_1("Setting [%1] - Already Forced - ignoring missionConfig",configName _optionEntry); } else { if ((isNil _settingName) && {(getNumber (_settingsConfig >> _settingName >> "movedToSQF")) == 0}) then { // New setting, that was first defined in missionConfigFile diff --git a/addons/common/functions/fnc_cbaSettings_convertHelper.sqf b/addons/common/functions/fnc_cbaSettings_convertHelper.sqf index b7ef446cf65..02fdfa0193a 100644 --- a/addons/common/functions/fnc_cbaSettings_convertHelper.sqf +++ b/addons/common/functions/fnc_cbaSettings_convertHelper.sqf @@ -44,7 +44,7 @@ private _settings = configProperties [configFile >> "ACE_Settings", "(isClass _x private _cbaIsGlobal = (!_isClientSettable) || _isForced; private _warnIfChangedMidMission = _cbaIsGlobal && {(getNumber (_config >> "canBeChanged")) == 0}; - if (_isForced) then {GVAR(cbaSettings_forcedSettings) pushBack (toLower _varName);}; + if (_isForced) then {GVAR(cbaSettings_forcedSettings) pushBack (toLowerANSI _varName);}; // Basic handling of setting types CBA doesn't support: if (_typeName == "ARRAY") exitWith { diff --git a/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf b/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf index d3a6f29f84b..57b93c99639 100644 --- a/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf +++ b/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf @@ -34,7 +34,7 @@ private _category = getText (_config >> "category"); private _cbaIsGlobal = (!_isClientSettable) || _isForced; private _warnIfChangedMidMission = _cbaIsGlobal && {(getNumber (_config >> "canBeChanged")) == 0}; -if (_isForced) then {GVAR(cbaSettings_forcedSettings) pushBack (toLower _varName);}; +if (_isForced) then {GVAR(cbaSettings_forcedSettings) pushBack (toLowerANSI _varName);}; // Basic handling of setting types CBA doesn't support: if (_typeName == "ARRAY") exitWith { @@ -103,4 +103,3 @@ private _return = [_varName, _cbaSettingType, [_localizedName, _localizedDescrip TRACE_1("returned",_return); if ((isNil "_return") || {!_return}) then {ERROR_1("Setting [%1] - CBA Error",_varName);}; _return - diff --git a/addons/common/functions/fnc_cbaSettings_settingChanged.sqf b/addons/common/functions/fnc_cbaSettings_settingChanged.sqf index 43711d4c970..cf9f18166ab 100644 --- a/addons/common/functions/fnc_cbaSettings_settingChanged.sqf +++ b/addons/common/functions/fnc_cbaSettings_settingChanged.sqf @@ -1,8 +1,8 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Function for handeling a cba setting being changed. - * Adds warning if global setting is changed after ace_settingsInitialized + * Function for handling a cba setting being changed. + * Adds warning if global setting is changed after ace_settingsInitialized. * * Arguments: * 0: Setting Name @@ -21,9 +21,7 @@ params ["_settingName", "_newValue", ["_canBeChanged", false]]; TRACE_2("",_settingName,_newValue); -["ace_settingChanged", [_settingName, _newValue]] call CBA_fnc_localEvent; - -if (!((toLower _settingName) in CBA_settings_needRestart)) exitWith {}; +if !((toLower _settingName) in CBA_settings_needRestart) exitWith {}; if (_canBeChanged) exitWith {WARNING_1("update cba setting [%1] to use correct Need Restart param",_settingName);}; if (!GVAR(settingsInitFinished)) exitWith {}; // Ignore changed event before CBA_settingsInitialized diff --git a/addons/common/functions/fnc_checkFiles.sqf b/addons/common/functions/fnc_checkFiles.sqf index 47de2290dd6..185ec7e5d1a 100644 --- a/addons/common/functions/fnc_checkFiles.sqf +++ b/addons/common/functions/fnc_checkFiles.sqf @@ -15,15 +15,20 @@ * Public: No */ +// Don't execute in scheduled environment +if (canSuspend) exitWith { + [FUNC(checkFiles), nil] call CBA_fnc_directCall; +}; + /////////////// -// check addons +// Check addons /////////////// -private _mainCfg = configFile >> "CfgPatches" >> "ace_main"; -private _mainVersion = getText (_mainCfg >> "versionStr"); -private _mainSource = configSourceMod _mainCfg; +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 "."; @@ -31,53 +36,62 @@ private _cbaRequiredStr = _cbaRequiredAr joinString "."; INFO_3("ACE is version %1 - CBA is version %2 (min required %3)",_mainVersion,_cbaVersionStr,_cbaRequiredStr); -if ([_cbaRequiredAr, _cbaVersionAr] call cba_versioning_fnc_version_compare) then { +if ([_cbaRequiredAr, _cbaVersionAr] call CBA_versioning_fnc_version_compare) then { private _errorMsg = format ["CBA version %1 is outdated (required %2)", _cbaVersionStr, _cbaRequiredStr]; ERROR(_errorMsg); + if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); }; }; -//private _addons = activatedAddons; // broken with High-Command module, see #2134 -private _addons = (cba_common_addons select {(_x select [0,4]) == "ace_"}) apply {toLower _x}; +//private _addons = activatedAddons; // Broken with High-Command module, see #2134 +private _addons = (CBA_common_addons select {(_x select [0, 4]) == "ace_"}) apply {toLowerANSI _x}; + private _oldAddons = []; private _oldSources = []; private _oldCompats = []; + { private _addonCfg = configFile >> "CfgPatches" >> _x; private _addonVersion = getText (_addonCfg >> "versionStr"); + if (_addonVersion != _mainVersion) then { private _addonSource = configSourceMod _addonCfg; + _oldSources pushBackUnique _addonSource; + + // Check ACE install call FUNC(checkFiles_diagnoseACE); + // Don't block game if it's just an old compat pbo if ((_x select [0, 10]) != "ace_compat") then { - if (hasInterface) then { - _oldAddons pushBack _x; - }; + _oldAddons pushBack _x; } else { - _oldCompats pushBack [_x, _addonVersion]; // Don't block game if it's just an old compat pbo + _oldCompats pushBack [_x, _addonVersion]; }; }; } forEach _addons; if (_oldAddons isNotEqualTo []) then { - _oldAddons = _oldAddons apply { format ["%1.pbo", _x] }; - private _errorMsg = ""; - if (count _oldAddons > 3) then { - _errorMsg = format ["The following files are outdated: %1, and %2 more.
ACE Main version is %3 from %4.
Loaded mods with outdated ACE files: %5", (_oldAddons select [0, 3]) joinString ", ", (count _oldAddons) -3, _mainVersion, _mainSource, (_oldSources joinString ", ")]; + _oldAddons = _oldAddons apply {format ["%1.pbo", _x]}; + + private _errorMsg = if (count _oldAddons > 3) then { + format ["The following files are outdated: %1, and %2 more.
ACE Main version is %3 from %4.
Loaded mods with outdated ACE files: %5", (_oldAddons select [0, 3]) joinString ", ", (count _oldAddons) - 3, _mainVersion, _mainSource, _oldSources joinString ", "]; } else { - _errorMsg = format ["The following files are outdated: %1.
ACE Main version is %2 from %3.
Loaded mods with outdated ACE files: %4", (_oldAddons) joinString ", ", _mainVersion, _mainSource, (_oldSources) joinString ", "]; + format ["The following files are outdated: %1.
ACE Main version is %2 from %3.
Loaded mods with outdated ACE files: %4", _oldAddons joinString ", ", _mainVersion, _mainSource, _oldSources joinString ", "]; }; + if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); }; + ERROR(_errorMsg); }; if (_oldCompats isNotEqualTo []) then { _oldCompats = _oldCompats apply {format ["%1 (%2)", _x select 0, _x select 1]}; + [{ // Lasts for ~10 seconds ERROR_WITH_TITLE_3("The following ACE compatiblity PBOs are outdated","%1. ACE Main version is %2 from %3.",_this select 0,_this select 1,_this select 2); @@ -85,92 +99,89 @@ if (_oldCompats isNotEqualTo []) then { }; /////////////// -// check extensions +// Check extensions /////////////// -private _platform = toLower (productVersion select 6); -if (!isServer && {_platform in ["linux", "osx"]}) then { +private _platform = toLowerANSI (productVersion select 6); + +if (_platform in ["linux", "osx"]) then { // Linux and OSX client ports do not support extensions at all - INFO("Operating system does not support extensions"); + if (hasInterface) then { + WARNING("Operating system does not support extensions"); + } else { + INFO("Operating system does not support extensions"); + }; } else { - { - 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 ((_isWindows || _isLinux) && {_isClient || _isServer}) then { - private _versionEx = _extension callExtension "version"; - if (_versionEx == "") then { - private _extensionFile = _extension; - if (productVersion select 7 == "x64") then { - _extensionFile = format ["%1_x64", _extensionFile]; - }; - - private _platformExt = [".dll", ".so"] select (_platform == "linux"); - _extensionFile = format ["%1%2", _extensionFile, _platformExt]; + ("ace" callExtension ["version", []]) params [["_versionEx", "", [""]], ["_returnCode", -1, [-1]]]; - private _errorMsg = format ["Extension %1 not found.", _extensionFile]; - ERROR(_errorMsg); + if (_returnCode != 0 || {_versionEx == ""}) then { + private _errorMsg = format ["Extension not found. [Return Code: %1]", _returnCode]; + ERROR(_errorMsg); - if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); - }; - } else { - // Print the current extension version - INFO_2("Extension version: %1: %2",_extension,_versionEx); - }; + if (hasInterface) then { + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); }; - } forEach ("true" configClasses (configFile >> "ACE_Extensions")); -}; -if (isArray (configFile >> "ACE_Extensions" >> "extensions")) then { - WARNING("extensions[] array no longer supported"); + } else { + _versionEx = _versionEx select [0, 8]; // git hash + INFO_1("Extension [Version: %1]",_versionEx); + }; }; + /////////////// -// check server version/addons +// Check server version/addons /////////////// if (isMultiplayer) then { - // don't check optional addons - _addons = _addons select {getNumber (configFile >> "CfgPatches" >> _x >> "ACE_isOptional") != 1}; + // Don't check optional addons + _addons = _addons select {getNumber (_cfgPatches >> _x >> "ACE_isOptional") != 1}; if (isServer) then { - // send servers version of ACE to all clients - GVAR(ServerVersion) = _mainVersion; - GVAR(ServerAddons) = _addons; - publicVariable QGVAR(ServerVersion); - publicVariable QGVAR(ServerAddons); + // Send server's version of ACE to all clients + GVAR(serverVersion) = _mainVersion; + GVAR(serverAddons) = _addons; + GVAR(serverSource) = _mainSource; + + publicVariable QGVAR(serverVersion); + publicVariable QGVAR(serverAddons); + publicVariable QGVAR(serverSource); } else { - // clients have to wait for the variables - [{ - if (isNil QGVAR(ServerVersion) || isNil QGVAR(ServerAddons)) exitWith {}; - - (_this select 0) params ["_mainVersion", "_addons"]; + GVAR(clientVersion) = _mainVersion; + GVAR(clientAddons) = _addons; - if (_mainVersion != GVAR(ServerVersion)) then { - private _errorMsg = format ["Client/Server Version Mismatch. Server: %1, Client: %2.", GVAR(ServerVersion), _mainVersion]; + private _fnc_check = { + if (GVAR(clientVersion) != GVAR(serverVersion)) then { + private _errorMsg = format ["Client/Server Version Mismatch. Server: %1, Client: %2. Server modDir: %3", GVAR(serverVersion), GVAR(clientVersion), GVAR(serverSource)]; + // Check ACE install call FUNC(checkFiles_diagnoseACE); + ERROR(_errorMsg); if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); }; }; - _addons = _addons - GVAR(ServerAddons); + private _addons = GVAR(clientAddons) - GVAR(serverAddons); + if (_addons isNotEqualTo []) then { - private _errorMsg = format ["Client/Server Addon Mismatch. Client has extra addons: %1.",_addons]; + private _errorMsg = format ["Client/Server Addon Mismatch. Client has additional addons: %1. Server modDir: %2", _addons, GVAR(serverSource)]; + // Check ACE install call FUNC(checkFiles_diagnoseACE); + ERROR(_errorMsg); if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); }; }; + }; - [_this select 1] call CBA_fnc_removePerFrameHandler; - }, 1, [_mainVersion,_addons]] call CBA_fnc_addPerFrameHandler; + // Clients have to wait for the variables + if (isNil QGVAR(serverVersion) || isNil QGVAR(serverAddons)) then { + GVAR(serverVersion) addPublicVariableEventHandler _fnc_check; + } else { + call _fnc_check; + }; }; }; diff --git a/addons/common/functions/fnc_checkFiles_diagnoseACE.sqf b/addons/common/functions/fnc_checkFiles_diagnoseACE.sqf index 5b7f80198b5..82241c45274 100644 --- a/addons/common/functions/fnc_checkFiles_diagnoseACE.sqf +++ b/addons/common/functions/fnc_checkFiles_diagnoseACE.sqf @@ -1,13 +1,13 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Diagnose ACE install problems, this will only be called if there is a known problem + * Diagnoses ACE install problems, this will only be called if there is a known problem. * * Arguments: * None * * Return Value: - * None + * ACE addons' WS IDs * * Example: * [] call ace_common_fnc_checkFiles_diagnoseACE @@ -16,43 +16,59 @@ */ // Only run once -if (missionNameSpace getVariable [QGVAR(checkFiles_diagnoseACE), false]) exitWith {}; +if (missionNamespace getVariable [QGVAR(checkFiles_diagnoseACE), false]) exitWith { + createHashMap // return +}; + GVAR(checkFiles_diagnoseACE) = true; -private _addons = cba_common_addons select {(_x select [0,4]) == "ace_"}; +private _addons = CBA_common_addons select {(_x select [0, 4]) == "ace_"}; private _cfgPatches = configFile >> "CfgPatches"; private _allMods = createHashMap; +private _getLoadedModsInfo = getLoadedModsInfo; -// Check ACE_ADDONs are in expected mod DIR +// Check if ACE_ADDONs are in expected mod DIR { - private _cfg = (_cfgPatches >> _x); + private _cfg = _cfgPatches >> _x; private _actualModDir = configSourceMod _cfg; private _expectedModDir = getText (_cfg >> "ACE_expectedModDir"); - if (_expectedModDir == "") then { _expectedModDir = "@ace" }; + + if (_expectedModDir == "") then { + _expectedModDir = "@ace"; + }; + private _expectedSteamID = getText (_cfg >> "ACE_expectedSteamID"); - if (_expectedSteamID == "") then { _expectedSteamID = "463939057" }; + + if (_expectedSteamID == "") then { + _expectedSteamID = "463939057" + }; (_allMods getOrDefault [_actualModDir, [], true]) pushBackUnique _expectedSteamID; + if (_actualModDir != _expectedModDir) then { - private _errorMsg = format ["%1 loading from unexpected modDir [%2]",_x,_actualModDir]; + private _errorMsg = format ["%1 loading from unexpected modDir [%2]", _x, _actualModDir]; systemChat _errorMsg; WARNING_1("%1",_errorMsg); }; } forEach _addons; -// Check all ACE ModDirs have expected steam WS ID +// Check if all ACE ModDirs have expected steam WS ID { private _modDir = _x; - if ((count _y) != 1) then { ERROR_2("Unexpected multiple steamIDs %1 - %2",_modDir,_y) }; - private _expectedSteamID = _y # 0; - private _index = getLoadedModsInfo findIf {_x#1 == _modDir}; - (getLoadedModsInfo param [_index, []]) params [["_modName", "$Error$"], "", "", "", "", "", "", ["_actualID", ""]]; + + if (count _y != 1) then { + ERROR_2("Unexpected multiple steamIDs %1 - %2",_modDir,_y); + }; + + private _expectedSteamID = _y select 0; + private _index = _getLoadedModsInfo findIf {_x select 1 == _modDir}; + (_getLoadedModsInfo param [_index, []]) params [["_modName", "$Error$"], "", "", "", "", "", "", ["_actualID", ""]]; if (_actualID != _expectedSteamID) then { - private _errorMsg = format ["%1 [%2] unexpected workshopID [%3]",_modDir,_modName,_actualID]; + private _errorMsg = format ["%1 [%2] unexpected workshopID [%3]", _modDir, _modName, _actualID]; systemChat _errorMsg; WARNING_1("%1",_errorMsg); }; } forEach _allMods; -_allMods +_allMods // return diff --git a/addons/common/functions/fnc_checkPBOs.sqf b/addons/common/functions/fnc_checkPBOs.sqf index f69f486d5e6..d54fda78ba8 100644 --- a/addons/common/functions/fnc_checkPBOs.sqf +++ b/addons/common/functions/fnc_checkPBOs.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: commy2 + * Author: commy2, johnb43 * Used to execute the checkPBOs module without placing the module. Don't use this together with the module. * Checks PBO versions and compares to the one running on server. * @@ -9,8 +9,8 @@ * 0 = Warn once * 1 = Warn permanently * 2 = Kick - * 1: Check all PBOs? (default: false) - * 2: Whitelist (default: "") + * 1: Check all PBOs? (default: false) + * 2: Whitelist (default: "") * * Return Value: * None @@ -24,83 +24,76 @@ 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_Version_ClientErrors params ["_missingAddon", "_missingAddonServer", "_oldVersionClient", "_oldVersionServer"]; - - (_this select 0) params ["_mode", "_checkAll", "_whitelist"]; - - // 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); "; + ["ace_versioning_clientCheckDone", { + // Don't let this event get triggered again + //IGNORE_PRIVATE_WARNING ["_thisType", "_thisId", "_thisArgs"]; + [_thisType, _thisId] call CBA_fnc_removeEventHandler; + + params ["_clientErrors"]; + _clientErrors params ["_missingAddonClient", "_additionalAddonClient", "_olderVersionClient", "_newerVersionClient"]; + _thisArgs params ["_mode"]; + + // Display error message(s) + if (_missingAddonClient || {_additionalAddonClient} || {_olderVersionClient} || {_newerVersionClient}) then { + private _errorMsg = "[ACE] Version mismatch:

"; + private _error = []; + + if (_missingAddonClient) then { + _errorMsg = _errorMsg + "Detected missing addon on client
"; + _error pushBack "Missing file(s)"; }; - if (_missingAddonServer) then { - _text = _text + "Detected missing addon on server
"; - _error = _error + "Additional file(s); "; + + if (_additionalAddonClient) then { + _errorMsg = _errorMsg + "Detected additional addon on client
"; + _error pushBack "Additional file(s)"; }; - if (_oldVersionClient) then { - _text = _text + "Detected old client version
"; - _error = _error + "Older version; "; + + if (_olderVersionClient) then { + _errorMsg = _errorMsg + "Detected older client version
"; + _error pushBack "Older version"; }; - if (_oldVersionServer) then { - _text = _text + "Detected old server version
"; - _error = _error + "Newer version; "; + + if (_newerVersionClient) then { + _errorMsg = _errorMsg + "Detected newer client version
"; + _error pushBack "Newer version"; }; - //[QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; + ERROR_2("[ACE] Version mismatch: %1: %2",profileName,_error joinString ", "); - ERROR(_error); + _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 00000000000..61ed7f62313 --- /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 997d54f33b8..170c2c6a8f3 100644 --- a/addons/common/functions/fnc_claim.sqf +++ b/addons/common/functions/fnc_claim.sqf @@ -30,10 +30,10 @@ _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 { + if (isNull _unit) then { [QGVAR(unlockVehicle), _target, _target] call CBA_fnc_targetEvent; + } else { + [QGVAR(lockVehicle), _target, _target] call CBA_fnc_targetEvent; }; }; diff --git a/addons/common/functions/fnc_defineVariable.sqf b/addons/common/functions/fnc_defineVariable.sqf index 6cf537b1f8b..e0e7c49e4de 100644 --- a/addons/common/functions/fnc_defineVariable.sqf +++ b/addons/common/functions/fnc_defineVariable.sqf @@ -24,7 +24,7 @@ params ["_name", "_value", "_defaultGlobal", "_category", ["_code", 0], ["_persi if (isNil "_defaultGlobal") exitWith {}; -if (!(_name isEqualType "")) exitwith { +if !(_name isEqualType "") exitWith { [format ["Tried to the deinfe a variable with an invalid name: %1 Arguments: %2", _name, _this]] call FUNC(debug); }; diff --git a/addons/common/functions/fnc_deprecateComponent.sqf b/addons/common/functions/fnc_deprecateComponent.sqf index 5408a896a10..1ed85de2336 100644 --- a/addons/common/functions/fnc_deprecateComponent.sqf +++ b/addons/common/functions/fnc_deprecateComponent.sqf @@ -23,8 +23,8 @@ _oldComponent params ["_oldComponentName", "_oldSettingName"]; _newComponent params ["_newComponentName", "_newSettingName"]; private _isReplacementAvailable = [_newComponentName] call FUNC(isModLoaded); -private _isDeprecatedLoaded = missionNamespace getvariable [_oldSettingName, false]; -private _isReplacementLoaded = missionNamespace getvariable [_newSettingName, false]; +private _isDeprecatedLoaded = missionNamespace getVariable [_oldSettingName, false]; +private _isReplacementLoaded = missionNamespace getVariable [_newSettingName, false]; if (_isDeprecatedLoaded && {_isReplacementAvailable} && {!_isReplacementLoaded}) then { [_newSettingName, true, true, true] call FUNC(setSetting); @@ -38,7 +38,7 @@ if (_isDeprecatedLoaded && {!_isReplacementLoaded}) then { switch (true) do { case (_componentMajor >= _major && {_componentMinor >= _minor} && {_componentPatch >= _patch}): { // Removed from this version private _message = format[ - "Component %1 is deprecated. It has been replaced by %2. The component %1 is no longer usable on this version. ", _oldComponentName, _newComponentName, _version]; + "Component %1 is deprecated. It has been replaced by %2. The component %1 is no longer usable on this version %3. ", _oldComponentName, _newComponentName, _version]; systemChat format["ACE [ERROR] - %1", _message]; ERROR(_message); }; diff --git a/addons/common/functions/fnc_disableAI.sqf b/addons/common/functions/fnc_disableAI.sqf index 52f1ed37c3d..a0c725c7db5 100644 --- a/addons/common/functions/fnc_disableAI.sqf +++ b/addons/common/functions/fnc_disableAI.sqf @@ -29,7 +29,7 @@ if !([_unit] call EFUNC(common,isPlayer)) then { _unit disableConversation true; } else { //Sanity check to make sure we don't enable unconsious AI - if (_unit getVariable ["ace_isunconscious", false] && alive _unit) exitWith { + if (_unit getVariable ["ACE_isUnconscious", false] && alive _unit) exitWith { ERROR("Enabling AI for unconsious unit"); }; diff --git a/addons/common/functions/fnc_disableAiUAV.sqf b/addons/common/functions/fnc_disableAiUAV.sqf new file mode 100644 index 00000000000..195e3ed2dc1 --- /dev/null +++ b/addons/common/functions/fnc_disableAiUAV.sqf @@ -0,0 +1,45 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Disables/Enables UAV AI crew members, can be run on any machine and is applied globally. + * + * Arguments: + * 0: Unit + * 1: Disable AI + * + * Return Value: + * None + * + * Example: + * [cursorObject, true] call ace_common_fnc_disableAiUAV + * + * Public: No + */ + +params [["_unit", objNull, [objNull]], ["_disable", true, [false]]]; + +// Allow disabling of Zeus remote controlled units +if (!alive _unit || {isPlayer _unit} || {!unitIsUAV _unit}) exitWith {}; + +if (_disable) then { + // Ignore if already disabled + if (!isNil "_jipID") exitWith {}; + + // Disable shooting and targeting on every machine + // Give predefined JIP ID, in case of simultaneous executions on different machines + private _jipID = [QGVAR(disableAiUAV), [_unit, _disable], QGVAR(disableAiUAV_) + hashValue _unit] call CBA_fnc_globalEventJIP; + [_jipID, _unit] call CBA_fnc_removeGlobalEventJIP; + + _unit setVariable [QGVAR(disableAiUavJipID), _jipID, true]; +} else { + // Restore shooting and targeting to each client's individual state prior to disabling + private _jipID = _unit getVariable QGVAR(disableAiUavJipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _unit setVariable [QGVAR(disableAiUavJipID), nil, true]; + + [QGVAR(disableAiUAV), [_unit, _disable]] call CBA_fnc_globalEvent; +}; diff --git a/addons/common/functions/fnc_disableUserInput.sqf b/addons/common/functions/fnc_disableUserInput.sqf index 8db3c7e8110..b89750e656e 100644 --- a/addons/common/functions/fnc_disableUserInput.sqf +++ b/addons/common/functions/fnc_disableUserInput.sqf @@ -143,11 +143,7 @@ if (_state) then { _ctrl ctrlSetEventHandler ["ButtonClick", toString { closeDialog 0; - if (["ace_medical"] call FUNC(isModLoaded)) then { - [player, "respawn_button"] call EFUNC(medical_status,setDead); - } else { - player setDamage 1; - }; + [player, "respawn_button"] call FUNC(setDead); [false] call FUNC(disableUserInput); }]; diff --git a/addons/common/functions/fnc_displayIcon.sqf b/addons/common/functions/fnc_displayIcon.sqf index 1b307fdf33c..db01bedb043 100644 --- a/addons/common/functions/fnc_displayIcon.sqf +++ b/addons/common/functions/fnc_displayIcon.sqf @@ -21,11 +21,11 @@ */ // positions for the icon UI -#define RIGHT_SIDE (safezoneW + safezoneX) -#define LEFT_SIDE safezoneX +#define RIGHT_SIDE (safeZoneW + safeZoneX) +#define LEFT_SIDE safeZoneX #define TOP_SIDE safeZoneY -#define BOTTOM_SIDE (safeZoneH + safezoneY) -#define ICON_WIDTH (2 * (((safezoneW / safezoneH) min 1.2) / 40)) +#define BOTTOM_SIDE (safeZoneH + safeZoneY) +#define ICON_WIDTH (2 * (((safeZoneW / safeZoneH) min 1.2) / 40)) #define X_POS_ICONS (RIGHT_SIDE - (1.5 * ICON_WIDTH)) #define Y_POS_ICONS (TOP_SIDE + (2.5 * ICON_WIDTH)) #define DIFFERENCE_ICONS (1.1 * ICON_WIDTH) @@ -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_displayTextStructured.sqf b/addons/common/functions/fnc_displayTextStructured.sqf index a9376552a95..ed494627702 100644 --- a/addons/common/functions/fnc_displayTextStructured.sqf +++ b/addons/common/functions/fnc_displayTextStructured.sqf @@ -30,7 +30,7 @@ if (typeName _text != "TEXT") then { if (_x isEqualType "" && {isLocalized _x}) then { _text set [_foreachIndex, localize _x]; }; - }foreach _text; + } forEach _text; _text = format _text; }; }; @@ -51,18 +51,18 @@ _ctrlHint ctrlSetBackgroundColor GVAR(displayTextColor); _ctrlHint ctrlSetTextColor GVAR(displayTextFontColor); // Use profile settings from CfgUIGrids.hpp -private _xPos = profilenamespace getVariable ["IGUI_GRID_ACE_displayText_X", ((safezoneX + safezoneW) - (10 *(((safezoneW / safezoneH) min 1.2) / 40)) - 2.9 *(((safezoneW / safezoneH) min 1.2) / 40))]; -private _yPos = profilenamespace getVariable ["IGUI_GRID_ACE_displayText_Y", safeZoneY + 0.175 * safezoneH]; -private _wPos = (_width *(((safezoneW / safezoneH) min 1.2) / 40)); -private _hPos = _size * (2 *((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)); +private _xPos = profileNamespace getVariable ["IGUI_GRID_ACE_displayText_X", ((safeZoneX + safeZoneW) - (10 *(((safeZoneW / safeZoneH) min 1.2) / 40)) - 2.9 *(((safeZoneW / safeZoneH) min 1.2) / 40))]; +private _yPos = profileNamespace getVariable ["IGUI_GRID_ACE_displayText_Y", safeZoneY + 0.175 * safeZoneH]; +private _wPos = (_width *(((safeZoneW / safeZoneH) min 1.2) / 40)); +private _hPos = _size * (2 *((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)); // Ensure still in bounds for large width/height -_xPos = safezoneX max (_xPos min (safezoneX + safezoneW - _wPos)); -_yPos = safeZoneY max (_yPos min (safeZoneY + safezoneH - _hPos)); +_xPos = safeZoneX max (_xPos min (safeZoneX + safeZoneW - _wPos)); +_yPos = safeZoneY max (_yPos min (safeZoneY + safeZoneH - _hPos)); // Zeus Interface Open and Display would be under the "CREATE" list if (!isNull curatorCamera) then { - _xPos = _xPos min ((safezoneX + safezoneW - 12.5 * (((safezoneW / safezoneH) min 1.2) / 40)) - _wPos); + _xPos = _xPos min ((safeZoneX + safeZoneW - 12.5 * (((safeZoneW / safeZoneH) min 1.2) / 40)) - _wPos); }; private _position = [_xPos, _yPos, _wPos, _hPos]; diff --git a/addons/common/functions/fnc_dumpArray.sqf b/addons/common/functions/fnc_dumpArray.sqf index 754b8113141..87437c37e26 100644 --- a/addons/common/functions/fnc_dumpArray.sqf +++ b/addons/common/functions/fnc_dumpArray.sqf @@ -34,8 +34,7 @@ if (IS_ARRAY(_var)) then { { [_x, _depth] call FUNC(dumpArray); - false - } count _var; + } forEach _var; diag_log text format ["%1],", _pad]; }; diff --git a/addons/common/functions/fnc_dumpPerformanceCounters.sqf b/addons/common/functions/fnc_dumpPerformanceCounters.sqf index fa0b4e4e6d6..309b82c673e 100644 --- a/addons/common/functions/fnc_dumpPerformanceCounters.sqf +++ b/addons/common/functions/fnc_dumpPerformanceCounters.sqf @@ -25,8 +25,7 @@ if (!isNil "ACE_PFH_COUNTER") then { private _isActive = ["ACTIVE", "REMOVED"] select isNil {CBA_common_PFHhandles select (_pfh select 0)}; diag_log text format ["Registered PFH: id=%1 [%2, delay %3], %4:%5", _pfh select 0, _isActive, _parameters select 1, _pfh select 1, _pfh select 2]; - false - } count ACE_PFH_COUNTER; + } forEach ACE_PFH_COUNTER; }; diag_log text format ["ACE COUNTER RESULTS"]; @@ -50,8 +49,7 @@ diag_log text format ["-------------------------------------------"]; }; _iter = _iter + 1; - false - } count _counterEntry; + } forEach _counterEntry; // results _averageResult = (_total / _count) * 1000; @@ -61,8 +59,7 @@ diag_log text format ["-------------------------------------------"]; } else { diag_log text format ["%1: No results", _counterEntry select 0]; }; - false -} count ACE_COUNTERS; +} forEach ACE_COUNTERS; /* // Dump PFH Trackers diff --git a/addons/common/functions/fnc_errorMessage.sqf b/addons/common/functions/fnc_errorMessage.sqf index 021fdba10cc..e98a5baf8f9 100644 --- a/addons/common/functions/fnc_errorMessage.sqf +++ b/addons/common/functions/fnc_errorMessage.sqf @@ -1,147 +1,141 @@ #include "..\script_component.hpp" +#include "\a3\ui_f\hpp\defineResincl.inc" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" /* - * Author: commy2, based on BIS_fnc_errorMsg and BIS_fnc_guiMessage by Karel Moricky (BI) - * Stops simulation and opens a textbox with error message. + * Author: commy2, johnb43, based on BIS_fnc_errorMsg and BIS_fnc_guiMessage by Karel Moricky (BI) + * Opens a textbox with an error message, used for PBO checking. * * Arguments: - * ? + * 0: Header + * 1: Text * * Return Value: * None * * Example: - * call ace_common_fnc_errorMessage + * ["[ACE] ERROR", "Test"] call ace_common_fnc_errorMessage * * Public: No */ -disableSerialization; +// Force stop any loading screens endLoadingScreen; -// no message without player possible +// No message without interface possible if (!hasInterface) exitWith {}; -// wait for display -if (isNull (call BIS_fnc_displayMission)) exitWith { - [{ - if (isNull (call BIS_fnc_displayMission)) exitWith {}; - - (_this select 0) call FUNC(errorMessage); - [_this select 1] call CBA_fnc_removePerFrameHandler; - - }, 1, _this] call CBA_fnc_addPerFrameHandler; -}; - -params ["_textHeader", "_textMessage", ["_onOK", {}], ["_onCancel", {}]]; - -if (_textMessage isEqualType "") then { - _textMessage = parseText _textMessage; -}; - -ARR_SELECT(_this,4,call BIS_fnc_displayMission) 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; - -_ctrlBcgCommonTop ctrlSetText _textHeader; - -private _ctrlButtonOKPos = ctrlPosition _ctrlButtonOK; -private _ctrlBcgCommonPos = ctrlPosition _ctrlBcgCommon; -private _bottomSpaceY = (_ctrlButtonOKPos select 1) - ((_ctrlBcgCommonPos select 1) + (_ctrlBcgCommonPos select 3)); - -private _ctrlTextPos = ctrlPosition _ctrlText; -private _marginX = (_ctrlTextPos select 0) - (_ctrlBcgCommonPos select 0); -private _marginY = (_ctrlTextPos select 1) - (_ctrlBcgCommonPos select 1); - -_ctrlText ctrlSetStructuredText _textMessage; -private _ctrlTextPosH = ctrlTextHeight _ctrlText; - -_ctrlBcgCommon ctrlSetPosition [ - _ctrlBcgCommonPos select 0, - _ctrlBcgCommonPos select 1, - _ctrlBcgCommonPos select 2, - _ctrlTextPosH + _marginY * 2 -]; -_ctrlBcgCommon ctrlCommit 0; - -_ctrlText ctrlSetPosition [ - (_ctrlBcgCommonPos select 0) + _marginX, - (_ctrlBcgCommonPos select 1) + _marginY, - (_ctrlBcgCommonPos select 2) - _marginX * 2, - _ctrlTextPosH -]; -_ctrlText ctrlCommit 0; - -private _bottomPosY = (_ctrlBcgCommonPos select 1) + _ctrlTextPosH + (_marginY * 2) + _bottomSpaceY; - -{ - private _xPos = ctrlPosition _x; - - _xPos set [1, _bottomPosY]; - _x ctrlSetPosition _xPos; - _x ctrlCommit 0; -} forEach [ - _ctrlBackgroundButtonOK, - _ctrlBackgroundButtonMiddle, - _ctrlBackgroundButtonCancel, - _ctrlButtonOK, - _ctrlButtonCancel -]; - -private _ctrlRscMessageBoxPos = ctrlPosition _ctrlRscMessageBox; -private _ctrlRscMessageBoxPosH = _bottomPosY + (_ctrlButtonOKPos select 3); - -_ctrlRscMessageBox ctrlSetPosition [ - 0.5 - (_ctrlBcgCommonPos select 2) / 2, - 0.5 - _ctrlRscMessageBoxPosH / 2, - (_ctrlBcgCommonPos select 2) + 0.5, - _ctrlRscMessageBoxPosH -]; - -_ctrlRscMessageBox ctrlEnable true; -_ctrlRscMessageBox ctrlCommit 0; - -if (_onOK isEqualTo {}) then { - _ctrlButtonOK ctrlEnable false; - _ctrlButtonOK ctrlSetFade 0; - _ctrlButtonOK ctrlSetText ""; - _ctrlButtonOK ctrlCommit 0; -} else { +[{ + !isNull (call BIS_fnc_displayMission) +}, { + params ["_textHeader", "_textMessage"]; + + disableSerialization; + + // Use curator display if present + private _curatorDisplay = findDisplay 312; + + private _mainDisplay = if (!isNull _curatorDisplay) then { + _curatorDisplay + } else { + call BIS_fnc_displayMission + }; + + if (_textMessage isEqualType "") then { + _textMessage = parseText _textMessage; + }; + + private _display = _mainDisplay createDisplay "RscDisplayCommonMessagePause"; + + if (isNull _display) exitWith {}; + + 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; + + _ctrlBcgCommonTop ctrlSetText _textHeader; + + private _ctrlButtonOKPos = ctrlPosition _ctrlButtonOK; + private _ctrlBcgCommonPos = ctrlPosition _ctrlBcgCommon; + private _bottomSpaceY = (_ctrlButtonOKPos select 1) - ((_ctrlBcgCommonPos select 1) + (_ctrlBcgCommonPos select 3)); + + private _ctrlTextPos = ctrlPosition _ctrlText; + private _marginX = (_ctrlTextPos select 0) - (_ctrlBcgCommonPos select 0); + private _marginY = (_ctrlTextPos select 1) - (_ctrlBcgCommonPos select 1); + + _ctrlText ctrlSetStructuredText _textMessage; + private _ctrlTextPosH = ctrlTextHeight _ctrlText; + + _ctrlBcgCommon ctrlSetPosition [ + _ctrlBcgCommonPos select 0, + _ctrlBcgCommonPos select 1, + _ctrlBcgCommonPos select 2, + _ctrlTextPosH + _marginY * 2 + ]; + _ctrlBcgCommon ctrlCommit 0; + + _ctrlText ctrlSetPosition [ + (_ctrlBcgCommonPos select 0) + _marginX, + (_ctrlBcgCommonPos select 1) + _marginY, + (_ctrlBcgCommonPos select 2) - _marginX * 2, + _ctrlTextPosH + ]; + _ctrlText ctrlCommit 0; + + private _bottomPosY = (_ctrlBcgCommonPos select 1) + _ctrlTextPosH + (_marginY * 2) + _bottomSpaceY; + + { + private _xPos = ctrlPosition _x; + + _xPos set [1, _bottomPosY]; + _x ctrlSetPosition _xPos; + _x ctrlCommit 0; + } forEach [ + _ctrlBackgroundButtonOK, + _ctrlBackgroundButtonMiddle, + _ctrlBackgroundButtonCancel, + _ctrlButtonOK, + _ctrlButtonCancel + ]; + + private _ctrlRscMessageBoxPos = ctrlPosition _ctrlRscMessageBox; + private _ctrlRscMessageBoxPosH = _bottomPosY + (_ctrlButtonOKPos select 3); + + _ctrlRscMessageBox ctrlSetPosition [ + 0.5 - (_ctrlBcgCommonPos select 2) / 2, + 0.5 - _ctrlRscMessageBoxPosH / 2, + (_ctrlBcgCommonPos select 2) + 0.5, + _ctrlRscMessageBoxPosH + ]; + + _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 1; true}]; -_ctrlButtonCancel ctrlAddEventHandler ["buttonClick", {(ctrlParent (_this select 0)) closeDisplay 2; true}]; + _ctrlButtonOK ctrlAddEventHandler ["ButtonClick", {(ctrlParent (_this select 0)) closeDisplay IDC_OK; true}]; -GVAR(errorOnOK) = _onOK; -GVAR(errorOnCancel) = _onCancel; + // Intercept all keystrokes except the enter keys + _display displayAddEventHandler ["KeyDown", {!((_this select 1) in [DIK_RETURN, DIK_NUMPADENTER])}]; -_display displayAddEventHandler ["unload", {call ([{}, GVAR(errorOnOK), GVAR(errorOnCancel)] select (_this select 1))}]; -_display displayAddEventHandler ["keyDown", {_this select 1 == 1}]; + // Close curator and mission displays (because of the message display, it doesn't quit the mission yet) + findDisplay 312 closeDisplay 0; + findDisplay 46 closeDisplay 0; +}, _this] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/common/functions/fnc_findUnloadPosition.sqf b/addons/common/functions/fnc_findUnloadPosition.sqf index 2047f7349d8..7fb4e41a73c 100644 --- a/addons/common/functions/fnc_findUnloadPosition.sqf +++ b/addons/common/functions/fnc_findUnloadPosition.sqf @@ -61,7 +61,7 @@ if (isNull _unloader || {_unloader in _vehicle}) then { // 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; +private _originAGL = ASLToAGL _originASL; // Do a manual search for empty pos (handles underwater, buildings or piers) TRACE_2("Checking for unload",_originAGL,_radiusOfItem); @@ -74,9 +74,9 @@ while {_rangeToCheck < _maxDistance} do { private _roundPointIsValid = false; - if (((AGLtoASL _roundAGL) select 2) > 0) then { + 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]]; + private _belowRoundArray = lineIntersectsSurfaces [(AGLToASL _roundAGL) vectorAdd [0, 0, 0.5], (AGLToASL _roundAGL) vectorAdd [0, 0, -1]]; TRACE_4("Testing for solid",_roundDistance,_roundAngle,_roundAGL,_belowRoundArray); if (_belowRoundArray isNotEqualTo []) then { @@ -85,7 +85,7 @@ while {_rangeToCheck < _maxDistance} do { // Point is above something: Terrain (null) or Building if ((isNull _aboveBuilding) || {_aboveBuilding isKindOf "Building"}) then { // Get the real intersection point - _roundAGL = ASLtoAGL ((_belowRoundArray select 0) select 0); + _roundAGL = ASLToAGL ((_belowRoundArray select 0) select 0); _roundPointIsValid = true; }; @@ -102,13 +102,13 @@ while {_rangeToCheck < _maxDistance} do { for "_index" from 0 to (COL_TEST_COUNT -1) do { // 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 _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 _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 _hitHeightOffset = ((AGLToASL _roundAGL) select 2) - (_hitGroundASL select 2); private _hit2dOffset = _roundAGL distance2D _hitGroundASL; private _slope = _hitHeightOffset atan2 _hit2dOffset; @@ -124,8 +124,8 @@ while {_rangeToCheck < _maxDistance} do { _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]; + _point1ASL = (AGLToASL _roundAGL) vectorAdd [_radiusOfItem * cos _angle, _radiusOfItem * sin _angle, 0.5]; + _point2ASL = (AGLToASL _roundAGL) vectorAdd [-_radiusOfItem * cos _angle, -_radiusOfItem * sin _angle, 1]; _testIntersections = lineIntersectsSurfaces [_point1ASL, _point2ASL]; if (_testIntersections isNotEqualTo []) exitWith { diff --git a/addons/common/functions/fnc_firedEH.sqf b/addons/common/functions/fnc_firedEH.sqf index cee874782a0..2c0c32994d5 100644 --- a/addons/common/functions/fnc_firedEH.sqf +++ b/addons/common/functions/fnc_firedEH.sqf @@ -50,8 +50,7 @@ if (_unit isKindOf "CAManBase") then { _gunner = _unit turretUnit _x; _turret = _x; }; - false - } count allTurrets [_unit, true]; + } forEach allTurrets [_unit, true]; // Ensure that at least the pilot is returned if there is no gunner if (isManualFire _unit && {isNull _gunner}) then { _gunner = effectiveCommander _unit; diff --git a/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf b/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf index 4e8aa1ec2a2..8982d6bbad3 100644 --- a/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf +++ b/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf @@ -17,6 +17,6 @@ params ["_unit"]; -if (currentWeapon _unit != "" && {currentWeapon _unit == primaryWeapon _unit} && {weaponLowered _unit} && {stance _unit == "STAND"} && {vehicle _unit == _unit}) then { +if (currentWeapon _unit != "" && {currentWeapon _unit == primaryWeapon _unit} && {weaponLowered _unit} && {stance _unit == "STAND"} && {isNull objectParent _unit}) then { [_unit, "amovpercmstpsraswrfldnon", 0] call FUNC(doAnimation); }; diff --git a/addons/common/functions/fnc_getAddon.sqf b/addons/common/functions/fnc_getAddon.sqf index b1a6f7cf995..ab3ad1c2173 100644 --- a/addons/common/functions/fnc_getAddon.sqf +++ b/addons/common/functions/fnc_getAddon.sqf @@ -22,7 +22,7 @@ params ["_config"]; // Return first addon if (_addons isNotEqualTo []) then { - (configSourceModList (configfile >> "CfgPatches" >> _addons select 0)) param [0, ""] + (configSourceModList (configFile >> "CfgPatches" >> _addons select 0)) param [0, ""] } else { // If nothing found at all, return "" "" diff --git a/addons/common/functions/fnc_getAllDefinedSetVariables.sqf b/addons/common/functions/fnc_getAllDefinedSetVariables.sqf index 6642a09789d..081836c1963 100644 --- a/addons/common/functions/fnc_getAllDefinedSetVariables.sqf +++ b/addons/common/functions/fnc_getAllDefinedSetVariables.sqf @@ -35,7 +35,6 @@ private _return = []; _return pushBack [_x select 0, typeName _val, _val, _x select 2, _x select 5]; }; }; - false -} count GVAR(OBJECT_VARIABLES_STORAGE); +} forEach GVAR(OBJECT_VARIABLES_STORAGE); _return diff --git a/addons/common/functions/fnc_getCountOfItem.sqf b/addons/common/functions/fnc_getCountOfItem.sqf index 5667b6c9800..5114f375d2d 100644 --- a/addons/common/functions/fnc_getCountOfItem.sqf +++ b/addons/common/functions/fnc_getCountOfItem.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: Dedmen + * Author: Dedmen, Blue, johnb43 * Return how many items of type _itemType the player has in his containers (Uniform, Vest, Backpack) * Doesn't count assignedItems, weapons, weapon attachments, magazines in weapons * @@ -19,13 +19,17 @@ params ["_unit", "_itemType"]; -private _countItemsInContainer = { - (getItemCargo _this) params ["_itemTypes", "_itemCounts"]; +private _count = 0; +private _isMagazine = isClass (configFile >> "CfgMagazines" >> _itemType); - private _index = _itemTypes find _itemType; - _itemCounts param [_index, 0] -}; +{ + (if (_isMagazine) then { + getMagazineCargo _x + } else { + getItemCargo _x + }) params ["_itemTypes", "_itemCounts"]; -((uniformContainer _unit) call _countItemsInContainer) + -((vestContainer _unit) call _countItemsInContainer) + -((backpackContainer _unit) call _countItemsInContainer) + _count = _count + (_itemCounts param [_itemTypes find _itemType, 0]); +} forEach [uniformContainer _unit, vestContainer _unit, backpackContainer _unit]; + +_count diff --git a/addons/common/functions/fnc_getDeathAnim.sqf b/addons/common/functions/fnc_getDeathAnim.sqf index 4d2e53d3dac..4e0b0578729 100644 --- a/addons/common/functions/fnc_getDeathAnim.sqf +++ b/addons/common/functions/fnc_getDeathAnim.sqf @@ -29,7 +29,9 @@ private _unitActionsCfg = configFile >> "CfgMovesBasic" >> "Actions" >> getText TRACE_2("Animation/Action",configName _unitAnimationCfg,configName _unitActionsCfg); -if (vehicle _unit != _unit) then { +if (isNull objectParent _unit) then { + _returnAnimation = getText (_unitActionsCfg >> "die"); +} else { private _interpolateArray = getArray (_unitAnimationCfg >> "interpolateTo"); for "_index" from 0 to (count _interpolateArray - 1) step 2 do { @@ -42,8 +44,6 @@ if (vehicle _unit != _unit) then { _returnAnimation = _indexAnimation; }; }; -} else { - _returnAnimation = getText (_unitActionsCfg >> "die"); }; //Fallback if nothing valid found: diff --git a/addons/common/functions/fnc_getDefaultAnim.sqf b/addons/common/functions/fnc_getDefaultAnim.sqf index 788fd2b6bd9..bd294ba0c04 100644 --- a/addons/common/functions/fnc_getDefaultAnim.sqf +++ b/addons/common/functions/fnc_getDefaultAnim.sqf @@ -17,7 +17,7 @@ params ["_unit"]; -private _anim = toLower animationState _unit; +private _anim = toLowerANSI animationState _unit; // stance is broken for some animations. private _stance = stance _unit; diff --git a/addons/common/functions/fnc_getDoorTurrets.sqf b/addons/common/functions/fnc_getDoorTurrets.sqf index fb652cfd1aa..1b6f22152a2 100644 --- a/addons/common/functions/fnc_getDoorTurrets.sqf +++ b/addons/common/functions/fnc_getDoorTurrets.sqf @@ -29,7 +29,6 @@ private _doorTurrets = []; if (((getNumber (_config >> "isCopilot")) == 0) && {count getArray (_config >> "weapons") > 0}) then { _doorTurrets pushBack _x; }; - false -} count _turrets; +} forEach _turrets; _doorTurrets diff --git a/addons/common/functions/fnc_getGunner.sqf b/addons/common/functions/fnc_getGunner.sqf index ffa0334a260..376f18070e5 100644 --- a/addons/common/functions/fnc_getGunner.sqf +++ b/addons/common/functions/fnc_getGunner.sqf @@ -19,7 +19,7 @@ params [["_vehicle", objNull, [objNull]], ["_weapon", "", [""]]]; // on foot -if (gunner _vehicle == _vehicle && {_weapon in weapons _vehicle || {toLower _weapon in ["throw", "put"]}}) exitWith {gunner _vehicle}; +if (gunner _vehicle == _vehicle && {_weapon in weapons _vehicle || {toLowerANSI _weapon in ["throw", "put"]}}) exitWith {gunner _vehicle}; // inside vehicle private _gunner = objNull; @@ -28,8 +28,7 @@ private _gunner = objNull; if (_weapon in (_vehicle weaponsTurret _x)) exitWith { _gunner = _vehicle turretUnit _x; }; - false -} count allTurrets [_vehicle, true]; +} forEach allTurrets [_vehicle, true]; // ensure that at least the pilot is returned if there is no gunner if (isManualFire _vehicle && {isNull _gunner}) then { diff --git a/addons/common/functions/fnc_getInPosition.sqf b/addons/common/functions/fnc_getInPosition.sqf index fdbad3ee4a4..eca21b125a9 100644 --- a/addons/common/functions/fnc_getInPosition.sqf +++ b/addons/common/functions/fnc_getInPosition.sqf @@ -23,7 +23,7 @@ params ["_unit", "_vehicle", "_position", ["_index", -1]]; -_position = toLower _position; +_position = toLowerANSI _position; // general if (!alive _vehicle || {locked _vehicle > 1}) exitWith {false}; @@ -38,9 +38,9 @@ private _enemiesInVehicle = false; //Possible Side Restriction { if (side _unit getFriend side _x < 0.6) exitWith {_enemiesInVehicle = true}; - false -} count crew _vehicle; +} forEach crew _vehicle; +//IGNORE_PRIVATE_WARNING ["_unit", "_isInside", "_vehicle", "_turret", "_index", "_fnc_getInEH", "_position"]; switch (_position) do { case "driver" : { if (CANGETINDRIVER) then { diff --git a/addons/common/functions/fnc_getItemType.sqf b/addons/common/functions/fnc_getItemType.sqf index e39605f0cc3..49f1b757da0 100644 --- a/addons/common/functions/fnc_getItemType.sqf +++ b/addons/common/functions/fnc_getItemType.sqf @@ -67,7 +67,7 @@ switch (true) do { case (_type == TYPE_UNIFORM): {["item", "uniform"]}; case (_type == TYPE_BINOCULAR_AND_NVG): { - switch (toLower _simulation) do { + switch (toLowerANSI _simulation) do { case ("weapon"): {["weapon", "binocular"]}; case ("binocular"): {["weapon", "binocular"]}; case ("nvgoggles"): {["item", "nvgoggles"]}; @@ -78,7 +78,7 @@ switch (true) do { case (_type == TYPE_WEAPON_VEHICLE): {["weapon", "vehicle"]}; case (_type == TYPE_ITEM): { - switch (toLower _simulation) do { + switch (toLowerANSI _simulation) do { case ("itemmap"): {["item", "map"]}; case ("itemgps"): {["item", "gps"]}; case ("itemradio"): {["item", "radio"]}; diff --git a/addons/common/functions/fnc_getMapData.sqf b/addons/common/functions/fnc_getMapData.sqf index b4cb56d75f9..379210ec8f2 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 f37e146288b..c6817b5d5b5 100644 --- a/addons/common/functions/fnc_getMapGridData.sqf +++ b/addons/common/functions/fnc_getMapGridData.sqf @@ -30,7 +30,7 @@ private _stepX = 1e10; private _stepY = 1e10; { - private _zoom = getnumber (_x >> "zoomMax"); + private _zoom = getNumber (_x >> "zoomMax"); if (_zoom < _zoomMax) then { _zoomMax = _zoom; _formatX = getText (_x >> "formatX"); @@ -38,13 +38,12 @@ private _stepY = 1e10; _stepX = getNumber (_x >> "stepX"); _stepY = getNumber (_x >> "stepY"); }; - false -} count configProperties [_cfgGrid, "isClass _x", false]; +} forEach configProperties [_cfgGrid, "isClass _x", false]; private _letterGrid = false; -if (toLower _formatX find "a" != -1) then {_letterGrid = true}; -if (toLower _formatY find "a" != -1) then {_letterGrid = true}; +if (toLowerANSI _formatX find "a" != -1) then {_letterGrid = true}; +if (toLowerANSI _formatY find "a" != -1) then {_letterGrid = true}; if (_letterGrid) exitWith { WARNING_3("Map Grid Warning (%1) - Map uses letter grids [%2, %3]",worldName,_formatX,_formatY); diff --git a/addons/common/functions/fnc_getNumberMagazinesIn.sqf b/addons/common/functions/fnc_getNumberMagazinesIn.sqf index fc2c3d06057..b71e6729dd0 100644 --- a/addons/common/functions/fnc_getNumberMagazinesIn.sqf +++ b/addons/common/functions/fnc_getNumberMagazinesIn.sqf @@ -25,8 +25,7 @@ if (_unit isKindOf "CAManBase") then { } else { { _return = _return + ({_x == _magazine} count magazines _x); - false - } count crew _unit; + } forEach crew _unit; (getMagazineCargo _unit) params [["_magNames", []], ["_magCount", []]]; { diff --git a/addons/common/functions/fnc_getSettingData.sqf b/addons/common/functions/fnc_getSettingData.sqf index a2dceb746c4..eeb8dff1d8a 100644 --- a/addons/common/functions/fnc_getSettingData.sqf +++ b/addons/common/functions/fnc_getSettingData.sqf @@ -32,7 +32,6 @@ scopeName "main"; if (_x select 0 == _name) then { _x breakOut "main"; }; - false -} count GVAR(settings); +} forEach GVAR(settings); [] diff --git a/addons/common/functions/fnc_getTurretIndex.sqf b/addons/common/functions/fnc_getTurretIndex.sqf index dcbaafb3b2c..75deced4121 100644 --- a/addons/common/functions/fnc_getTurretIndex.sqf +++ b/addons/common/functions/fnc_getTurretIndex.sqf @@ -24,7 +24,6 @@ scopeName "main"; { if (_unit == (_vehicle turretUnit _x)) then {_x breakOut "main"}; - nil -} count allTurrets [_vehicle, true]; +} forEach allTurrets [_vehicle, true]; [] diff --git a/addons/common/functions/fnc_getVehicleCrew.sqf b/addons/common/functions/fnc_getVehicleCrew.sqf index 00a90b1ab2c..a1bc06f6aba 100644 --- a/addons/common/functions/fnc_getVehicleCrew.sqf +++ b/addons/common/functions/fnc_getVehicleCrew.sqf @@ -29,11 +29,10 @@ private _crew = []; }; } else { // otherwise check if we search for that type. toLower, because fullCrew returns "driver" vs. "Turret". - if (toLower (_x select 1) in _types) then { + if (toLowerANSI (_x select 1) in _types) then { _crew pushBack (_x select 0); }; }; - false -} count fullCrew _vehicle; +} forEach fullCrew _vehicle; _crew diff --git a/addons/common/functions/fnc_getVehicleIcon.sqf b/addons/common/functions/fnc_getVehicleIcon.sqf index 208bb144d80..6bda8f63108 100644 --- a/addons/common/functions/fnc_getVehicleIcon.sqf +++ b/addons/common/functions/fnc_getVehicleIcon.sqf @@ -28,14 +28,18 @@ private _objectType = if (_object isEqualType objNull) then { private _cachedValue = GVAR(vehicleIconCache) get _objectType; if (isNil "_cachedValue") then { - private _vehicleValue = getText (configfile >> "CfgVehicles" >> _objectType >> "icon"); - private _vehicleIconValue = getText (configfile >> "CfgVehicleIcons" >> _vehicleValue); + 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; + if (_vehicleValue != "" && {fileExists (_vehicleValue + ".paa")}) then { + _cachedValue = _vehicleValue + ".paa"; + } else { + _cachedValue = DEFAULT_TEXTURE; + }; }; } else { _cachedValue = _vehicleIconValue; diff --git a/addons/common/functions/fnc_getWeaponModes.sqf b/addons/common/functions/fnc_getWeaponModes.sqf index 55e260ef27c..42a29681f23 100644 --- a/addons/common/functions/fnc_getWeaponModes.sqf +++ b/addons/common/functions/fnc_getWeaponModes.sqf @@ -1,35 +1,45 @@ #include "..\script_component.hpp" /* - * Author: commy2 + * Author: commy2, johnb43 * Get the available firing modes of a weapon. Will ignore the AI helper modes. * * Arguments: * 0: Weapon + * 1: Muzzle (default: weapon) * * Return Value: * Firing Modes * * Example: - * ["gun"] call ace_common_fnc_getWeaponModes + * "arifle_AK12_F" call ace_common_fnc_getWeaponModes * * Public: Yes */ -params [["_weapon", "", [""]]]; +params [["_weapon", "", [""]], ["_muzzle", nil, [""]]]; private _config = configFile >> "CfgWeapons" >> _weapon; +if (!isNil "_muzzle") then { + _config = _config >> _muzzle +}; + +if (!isClass _config) exitWith { + [] // return +}; + private _modes = []; { if (getNumber (_config >> _x >> "showToPlayer") == 1) then { - _modes pushBack _x; - }; - - if (_x == "this") then { - _modes pushBack _weapon; + if (_x == "this") then { + _modes pushBack (configName _config); + } else { + if (isClass (_config >> _x)) then { + _modes pushBack (configName (_config >> _x)); + }; + }; }; - false -} count getArray (_config >> "modes"); +} forEach getArray (_config >> "modes"); -_modes +_modes // return diff --git a/addons/common/functions/fnc_getWeaponMuzzles.sqf b/addons/common/functions/fnc_getWeaponMuzzles.sqf index 11fffaf1960..0184a0c8c83 100644 --- a/addons/common/functions/fnc_getWeaponMuzzles.sqf +++ b/addons/common/functions/fnc_getWeaponMuzzles.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: commy2 + * Author: commy2, johnb43 * Get the muzzles of a weapon. * * Arguments: @@ -10,19 +10,30 @@ * All weapon muzzles * * Example: - * ["gun"] call ace_common_fnc_getWeaponMuzzles + * "arifle_AK12_F" call ace_common_fnc_getWeaponMuzzles * * Public: Yes */ params [["_weapon", "", [""]]]; -private _muzzles = getArray (configFile >> "CfgWeapons" >> _weapon >> "muzzles"); +private _config = configFile >> "CfgWeapons" >> _weapon; +if (!isClass _config) exitWith { + [] // return +}; + +private _muzzles = []; + +// Get config case muzzle names { if (_x == "this") then { - _muzzles set [_forEachIndex, configName (configFile >> "CfgWeapons" >> _weapon)]; + _muzzles pushBack (configName _config); + } else { + if (isClass (_config >> _x)) then { + _muzzles pushBack (configName (_config >> _x)); + }; }; -} forEach _muzzles; +} forEach getArray (_config >> "muzzles"); -_muzzles +_muzzles // return diff --git a/addons/common/functions/fnc_getWeaponState.sqf b/addons/common/functions/fnc_getWeaponState.sqf index 7ccb016c7a9..2fadbd23eac 100644 --- a/addons/common/functions/fnc_getWeaponState.sqf +++ b/addons/common/functions/fnc_getWeaponState.sqf @@ -42,7 +42,6 @@ private _ammo = _muzzles apply {0}; _ammo set [_index, _x select 1]; }; }; - false -} count magazinesAmmoFull _unit; +} forEach magazinesAmmoFull _unit; [_attachments, _muzzles, _magazines, _ammo]; diff --git a/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf new file mode 100644 index 00000000000..2194c2aca05 --- /dev/null +++ b/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf @@ -0,0 +1,104 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, johnb43 + * Returns the wheel hitpoints and their selections. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * 0: Wheel hitpoints + * 1: Wheel hitpoint selections + * + * Example: + * cursorObject call ace_common_fnc_getWheelHitPointsWithSelections + * + * Public: No + */ + +params ["_vehicle"]; +TRACE_1("params",_vehicle); + +// TODO: Fix for GM vehicles +GVAR(wheelSelections) getOrDefaultCall [typeOf _vehicle, { + // Get the vehicles wheel config + private _wheels = configOf _vehicle >> "Wheels"; + + if (isClass _wheels) then { + // Get all hitpoints and selections + (getAllHitPointsDamage _vehicle) params ["_hitPoints", "_hitPointSelections"]; + + // Get all wheels and read selections from config + _wheels = "true" configClasses _wheels; + + private _wheelHitPoints = []; + private _wheelHitPointSelections = []; + + { + private _wheelName = configName _x; + private _wheelCenter = getText (_x >> "center"); + private _wheelBone = getText (_x >> "boneName"); + private _wheelBoneNameResized = _wheelBone select [0, 9]; // Count "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles. + + TRACE_4("",_wheelName,_wheelCenter,_wheelBone,_wheelBoneNameResized); + + private _wheelHitPoint = ""; + private _wheelHitPointSelection = ""; + + // Commy's orginal method + { + if ((_wheelBoneNameResized != "") && {_x find _wheelBoneNameResized == 0}) exitWith { // same as above. Requirement for physx. + _wheelHitPoint = _hitPoints select _forEachIndex; + _wheelHitPointSelection = _hitPointSelections select _forEachIndex; + TRACE_2("wheel found [Orginal]",_wheelName,_wheelHitPoint); + }; + } forEach _hitPointSelections; + + + if (_vehicle isKindOf "Car") then { + // Backup method, search for the closest hitpoint to the wheel's center selection pos. + // Ref #2742 - RHS's HMMWV + if (_wheelHitPoint == "") then { + private _wheelCenterPos = _vehicle selectionPosition _wheelCenter; + if (_wheelCenterPos isEqualTo [0, 0, 0]) exitWith {TRACE_1("no center?",_wheelCenter);}; + + + private _bestDist = 99; + private _bestIndex = -1; + { + if (_x != "") then { + // Filter out things that definitly aren't wheeels (#3759) + if ((toLowerANSI (_hitPoints select _forEachIndex)) in ["hitengine", "hitfuel", "hitbody"]) exitWith {TRACE_1("filter",_x)}; + private _xPos = _vehicle selectionPosition _x; + if (_xPos isEqualTo [0, 0, 0]) exitWith {}; + private _xDist = _wheelCenterPos distance _xPos; + if (_xDist < _bestDist) then { + _bestIndex = _forEachIndex; + _bestDist = _xDist; + }; + }; + } forEach _hitPointSelections; + + TRACE_2("closestPoint",_bestDist,_bestIndex); + if (_bestIndex != -1) then { + _wheelHitPoint = _hitPoints select _bestIndex; + _wheelHitPointSelection = _hitPointSelections select _bestIndex; + TRACE_2("wheel found [Backup]",_wheelName,_wheelHitPoint); + }; + }; + }; + + if ((_wheelHitPoint != "") && {_wheelHitPointSelection != ""}) then { + _wheelHitPoints pushBack _wheelHitPoint; + _wheelHitPointSelections pushBack _wheelHitPointSelection; + }; + } forEach _wheels; + + [_wheelHitPoints, _wheelHitPointSelections] + } else { + // Exit with nothing if the vehicle has no wheels class + TRACE_1("No Wheels",_wheels); + + [[], []] + } +}, true] // return diff --git a/addons/common/functions/fnc_goKneeling.sqf b/addons/common/functions/fnc_goKneeling.sqf index 881fad7669f..303a413385d 100644 --- a/addons/common/functions/fnc_goKneeling.sqf +++ b/addons/common/functions/fnc_goKneeling.sqf @@ -18,7 +18,7 @@ params ["_unit"]; // Animation changes even inside vehicle post-1.60 -if (stance _unit == "PRONE" || {vehicle _unit != _unit} || {_unit call EFUNC(common,isSwimming)}) exitWith {}; +if (stance _unit == "PRONE" || {!isNull objectParent _unit} || {_unit call EFUNC(common,isSwimming)}) exitWith {}; [ _unit, diff --git a/addons/common/functions/fnc_hasItem.sqf b/addons/common/functions/fnc_hasItem.sqf index f446c5dac0b..ac0be8b10e0 100644 --- a/addons/common/functions/fnc_hasItem.sqf +++ b/addons/common/functions/fnc_hasItem.sqf @@ -1,21 +1,21 @@ #include "..\script_component.hpp" /* * Author: Glowbal - * Check if unit has item. Note: case-sensitive. + * Check if given unit has an item of given classname. Note: Case sensitive. * * Arguments: * 0: Unit - * 1: Item Classname + * 1: Item classname * * Return Value: - * Unit has Item + * Unit has item * * Example: - * [bob, "item"] call ace_common_fnc_hasItem + * [player, "ACE_Banana"] call ace_common_fnc_hasItem * * Public: Yes */ params [["_unit", objNull, [objNull]], ["_item", "", [""]]]; -_item in (_unit call EFUNC(common,uniqueItems)) +_item in (_unit call FUNC(uniqueItems)) // return diff --git a/addons/common/functions/fnc_hasMagazine.sqf b/addons/common/functions/fnc_hasMagazine.sqf index 7874bcbd16b..9f35aafdba8 100644 --- a/addons/common/functions/fnc_hasMagazine.sqf +++ b/addons/common/functions/fnc_hasMagazine.sqf @@ -1,23 +1,21 @@ #include "..\script_component.hpp" /* * Author: Glowbal - * Check if given unit has a magazine of given classname + * Check if given unit has a magazine of given classname. Note: Case sensitive. * * Arguments: * 0: Unit - * 1: Magazine Classname + * 1: Magazine classname * * Return Value: - * has Magazine + * Unit has magazine * * Example: - * [bob, "magazine"] call ace_common_fnc_hasMagazine + * [player, "30Rnd_65x39_caseless_mag"] call ace_common_fnc_hasMagazine * * Public: yes - * - * Note: Case sensitive */ params [["_unit", objNull, [objNull]], ["_magazine", "", [""]]]; -_magazine in magazines _unit // return +_magazine in ([_unit, 2] call FUNC(uniqueItems)) // return diff --git a/addons/common/functions/fnc_isAwake.sqf b/addons/common/functions/fnc_isAwake.sqf index f564e5e8728..1ab4ed21b0b 100644 --- a/addons/common/functions/fnc_isAwake.sqf +++ b/addons/common/functions/fnc_isAwake.sqf @@ -17,4 +17,4 @@ params ["_unit"]; -alive _unit && {!(_unit getVariable ["ACE_isUnconscious", false])} +lifeState _unit in ["HEALTHY", "INJURED"] diff --git a/addons/common/functions/fnc_moduleLSDVehicles.sqf b/addons/common/functions/fnc_moduleLSDVehicles.sqf index fde230b0cab..16a6235ee1a 100644 --- a/addons/common/functions/fnc_moduleLSDVehicles.sqf +++ b/addons/common/functions/fnc_moduleLSDVehicles.sqf @@ -24,12 +24,11 @@ if (isNil QGVAR(LSD_Vehicles)) then { }; { - _hSCount = count (getArray (configOf _x >> "hiddenSelections")); + private _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_nearestVehiclesFreeSeat.sqf b/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf index 71f62959b98..21087510667 100644 --- a/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf +++ b/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf @@ -22,7 +22,7 @@ params ["_unit", ["_distance", 10], ["_cargoOnly", false]]; private _nearVehicles = nearestObjects [_unit, ["Car", "Air", "Tank", "Ship_F", "Pod_Heli_Transport_04_crewed_base_F"], _distance]; _nearVehicles select { // Filter cargo seats that will eject unconscious units (e.g. quad bike) - private _canSitInCargo = (!(_unit getVariable ['ACE_isUnconscious', false])) || {(getNumber (configOf _x >> "ejectDeadCargo")) == 0}; + private _canSitInCargo = (_unit call EFUNC(common,isAwake)) || {(getNumber (configOf _x >> "ejectDeadCargo")) == 0}; ((fullCrew [_x, "", true]) findIf { _x params ["_body", "_role", "_cargoIndex"]; (isNull _body) // seat empty diff --git a/addons/common/functions/fnc_parseList.sqf b/addons/common/functions/fnc_parseList.sqf index 93ceccf17db..a559994bfa5 100644 --- a/addons/common/functions/fnc_parseList.sqf +++ b/addons/common/functions/fnc_parseList.sqf @@ -32,8 +32,7 @@ private _whitespaceList = []; } else { _whitespaceList pushBack ([_x] call CBA_fnc_trim); }; - false -} count _list; +} forEach _list; _list = _whitespaceList; TRACE_1("Whitespace List",_list); @@ -46,8 +45,7 @@ if (_checkNil) then { if (!isNil _x) then { _nilCheckedList pushBack (missionNamespace getVariable _x); }; - false - } count _list; + } forEach _list; _list = _nilCheckedList; }; diff --git a/addons/common/functions/fnc_playConfigSound3D.sqf b/addons/common/functions/fnc_playConfigSound3D.sqf index 788a2a6b4e3..1069cf0f185 100644 --- a/addons/common/functions/fnc_playConfigSound3D.sqf +++ b/addons/common/functions/fnc_playConfigSound3D.sqf @@ -35,7 +35,7 @@ ISNILS(_distance,_cfgDistance); _fileName = _fileName select [1]; // add file extension .wss as default -if !(toLower (_fileName select [count _fileName - 4]) in [".wav", ".ogg", ".wss"]) then { +if !(toLowerANSI (_fileName select [count _fileName - 4]) in [".wav", ".ogg", ".wss"]) then { ADD(_fileName,".wss"); }; TRACE_5("vars",_fileName,_posASL,_volume,_pitch,_distance); diff --git a/addons/common/functions/fnc_positionToASL.sqf b/addons/common/functions/fnc_positionToASL.sqf index b286d2f7ab6..808bfe35636 100644 --- a/addons/common/functions/fnc_positionToASL.sqf +++ b/addons/common/functions/fnc_positionToASL.sqf @@ -20,5 +20,5 @@ if (surfaceIsWater _this) then { _this } else { - ATLtoASL _this + ATLToASL _this }; diff --git a/addons/common/functions/fnc_progressBar.sqf b/addons/common/functions/fnc_progressBar.sqf index 9b5519c232f..36f04b18f8c 100644 --- a/addons/common/functions/fnc_progressBar.sqf +++ b/addons/common/functions/fnc_progressBar.sqf @@ -57,7 +57,7 @@ if (_dialog) then { //Adjust position based on user setting: private _ctrlPos = ctrlPosition (uiNamespace getVariable QGVAR(ctrlProgressBarTitle)); -_ctrlPos set [1, ((0 + 29 * GVAR(settingProgressBarLocation)) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2))]; +_ctrlPos set [1, ((0 + 29 * GVAR(settingProgressBarLocation)) * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25) + (safeZoneY + (safeZoneH - (((safeZoneW / safeZoneH) min 1.2) / 1.2))/2))]; (uiNamespace getVariable QGVAR(ctrlProgressBG)) ctrlSetPosition _ctrlPos; (uiNamespace getVariable QGVAR(ctrlProgressBG)) ctrlCommit 0; diff --git a/addons/common/functions/fnc_readSettingsFromParamsArray.sqf b/addons/common/functions/fnc_readSettingsFromParamsArray.sqf index 7273fc61caf..0134bc210c2 100644 --- a/addons/common/functions/fnc_readSettingsFromParamsArray.sqf +++ b/addons/common/functions/fnc_readSettingsFromParamsArray.sqf @@ -17,7 +17,7 @@ */ //paramsArray is a normal variable not a command -private _paramsArray = missionnamespace getVariable ["paramsArray", []]; +private _paramsArray = missionNamespace getVariable ["paramsArray", []]; TRACE_1("Reading missionConfigFile params",_paramsArray); diff --git a/addons/common/functions/fnc_registerItemReplacement.sqf b/addons/common/functions/fnc_registerItemReplacement.sqf index ce2fd7e393b..f1e068c322f 100644 --- a/addons/common/functions/fnc_registerItemReplacement.sqf +++ b/addons/common/functions/fnc_registerItemReplacement.sqf @@ -20,15 +20,23 @@ params [["_oldItem", "", [0,""]], ["_newItems", "", ["", []]], ["_replaceInherited", false, [false]]]; TRACE_3("registerItemReplacement",_oldItem,_newItems,_replaceInherited); - // Setup on first run if (isNil QGVAR(itemReplacements)) then { - GVAR(itemReplacements) = [] call CBA_fnc_createNamespace; + GVAR(itemReplacements) = createHashMap; GVAR(inheritedReplacements) = []; GVAR(oldItems) = []; ["loadout", LINKFUNC(replaceRegisteredItems)] call CBA_fnc_addPlayerEventHandler; }; +// Get config case - if item doesn't exist, "" is returned +if (_oldItem isEqualType "") then { + _oldItem = _oldItem call FUNC(getConfigName); +}; + +if (_oldItem isEqualTo "") exitWith { + ERROR("Item doesn't exist"); +}; + // Save item replacement // $ prefix is used for types (numbers) and replacements with inheritance if (_replaceInherited) then { @@ -42,9 +50,8 @@ if (_newItems isEqualType "") then { _newItems = [_newItems]; }; -private _oldReplacements = GVAR(itemReplacements) getVariable [_oldItem, []]; +private _oldReplacements = GVAR(itemReplacements) getOrDefault [_oldItem, [], true]; _oldReplacements append _newItems; -GVAR(itemReplacements) setVariable [_oldItem, _oldReplacements]; // Force item scan when new replacement was registered in PostInit if !(isNull ACE_player) then { diff --git a/addons/common/functions/fnc_removeCanInteractWithCondition.sqf b/addons/common/functions/fnc_removeCanInteractWithCondition.sqf index 9cc3fda3c3f..841a9a00b15 100644 --- a/addons/common/functions/fnc_removeCanInteractWithCondition.sqf +++ b/addons/common/functions/fnc_removeCanInteractWithCondition.sqf @@ -17,17 +17,5 @@ params ["_conditionName"]; -_conditionName = toLower _conditionName; - -private _conditions = missionNamespace getVariable [QGVAR(InteractionConditions), [[],[]]]; - -_conditions params ["_conditionNames", "_conditionFuncs"]; - -private _index = _conditionNames find _conditionName; - -if (_index == -1) exitWith {}; - -_conditionNames deleteAt _index; -_conditionFuncs deleteAt _index; - -GVAR(InteractionConditions) = _conditions; +_conditionName = toLowerANSI _conditionName; +GVAR(InteractionConditions) deleteAt _conditionName; diff --git a/addons/common/functions/fnc_replaceRegisteredItems.sqf b/addons/common/functions/fnc_replaceRegisteredItems.sqf index bfe2e493e01..baa591c8d89 100644 --- a/addons/common/functions/fnc_replaceRegisteredItems.sqf +++ b/addons/common/functions/fnc_replaceRegisteredItems.sqf @@ -42,7 +42,7 @@ for "_i" from 0 to count _newItems - 1 do { private _replacements = []; // Determine replacement items: direct replacements, ... - private _directReplacements = GVAR(itemReplacements) getVariable _item; + private _directReplacements = GVAR(itemReplacements) get _item; if (!isNil "_directReplacements") then { _doReplace = true; _replacements append _directReplacements; @@ -50,7 +50,7 @@ for "_i" from 0 to count _newItems - 1 do { // ... item type replacements ... private _type = getNumber (_cfgWeapons >> _item >> "ItemInfo" >> "type"); - private _typeReplacements = GVAR(itemReplacements) getVariable ("$" + str _type); + private _typeReplacements = GVAR(itemReplacements) get ("$" + str _type); if (!isNil "_typeReplacements") then { _doReplace = true; _replacements append _typeReplacements; @@ -59,7 +59,7 @@ for "_i" from 0 to count _newItems - 1 do { // ... and inherited replacements { if (_item isKindOf [_x, _cfgWeapons]) then { - private _inheritedReplacements = GVAR(itemReplacements) getVariable _x; + private _inheritedReplacements = GVAR(itemReplacements) get _x; if (!isNil "_inheritedReplacements") then { _doReplace = true; _replacements append _inheritedReplacements; diff --git a/addons/common/functions/fnc_resetAllDefaults.sqf b/addons/common/functions/fnc_resetAllDefaults.sqf index 4d9f42a13be..ef747241830 100644 --- a/addons/common/functions/fnc_resetAllDefaults.sqf +++ b/addons/common/functions/fnc_resetAllDefaults.sqf @@ -27,8 +27,7 @@ if (isPlayer _unit) then { // clear all disable user input { [_x, false] call FUNC(setDisableUserInputStatus); - false - } count GVAR(DISABLE_USER_INPUT_COLLECTION); + } forEach GVAR(DISABLE_USER_INPUT_COLLECTION); }; }; @@ -36,5 +35,4 @@ if (isPlayer _unit) then { if !(_x select 4) then { _unit setVariable [_x select 0, nil, _x select 3]; }; - false -} count ([_unit] call FUNC(getAllDefinedSetVariables)); +} forEach ([_unit] call FUNC(getAllDefinedSetVariables)); diff --git a/addons/common/functions/fnc_restoreVariablesJIP.sqf b/addons/common/functions/fnc_restoreVariablesJIP.sqf index 905353d8ab2..ac22cd3fa07 100644 --- a/addons/common/functions/fnc_restoreVariablesJIP.sqf +++ b/addons/common/functions/fnc_restoreVariablesJIP.sqf @@ -24,6 +24,4 @@ _respawnVariables pushBack "ACE_PersistentFunctions"; { _unit setVariable [_x, _unit getVariable _x, true]; - false -} count _respawnVariables; -nil +} forEach _respawnVariables; diff --git a/addons/common/functions/fnc_rscObjectHelper.sqf b/addons/common/functions/fnc_rscObjectHelper.sqf index c7d1342de96..95ddb2f74bc 100644 --- a/addons/common/functions/fnc_rscObjectHelper.sqf +++ b/addons/common/functions/fnc_rscObjectHelper.sqf @@ -30,7 +30,7 @@ private _bottomRightY = 1; private _return = []; -switch (toLower _func) do { +switch (toLowerANSI _func) do { case ("2d"): { _array params ["_pointX", "_z", "_pointY"]; diff --git a/addons/common/functions/fnc_runTests.sqf b/addons/common/functions/fnc_runTests.sqf index 4a449fb7eb8..a430cadabaa 100644 --- a/addons/common/functions/fnc_runTests.sqf +++ b/addons/common/functions/fnc_runTests.sqf @@ -30,7 +30,7 @@ INFO_1("ace_common_fnc_runTests starting for [%1]",_specificTest); _total = _total + 1; private _testFile = getText _x; diag_log text format ["----- Starting Testing %1 [%2] -----", _testName, _testFile]; - private _return = ([nil] apply (compile preProcessFileLineNumbers _testFile)) select 0; + private _return = ([nil] apply (compile preprocessFileLineNumbers _testFile)) select 0; if ((isNil "_return") || {_return isNotEqualTo true}) then { systemChat format ["Test [%1] Failed", _testName]; diag_log text format ["----- Finished Testing %1 [Failed] -----", _testName]; diff --git a/addons/common/functions/fnc_sanitizeString.sqf b/addons/common/functions/fnc_sanitizeString.sqf index c30cbe12922..7d0b2dd2f1a 100644 --- a/addons/common/functions/fnc_sanitizeString.sqf +++ b/addons/common/functions/fnc_sanitizeString.sqf @@ -47,7 +47,6 @@ private _array = []; _array pushBack _x; }; }; - false -} count toArray _string; +} forEach toArray _string; toString _array // return diff --git a/addons/common/functions/fnc_setDead.sqf b/addons/common/functions/fnc_setDead.sqf new file mode 100644 index 00000000000..f6d62abd349 --- /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_setPlayerOwner.sqf b/addons/common/functions/fnc_setPlayerOwner.sqf index 2b37349f9af..010f0b9b462 100644 --- a/addons/common/functions/fnc_setPlayerOwner.sqf +++ b/addons/common/functions/fnc_setPlayerOwner.sqf @@ -17,7 +17,7 @@ * Public: No */ -if (missionNameSpace getVariable [QGVAR(setPlayerOwnerRunning), false]) exitWith {}; +if (missionNamespace getVariable [QGVAR(setPlayerOwnerRunning), false]) exitWith {}; GVAR(setPlayerOwnerRunning) = true; if (isServer) then { diff --git a/addons/common/functions/fnc_setSetting.sqf b/addons/common/functions/fnc_setSetting.sqf index 93c6045a6cf..9135c12ea52 100644 --- a/addons/common/functions/fnc_setSetting.sqf +++ b/addons/common/functions/fnc_setSetting.sqf @@ -29,8 +29,8 @@ if (!_broadcastChanges) exitWith { ERROR_1("Setting [%1] - SetSetting no longer supports non-global settings",_name); }; -if ([_settingName, "mission"] call CBA_settings_fnc_isForced) then { - WARNING_1("Setting [%1] - Already mission forced - Ignoring",_settingName); +if ([_name, "mission"] call CBA_settings_fnc_isForced) then { + WARNING_1("Setting [%1] - Already mission forced - Ignoring",_name); }; [QGVAR(setSetting), [_name, _value], (format [QGVAR(setSetting_%1), _name])] call CBA_fnc_globalEventJIP; diff --git a/addons/common/functions/fnc_setWeaponLightLaserState.sqf b/addons/common/functions/fnc_setWeaponLightLaserState.sqf new file mode 100644 index 00000000000..7f50573acb7 --- /dev/null +++ b/addons/common/functions/fnc_setWeaponLightLaserState.sqf @@ -0,0 +1,59 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Toggles the unit's current weapon's light & laser. + * API for persistent lasers. Doesn't work on AI, as they have their own logic. + * + * Arguments: + * 0: Unit + * 1: Weapon light/laser state (default: false) + * + * Return Value: + * None + * + * Example: + * [player, true] call ace_common_fnc_setWeaponLightLaserState + * + * Public: Yes + */ + +params [["_unit", objNull, [objNull]], ["_state", false, [false]]]; + +if (!local _unit || {!alive _unit} || {!(_unit call FUNC(isPlayer))}) exitWith {}; + +if !(_unit call CBA_fnc_canUseWeapon) exitWith {}; + +private _currentWeapon = currentWeapon _unit; + +// Exit if unit has no weapon selected +if (_currentWeapon == "") exitWith {}; + +private _weaponIndex = [_unit, _currentWeapon] call FUNC(getWeaponIndex); + +// Ignore binoculars +if (_weaponIndex == -1) exitWith {}; + +_unit setVariable [QGVAR(laserEnabled_) + str _weaponIndex, _state]; + +// Turn off light/laser (switching between weapons can leave previous weapon laser on) +action ["GunLightOff", _unit]; +action ["IRLaserOff", _unit]; + +// Light/laser is off, don't need to do anything more +if (!_state) exitWith {}; + +// Turn laser on next frame (if weapon hasn't changed) +[{ + params ["_unit", "_currentWeapon"]; + + private _weaponState = (weaponState _unit) select [0, 3]; + + if (_weaponState select 0 != _currentWeapon) exitWith {}; + + action ["GunLightOn", _unit]; + action ["IRLaserOn", _unit]; + + _unit selectWeapon _weaponState; +}, [_unit, _currentWeapon]] call CBA_fnc_execNextFrame; + +nil diff --git a/addons/common/functions/fnc_showHud.sqf b/addons/common/functions/fnc_showHud.sqf index 1ca7ca81068..b552b7230af 100644 --- a/addons/common/functions/fnc_showHud.sqf +++ b/addons/common/functions/fnc_showHud.sqf @@ -6,8 +6,8 @@ * * Arguments: * 0: Source ID (default: "") - * 1: Show Hud Bool Array (8 to set, empty to remove) (default: []) - * - [hud, info, radar, compass, direction, menu, group, cursors] + * 1: Show Hud Bool Array (10 to set, empty to remove) (default: []) + * - [hud, info, radar, compass, direction, menu, group, cursors, panels, kills] * - hud: Boolean - show scripted HUD (same as normal showHUD true/false) * - info: Boolean - show vehicle + soldier info (hides weapon info from the HUD as well) * - radar: Boolean - show vehicle radar @@ -17,7 +17,8 @@ * - group: Boolean - show group info bar (hides squad leader info bar) * - cursors: Boolean - show HUD weapon cursors (connected with scripted HUD) * - panels: Boolean - show vehicle panels / GPS - * - ???: Boolean - Possibly related to changelog entry `Added: A new showKillConfirmations parameter for the showHud command` + * - kills: Boolean - show "x killed by y" systemChat messages + * - showIcon3D: is unsupported as it has inverted logic * * Return Value: * Resulting ShowHud Array @@ -56,7 +57,7 @@ private _resultMask = []; for "_index" from 0 to 9 do { private _set = true; //Default to true { - if (!(_x select _index)) exitWith { + if !(_x select _index) exitWith { _set = false; //Any false will make it false }; } forEach _masks; @@ -64,6 +65,6 @@ for "_index" from 0 to 9 do { }; TRACE_2("showHud",_resultMask,keys GVAR(showHudHash)); -showHud _resultMask; +showHUD _resultMask; _resultMask diff --git a/addons/common/functions/fnc_statusEffect_addType.sqf b/addons/common/functions/fnc_statusEffect_addType.sqf index c7bd61762e9..5535b0d9145 100644 --- a/addons/common/functions/fnc_statusEffect_addType.sqf +++ b/addons/common/functions/fnc_statusEffect_addType.sqf @@ -32,6 +32,6 @@ GVAR(statusEffect_sendJIP) pushBack _sendJIP; //We add reasons at any time, but more efficenet to add all common ones at one time during init if (isServer && {_commonReasonsArray isNotEqualTo []}) then { //Switch case to lower: - _commonReasonsArray = _commonReasonsArray apply { toLower _x }; + _commonReasonsArray = _commonReasonsArray apply { toLowerANSI _x }; missionNamespace setVariable [(format [QGVAR(statusEffects_%1), _name]), _commonReasonsArray, true]; }; diff --git a/addons/common/functions/fnc_statusEffect_set.sqf b/addons/common/functions/fnc_statusEffect_set.sqf index 6e8a74bd3e4..a4bf352a565 100644 --- a/addons/common/functions/fnc_statusEffect_set.sqf +++ b/addons/common/functions/fnc_statusEffect_set.sqf @@ -32,7 +32,7 @@ if (isNull _object) exitWith {TRACE_1("null",_object);}; [_object, true] call FUNC(statusEffect_resetVariables); //Check for mismatch, and set object ref //check ID case and set globally if not already set: -_ID = toLower _ID; +_ID = toLowerANSI _ID; private _statusReasons = missionNamespace getVariable [(format [QGVAR(statusEffects_%1), _effectName]), []]; private _statusIndex = _statusReasons find _ID; if (_statusIndex == -1) then { diff --git a/addons/common/functions/fnc_swayLoop.sqf b/addons/common/functions/fnc_swayLoop.sqf index 069d908d1a1..adbc32053fc 100644 --- a/addons/common/functions/fnc_swayLoop.sqf +++ b/addons/common/functions/fnc_swayLoop.sqf @@ -17,12 +17,12 @@ private _baseline = 1; if (GVAR(swayFactorsBaseline) isNotEqualTo []) then { - _baseline = 1 max ([missionNamespace, "ACE_setCustomAimCoef_baseline", "max"] call EFUNC(common,arithmeticGetResult)); + _baseline = 1 max ([missionNamespace, "ACE_setCustomAimCoef_baseline", "max"] call FUNC(arithmeticGetResult)); }; private _multiplier = 1; if (GVAR(swayFactorsMultiplier) isNotEqualTo []) then { - _multiplier = [missionNamespace, "ACE_setCustomAimCoef_multiplier", "product"] call EFUNC(common,arithmeticGetResult); + _multiplier = [missionNamespace, "ACE_setCustomAimCoef_multiplier", "product"] call FUNC(arithmeticGetResult); }; ACE_player setCustomAimCoef (_baseline * _multiplier); diff --git a/addons/common/functions/fnc_switchAttachmentMode.sqf b/addons/common/functions/fnc_switchAttachmentMode.sqf new file mode 100644 index 00000000000..ab1dac6c1c7 --- /dev/null +++ b/addons/common/functions/fnc_switchAttachmentMode.sqf @@ -0,0 +1,73 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Switch attachment from one mode to another - based on CBA_accessory_fnc_switchAttachment + * ToDo: Port this to CBA? + * + * Arguments: + * 0: Unit + * 1: Weapon (String or CBA-Weapon-Index (not ace's getWeaponIndex)) + * 2: From + * 3: To + * + * Return Value: + * None + * + * Example: + * [player, 0, "ACE_DBAL_A3_Green_VP", "ACE_DBAL_A3_Green"] call ace_common_fnc_switchAttachmentMode + * + * Public: No + */ + +params ["_unit", "_weapon", "_currItem", "_switchItem"]; +TRACE_4("switchAttachmentMode",_unit,_weapon,_currItem,_switchItem); + +if (_weapon isEqualTo "") exitWith {}; + +private _exit = _unit != ACE_player; +switch (_weapon) do { + case 0; + case (primaryWeapon _unit): { + private _currWeaponType = 0; + _unit removePrimaryWeaponItem _currItem; + [{ + params ["_unit", "", "_switchItem"]; + _unit addPrimaryWeaponItem _switchItem; + ["CBA_attachmentSwitched", _this] call CBA_fnc_localEvent; + }, [_unit, _currItem, _switchItem, _currWeaponType]] call CBA_fnc_execNextFrame; + }; + case 1; + case (handgunWeapon _unit): { + private _currWeaponType = 1; + _unit removeHandgunItem _currItem; + [{ + params ["_unit", "", "_switchItem"]; + _unit addHandgunItem _switchItem; + ["CBA_attachmentSwitched", _this] call CBA_fnc_localEvent; + }, [_unit, _currItem, _switchItem, _currWeaponType]] call CBA_fnc_execNextFrame; + }; + case 2; + case (secondaryWeapon _unit): { + private _currWeaponType = 2; + _unit removeSecondaryWeaponItem _currItem; + [{ + params ["_unit", "", "_switchItem"]; + _unit addSecondaryWeaponItem _switchItem; + ["CBA_attachmentSwitched", _this] call CBA_fnc_localEvent; + }, [_unit, _currItem, _switchItem, _currWeaponType]] call CBA_fnc_execNextFrame; + }; + default { + ERROR_1("bad weapon - %1",_this); + _exit = true; + }; +}; +if (_exit) exitWith {}; // Don't notify if the unit isn't the local player or if an invalid weapon was passed + +private _configSwitchItem = configFile >> "CfgWeapons" >> _switchItem; +private _switchItemHintText = getText (_configSwitchItem >> "MRT_SwitchItemHintText"); +private _switchItemHintImage = getText (_configSwitchItem >> "picture"); + +playSound "click"; +if (_switchItemHintText != "") then { + [[_switchItemHintImage, 2.0], [_switchItemHintText], true] call CBA_fnc_notify; +}; diff --git a/addons/common/functions/fnc_switchPersistentLaser.sqf b/addons/common/functions/fnc_switchPersistentLaser.sqf index a2b7b9c1a8d..5c61693c54f 100644 --- a/addons/common/functions/fnc_switchPersistentLaser.sqf +++ b/addons/common/functions/fnc_switchPersistentLaser.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: Dystopian + * Author: Dystopian, johnb43 * Controls persistent laser state. * * Arguments: @@ -17,51 +17,87 @@ params ["_enabled"]; +if (!hasInterface) exitWith {}; + +// Reset state +{ + ACE_player setVariable [QGVAR(laserEnabled_) + str _x, nil]; +} forEach [0, 1, 2]; + if (!_enabled) exitWith { if (isNil QGVAR(laserKeyDownEH)) exitWith {}; - ["KeyDown", GVAR(laserKeyDownEH)] call CBA_fnc_removeDisplayHandler; + + removeUserActionEventHandler ["headlights", "Activate", GVAR(laserKeyDownEH)]; + ["loadout", GVAR(laserLoadoutEH)] call CBA_fnc_removePlayerEventHandler; ["turret", GVAR(laserTurretEH)] call CBA_fnc_removePlayerEventHandler; ["vehicle", GVAR(laserVehicleEH)] call CBA_fnc_removePlayerEventHandler; ["weapon", GVAR(laserWeaponEH)] call CBA_fnc_removePlayerEventHandler; + + GVAR(laserKeyDownEH) = nil; + GVAR(laserLoadoutEH) = nil; + GVAR(laserTurretEH) = nil; + GVAR(laserVehicleEH) = nil; + GVAR(laserWeaponEH) = nil; }; -GVAR(laserKeyDownEH) = ["KeyDown", { - if !((_this select 1) in actionKeys "headlights") exitWith {false}; - private _weapon = currentWeapon ACE_player; +private _fnc_getLightLaserState = { + private _currentWeapon = currentWeapon ACE_player; + + if (_currentWeapon == "") exitWith {}; + + // Ignore in vehicle except FFV + if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {}; + + private _weaponIndex = [ACE_player, _currentWeapon] call FUNC(getWeaponIndex); + + if (_weaponIndex == -1) exitWith {}; + + // Light/laser state only changes in the next frame + // However, as by default changing attachment modes is CTRL + L, the vanilla EH triggers when lights are bound to L (even despite CBA intercepting keystroke) + // Therefore, add an extra frame of delay, after which the previous laser state will have been restored + [{ + ACE_player setVariable [ + QGVAR(laserEnabled_) + str (_this select 1), + ACE_player isIRLaserOn (_this select 0) || {ACE_player isFlashlightOn (_this select 0)} + ]; + }, [_currentWeapon, _weaponIndex], 2] call CBA_fnc_execAfterNFrames; +}; + +// Get current weapon light/laser state +call _fnc_getLightLaserState; + +// Update state every time it's changed +GVAR(laserKeyDownEH) = addUserActionEventHandler ["headlights", "Activate", _fnc_getLightLaserState]; + +// Dropping weapons, as well as switching light/laser attachments turns off lights/lasers +GVAR(lastWeapons) = (getUnitLoadout ACE_player) select [0, 3]; + +// Monitor weapon addition/removal here +GVAR(laserLoadoutEH) = ["loadout", { + params ["_unit", "_loadout"]; + + private _weapons = _loadout select [0, 3]; + + if (_weapons isEqualTo GVAR(lastWeapons)) exitWith {}; + + GVAR(lastWeapons) = _weapons; + [ - { - params ["_weapon", "_laserWasEnabled"]; - private _laserEnabled = ACE_player isIRLaserOn _weapon || {ACE_player isFlashlightOn _weapon}; - if (_laserEnabled && {_laserWasEnabled} || {!_laserEnabled && {!_laserWasEnabled}}) exitWith {}; - private _weaponIndex = [ACE_player, _weapon] call FUNC(getWeaponIndex); - ACE_player setVariable [QGVAR(laserEnabled_) + str _weaponIndex, [nil, true] select _laserEnabled]; - }, - [_weapon, ACE_player isIRLaserOn _weapon || {ACE_player isFlashlightOn _weapon}] - ] call CBA_fnc_execNextFrame; - false -}] call CBA_fnc_addDisplayHandler; - -private _laserEH = { - if (sunOrMoon == 1) exitWith {}; - params ["_player"]; - private _weaponIndex = [_player, currentWeapon _player] call FUNC(getWeaponIndex); - if ( - !(_player getVariable [QGVAR(laserEnabled_) + str _weaponIndex, false]) - || {_weaponIndex > 0 && {"" != primaryWeapon _player}} // Arma switches to primary weapon if exists - || {!(_player call CBA_fnc_canUseWeapon)} // ignore in vehicle except FFV - ) exitWith {}; + _unit, + _unit getVariable [QGVAR(laserEnabled_) + str ([_unit, currentWeapon _unit] call FUNC(getWeaponIndex)), false] + ] call FUNC(setWeaponLightLaserState); +}] call CBA_fnc_addPlayerEventHandler; + +private _fnc_switchPersistentLaserEH = { + params ["_unit"]; + [ - // wait for weapon in "ready to fire" direction - {0.01 > getCameraViewDirection _this vectorDistance (_this weaponDirection currentWeapon _this)}, - {{_this action [_x, _this]} forEach ["GunLightOn", "IRLaserOn"]}, - _player, - 3, - {{_this action [_x, _this]} forEach ["GunLightOn", "IRLaserOn"]} - ] call CBA_fnc_waitUntilAndExecute; + _unit, + _unit getVariable [QGVAR(laserEnabled_) + str ([_unit, currentWeapon _unit] call FUNC(getWeaponIndex)), false] + ] call FUNC(setWeaponLightLaserState); }; -GVAR(laserLoadoutEH) = ["loadout", _laserEH] call CBA_fnc_addPlayerEventHandler; -GVAR(laserTurretEH) = ["turret", _laserEH] call CBA_fnc_addPlayerEventHandler; -GVAR(laserVehicleEH) = ["vehicle", _laserEH] call CBA_fnc_addPlayerEventHandler; -GVAR(laserWeaponEH) = ["weapon", _laserEH] call CBA_fnc_addPlayerEventHandler; +GVAR(laserTurretEH) = ["turret", _fnc_switchPersistentLaserEH] call CBA_fnc_addPlayerEventHandler; +GVAR(laserVehicleEH) = ["vehicle", _fnc_switchPersistentLaserEH] call CBA_fnc_addPlayerEventHandler; +GVAR(laserWeaponEH) = ["weapon", _fnc_switchPersistentLaserEH] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/common/functions/fnc_switchToGroupSide.sqf b/addons/common/functions/fnc_switchToGroupSide.sqf index 94d8c527010..1a3e5888556 100644 --- a/addons/common/functions/fnc_switchToGroupSide.sqf +++ b/addons/common/functions/fnc_switchToGroupSide.sqf @@ -58,7 +58,7 @@ if (_switch) then { private _newGroup = createGroup (_x select 1); [_unit] joinSilent _newGroup; }; - if (count units _currentGroup == 0) then { + if (units _currentGroup isEqualTo []) then { deleteGroup _currentGroup; }; _previousGroupsList set [_forEachIndex, objNull]; diff --git a/addons/common/functions/fnc_throttledPublicVariable.sqf b/addons/common/functions/fnc_throttledPublicVariable.sqf index 3c1ed2761bd..e6b1fdbaf64 100644 --- a/addons/common/functions/fnc_throttledPublicVariable.sqf +++ b/addons/common/functions/fnc_throttledPublicVariable.sqf @@ -29,8 +29,7 @@ if (isNil QGVAR(publishSchedId)) then { { _x params ["_unit", "_varName"]; _unit setVariable [_varName, _unit getVariable _varName, true]; - false - } count GVAR(publishVarNames); + } forEach GVAR(publishVarNames); GVAR(publishVarNames) = []; GVAR(publishNextTime) = 1e7; diff --git a/addons/common/functions/fnc_uniqueItems.sqf b/addons/common/functions/fnc_uniqueItems.sqf index dc783ebbea7..5b2177a3767 100644 --- a/addons/common/functions/fnc_uniqueItems.sqf +++ b/addons/common/functions/fnc_uniqueItems.sqf @@ -1,37 +1,86 @@ #include "..\script_component.hpp" /* - * Author: mharis001 - * Returns list of unique items in a unit's inventory. - * Items are cached if unit is ACE_player. + * Author: mharis001, Blue, Brett Mayson + * Returns list of unique items in the target's inventory. * * Arguments: - * 0: Unit + * 0: Target + * 1: Include magazines + * 0: No (default) + * 1: Yes + * 2: Only magazines * * Return Value: * Items * * Example: - * [player] call ace_common_fnc_uniqueItems + * [player, 2] call ace_common_fnc_uniqueItems * * Public: No */ -params ["_unit"]; +params ["_target", ["_includeMagazines", 0]]; private _fnc_getItems = { - private _items = (getItemCargo uniformContainer _unit) select 0; - _items append ((getItemCargo vestContainer _unit) select 0); - _items append ((getItemCargo backpackContainer _unit) select 0); + private _items = []; - _items arrayIntersect _items + private _inventoryItems = (getItemCargo uniformContainer _target) select 0; + _inventoryItems append ((getItemCargo vestContainer _target) select 0); + _inventoryItems append ((getItemCargo backpackContainer _target) select 0); + + private _magazines = magazines _target; + + _items set [0, _inventoryItems arrayIntersect _inventoryItems]; + _items set [1, _magazines arrayIntersect _magazines]; + + _items }; -// Use cached items list if unit is ACE_player -if (_unit isEqualTo ACE_player) then { +// Cache items list if unit is ACE_player +if (_target isEqualTo ACE_player) then { if (isNil QGVAR(uniqueItemsCache)) then { GVAR(uniqueItemsCache) = call _fnc_getItems; }; - +GVAR(uniqueItemsCache) + + switch (_includeMagazines) do { + case 0: { + GVAR(uniqueItemsCache) select 0 + }; + case 1: { + (GVAR(uniqueItemsCache) select 1) + (GVAR(uniqueItemsCache) select 0) + }; + case 2: { + GVAR(uniqueItemsCache) select 1 + }; + }; } else { - call _fnc_getItems; + if (_target isKindOf "CAManBase") then { + private _items = call _fnc_getItems; + + switch (_includeMagazines) do { + case 0: { + _items select 0 + }; + case 1: { + (_items select 1) + (_items select 0) + }; + case 2: { + _items select 1 + }; + }; + } else { + private _items = switch (_includeMagazines) do { + case 0: { + itemCargo _target + }; + case 1: { + (magazineCargo _target) + (itemCargo _target) + }; + case 2: { + magazineCargo _target + }; + }; + + _items arrayIntersect _items + }; }; diff --git a/addons/common/functions/fnc_unloadPersonLocal.sqf b/addons/common/functions/fnc_unloadPersonLocal.sqf index 0378c6a4b86..24e44fc6797 100644 --- a/addons/common/functions/fnc_unloadPersonLocal.sqf +++ b/addons/common/functions/fnc_unloadPersonLocal.sqf @@ -34,7 +34,7 @@ if (_emptyPos isEqualTo []) then { }; }; -if (count _emptyPos != 3) exitwith { +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); if ((!isNull _unloader) && {[_unloader] call FUNC(isPlayer)}) then { //display text saying there are no safe places to exit the vehicle diff --git a/addons/common/initSettings.inc.sqf b/addons/common/initSettings.inc.sqf index 41fcdafecd5..a784ac64a95 100644 --- a/addons/common/initSettings.inc.sqf +++ b/addons/common/initSettings.inc.sqf @@ -1,5 +1,6 @@ private _category = format ["ACE %1", LLSTRING(DisplayName)]; -private _categoryColors = [_category, format ["| %1 |", LLSTRING(subcategory_colors)]]; +private _categoryColors = [_category, LSTRING(subcategory_colors)]; +private _categorySway = [_category, LSTRING(subcategory_sway)]; [ QGVAR(checkPBOsAction), @@ -87,7 +88,7 @@ private _categoryColors = [_category, format ["| %1 |", LLSTRING(subcategory_col QGVAR(epilepsyFriendlyMode), "CHECKBOX", [LSTRING(EpilepsyFriendlyMode), LSTRING(EpilepsyFriendlyModeTooltip)], - format ["ACE %1", localize LSTRING(DisplayName)], + _category, false, 2 ] call CBA_fnc_addSetting; @@ -96,7 +97,45 @@ private _categoryColors = [_category, format ["| %1 |", LLSTRING(subcategory_col QGVAR(progressBarInfo), "LIST", [LSTRING(progressBarInfoName), LSTRING(progressBarInfoDesc)], - format ["ACE %1", localize LSTRING(DisplayName)], + _category, [[0, 1, 2], [LSTRING(None), LSTRING(progressBarInfoPercentage), LSTRING(progressBarInfoTime)], 2], 0 ] call CBA_fnc_addSetting; + +[ + QGVAR(enableSway), + "CHECKBOX", + [LSTRING(enableSway), LSTRING(enableSway_Description)], + _categorySway, + true, + 1, + {}, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(swayFactor), + "SLIDER", + [LSTRING(SwayFactor), LSTRING(SwayFactor_Description)], + _categorySway, + [0, 5, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(restedSwayFactor), + "SLIDER", + [LSTRING(RestedSwayFactor), LSTRING(RestedSwayFactor_Description)], + _categorySway, + [0, 5, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(deployedSwayFactor), + "SLIDER", + [LSTRING(DeployedSwayFactor), LSTRING(DeployedSwayFactor_Description)], + _categorySway, + [0, 5, 1, 2], + 1 +] call CBA_fnc_addSetting; diff --git a/addons/common/scripts/checkVersionNumber.sqf b/addons/common/scripts/checkVersionNumber.sqf deleted file mode 100644 index 0f2c055500e..00000000000 --- a/addons/common/scripts/checkVersionNumber.sqf +++ /dev/null @@ -1,160 +0,0 @@ -// by commy2 -#include "..\script_component.hpp" - -private _aceWhitelist = missionNamespace getVariable ["ACE_Version_Whitelist", []]; -private _files = CBA_common_addons select { - (_x select [0,3] != "a3_") && - {_x select [0,4] != "ace_"} && - {!((toLower _x) in _aceWhitelist)} -}; - -private _versions = []; -{ - getText (configFile >> "CfgPatches" >> _x >> "version") splitString "." params [["_major", "0"], ["_minor", "0"]]; - private _version = parseNumber _major + parseNumber _minor/100; - _versions set [_forEachIndex, _version]; -} forEach _files; - -if (isServer) then { - ACE_Version_ServerVersions = [_files, _versions]; - publicVariable "ACE_Version_ServerVersions"; -} else { - ACE_Version_ClientVersions = [_files, _versions]; -}; - -// Begin client version check -if (!isServer) then { - // Wait for server to send the servers files and version numbers - waitUntil { - sleep 1; - !isNil "ACE_Version_ClientVersions" && {!isNil "ACE_Version_ServerVersions"} - }; - - private _client = profileName; - - _files = ACE_Version_ClientVersions select 0; - _versions = ACE_Version_ClientVersions select 1; - - private _serverFiles = ACE_Version_ServerVersions select 0; - private _serverVersions = ACE_Version_ServerVersions select 1; - - // Compare client and server files and versions - private _missingAddons = []; - private _oldVersionsClient = []; - private _oldVersionsServer = []; - { - private _serverVersion = _serverVersions select _forEachIndex; - - private _index = _files find _x; - if (_index == -1) then { - if (_x != "ace_server") then {_missingAddons pushBack _x;}; - } else { - - private _clientVersion = _versions select _index; - - if (_clientVersion < _serverVersion) then { - _oldVersionsClient pushBack [_x, _clientVersion, _serverVersion]; - }; - - if (_clientVersion > _serverVersion) then { - _oldVersionsServer pushBack [_x, _clientVersion, _serverVersion]; - }; - }; - } forEach _serverFiles; - - // find client files which the server doesn't have - private _missingAddonsServer = []; - { - private _index = _serverFiles find _x; - if (_index == -1) then { - _missingAddonsServer pushBack _x; - } - } forEach _files; - - // display and log error messages - private _fnc_cutComma = { - private _string = _this; - _string = toArray _string; - - private _count = count _string; - _string set [_count - 2, toArray "." select 0]; - _string set [_count - 1, -1]; - _string = _string - [-1]; - - toString _string; - }; - - private _missingAddon = false; - if (count _missingAddons > 0) then { - _missingAddon = true; - - private _error = format ["[ACE] %1: ERROR client missing addon(s): ", _client]; - { - _error = _error + format ["%1, ", _x]; - - if (_forEachIndex > 9) exitWith {}; - } forEach _missingAddons; - - _error = _error call _fnc_cutComma; - - diag_log text _error; - [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; - [QGVAR(serverLog), _error] call CBA_fnc_serverEvent; - }; - - private _missingAddonServer = false; - if (count _missingAddonsServer > 0) then { - _missingAddonServer = true; - - private _error = format ["[ACE] %1: ERROR server missing addon(s): ", _client]; - { - _error = _error + format ["%1, ", _x]; - - if (_forEachIndex > 9) exitWith {}; - } forEach _missingAddonsServer; - - _error = _error call _fnc_cutComma; - - diag_log text _error; - [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; - [QGVAR(serverLog), _error] call CBA_fnc_serverEvent; - }; - - private _oldVersionClient = false; - if (count _oldVersionsClient > 0) then { - _oldVersionClient = true; - - private _error = format ["[ACE] %1: ERROR outdated client addon(s): ", _client]; - { - _error = _error + format ["%1 (client: %2, server: %3), ", _x select 0, _x select 1, _x select 2]; - - if (_forEachIndex > 9) exitWith {}; - } forEach _oldVersionsClient; - - _error = _error call _fnc_cutComma; - - diag_log text _error; - [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; - [QGVAR(serverLog), _error] call CBA_fnc_serverEvent; - }; - - private _oldVersionServer = false; - if (count _oldVersionsServer > 0) then { - _oldVersionServer = true; - - private _error = format ["[ACE] %1: ERROR outdated server addon(s): ", _client]; - { - _error = _error + format ["%1 (client: %2, server: %3), ", _x select 0, _x select 1, _x select 2]; - - if (_forEachIndex > 9) exitWith {}; - } forEach _oldVersionsServer; - - _error = _error call _fnc_cutComma; - - diag_log text _error; - [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; - [QGVAR(serverLog), _error] call CBA_fnc_serverEvent; - }; - - ACE_Version_ClientErrors = [_missingAddon, _missingAddonServer, _oldVersionClient, _oldVersionServer]; -}; diff --git a/addons/common/stringtable.xml b/addons/common/stringtable.xml index 64d5fc61f39..edc47ccbdf2 100644 --- a/addons/common/stringtable.xml +++ b/addons/common/stringtable.xml @@ -44,7 +44,7 @@ Avancé Fejlett Avanzato - アドバンスド + 高度な 고급 進階 进阶 @@ -402,7 +402,7 @@ [ACE] Itens diversos [ACE] Egyéb tárgyak [ACE] Oggetti vari - [ACE] その他アイテム + [ACE] その他のアイテム [ACE] 기타 물품. [ACE] 雜項 [ACE] 杂项 @@ -498,7 +498,7 @@ 设定当玩家有错误的 PBO 时要如何处理。 Nastavuje jakou akci provést pokud hráč nemá správné PBO. Określa akcję, która ma być podjęta, jeśli gracz nie ma właściwych PBO. - プレイヤーが不正規のPBOを所持している場合の動作を決定します。 + プレイヤーが不正規のPBOを所持している場合の動作を定義します。 Define la accion a tomar si un jugador no tiene el PBO correcto Definisce l'azione che verrà presa se il giocatore non ha gli stessi PBO. Определяет, какое действие будет предпринято, если игрок не имеет корректные PBO. @@ -658,7 +658,7 @@ Az ACE-súgók hátterének színe. A cor de fundo das hints do ACE. ACE によるヒントの背景色を指定します。 - ACE힌트의 배경색을 정합니다. + ACE 힌트의 배경색을 정합니다. 設定ACE提示的背景顏色. 设定 ACE 提示的背景颜色。 @@ -726,7 +726,7 @@ Enable gunlight after weapon switch or vehicle enter/exit if it was previously enabled. Включать ЛЦУ/тактический фонарь после смены оружия или входа/выхода из машины, если он был до этого включен. - 銃のライト等を点けていると武器を切り替えた後や車両を乗り降りしても、ライト等を点けたままにします。 + 銃のライトをつけていた場合、武器の切り替え後または車両の出入り後にライトを再度点灯します。 Abilita la torcia/laser dopo il cambio dell'arma o l'entrata/uscita del veicolo se precedentemente attiva. 이전에 무기의 손전등/레이저를 켠 경우 무기 전환이나 차량 승하차시 켠 상태를 유지합니다. Aktiviert Laserpointer/Taktisches Licht nach einem Waffenwechsel oder dem Auf-/Absitzen, falls es zuvor aktiv war. @@ -1360,7 +1360,7 @@ Non hai più spazio Nincs több hely В инвентаре нет места - インベントリに空きがない + インベントリに空きがありません 넣을 공간이 없습니다 無可用空間 无可用空间 @@ -1406,7 +1406,7 @@ 음악 끄기 허용 允許調低音樂音量 允许调低音乐音量 - 音楽の音量低下を許可 + 音楽音量の低減を許可 Permesso di abbassare la musica Zezwól na przyciszanie muzyki Разрешить приглушение музыки @@ -1422,7 +1422,7 @@ ACE 스크립트가 음악을 끌 수 있습니다. 允許ACE腳本去控制音樂的音量 允许 ACE 脚本去控制音乐的音量。 - ACEのスクリプトに音量低下を許可します。 + ACEのスクリプトに音楽音量の低減を許可します。 Permetti agli script di ACEdi abbassare la musica. Zezwól skrypty ACE na przyciszanie muzyki. Позволить скриптам ACE приглушать музыку @@ -1435,7 +1435,7 @@ Epilepsy friendly mode Epilepsiefreundlicher Modus - けいれん回避モード + てんかん対応モード Tryb dla epileptyków Mode adapté à l'épilepsie Modalità per Epilettici @@ -1448,7 +1448,7 @@ 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. @@ -1464,7 +1464,7 @@ 旗帜(ACE-黑色): 旗幟(ACE-黑色) Bandiera (ACE - Nera) - 旗 (ACE - 黒) + 旗 (ACE - 黒色) Flaga (ACE - Czarna) Флаг (ACE - Черный) Bandeira (ACE - Preto) @@ -1480,7 +1480,7 @@ 旗帜(ACE-白色): 旗幟(ACE-白色) Bandiera (ACE - Bianca) - 旗 (ACE - 白) + 旗 (ACE - 白色) Flaga (ACE - Biała) Флаг (ACE - Белый) Bandeira (ACE - Branco) @@ -1544,7 +1544,7 @@ 在自我互动菜单内显示动作 Pokaż akcje w menu interakcji własnej Mostra a ação no menu de auto-interação - セルフ インタラクションにアクションを表示 + セルフ・インタラクションにアクションを表示します Mostra le azioni nel menu di interazione con se stessi Mostrar la acción en el menú de interacción propio Zobrazit akci v menu vlastních interakcí @@ -1582,7 +1582,7 @@ 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. @@ -1828,5 +1828,126 @@ 下方 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. + + + Release + Отпустить + Soltar + Puść + Položit + Lâcher + Loslassen + Soltar + Lascia + Elengedés + 離す + 놓기 + 放開 + 放开 + Bırak + diff --git a/addons/compat_aegis/$PBOPREFIX$ b/addons/compat_aegis/$PBOPREFIX$ new file mode 100644 index 00000000000..1fc86838473 --- /dev/null +++ b/addons/compat_aegis/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_aegis diff --git a/addons/compat_aegis/compat_aegis_realisticnames/CfgVehicles.hpp b/addons/compat_aegis/compat_aegis_realisticnames/CfgVehicles.hpp new file mode 100644 index 00000000000..19a1bef5104 --- /dev/null +++ b/addons/compat_aegis/compat_aegis_realisticnames/CfgVehicles.hpp @@ -0,0 +1,21 @@ +class CfgVehicles { + class APC_Wheeled_01_base_v2_F; + class B_APC_Wheeled_01_cannon_v2_F: APC_Wheeled_01_base_v2_F { + displayName = ECSTRING(realisticnames,APC_Wheeled_01_cannon_Name); + }; + + class B_APC_Wheeled_01_base_F; + class B_APC_Wheeled_01_medical_F: B_APC_Wheeled_01_base_F { + displayName = SUBCSTRING(APC_Wheeled_01_medical_Name); + }; + + class APC_Tracked_02_medical_base_F; + class O_R_APC_Tracked_02_medical_F: APC_Tracked_02_medical_base_F { + displayName = SUBCSTRING(APC_Tracked_02_medical_Name); + }; + + class APC_Tracked_03_base_v2_F; + class B_A_APC_tracked_03_cannon_v2_F: APC_Tracked_03_base_v2_F { + displayName = ECSTRING(realisticnames,APC_tracked_03_cannon_Name); + }; +}; diff --git a/addons/compat_aegis/compat_aegis_realisticnames/config.cpp b/addons/compat_aegis/compat_aegis_realisticnames/config.cpp new file mode 100644 index 00000000000..add9f50a3a4 --- /dev/null +++ b/addons/compat_aegis/compat_aegis_realisticnames/config.cpp @@ -0,0 +1,26 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "A3_Aegis_Armor_F_Aegis_APC_Wheeled_01", + "A3_Aegis_Armor_F_Aegis_APC_Tracked_02", + "A3_Aegis_Armor_F_Aegis_APC_Tracked_03", + "ace_realisticnames" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + // this prevents any patched class from requiring this addon + addonRootClass = "A3_Characters_F"; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_aegis/compat_aegis_realisticnames/script_component.hpp b/addons/compat_aegis/compat_aegis_realisticnames/script_component.hpp new file mode 100644 index 00000000000..b8d0682fa4f --- /dev/null +++ b/addons/compat_aegis/compat_aegis_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_aegis/compat_aegis_realisticnames/stringtable.xml b/addons/compat_aegis/compat_aegis_realisticnames/stringtable.xml new file mode 100644 index 00000000000..6d7dfa47a12 --- /dev/null +++ b/addons/compat_aegis/compat_aegis_realisticnames/stringtable.xml @@ -0,0 +1,37 @@ + + + + + Badger IFV (Medical) + SPz Badger (Medizin) + Badger IFV (médico) + Badger IFV (sprzęt medyczny) + Badger IFV (zdravotnický) + Badger IFV (médical) + БМП Badger (медицинский) + Badger IFV (médico) + Badger IFV (medico) + バジャー IFV(医療) + 뱃져 보병전투차 (의료) + "蜜獾"步兵戰車(醫療用) + "蜜獾"(医疗) + Badger IFV (Sıhhiye) + + + BM-2T Stalker (Medical) + BM-2T Stalker (Medizin) + BM-2T Stalker (médico) + BM-2T Stalker (sprzęt medyczny) + BM-2T Stalker (zdravotnický) + BM-2T Stalker (médical) + БМ-2Т Сталкер (медицинский) + BM-2T Stalker (médico) + BM-2T Stalker (medico) + BM-2T ストーカー(医療) + BM-2T 스토커 (의료) + BM-2T"潛行者"步兵戰車(醫療用) + BM-2T "潜行者"(医疗) + BM-2T Stalker (Sıhhiye) + + + diff --git a/addons/compat_aegis/compat_aegis_vehicles/CfgVehicles.hpp b/addons/compat_aegis/compat_aegis_vehicles/CfgVehicles.hpp new file mode 100644 index 00000000000..5d0e86faafd --- /dev/null +++ b/addons/compat_aegis/compat_aegis_vehicles/CfgVehicles.hpp @@ -0,0 +1,95 @@ +class CfgVehicles { + class Tank; + class Tank_F: Tank { + class Turrets { + class MainTurret; + }; + }; + + class APC_Tracked_03_base_F: Tank_F { + class Turrets: Turrets { + class MainTurret: MainTurret {}; + }; + }; + class APC_Tracked_03_base_v2_F: APC_Tracked_03_base_F { + class Turrets: Turrets { + class MainTurret: MainTurret { + weapons[] = {"autocannon_40mm_CTWS", "ACE_LMG_coax_L94A1_mem3"}; // Aegis upgrades to a 40mm cannon, but we want realistic MG name + }; + }; + }; + + class MBT_01_base_F: Tank_F { + class Turrets: Turrets { + class MainTurret: MainTurret { + // Overwrite the changes Aegis makes for the .338 coax MG on the Slammer/Merkava + // The idea is: + // 1) keep it as realistic as possible + // 2) easier to overwrite something with skipWhenMissingDependencies than to not overwrite something if another mod is loaded + weapons[] = {"cannon_120mm", "ACE_LMG_coax_MAG58_mem3"}; // Base 1.82: "cannon_120mm","LMG_coax" + magazines[] = { + "24Rnd_120mm_APFSDS_shells_Tracer_Red", + "12Rnd_120mm_HE_shells_Tracer_Red", + "12Rnd_120mm_HEAT_MP_T_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "4Rnd_120mm_LG_cannon_missiles" // Aegis adds laser-guided munitions + }; + }; + }; + }; + + class B_MBT_01_base_F: MBT_01_base_F {}; + class B_MBT_01_cannon_F: B_MBT_01_base_F {}; + class B_MBT_01_TUSK_F: B_MBT_01_cannon_F { + class Turrets: Turrets { + class MainTurret: MainTurret { + weapons[] = {"cannon_120mm", "ACE_LMG_coax_MAG58_mem3"}; // Base 1.82: "cannon_120mm","LMG_coax" + magazines[] = { + "24Rnd_120mm_APFSDS_shells_Tracer_Red", + "12Rnd_120mm_HE_shells_Tracer_Red", + "12Rnd_120mm_HEAT_MP_T_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "200Rnd_762x51_Belt_Red", + "4Rnd_120mm_LG_cannon_missiles" // Aegis adds laser-guided munitions + }; + }; + }; + }; +}; diff --git a/addons/compat_aegis/compat_aegis_vehicles/config.cpp b/addons/compat_aegis/compat_aegis_vehicles/config.cpp new file mode 100644 index 00000000000..fd16fa86865 --- /dev/null +++ b/addons/compat_aegis/compat_aegis_vehicles/config.cpp @@ -0,0 +1,25 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "A3_Aegis_Armor_F_Aegis_MBT_01", + "A3_Aegis_Armor_F_Aegis_APC_Tracked_03", + "ace_vehicles" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + // this prevents any patched class from requiring this addon + addonRootClass = "A3_Characters_F"; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_aegis/compat_aegis_vehicles/script_component.hpp b/addons/compat_aegis/compat_aegis_vehicles/script_component.hpp new file mode 100644 index 00000000000..17370c415fd --- /dev/null +++ b/addons/compat_aegis/compat_aegis_vehicles/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT vehicles +#define SUBCOMPONENT_BEAUTIFIED Vehicles +#include "..\script_component.hpp" diff --git a/addons/compat_aegis/config.cpp b/addons/compat_aegis/config.cpp new file mode 100644 index 00000000000..2de723b9a48 --- /dev/null +++ b/addons/compat_aegis/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"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + // this prevents any patched class from requiring this addon + addonRootClass = "A3_Characters_F"; + }; +}; diff --git a/addons/compat_aegis/script_component.hpp b/addons/compat_aegis/script_component.hpp new file mode 100644 index 00000000000..d6fb73bd462 --- /dev/null +++ b/addons/compat_aegis/script_component.hpp @@ -0,0 +1,5 @@ +#define COMPONENT compat_aegis +#define COMPONENT_BEAUTIFIED Aegis Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/compat_csla/compat_csla_explosives/CfgMagazines.hpp b/addons/compat_csla/compat_csla_explosives/CfgMagazines.hpp index b29f7e717dc..0c8a8aa6fd8 100644 --- a/addons/compat_csla/compat_csla_explosives/CfgMagazines.hpp +++ b/addons/compat_csla/compat_csla_explosives/CfgMagazines.hpp @@ -1,15 +1,15 @@ class CfgMagazines { class US85_Magazine; class US85_ATMine_mag: US85_Magazine { - EGVAR(explosives,SetupObject) = "ACE_Explosives_Place_US85_ATMine_mag"; + 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"; + 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"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_US85_SatchelCharge_Mag"; useAction = 0; }; }; diff --git a/addons/compat_cup_terrains/CfgVehicles.hpp b/addons/compat_cup_terrains/CfgVehicles.hpp index 08176b77fed..3fbd69f2913 100644 --- a/addons/compat_cup_terrains/CfgVehicles.hpp +++ b/addons/compat_cup_terrains/CfgVehicles.hpp @@ -1,3 +1,6 @@ +class CBA_Extended_EventHandlers; +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} + class CfgVehicles { class House; class House_Small_F; @@ -5,7 +8,7 @@ class CfgVehicles { class House_EP1: House {}; class Land_Benzina_schnell: House { - transportFuel = 0; + 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 { @@ -18,22 +21,22 @@ class CfgVehicles { }; }; class Land_A_FuelStation_Feed: Strategic { - transportFuel = 0; + 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 { - transportFuel = 0; + 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 { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class FuelStation: House_Small_F { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{1.25, .2, -1.1}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; class ACE_Actions { @@ -45,4 +48,9 @@ class CfgVehicles { }; }; }; + class WarfareBBaseStructure; + class Base_WarfareBVehicleServicePoint: WarfareBBaseStructure { + // "vehicle service point" (a conex /w barrels) - need hooks??? + XEH_INHERITED; + }; }; diff --git a/addons/compat_cup_units/CfgGlasses.hpp b/addons/compat_cup_units/CfgGlasses.hpp new file mode 100644 index 00000000000..1620f74212b --- /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/config.cpp b/addons/compat_cup_units/config.cpp index bde1052a110..c3ba110e742 100644 --- a/addons/compat_cup_units/config.cpp +++ b/addons/compat_cup_units/config.cpp @@ -15,4 +15,5 @@ class CfgPatches { }; }; +#include "CfgGlasses.hpp" #include "CfgWeapons.hpp" diff --git a/addons/compat_cup_vehicles/CfgVehicles.hpp b/addons/compat_cup_vehicles/CfgVehicles.hpp index 47c7f901f5e..ce502abad53 100644 --- a/addons/compat_cup_vehicles/CfgVehicles.hpp +++ b/addons/compat_cup_vehicles/CfgVehicles.hpp @@ -1,4 +1,31 @@ class CfgVehicles { + class CUP_nHMMWV_Base; + class CUP_nM1025_SOV_Base: CUP_nHMMWV_Base { + class EGVAR(interaction,anims) { + class hide_backpacks { + positions[] = { + "(_target selectionPosition ['vhc_backpacks', 'ViewGeometry', 'AveragePoint']) vectorAdd [-1, 0, 0]", + "(_target selectionPosition ['vhc_backpacks', 'ViewGeometry', 'AveragePoint']) vectorAdd [1.3, 0, 0]" + }; + items[] = {"CUP_B_USPack_Coyote", "CUP_B_USPack_Coyote", "CUP_B_AssaultPack_ACU", "CUP_B_AssaultPack_ACU", "CUP_B_AssaultPack_Coyote"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; + + class Car_F; + class CUP_ECVHMMWV_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_deploy2 { + positions[] = {"(_target selectionPosition ['vhc_rear_trunk_door', 'FireGeometry', 'AveragePoint']) vectorAdd [-0.7, 0, 0]"}; + items[] = {"CUP_B_USPack_Coyote", "CUP_B_AssaultPack_ACU"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; + class CUP_MTVR_Base; class CUP_MTVR_Reammo_Base: CUP_MTVR_Base { EGVAR(rearm,defaultSupply) = 1200; @@ -106,6 +133,17 @@ class CfgVehicles { class CUP_BTR90_HQ_Base: CUP_BTR90_Base { delete ace_viewports; }; // no cargo seats class Tank_F; + class CUP_AAV_Base: Tank_F { + class EGVAR(interaction,anims) { + class Hide_Bags_Deployment { + positions[] = {{1.7, -0.7, -0.3}, {1.7, -2.55, -0.3}}; + items[] = {"CUP_B_USPack_Coyote", "CUP_B_USPack_Coyote"}; + name = "$STR_CUP_dn_USpack_coyote"; + text = "$STR_CUP_dn_USpack_coyote"; + }; + }; + }; + class CUP_M2Bradley_Base: Tank_F { ace_hunterkiller = 1; class ace_viewports { @@ -148,5 +186,141 @@ class CfgVehicles { 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/compat_cup_repair/CfgVehicles.hpp b/addons/compat_cup_vehicles/compat_cup_repair/CfgVehicles.hpp new file mode 100644 index 00000000000..29a471f4516 --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_repair/CfgVehicles.hpp @@ -0,0 +1,196 @@ +class CfgVehicles { + class Car_F; + class CUP_Datsun_Base: Car_F { + class EGVAR(interaction,anims) { + class hideSpareTire { + positions[] = {{-0.23, -0.25, -0.8}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class CUP_Datsun_AA_Base: CUP_Datsun_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hideSpareTire: hideSpareTire { + enabled = 0; + }; + }; + }; + + class CUP_Tigr_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_ReserveWheel { + positions[] = {{0.57, -2.3, -0.55}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class CUP_Tigr_STS_PK_Base: CUP_Tigr_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_ReserveWheel: hide_ReserveWheel {}; + }; + }; + class CUP_Tigr_233014_PK_Base: CUP_Tigr_STS_PK_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_ReserveWheel: hide_ReserveWheel { + positions[] = {{0.57, -2.3, -0.85}}; + }; + }; + }; + class CUP_Tigr_M_PK_Base: CUP_Tigr_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_ReserveWheel: hide_ReserveWheel {}; + }; + }; + class CUP_Tigr_233114_PK_Base: CUP_Tigr_M_PK_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_ReserveWheel: hide_ReserveWheel { + positions[] = {{0.57, -2.3, -0.85}}; + }; + }; + }; + + class CUP_LR_Base: Car_F { + class EGVAR(interaction,anims) { + class selection_wheelfront { + positions[] = {"_target selectionPosition ['selection_wheelfront', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + class selection_wheels { + positions[] = { + "(_target selectionPosition ['selection_wheels', 'ViewGeometry', 'AveragePoint']) vectorAdd [-1.1, 0, 0]", + "(_target selectionPosition ['selection_wheels', 'ViewGeometry', 'AveragePoint']) vectorAdd [1.1, 0, 0]" + }; + items[] = {"ACE_Wheel", "ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class CUP_nHMMWV_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_spare_wheel { + positions[] = {"_target selectionPosition ['vhc_spare_wheel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + // Don't inherit, as it's easier for the main compat + class CUP_nM1025_SOV_Base: CUP_nHMMWV_Base { + class EGVAR(interaction,anims) { + class hide_spare_wheel { + positions[] = {"_target selectionPosition ['vhc_spare_wheel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class CUP_RG31_BASE: Car_F { + class EGVAR(interaction,anims) { + class left_spare { + positions[] = {"_target selectionPosition ['left_spare', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + class right_spare { + positions[] = {"_target selectionPosition ['right_spare', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class CUP_UAZ_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_spare_wheel { + positions[] = {"_target selectionPosition ['spare_wheel', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class CUP_UAZ_Armed_Base: CUP_UAZ_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel {}; + }; + }; + class CUP_UAZ_AA_Base: CUP_UAZ_Armed_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel { + positions[] = {{0.18, -1.8, 0.75}}; + }; + }; + }; + class CUP_UAZ_AGS30_Base: CUP_UAZ_Armed_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel { + positions[] = {{0.18, -1.9, 0.75}}; + }; + }; + }; + class CUP_UAZ_MG_Base: CUP_UAZ_Armed_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel { + positions[] = {{0.18, -1.9, 0.2}}; + }; + }; + }; + // Visual is bugged, but it works + class CUP_UAZ_METIS_Base: CUP_UAZ_Armed_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel { + positions[] = {{0.18, -1.9, 0.65}}; + }; + }; + }; + class CUP_UAZ_SPG9_Base: CUP_UAZ_Armed_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel { + positions[] = {{0.18, -1.9, 1.05}}; + }; + }; + }; + + class CUP_UAZ_Unarmed_Base: CUP_UAZ_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel {}; + }; + }; + class CUP_UAZ_Open_Base: CUP_UAZ_Unarmed_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel { + positions[] = {{0.135, -1.3, 0.7}}; + }; + }; + }; + + class CUP_ECVHMMWV_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_spare_tire { + positions[] = {"(_target selectionPosition ['vhc_rear_trunk_door', 'FireGeometry', 'AveragePoint']) vectorAdd [0.05, -0.4, 0.2]"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + class hide_deploy1 { + positions[] = {"(_target selectionPosition ['vhc_rear_trunk_door', 'FireGeometry', 'AveragePoint']) vectorAdd [0.05, 0.5, 0.7]"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; +}; diff --git a/addons/compat_cup_vehicles/compat_cup_repair/config.cpp b/addons/compat_cup_vehicles/compat_cup_repair/config.cpp new file mode 100644 index 00000000000..9a2785e7ef2 --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_repair/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_repair" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_repair/script_component.hpp b/addons/compat_cup_vehicles/compat_cup_repair/script_component.hpp new file mode 100644 index 00000000000..1af928486c3 --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_repair/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT repair +#define SUBCOMPONENT_BEAUTIFIED Repair +#include "..\script_component.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_trenches/CfgVehicles.hpp b/addons/compat_cup_vehicles/compat_cup_trenches/CfgVehicles.hpp new file mode 100644 index 00000000000..9d9bc2d62ee --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_trenches/CfgVehicles.hpp @@ -0,0 +1,111 @@ +class CfgVehicles { + class Car_F; + class CUP_Tigr_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_tools { + positions[] = {{1.15, -1.5, -0.68}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class CUP_Tigr_STS_PK_Base: CUP_Tigr_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools: hide_tools {}; + }; + }; + class CUP_Tigr_233014_PK_Base: CUP_Tigr_STS_PK_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools: hide_tools { + positions[] = {{1.15, -1.5, -1}}; + }; + }; + }; + class CUP_Tigr_M_PK_Base: CUP_Tigr_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools: hide_tools {}; + }; + }; + class CUP_Tigr_233114_PK_Base: CUP_Tigr_M_PK_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools: hide_tools { + positions[] = {{1.15, -1.5, -1}}; + }; + }; + }; + + // Interaction added to both sides, as the whole vehicle is mirrored if in left/right side + class CUP_LR_Base: Car_F { + class EGVAR(interaction,anims) { + class selection_tool { + positions[] = {{-0.53, 1.65, -0.2}, {0.53, 1.65, -0.2}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class CUP_LR_MG_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_tool: selection_tool { + positions[] = {{-0.6, 1.4, 1.4}, {0.45, 1.4, 1.4}}; + }; + }; + }; + class CUP_LR_SPG9_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_tool: selection_tool {}; + }; + }; + class CUP_LR_AA_Base: CUP_LR_SPG9_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_tool: selection_tool { + positions[] = {{-0.55, 1.77, -0.75}, {0.55, 1.77, -0.75}}; + }; + }; + }; + class CUP_LR_Ambulance_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_tool: selection_tool { + positions[] = {{-0.55, 2.1, -0.2}, {0.55, 2.1, -0.2}}; + }; + }; + }; + class CUP_LR_Special_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_tool: selection_tool { + positions[] = {{-0.6, 1.4, 1.4}, {0.45, 1.4, 1.4}}; + }; + }; + }; + + class CUP_ECVHMMWV_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_front_tool_rack { + positions[] = {"(_target selectionPosition ['vhc_rear_trunk_door', 'FireGeometry', 'AveragePoint']) vectorAdd [0.37, 4, 0.2]"}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + + class Tank_F; + class CUP_leopard_1A3_base: Tank_F { + class EGVAR(interaction,anims) { + class hide_Tools_L { + positions[] = {{-2.2, 0, 0.2}, {-2.2, -1.8, 0.2}}; + items[] = {"ACE_EntrenchingTool", "ACE_wirecutter"}; + name = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + text = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + }; + class hide_Tools_R { + positions[] = {{0.9, -1.5, 0.23}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; +}; diff --git a/addons/compat_cup_vehicles/compat_cup_trenches/config.cpp b/addons/compat_cup_vehicles/compat_cup_trenches/config.cpp new file mode 100644 index 00000000000..8f05885bd6f --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_trenches/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_trenches" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_trenches/script_component.hpp b/addons/compat_cup_vehicles/compat_cup_trenches/script_component.hpp new file mode 100644 index 00000000000..10b90eb71e5 --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_trenches/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT trenches +#define SUBCOMPONENT_BEAUTIFIED Trenches +#include "..\script_component.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/config.cpp b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/config.cpp index 1abe0de6ea6..10eb5da69f0 100644 --- a/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/config.cpp +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/config.cpp @@ -15,6 +15,8 @@ class CfgPatches { authors[] = {"Community Upgrade Project", "Mike"}; url = ECSTRING(main,URL); VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); }; }; diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp index 186690908c2..60a83030df2 100644 --- a/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp @@ -1,36 +1,117 @@ class CfgVehicles { class CUP_T810_Unarmed_Base; class CUP_T810_Refuel_Base: CUP_T810_Unarmed_Base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-1.01, 0.21, -0.5},{1.08, 0.2, -0.5}}; EGVAR(refuel,fuelCargo) = 10000; }; class Truck_02_fuel_base_F; class CUP_Kamaz_5350_Refuel_Base: Truck_02_fuel_base_F { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.02, -3.33, -1.05}}; EGVAR(refuel,fuelCargo) = 10000; }; class CUP_Ural_Support_Base; class CUP_Ural_Refuel_Base: CUP_Ural_Support_Base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.05, -3.65, -0.42}}; EGVAR(refuel,fuelCargo) = 10000; }; class CUP_V3S_Open_Base; class CUP_V3S_Refuel_Base: CUP_V3S_Open_Base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.35, -3.35, -0.4},{0.40, -3.35, -0.4}}; EGVAR(refuel,fuelCargo) = 6500; }; class CUP_MTVR_Base; class CUP_MTVR_Refuel_Base: CUP_MTVR_Base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-1.09, -0.01, -0.5},{1, -0.01, -0.5}}; EGVAR(refuel,fuelCargo) = 10000; }; + + class Car_F; + class CUP_LR_Base: Car_F { + class EGVAR(interaction,anims) { + class selection_jerry { + positions[] = {{-0.65, 2.7, -0.55}, {0.65, 2.7, -0.55}, {-1, -0.25, -0.75}, {1, -0.25, -0.75}}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class CUP_LR_MG_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_jerry: selection_jerry { + positions[] = {{-0.55, 2.45, 1.05}, {0.55, 2.45, 1.05}, {-1, -0.53, 0.9}, {1, -0.53, 0.9}}; + }; + }; + }; + class CUP_LR_SPG9_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_jerry: selection_jerry {}; + }; + }; + class CUP_LR_AA_Base: CUP_LR_SPG9_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_jerry: selection_jerry { + positions[] = {{-0.65, 2.8, -1.1}, {0.65, 2.8, -1.1}, {-1, -0.15, -1.3}, {1, -0.15, -1.3}}; + }; + }; + }; + class CUP_LR_Ambulance_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_jerry: selection_jerry { + positions[] = {{-0.65, 3.1, -0.55}, {0.65, 3.1, -0.55}}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + }; + }; + class CUP_LR_Special_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_jerry: selection_jerry { + positions[] = {{-0.7, 2.45, 1.05}, {0.55, 2.45, 1.05}}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + }; + }; + + class CUP_nHMMWV_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_jerrycans { + positions[] = {"(_target selectionPosition 'vhc_jerrycans') vectorAdd [0, 0, 0.15]"}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + // Don't inherit, as it's easier for the main compat + class CUP_nM1025_SOV_Base: CUP_nHMMWV_Base { + class EGVAR(interaction,anims) { + class hide_jerrycans { + positions[] = {"(_target selectionPosition 'vhc_jerrycans') vectorAdd [0, 0, 0.15]"}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class hide_rear_rack_content { + positions[] = {"_target selectionPosition ['vhc_rear_rack_content', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + class CUP_ECVHMMWV_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_jerrycans { + positions[] = {"(_target selectionPosition ['vhc_rear_trunk_door', 'FireGeometry', 'AveragePoint']) vectorAdd [-0.85, -0.22, -0.1]"}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; }; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgVehicles.hpp b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgVehicles.hpp index 29322b58868..c96253ec51c 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgVehicles.hpp +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgVehicles.hpp @@ -19,7 +19,7 @@ class CfgVehicles { magazineLocation = "_target selectionPosition 'otochlaven'"; proxyWeapon = "CUP_proxy_mortar_82mm"; disassembleWeapon = "CUP_2b14_carry"; - disassembleTurret = "ace_csw_mortarBaseplate"; + disassembleTurret = QEGVAR(csw,mortarBaseplate); desiredAmmo = 1; ammoLoadTime = 3; ammoUnloadTime = 3; @@ -29,14 +29,14 @@ class CfgVehicles { class CUP_M252_base: CUP_2b14_82mm_Base { class ace_csw: ace_csw { disassembleWeapon = "CUP_m252_carry"; - disassembleTurret = "ace_csw_mortarBaseplate"; + disassembleTurret = QEGVAR(csw,mortarBaseplate); }; }; class CUP_L16A2_base: CUP_M252_base { class ace_csw: ace_csw { disassembleWeapon = "CUP_l16a2_carry"; - disassembleTurret = "ace_csw_mortarBaseplate"; + disassembleTurret = QEGVAR(csw,mortarBaseplate); }; }; @@ -47,7 +47,7 @@ class CfgVehicles { proxyWeapon = "CUP_proxy_m2"; magazineLocation = "_target selectionPosition 'magazine'"; disassembleWeapon = "CUP_m2_carry"; - disassembleTurret = "ace_csw_m3Tripod"; + disassembleTurret = QEGVAR(csw,m3Tripod); desiredAmmo = 100; ammoLoadTime = 10; ammoUnloadTime = 8; @@ -57,7 +57,7 @@ class CfgVehicles { class CUP_M2StaticMG_MiniTripod_base: CUP_M2StaticMG_base { class ace_csw: ace_csw { enabled = 1; - disassembleTurret = "ace_csw_m3TripodLow"; + disassembleTurret = QEGVAR(csw,m3TripodLow); }; }; @@ -65,9 +65,9 @@ class CfgVehicles { class ace_csw { enabled = 1; proxyWeapon = "CUP_proxy_DSHKM"; - magazineLocation = "_target selectionPosition 'magazine'"; + magazineLocation = "_target selectionPosition 'otocvez'"; disassembleWeapon = "CUP_DSHKM_carry"; - disassembleTurret = "ace_csw_kordTripod"; + disassembleTurret = QEGVAR(csw,kordTripod); desiredAmmo = 100; ammoLoadTime = 10; ammoUnloadTime = 8; @@ -87,7 +87,7 @@ class CfgVehicles { proxyWeapon = "CUP_proxy_KORD"; magazineLocation = "_target selectionPosition 'magazine'"; disassembleWeapon = "CUP_KORD_carry"; - disassembleTurret = "ace_csw_kordTripod"; + disassembleTurret = QEGVAR(csw,kordTripod); desiredAmmo = 100; ammoLoadTime = 10; ammoUnloadTime = 8; @@ -97,7 +97,7 @@ class CfgVehicles { class CUP_KORD_MiniTripod_Base: CUP_KORD_Base { class ace_csw: ace_csw { enabled = 1; - disassembleTurret = "ace_csw_kordTripodLow"; + disassembleTurret = QEGVAR(csw,kordTripodLow); }; }; @@ -108,7 +108,7 @@ class CfgVehicles { proxyWeapon = "CUP_proxy_AGS30"; magazineLocation = "_target selectionPosition 'otochlaven'"; disassembleWeapon = "CUP_AGS30_carry"; - disassembleTurret = "ace_csw_sag30Tripod"; + disassembleTurret = QEGVAR(csw,sag30Tripod); desiredAmmo = 29; ammoLoadTime = 10; ammoUnloadTime = 8; @@ -119,17 +119,17 @@ class CfgVehicles { class ace_csw { enabled = 1; proxyWeapon = "CUP_proxy_MK19"; - magazineLocation = "_target selectionPosition 'magazine'"; + magazineLocation = "_target selectionPosition 'otochlaven'"; disassembleWeapon = "CUP_MK19_carry"; - disassembleTurret = "ace_csw_m3TripodLow"; + disassembleTurret = QEGVAR(csw,m3TripodLow); desiredAmmo = 48; ammoLoadTime = 10; ammoUnloadTime = 8; }; }; - class AT_01_base_F; - class CUP_Metis_Base: AT_01_base_F { + class StaticATWeapon; + class CUP_Metis_Base: StaticATWeapon { class ace_csw { enabled = 1; proxyWeapon = "CUP_proxy_AT13"; @@ -142,14 +142,13 @@ class CfgVehicles { }; }; - class StaticATWeapon; 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"; + disassembleTurret = QEGVAR(csw,m220Tripod); desiredAmmo = 1; ammoLoadTime = 8; ammoUnloadTime = 5; @@ -166,9 +165,9 @@ class CfgVehicles { class ace_csw { enabled = 1; proxyWeapon = "CUP_proxy_SPG9"; - magazineLocation = "_target selectionPosition 'otochlaven'"; + magazineLocation = "_target selectionPosition 'handle'"; disassembleWeapon = "CUP_SPG9_carry"; - disassembleTurret = "ace_csw_spg9Tripod"; + disassembleTurret = QEGVAR(csw,spg9Tripod); desiredAmmo = 1; ammoLoadTime = 5; ammoUnloadTime = 3; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgWeapons.hpp b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgWeapons.hpp index 3e162335681..56213219040 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgWeapons.hpp +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgWeapons.hpp @@ -15,7 +15,7 @@ class CfgWeapons { deployTime = 20; pickupTime = 25; class assembleTo { - ace_csw_mortarBaseplate = "CUP_O_2b14_82mm_RU"; + ace_csw_mortarBaseplate = "CUP_I_2b14_82mm_AAF"; }; }; class WeaponSlotsInfo: WeaponSlotsInfo { @@ -31,7 +31,7 @@ class CfgWeapons { picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\M252\data\ui\icomap_mortar_m251_ca.paa"; class ace_csw: ace_csw { class assembleTo { - ace_csw_mortarBaseplate = "CUP_B_M252_US"; + ace_csw_mortarBaseplate = "CUP_I_M252_AAF"; }; }; }; @@ -42,7 +42,7 @@ class CfgWeapons { picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\M252\data\ui\icomap_mortar_m251_ca.paa"; class ace_csw: ace_csw { class assembleTo { - ace_csw_mortarBaseplate = "CUP_B_L16A2_BAF_MPT"; + ace_csw_mortarBaseplate = "CUP_I_L16A2_AAF"; }; }; }; @@ -58,8 +58,9 @@ class CfgWeapons { deployTime = 4; pickupTime = 4; class assembleTo { - ace_csw_m3Tripod = "CUP_B_M2StaticMG_US"; - ace_csw_m3TripodLow = "CUP_B_M2StaticMG_MiniTripod_US"; + ace_csw_m3Tripod = "CUP_I_M2StaticMG_AAF"; + ace_csw_m3TripodLow = "CUP_I_M2StaticMG_MiniTripod_AAF"; + EGVAR(compat_spe,m3Tripod) = "CUP_I_M2StaticMG_MiniTripod_AAF"; }; }; class WeaponSlotsInfo: WeaponSlotsInfo { @@ -81,8 +82,8 @@ class CfgWeapons { deployTime = 4; pickupTime = 4; class assembleTo { - ace_csw_kordTripod = "CUP_O_DSHKM_ChDKZ"; - ace_csw_kordTripodLow = "CUP_O_DSHkM_MiniTriPod_ChDKZ"; + ace_csw_kordTripod = "CUP_I_DSHKM_AAF"; + ace_csw_kordTripodLow = "CUP_I_DSHKM_MiniTriPod_AAF"; }; }; class WeaponSlotsInfo: WeaponSlotsInfo { @@ -104,8 +105,8 @@ class CfgWeapons { deployTime = 4; pickupTime = 4; class assembleTo { - ace_csw_kordTripod = "CUP_O_KORD_high_RU"; - ace_csw_kordTripodLow = "CUP_O_KORD_RU"; + ace_csw_kordTripod = "CUP_I_KORD_high_AAF"; + ace_csw_kordTripodLow = "CUP_I_KORD_AAF"; }; }; class WeaponSlotsInfo: WeaponSlotsInfo { @@ -127,7 +128,7 @@ class CfgWeapons { deployTime = 4; pickupTime = 4; class assembleTo { - ace_csw_sag30Tripod = "CUP_O_AGS_RU"; + ace_csw_sag30Tripod = "CUP_I_AGS_AAF"; }; }; class WeaponSlotsInfo: WeaponSlotsInfo { @@ -149,7 +150,7 @@ class CfgWeapons { deployTime = 4; pickupTime = 4; class assembleTo { - ace_csw_m3TripodLow = "CUP_B_MK19_TriPod_US"; + ace_csw_m3TripodLow = "CUP_I_MK19_TriPod_AAF"; }; }; class WeaponSlotsInfo: WeaponSlotsInfo { @@ -168,7 +169,7 @@ class CfgWeapons { type = "mount"; deployTime = 4; pickupTime = 4; - deploy = "CUP_O_Metis_RU"; + deploy = "CUP_I_Metis_AAF"; }; class WeaponSlotsInfo: WeaponSlotsInfo { mass = 300; @@ -186,7 +187,7 @@ class CfgWeapons { deployTime = 4; pickupTime = 4; class assembleTo { - ace_csw_m220Tripod = "CUP_B_TOW_TriPod_US"; + ace_csw_m220Tripod = "CUP_I_TOW_TriPod_AAF"; }; }; class WeaponSlotsInfo: WeaponSlotsInfo { @@ -200,7 +201,7 @@ class CfgWeapons { class CUP_TOW2_carry: CUP_TOW_carry { class ace_csw: ace_csw { class assembleTo { - ace_csw_m220Tripod = "CUP_B_TOW2_TriPod_US"; + ace_csw_m220Tripod = "CUP_I_TOW2_TriPod_AAF"; }; }; }; @@ -216,7 +217,7 @@ class CfgWeapons { deployTime = 4; pickupTime = 4; class assembleTo { - ace_csw_spg9Tripod = "CUP_B_SPG9_CDF"; + ace_csw_spg9Tripod = "CUP_I_SPG9_AAF"; }; }; class WeaponSlotsInfo: WeaponSlotsInfo { @@ -257,12 +258,12 @@ class CfgWeapons { magazineReloadTime = 0.5; }; - class CUP_Vmlauncher_AT13_single_veh; + 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_Vmlauncher_TOW_single_veh; class CUP_proxy_TOW: CUP_Vmlauncher_TOW_single_veh { magazineReloadTime = 0.5; }; @@ -272,7 +273,7 @@ class CfgWeapons { magazineReloadTime = 0.5; }; - class CUP_Vcannon_M119_veh; + class CUP_Vcannon_M119_veh; class CUP_proxy_M119: CUP_Vcannon_M119_veh { magazineReloadTime = 0.5; }; @@ -287,4 +288,3 @@ class CfgWeapons { magazineReloadTime = 0.5; }; }; - diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml b/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml index fdfcc374361..86e56ee3d90 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml @@ -4,70 +4,179 @@ [CSW] AGS30 Belt [CSW] AGS30 ベルト + [CSW] Лента AGS 30 + [CSW] AGS-30 벨트 + [CSW] AGS30 Gurt + [CSW] Cinta de AGS30 + [CSW] Nastro AGS30 + [CSW] Cinto de AGS30 + [CSW] Ceinture AGS30 [CSW] MK19 Belt [CSW] Mk19 ベルト + [CSW] Лента Mk19 + [CSW] Mk.19 벨트 + [CSW] MK19 Gurt + [CSW] Cinta de MK19 + [CSW] Nastro MK19 + [CSW] Cinto de MK19 + [CSW] Ceinture MK19 [CSW] TOW Tube [CSW] TOW チューブ + [CSW] Туба TOW + [CSW] TOW 튜브 + [CSW] TOW Rohr + [CSW] Tubo de TOW + [CSW] Tubo TOW + [CSW] Tubo de TOW + [CSW] Tube TOW [CSW] TOW2 Tube [CSW] TOW2 チューブ + [CSW] Туба TOW-2 + [CSW] TOW2 튜브 + [CSW] TOW2 Rohr + [CSW] Tubo de TOW2 + [CSW] Tubo TOW2 + [CSW] Tubo de TOW2 + [CSW] Tube 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] Cartucho PG-9 + [CSW] Projectile 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] Cartucho OG-9 + [CSW] Projectile 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] M84 Fumígeno [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 index 1658715ddbd..eeb7e6037f2 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgAmmo.hpp +++ b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgAmmo.hpp @@ -4,18 +4,18 @@ class CfgAmmo { hit = 3000; indirectHit = 3000; indirectHitRange = 5; - ace_explosives_explodeOnDefuse = 0.02; + EGVAR(explosives,explodeOnDefuse) = 0.02; }; class CUP_PipeBomb_Ammo: PipeBombBase { hit = 3000; indirectHit = 3000; indirectHitRange = 5; - ace_explosives_explodeOnDefuse = 0.02; + EGVAR(explosives,explodeOnDefuse) = 0.02; }; class CUP_Mine_Ammo; class CUP_IED_V1_Ammo: CUP_Mine_Ammo { - ace_explosives_explodeOnDefuse = 0.06; + EGVAR(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 index 15df2f73335..51dc9d0d781 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgMagazines.hpp +++ b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgMagazines.hpp @@ -2,9 +2,9 @@ class CfgMagazines { class CA_Magazine; class CUP_TimeBomb_M: CA_Magazine { scope = 1; - ace_explosives_placeable = 1; + EGVAR(explosives,placeable) = 1; useAction = 0; - ace_explosives_setupObject = "ACE_PipeBomb_place_CUP"; + EGVAR(explosives,setupObject) = "ACE_PipeBomb_place_CUP"; class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch", "Cellphone"}; class Timer { @@ -16,9 +16,9 @@ class CfgMagazines { }; }; class CUP_Mine_M: CUP_TimeBomb_M { - ace_explosives_placeable = 1; + EGVAR(explosives,placeable) = 1; useAction = 0; - ace_explosives_setupObject = "ACE_Mine_place_CUP"; + EGVAR(explosives,setupObject) = "ACE_Mine_place_CUP"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -27,9 +27,9 @@ class CfgMagazines { }; }; class CUP_MineE_M: CUP_TimeBomb_M { - ace_explosives_placeable = 1; + EGVAR(explosives,placeable) = 1; useAction = 0; - ace_explosives_setupObject = "ACE_MineE_place_CUP"; + EGVAR(explosives,setupObject) = "ACE_MineE_place_CUP"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -39,20 +39,20 @@ class CfgMagazines { }; class CUP_IED_V1_M: CUP_Mine_M { - ace_explosives_placeable = 1; + EGVAR(explosives,placeable) = 1; useAction = 0; - ace_explosives_setupObject = "ACE_IED_V1_place_CUP"; + EGVAR(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"; + EGVAR(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"; + EGVAR(explosives,setupObject) = "ACE_IED_V3_place_CUP"; class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch", "Cellphone", "PressurePlate"}; class Timer { @@ -77,7 +77,7 @@ class CfgMagazines { }; class CUP_IED_V4_M: CUP_IED_V1_M { useAction = 0; - ace_explosives_setupObject = "ACE_IED_V4_place_CUP"; + EGVAR(explosives,setupObject) = "ACE_IED_V4_place_CUP"; class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch", "Cellphone", "PressurePlate"}; class Timer { diff --git a/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgVehicles.hpp b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgVehicles.hpp index d10c315c3d7..17a7c59848e 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgVehicles.hpp +++ b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgVehicles.hpp @@ -1,32 +1,31 @@ class CfgVehicles { class ACE_Explosives_Place; class ACE_PipeBomb_place_CUP: ACE_Explosives_Place { - displayName = "Satchel Charge"; + displayName = "$STR_CUP_dn_PipeBomb"; 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"; + displayName = "$STR_CUP_dn_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"; + displayName = "$STR_CUP_dn_MineE"; 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"; + displayName = "$STR_A3_CfgVehicles_IEDUrbanSmall_F"; 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 { + displayName = "$STR_A3_CfgVehicles_IEDUrbanBig_F"; model = "\CUP\Weapons\CUP_Weapons_Put\CUP_IED_V2.p3d"; }; class ACE_IED_V3_place_CUP: ACE_IED_V1_place_CUP { + displayName = "$STR_A3_CfgVehicles_IEDLandSmall_F"; model = "\CUP\Weapons\CUP_Weapons_Put\CUP_IED_V3.p3d"; }; class ACE_IED_V4_place_CUP: ACE_IED_V1_place_CUP { + displayName = "$STR_A3_CfgVehicles_IEDLandBig_F"; model = "\CUP\Weapons\CUP_Weapons_Put\CUP_IED_V4.p3d"; }; }; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp b/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp index 2632a43e61e..220af016575 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp +++ b/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp @@ -7,20 +7,51 @@ class CfgAmmo { class ace_missileguidance { enabled = 1; - minDeflection = 0.00005; - maxDeflection = 0.025; - incDeflection = 0.00005; + + pitchRate = 120; // degrees per second + yawRate = 120; + stabilityCoefficient = 0.2; + bangBangGuidance = 0; + canVanillaLock = 0; + + // Guidance type for munitions defaultSeekerType = "Optic"; - seekerTypes[] = {"Optic"}; + seekerTypes[] = { "Optic" }; + defaultSeekerLockMode = "LOBL"; - seekerLockModes[] = {"LOBL"}; - seekerAngle = 180; - seekerAccuracy = 1; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "Direct"; + navigationTypes[] = { "Direct", "ZeroEffortMiss" }; + + navigationGain = 3; + + seekerAngle = 180; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + seekerMinRange = 0; - seekerMaxRange = 2500; + 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"}; + attackProfiles[] = { "JAV_TOP", "JAV_DIR" }; + useModeForAttackProfile = 1; + + class navigationStates { + class initial { + transitionCondition = QEFUNC(missileguidance,javelin_midCourseTransition); + navigationType = "Direct"; + }; + class terminal { + transitionCondition = ""; + navigationType = "ZeroEffortMiss"; + }; + // transitions from initial -> termimal + states[] = {"initial", "terminal"}; + }; }; }; }; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/CfgWeapons.hpp b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/CfgWeapons.hpp index 14114854aaa..5a8e1ca4e33 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/CfgWeapons.hpp +++ b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/CfgWeapons.hpp @@ -34,7 +34,7 @@ class CfgWeapons { // Binocular class CUP_NVG_PVS14: NVGoggles { - NVG_BINO_PRESET; + NVG_MONO_PRESET(3); NVG_GREEN_PRESET; }; class CUP_NVG_PVS15_black: NVGoggles { @@ -107,12 +107,12 @@ class CfgWeapons { displayName = SUBCSTRING(CUP_NVG_GPNVG_tan_WP); NVG_WP_PRESET; }; - class CUP_GPNVG_green_WP: CUP_NVG_GPNVG_green { - displayName = SUBCSTRING(CUP_GPNVG_green_WP); + class CUP_NVG_GPNVG_green_WP: CUP_NVG_GPNVG_green { + displayName = SUBCSTRING(CUP_NVG_GPNVG_green_WP); NVG_WP_PRESET; }; - class CUP_GPNVG_winter_WP: CUP_NVG_GPNVG_winter { - displayName = SUBCSTRING(CUP_GPNVG_winter_WP); + 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 index 677ff00c0e0..4730cdf3a9c 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/config.cpp +++ b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { 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_GPNVG_green_WP", "CUP_GPNVG_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[] = { diff --git a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml index ef8d46895db..5e31f93caf7 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml +++ b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml @@ -10,76 +10,93 @@ 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 (Verde, FB) - AN/PVS-15 (Zielone, WP) - AN/PVS-15 (grün, WP) - AN/PVS-15 (녹색, 백색광) - AN/PVS-15 (vertes, WP) - AN/PVS-15 (Зелёный, БФ) - - - AN/PVS-15 (Green, WP) AN/PVS-15 (ブラック、白色蛍光) AN/PVS-15 (Nero, FB) AN/PVS-15 (Czarne, WP) AN/PVS-15 (Schwarz, WP) AN/PVS-15 (검정, 백색광) - AN/PVS-15 (noires, WP) + AN/PVS-15 (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 (Marroncina, FB) - AN/PVS-15 (jasnobrązowa, WP) - AN/PVS-15 (hellbraun, WP) + 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 (Marron clair, WP) + AN/PVS-15 (Желтовато-коричневый, БФ) + AN/PVS-15 (Marrones, WP) AN/PVS-15 (Winter, WP) AN/PVS-15 (冬季迷彩, 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 (Verde, FB) - GPNVG (Zielone, WP) - GPNVG (grün, WP) - GPNVG (녹색, 백색광) - GPNVG (vertes, WP) - GPNVG (Зелёный, БФ) + GPNVG (ブラック、白色蛍光) + GPNVG (Nero, FB) + GPNVG (Czarne, WP) + GPNVG (Schwarz, WP) + GPNVG (검정, 백색광) + GPNVG (Noires, WP) + GPNVG (Чёрный, БФ) + GPNVG (Negras, WP) GPNVG (Tan, WP) GPNVG (タン, 白色蛍光) - GPNVG (Marroncina, FB) - GPNVG (jasnobrązowa, WP) - GPNVG (hellbraun, WP) + GPNVG (Marroncino, FB) + GPNVG (Jasnobrązowa, WP) + GPNVG (Hellbraun, WP) GPNVG (황갈색, 백색광) - GPNVG (marron clair, WP) - GPNVG (желтовато-коричневый, БФ) + GPNVG (Marron clair, WP) + GPNVG (Желтовато-коричневый, БФ) + GPNVG (Marrones, WP) - + GPNVG (Green, WP) - GPNVG (ブラック、白色蛍光) - GPNVG (Nero, FB) - GPNVG (Czarne, WP) - GPNVG (Schwarz, WP) - GPNVG (검정, 백색광) - GPNVG (noires, WP) - GPNVG (Чёрный, БФ) + 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 (설상, 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 index e5fd0225558..54dd0271ccc 100644 --- a/addons/compat_cup_weapons/config.cpp +++ b/addons/compat_cup_weapons/config.cpp @@ -15,6 +15,6 @@ class CfgPatches { }; }; +#include "CfgEventHandlers.hpp" #include "CfgMagazines.hpp" #include "CfgWeapons.hpp" -#include "CfgEventHandlers.hpp" diff --git a/addons/compat_gm/CfgVehicles.hpp b/addons/compat_gm/CfgVehicles.hpp index 6d03465cd7f..d470e8a615d 100644 --- a/addons/compat_gm/CfgVehicles.hpp +++ b/addons/compat_gm/CfgVehicles.hpp @@ -81,15 +81,242 @@ class CfgVehicles { class gm_brdm2_base: gm_wheeled_APC_base { EGVAR(refuel,fuelCapacity) = 290; + + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_01', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + }; + class AmmoBox_02_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_02', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + }; + class AmmoBox_03_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_03', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + }; + }; + }; + class gm_brdm2um_base: gm_brdm2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class AmmoBox_01_unhide: AmmoBox_01_unhide { + positions[] = {{-0.1, -1.9, -0.5}}; + }; + class AmmoBox_02_unhide: AmmoBox_02_unhide { + positions[] = {{-0.55, -0.35, -0.35}}; + }; + class AmmoBox_03_unhide: AmmoBox_03_unhide { + positions[] = {{0.3, -1.85, -0.5}}; + }; + }; }; class gm_btr60_base: gm_wheeled_APC_base { EGVAR(refuel,fuelCapacity) = 290; EGVAR(cookoff,cookoffSelections)[] = {"commanderturret_hatch"}; + + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_01', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_02_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_02', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_03_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_03', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_04_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_04', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_05_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_05', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_06_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_06', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_07_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_07', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + }; + }; + }; + + class gm_ural375d_base: gm_wheeled_truck_base { + EGVAR(refuel,fuelCapacity) = 360; + + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + positions[] = {{-0.55, 1.83, 0.7}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 2.5; + }; + class AmmoBox_02_unhide { + phase = 0; + positions[] = {{0, 1.83, 0.7}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 3; + }; + class AmmoBox_03_unhide { + phase = 0; + positions[] = {{0.55, 1.83, 0.7}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 2.5; + }; + class AmmoBox_04_unhide { + phase = 0; + positions[] = {{-0.45, 1.83, 0.7}}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + distance = 2.5; + }; + }; + }; + class gm_ural375d_mlrs_base: gm_ural375d_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class AmmoBox_01_unhide: AmmoBox_01_unhide { + positions[] = {{-0.55, 2, 0.5}}; + }; + class AmmoBox_02_unhide: AmmoBox_02_unhide { + positions[] = {{0, 2, 0.5}}; + }; + class AmmoBox_03_unhide: AmmoBox_03_unhide { + positions[] = {{0.55, 2, 0.5}}; + }; + class AmmoBox_04_unhide: AmmoBox_04_unhide { + positions[] = {{-0.45, 2, 0.5}}; + }; + }; + }; + class gm_ural375d_medic_base: gm_ural375d_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class AmmoBox_01_unhide: AmmoBox_01_unhide { + positions[] = {{-0.55, 2, 0.7}}; + }; + class AmmoBox_02_unhide: AmmoBox_02_unhide { + positions[] = {{0, 2, 0.7}}; + }; + class AmmoBox_03_unhide: AmmoBox_03_unhide { + positions[] = {{0.55, 2, 0.7}}; + }; + class AmmoBox_04_unhide: AmmoBox_04_unhide { + positions[] = {{-0.45, 2, 0.7}}; + }; + }; }; class gm_ural4320_base: gm_wheeled_truck_base { EGVAR(refuel,fuelCapacity) = 360; + + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + positions[] = {{-0.55, 1.47, 0.7}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 2.5; + }; + class AmmoBox_02_unhide { + phase = 0; + positions[] = {{0, 1.47, 0.7}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 3; + }; + class AmmoBox_03_unhide { + phase = 0; + positions[] = {{0.55, 1.47, 0.7}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 2.5; + }; + class AmmoBox_04_unhide { + phase = 0; + positions[] = {{-0.45, 1.47, 0.7}}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + distance = 2.5; + }; + }; + }; + class gm_ural4320_repair_base: gm_ural4320_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class AmmoBox_01_unhide: AmmoBox_01_unhide { + positions[] = {{-0.55, 1.62, 0.7}}; + }; + class AmmoBox_02_unhide: AmmoBox_02_unhide { + positions[] = {{0, 1.62, 0.7}}; + }; + class AmmoBox_03_unhide: AmmoBox_03_unhide { + positions[] = {{0.55, 1.62, 0.7}}; + }; + class AmmoBox_04_unhide: AmmoBox_04_unhide { + positions[] = {{-0.45, 1.62, 0.7}}; + }; + }; + }; + class gm_ural44202_base: gm_ural4320_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class AmmoBox_01_unhide: AmmoBox_01_unhide { + positions[] = {{-0.55, 1.37, 0.7}}; + }; + class AmmoBox_02_unhide: AmmoBox_02_unhide { + positions[] = {{0, 1.37, 0.7}}; + }; + class AmmoBox_03_unhide: AmmoBox_03_unhide { + positions[] = {{0.55, 1.37, 0.7}}; + }; + class AmmoBox_04_unhide: AmmoBox_04_unhide { + positions[] = {{-0.45, 1.37, 0.7}}; + }; + }; }; class gm_ural4320_reammo_base: gm_ural4320_base { @@ -190,9 +417,103 @@ class CfgVehicles { EGVAR(refuel,fuelCapacity) = 460; EGVAR(cookoff,cookoffSelections)[] = {"mainturret_hatch","commanderturret_hatch"}; }; + class gm_bmp1sp2_base: gm_bmp1_base { + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + positions[] = {{-1.2, -2.52, -1.2}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_02_unhide { + phase = 0; + positions[] = {{-1.3, -2, -1.2}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_03_unhide { + phase = 0; + positions[] = {{-1.35, -1.43, -1.2}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_04_unhide { + phase = 0; + positions[] = {{1.2, -2.52, -1.2}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_05_unhide { + phase = 0; + positions[] = {{1.3, -2, -1.2}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_06_unhide { + phase = 0; + positions[] = {{1.35, -1.43, -1.2}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_07_unhide { + phase = 0; + positions[] = {{-1.45, 0.1, -1.3}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_08_unhide { + phase = 0; + positions[] = {{-1.45, 2, -1.3}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_09_unhide { + phase = 0; + positions[] = {{1.45, 2, -1.3}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + }; + }; class gm_pt76_base: gm_tracked_Tank_base { EGVAR(refuel,fuelCapacity) = 250; + + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + positions[] = {{0.08, -1.75, -1}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 2.5; + }; + class AmmoBox_02_unhide { + phase = 0; + positions[] = {{0.08, -1.38, -1}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 2.5; + }; + class AmmoBox_03_unhide { + phase = 0; + positions[] = {{0.08, -2.15, -1}}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + distance = 2.5; + }; + }; }; class gm_t55_base: gm_tracked_Tank_base { @@ -204,6 +525,21 @@ class CfgVehicles { EGVAR(refuel,fuelCapacity) = 812; }; + class gm_tracked_Artillery_base; + class gm_2s1_base: gm_tracked_Artillery_base { + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, -1.3, 0] vectorAdd ([[0, -1.1, -0.35], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + distance = 2.5; + }; + }; + }; + // WEST class gm_Leopard1_base; class gm_Leopard1a0_base: gm_Leopard1_base { @@ -211,6 +547,27 @@ class CfgVehicles { EGVAR(cookoff,cookoffSelections)[] = {"mainturret_hatch_1","commanderturret_hatch"}; }; + class gm_Leopard1a1_base: gm_Leopard1a0_base { + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, -0.6, 0] vectorAdd ([[0.7, -2, -0.6], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + }; + class AmmoBox_02_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, -0.6, 0] vectorAdd ([[-0.3, -1.95, -0.6], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + }; + }; + }; + class gm_Gepard_base: gm_Leopard1_base { EGVAR(refuel,fuelCapacity) = 985; }; @@ -257,42 +614,39 @@ class CfgVehicles { 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 openDoor_L { + displayNameDefault = "$STR_a3_cfgvehicles_useractions_openldoor0"; + displayName = "$STR_a3_cfgvehicles_useractions_openldoor0"; + 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(QQEGVAR(fastroping,doorsLocked),false)])}); + statement = "this animateDoor ['door_2_1_source',1]"; + }; + class openDoor_R: openDoor_L { + displayNameDefault = "$STR_a3_cfgvehicles_useractions_openrdoor0"; + displayName = "$STR_a3_cfgvehicles_useractions_openrdoor0"; + condition = QUOTE((this animationSourcePhase 'door_2_2_unhide' > 0.5) && (this doorPhase 'door_2_2_source' < 0.5) && {alive this} && {!(this getVariable [ARR_2(QQEGVAR(fastroping,doorsLocked),false)])}); + statement = "this animateDoor ['door_2_2_source',1]"; + }; + + class closeDoor_L { + displayNameDefault = "$STR_a3_cfgvehicles_useractions_closeldoor0"; + displayName = "$STR_a3_cfgvehicles_useractions_closeldoor0"; + 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(QQEGVAR(fastroping,doorsLocked),false)])}); + statement = "this animateDoor ['door_2_1_source',0]"; + }; + class closeDoor_R: closeDoor_L { + displayNameDefault = "$STR_a3_cfgvehicles_useractions_closerdoor0"; + displayName = "$STR_a3_cfgvehicles_useractions_closerdoor0"; + condition = QUOTE((this animationSourcePhase 'door_2_2_unhide' > 0.5) && (this doorPhase 'door_2_2_source' > 0.5) && {alive this} && {!(this getVariable [ARR_2(QQEGVAR(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 { diff --git a/addons/compat_gm/compat_gm_explosives/CfgAmmo.hpp b/addons/compat_gm/compat_gm_explosives/CfgAmmo.hpp index 3da49f45abe..a8f9ca632e5 100644 --- a/addons/compat_gm/compat_gm_explosives/CfgAmmo.hpp +++ b/addons/compat_gm/compat_gm_explosives/CfgAmmo.hpp @@ -1,9 +1,10 @@ class CfgAmmo { - class PipeBombBase; - class gm_explosive_petn_charge: PipeBombBase { + class gm_explosive_petn_base; + class gm_explosive_charge_petn: gm_explosive_petn_base { EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; }; - class gm_explosive_plnp_charge: PipeBombBase { + class gm_explosive_plnp_base; + class gm_explosive_charge_plnp: gm_explosive_plnp_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 index 17d51d3b457..f0afb3b90cd 100644 --- a/addons/compat_gm/compat_gm_explosives/CfgMagazines.hpp +++ b/addons/compat_gm/compat_gm_explosives/CfgMagazines.hpp @@ -2,9 +2,8 @@ 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); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_gm_explosive_petn); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch"}; @@ -21,9 +20,8 @@ class CfgMagazines { 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); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_gm_explosive_plnp); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch"}; @@ -40,8 +38,8 @@ class CfgMagazines { 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); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_gm_mine_tm46); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -51,8 +49,8 @@ class CfgMagazines { }; }; class gm_mine_at_dm21: gm_mine_at_base { - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) =QEGVAR(explosives,Place_gm_explosive_dm21); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_gm_explosive_dm21); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -62,8 +60,8 @@ class CfgMagazines { }; }; class gm_mine_at_mn111: gm_mine_at_base { - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) =QEGVAR(explosives,Place_gm_explosive_m111); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_gm_explosive_m111); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -74,8 +72,8 @@ class CfgMagazines { }; class gm_mine_ap_dm31: gm_mine_at_base { - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) =QEGVAR(explosives,Place_gm_explosive_dm31); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_gm_explosive_dm31); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; diff --git a/addons/compat_gm/compat_gm_explosives/CfgVehicles.hpp b/addons/compat_gm/compat_gm_explosives/CfgVehicles.hpp index bb279c82b94..ea201aa579a 100644 --- a/addons/compat_gm/compat_gm_explosives/CfgVehicles.hpp +++ b/addons/compat_gm/compat_gm_explosives/CfgVehicles.hpp @@ -9,7 +9,7 @@ class CfgVehicles { // CHARGE class EGVAR(explosives,Place_gm_explosive_petn): EGVAR(explosives,Place) { - displayName = "PETN Charge"; + displayName = "$STR_DN_GM_EXPLOSIVE_PETN_CHARGE"; model = "gm\gm_weapons\gm_put\gm_explosive_charge_petn"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -18,7 +18,7 @@ class CfgVehicles { }; }; class EGVAR(explosives,Place_gm_explosive_plnp): EGVAR(explosives,Place) { - displayName = "PLNP Charge"; + displayName = "$STR_DN_GM_EXPLOSIVE_PLNP_CHARGE"; model = "gm\gm_weapons\gm_put\gm_explosive_charge_plnp"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -28,7 +28,7 @@ class CfgVehicles { }; // AT MINE class EGVAR(explosives,Place_gm_mine_tm46): EGVAR(explosives,Place) { - displayName = "AT Mine TM46"; + displayName = "$STR_DN_GM_MINE_AT_TM46"; model = "gm\gm_weapons\gm_put\gm_mine_at_tm46"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -37,7 +37,7 @@ class CfgVehicles { }; }; class EGVAR(explosives,Place_gm_explosive_dm21): EGVAR(explosives,Place) { - displayName = "AT Mine DM21"; + displayName = "$STR_DN_GM_MINE_AT_DM21"; model = "gm\gm_weapons\gm_put\gm_mine_at_dm21"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -46,7 +46,7 @@ class CfgVehicles { }; }; class EGVAR(explosives,Place_gm_explosive_m111): EGVAR(explosives,Place) { - displayName = "MN 111"; + displayName = "$STR_DN_GM_MINE_AT_MN111"; model = "gm\gm_weapons\gm_launchers\gm_platan\gm_mine_at_mn111_disarmed"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -56,7 +56,7 @@ class CfgVehicles { }; // AP class EGVAR(explosives,Place_gm_explosive_dm31): EGVAR(explosives,Place) { - displayName = "AP Mine DM31"; + displayName = "$STR_DN_GM_MINE_AP_DM31"; model = "gm\gm_weapons\gm_put\gm_mine_ap_dm31"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { diff --git a/addons/compat_gm/compat_gm_explosives/config.cpp b/addons/compat_gm/compat_gm_explosives/config.cpp index e240c283896..9b4d16a1e6c 100644 --- a/addons/compat_gm/compat_gm_explosives/config.cpp +++ b/addons/compat_gm/compat_gm_explosives/config.cpp @@ -8,6 +8,7 @@ class CfgPatches { requiredVersion = REQUIRED_VERSION; requiredAddons[] = { "gm_core", + "gm_weapons_put", "ace_explosives" }; skipWhenMissingDependencies = 1; diff --git a/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp b/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp index 46a4deeefd6..aa51d469799 100644 --- a/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp +++ b/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp @@ -1,6 +1,336 @@ class CfgVehicles { - class gm_ural4320_base; - class gm_ural4320_refuel_base: gm_ural4320_base { - transportFuel = 0; + class gm_typ2_base; + class gm_typ251_base: gm_typ2_base { + class EGVAR(interaction,anims) { + class canister_01_unhide { + phase = 0; + positions[] = {{-0.55, -0.17, 0.4}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class canister_02_unhide { + phase = 0; + positions[] = {{-0.55, -0.65, 0.4}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class gm_typ253_base: gm_typ2_base { + class EGVAR(interaction,anims) { + class canister_01_unhide { + phase = 0; + positions[] = {{-0.55, -0.19, 0.4}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class canister_02_unhide { + phase = 0; + positions[] = {{-0.55, -0.68, 0.4}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + class gm_wheeled_truck_base; + class gm_ural375d_base: gm_wheeled_truck_base { + class EGVAR(interaction,anims) { + class fuelcan_1_1_unhide { + phase = 0; + positions[] = {{-0.95, 3.15, -0.45}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class fuelcan_1_2_unhide { + phase = 0; + positions[] = {{0.9, 3.15, -0.45}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class gm_ural375d_mlrs_base: gm_ural375d_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class fuelcan_1_1_unhide: fuelcan_1_1_unhide { + positions[] = {{-0.95, 3.35, -0.55}}; + }; + class fuelcan_1_2_unhide: fuelcan_1_2_unhide { + positions[] = {{0.9, 3.35, -0.55}}; + }; + }; + }; + class gm_ural375d_medic_base: gm_ural375d_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class fuelcan_1_1_unhide: fuelcan_1_1_unhide { + positions[] = {{-0.95, 3.35, -0.45}}; + }; + class fuelcan_1_2_unhide: fuelcan_1_2_unhide { + positions[] = {{0.9, 3.35, -0.45}}; + }; + }; + }; + + class gm_ural4320_base: gm_wheeled_truck_base { + class EGVAR(interaction,anims) { + class fuelcan_1_1_unhide { + phase = 0; + positions[] = {{-0.9, 3.1, -0.4}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class fuelcan_1_2_unhide { + phase = 0; + positions[] = {{0.9, 3.1, -0.4}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class gm_ural4320_repair_base: gm_ural4320_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class fuelcan_1_1_unhide: fuelcan_1_1_unhide { + positions[] = {{-0.9, 3.25, -0.4}}; + }; + class fuelcan_1_2_unhide: fuelcan_1_2_unhide { + positions[] = {{0.9, 3.25, -0.4}}; + }; + }; + }; + class gm_ural44202_base: gm_ural4320_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class fuelcan_1_1_unhide: fuelcan_1_1_unhide { + positions[] = {{-0.9, 3, -0.4}}; + }; + class fuelcan_1_2_unhide: fuelcan_1_2_unhide { + positions[] = {{0.9, 3, -0.4}}; + }; + }; + }; + + class gm_wheeled_APC_base; + class gm_brdm2_base: gm_wheeled_APC_base { + class EGVAR(interaction,anims) { + class FuelCanister_01_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_01', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_02_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_02', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_03_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_03', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class gm_brdm2um_base: gm_brdm2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class FuelCanister_01_unhide: FuelCanister_01_unhide { + positions[] = {{0.87, -3, -1.2}}; + }; + class FuelCanister_02_unhide: FuelCanister_02_unhide { + positions[] = {{-0.87, -3, -1.2}}; + }; + class FuelCanister_03_unhide: FuelCanister_03_unhide { + positions[] = {{-0.4, -1.85, -0.5}}; + }; + }; + }; + + class gm_btr60_base: gm_wheeled_APC_base { + class EGVAR(interaction,anims) { + class FuelCanister_01_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_01', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_02_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_02', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_03_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_03', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_04_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_04', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_05_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_05', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_06_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_06', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class gm_btr60pa_base: gm_btr60_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class FuelCanister_05_unhide: FuelCanister_05_unhide { + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + class FuelCanister_06_unhide: FuelCanister_06_unhide { + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + }; + }; + class gm_btr60pb_base: gm_btr60_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class FuelCanister_03_unhide: FuelCanister_03_unhide { + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + class FuelCanister_04_unhide: FuelCanister_04_unhide { + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + }; + }; + class gm_btr60pu12_base: gm_btr60_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class FuelCanister_03_unhide: FuelCanister_03_unhide { + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + class FuelCanister_04_unhide: FuelCanister_04_unhide { + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + }; + }; + + class gm_bmp1_base; + class gm_bmp1sp2_base: gm_bmp1_base { + class EGVAR(interaction,anims) { + class FuelCanister_01_unhide { + phase = 0; + positions[] = {{-1.2, -2.52, -1.2}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_02_unhide { + phase = 0; + positions[] = {{1.2, -2.52, -1.2}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + class gm_zsu234_base; + class gm_zsu234v1_base: gm_zsu234_base { + class EGVAR(interaction,anims) { + class FuelCanister_01_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, 0.2, 0] vectorAdd ([[-0.85, -2.2, -0.9], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_02_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, 0.2, 0] vectorAdd ([[0.7, -2.25, -0.85], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_03_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, 0.2, 0] vectorAdd ([[0.92, -2.25, -0.85], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + class gm_tracked_Tank_base; + class gm_pt76_base: gm_tracked_Tank_base { + class EGVAR(interaction,anims) { + class FuelTank_01_unhide { + phase = 0; + positions[] = {{-1, -2.85, -1}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelTank_02_unhide { + phase = 0; + positions[] = {{1, -2.85, -1}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + class gm_Leopard1a0_base; + class gm_Leopard1a1_base: gm_Leopard1a0_base { + class EGVAR(interaction,anims) { + class FuelCanister_01_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, -0.6, 0] vectorAdd ([[0.25, -1.9, -0.55], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + distance = 2.5; + }; + class FuelCanister_02_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, -0.6, 0] vectorAdd ([[-0.8, -1.65, -0.55], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_03_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, -0.6, 0] vectorAdd ([[0.8, -1.8, -0.55], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; }; }; diff --git a/addons/compat_gm/compat_gm_repair/CfgVehicles.hpp b/addons/compat_gm/compat_gm_repair/CfgVehicles.hpp new file mode 100644 index 00000000000..12f9253bba6 --- /dev/null +++ b/addons/compat_gm/compat_gm_repair/CfgVehicles.hpp @@ -0,0 +1,100 @@ +class CfgVehicles { + class gm_wheeled_car_base; + class gm_uaz469_base: gm_wheeled_car_base { + class EGVAR(interaction,anims) { + class spare_wheel_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['spare_wheel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class gm_wheeled_APC_base; + class gm_brdm2_base: gm_wheeled_APC_base { + class EGVAR(interaction,anims) { + class SpareWheel_01_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['sparewheel_01', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + distance = 2.5; + }; + class SpareWheel_02_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['sparewheel_02', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class gm_brdm2um_base: gm_brdm2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class SpareWheel_01_unhide: SpareWheel_01_unhide { + positions[] = {{0.2, -0.7, -0.25}}; + distance = 2; + }; + class SpareWheel_02_unhide: SpareWheel_02_unhide { + positions[] = {{0, -1.6, -0.4}}; + }; + }; + }; + + class gm_btr60_base: gm_wheeled_APC_base { + class EGVAR(interaction,anims) { + class SpareWheel_01_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['sparewheel_01', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + distance = 3; + }; + class SpareWheel_02_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['sparewheel_02', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + class SpareWheel_03_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['sparewheel_03', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class gm_bmp1_base; + class gm_bmp1sp2_base: gm_bmp1_base { + class EGVAR(interaction,anims) { + class spareTracks_1_1_unhide { + phase = 0; + positions[] = {"(_target selectionPosition ['door_1_1', 'FireGeometry', 'AveragePoint']) vectorAdd [0, 0, -0.15]"}; + items[] = {"ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + class spareTracks_1_2_unhide { + phase = 0; + positions[] = {"(_target selectionPosition ['door_1_2', 'FireGeometry', 'AveragePoint']) vectorAdd [0, 0, -0.15]"}; + items[] = {"ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + class spareTracks_2_1_unhide { + phase = 0; + positions[] = {{-1.1, -2.7, -1.3}, {1.1, -2.7, -1.3}}; + items[] = {"ACE_Track", "ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; +}; diff --git a/addons/compat_gm/compat_gm_repair/config.cpp b/addons/compat_gm/compat_gm_repair/config.cpp new file mode 100644 index 00000000000..6fae9858b4b --- /dev/null +++ b/addons/compat_gm/compat_gm_repair/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_repair" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_gm/compat_gm_repair/script_component.hpp b/addons/compat_gm/compat_gm_repair/script_component.hpp new file mode 100644 index 00000000000..1af928486c3 --- /dev/null +++ b/addons/compat_gm/compat_gm_repair/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT repair +#define SUBCOMPONENT_BEAUTIFIED Repair +#include "..\script_component.hpp" diff --git a/addons/compat_gm/compat_gm_trenches/CfgVehicles.hpp b/addons/compat_gm/compat_gm_trenches/CfgVehicles.hpp new file mode 100644 index 00000000000..b5c32d8be1e --- /dev/null +++ b/addons/compat_gm/compat_gm_trenches/CfgVehicles.hpp @@ -0,0 +1,47 @@ +class CfgVehicles { + class gm_wheeled_truck_base; + class gm_ural375d_base: gm_wheeled_truck_base { + class EGVAR(interaction,anims) { + class tools_unhide { + phase = 0; + positions[] = {{0.9, 3.15, -0.5}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class gm_ural375d_mlrs_base: gm_ural375d_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class tools_unhide: tools_unhide { + positions[] = {{0.9, 3.35, -0.65}}; + }; + }; + }; + class gm_ural375d_medic_base: gm_ural375d_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class tools_unhide: tools_unhide { + positions[] = {{0.9, 3.35, -0.5}}; + }; + }; + }; + + class gm_ural4320_base: gm_wheeled_truck_base { + class EGVAR(interaction,anims) { + class tools_unhide { + phase = 0; + positions[] = {{0.93, 2.7, -0.5}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class gm_ural44202_base: gm_ural4320_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class tools_unhide: tools_unhide { + positions[] = {{0.9, 2.6, -0.5}}; + }; + }; + }; +}; diff --git a/addons/compat_gm/compat_gm_trenches/config.cpp b/addons/compat_gm/compat_gm_trenches/config.cpp new file mode 100644 index 00000000000..13c4dd0816d --- /dev/null +++ b/addons/compat_gm/compat_gm_trenches/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_trenches" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_gm/compat_gm_trenches/script_component.hpp b/addons/compat_gm/compat_gm_trenches/script_component.hpp new file mode 100644 index 00000000000..10b90eb71e5 --- /dev/null +++ b/addons/compat_gm/compat_gm_trenches/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT trenches +#define SUBCOMPONENT_BEAUTIFIED Trenches +#include "..\script_component.hpp" diff --git a/addons/compat_rf/$PBOPREFIX$ b/addons/compat_rf/$PBOPREFIX$ new file mode 100644 index 00000000000..78e6f45daf4 --- /dev/null +++ b/addons/compat_rf/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_rf diff --git a/addons/compat_rf/CfgVehicles.hpp b/addons/compat_rf/CfgVehicles.hpp new file mode 100644 index 00000000000..fa0343908a9 --- /dev/null +++ b/addons/compat_rf/CfgVehicles.hpp @@ -0,0 +1,25 @@ +class CfgVehicles { + // Applies the offset to all RF Offroads which can have the optional tank in the back + class Offroad_01_unarmed_base_F; + class Pickup_01_base_rf: Offroad_01_unarmed_base_F { + EXGVAR(field_rations,offset)[] = {-0.04, -2.45, -0.9}; + }; + + // Enable Water Source by Default + class C_IDAP_Pickup_rf; + class C_IDAP_Pickup_water_rf: C_IDAP_Pickup_rf { + EXGVAR(field_rations,waterSupply) = 500; + }; + + class O_Truck_03_fuel_F; + class C_Truck_03_water_rf: O_Truck_03_fuel_F { + EXGVAR(field_rations,waterSupply) = 10000; + EXGVAR(field_rations,offset)[] = {0, -5.05, -0.3}; + }; + + class B_Truck_01_fuel_F; + class C_Truck_01_water_rf: B_Truck_01_fuel_F { + EXGVAR(field_rations,waterSupply) = 10000; + EXGVAR(field_rations,offset)[] = {-0.41, -5.15, -0.3}; + }; +}; diff --git a/addons/compat_rf/CfgWeapons.hpp b/addons/compat_rf/CfgWeapons.hpp new file mode 100644 index 00000000000..d1daa7c7100 --- /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 00000000000..553c199ee6f --- /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 00000000000..2de1cf96735 --- /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 00000000000..0b98185fa03 --- /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 00000000000..9915ad1d44f --- /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 00000000000..52231bcf071 --- /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 00000000000..2983525ec87 --- /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 00000000000..c2d9003f11a --- /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 00000000000..47003c4a42b --- /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 00000000000..b8d0682fa4f --- /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 00000000000..732e03df0d5 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/stringtable.xml @@ -0,0 +1,702 @@ + + + + + EOTech MRDS (Khaki) + EOTech MRDS (カーキ) + 이오텍 MRDS (카키) + EOTech MRDS (Khaki) + EOTech MRDS (Cachi) + EOTech MRDS (Khaki) + EOTech MRDS (Caqui) + + + EOTech MRDS (Tan) + EOTech MRDS (タン) + 이오텍 MRDS (황갈) + EOTech MRDS (Hellbraun) + EOTech MRDS (Marroncino) + EOTech MRDS (Marron) + EOTech MRDS (Tan) + + + C-More Railway (Green, Desert) + C-More レイルウェイ (グリーン、砂漠迷彩) + 씨모어 레일웨이 (녹색, 사막) + C-More Railway (Grün, Wüste) + C-More Railway (Verde, Deserto) + C-More Railway (Vert, Désert) + C-More Railway (Verde, Desierto) + + + C-More Railway (Green, Woodland) + C-More レイルウェイ (グリーン、森林迷彩) + 씨모어 레일웨이 (녹색, 수풀 위장) + C-More Railway (Grün, Grünes Tarnmuster) + C-More Railway (Verde, Boschivo) + C-More Railway (Vert, Woodland) + C-More Railway (Verde, Boscoso) + + + C-More Railway (Red, Desert) + C-More レイルウェイ (グリーン、砂漠迷彩) + 씨모어 레일웨이 (빨강, 사막) + C-More Railway (Rot, Wüste) + C-More Railway (Rosso, Desert) + C-More Railway (Rouge, Désert) + C-More Railway (Rojo, Desierto) + + + C-More Railway (Red, Woodland) + C-More レイルウェイ (グリーン、森林迷彩) + 씨모어 레일웨이 (빨강, 수풀) + C-More Railway (Rot, Grünes Tarnmuster) + C-More Railway (Rosso, Boschivo) + C-More Railway (Rouge, Woodland) + C-More Railway (Rojo, Boscoso) + + + Aimpoint Micro R-1 + Aimpoint マイクロ R-1 + 에임포인트 마이크로 R-1 + Aimpoint Micro R-1 + Aimpoint Micro R-1 + Aimpoint Micro R-1 + Aimpoint Micro R-1 + + + Vortex Spitfire Prism + Vortex スピットファイア プリズム + 버텍스 스핏파이어 프리즘 + Vortex Spitfire Prism + Vortex Spitfire Prism + Vortex Spitfire Prism + Vortex Spitfire Prism + + + Vortex Spitfire Prism (Tan) + Vortex スピットファイア プリズム (タン) + 버텍스 스핏파이어 프리즘 (황갈) + Vortex Spitfire Prism (Hellbraun) + Vortex Spitfire Prism (Marroncino) + Vortex Spitfire Prism (Marron) + Vortex Spitfire Prism (Tan) + + + Vortex Spitfire Prism (Khaki) + Vortex スピットファイア プリズム (カーキ) + 버텍스 스핏파이어 프리즘 (카키) + Vortex Spitfire Prism (Khaki) + Vortex Spitfire Prism (Cachi) + Vortex Spitfire Prism (Khaki) + Vortex Spitfire Prism (Caqui) + + + Vortex Spitfire Prism (Pistol) + Vortex スピットファイア プリズム (ピストル用) + 버텍스 스핏파이어 프리즘 (권총용) + Vortex Spitfire Prism (Pistole) + Vortex Spitfire Prism (Pistola) + Vortex Spitfire Prism (Pistol) + Vortex Spitfire Prism (Pistola) + + + Glock 19X + グロック 19X + 글록 19X + Glock 19X + Glock 19X + Glock 19X + Glock 19X + + + Glock 19X (Khaki) + グロック 19X (カーキ) + 글록 19X (카키) + Glock 19X (Khaki) + Glock 19X (Cachi) + Glock 19X (Khaki) + Glock 19X (Caqui) + + + Glock 19X (Tan) + グロック 19X (タン) + 글록 19X (황갈) + Glock 19X (Hellbraun) + Glock 19X (Marroncino) + Glock 19X (Marron) + Glock 19X (Tan) + + + Glock 19X Auto + グロック 19X オート + 글록 19X 기관권총 + Glock 19X Auto + Glock 19X Auto + Glock 19X Auto + Glock 19X Auto + + + Glock 19X Auto (Khaki) + グロック 19X オート (カーキ) + 글록 19X 기관권총 (카키) + Glock 19X Auto (Khaki) + Glock 19X Auto (Cachi) + Glock 19X Auto (Khaki) + Glock 19X Auto (Caqui) + + + Glock 19X Auto (Tan) + グロック 19X オート (タン) + 글록 19X 기관권총 (황갈) + Glock 19X Auto (Hellbraun) + Glock 19X Auto (Marroncino) + Glock 19X Auto (Marron) + Glock 19X Auto (Tan) + + + 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 + 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 (Classique) + Desert Eagle Mark XIX L5 (Clasica) + + + 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 (Bronze) + Desert Eagle Mark XIX L5 (Bronce) + + + 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 (Cuivre) + Desert Eagle Mark XIX L5 (Cobre) + + + Desert Eagle Mark XIX L5 (Gold) + デザートイーグル Mark XIX L5 (ゴールド) + 데저트 이글 마크 XIX L5 (금색) + Desert Eagle Mark XIX L5 (Gold) + Desert Eagle Mark XIX L5 (Oro) + Desert Eagle Mark XIX L5 (Or) + Desert Eagle Mark XIX L5 (Oro) + + + HERA H6 (Tan) + HERA H6 (タン) + 헤라 H6 (황갈) + HERA H6 (Hellbraun) + HERA H6 (Marroncino) + HERA H6 (Marron) + HERA H6 (Tan) + + + HERA H6 (Olive) + HERA H6 (オリーブ) + 헤라 H6 (올리브) + HERA H6 (Olivgrün) + HERA H6 (Oliva) + HERA H6 (Olive) + HERA H6 (Oliva) + + + HERA H6 (Black) + HERA H6 (ブラック) + 헤라 H6 (검정) + HERA H6 (Schwarz) + HERA H6 (Nero) + HERA H6 (Noir) + HERA H6 (Negro) + + + HERA H6 (Digital) + HERA H6 (AAF迷彩) + 헤라 H6 (AAF 디지털) + HERA H6 (Digital) + HERA H6 (Digitale) + HERA H6 (Digital) + HERA H6 (Digital) + + + HERA H6 (Gold) + HERA H6 (ゴールド) + 헤라 H6 (금색) + HERA H6 (Gold) + HERA H6 (Oro) + HERA H6 (Or) + HERA H6 (Oro) + + + VS-121 (Black) + VS-121 (ブラック) + VS-121 (검정) + VS-121 (Schwarz) + VS-121 (Nero) + VS-121 (Noir) + VS-121 (Negro) + + + VS-121 (Tan) + VS-121 (タン) + VS-121 (황갈) + VS-121 (Hellbraun) + VS-121 (Marroncino) + VS-121 (Marron) + VS-121 (Tan) + + + Vector SMG (Black) + ベクター SMG (ブラック) + 벡터 SMG (검정) + Vector SMG (Schwarz) + Vector SMG (Nero) + Vector SMG (Noir) + Vector SMG (Negro) + + + ASh-12 (Black) + ASh-12 (ブラック) + ASh-12 (검정) + ASh-12 (Schwarz) + ASh-12 (Nero) + ASh-12 (Noir) + ASh-12 (Negro) + + + ASh-12 (Desert) + ASh-12 (砂漠迷彩) + ASh-12 (사막) + ASh-12 (Wüste) + ASh-12 (Deserto) + ASh-12 (Désert ) + ASh-12 (Desierto) + + + ASh-12 (Urban) + ASh-12 (市街地迷彩) + ASh-12 (도심) + ASh-12 (Urban) + ASh-12 (Urbano) + ASh-12 (Urbain) + ASh-12 (Urbano) + + + ASh-12 (Woodland) + ASh-12 (森林迷彩) + ASh-12 (수풀) + ASh-12 (Grünes Tarnmuster) + ASh-12 (Boschivo) + ASh-12 (Woodland) + ASh-12 (Boscoso) + + + ASh-12 GL (Black) + ASh-12 GL (ブラック) + ASh-12 GL (검정) + ASh-12 GL (Schwarz) + ASh-12 GL (Nero) + ASh-12 GL (Noir) + ASh-12 GL (Negro) + + + ASh-12 GL (Desert) + ASh-12 GL (砂漠迷彩) + ASh-12 GL (사막) + ASh-12 GL (Wüste) + ASh-12 GL (Deserto) + ASh-12 GL (Désert) + ASh-12 GL (Desierto) + + + ASh-12 GL (Urban) + ASh-12 GL (市街地迷彩) + ASh-12 GL (도심) + ASh-12 GL (Urban) + ASh-12 GL (Urbano) + ASh-12 GL (Urbain) + 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 GL (Woodland) + ASh-12 GL (Boscoso) + + + ASh-12 LR (Black) + ASh-12 LR (ブラック) + ASh-12 LR (검정) + ASh-12 LR (Schwarz) + ASh-12 LR (Nero) + ASh-12 LR (Noir) + ASh-12 LR (Negro) + + + ASh-12 LR (Desert) + ASh-12 LR (砂漠迷彩) + ASh-12 LR (사막) + ASh-12 LR (Wüste) + ASh-12 LR (Deserto) + ASh-12 LR (Désert) + ASh-12 LR (Desierto) + + + ASh-12 LR (Urban) + ASh-12 LR (市街地迷彩) + ASh-12 LR (도심) + ASh-12 LR (Urban) + ASh-12 LR (Urbano) + ASh-12 LR (Urbain) + ASh-12 LR (Urbano) + + + ASh-12 LR (Woodland) + ASh-12 LR (森林迷彩) + ASh-12 LR (수풀) + ASh-12 LR (Grünes Tarnmuster) + ASh-12 LR (Boschivo) + ASh-12 LR (Woodland) + ASh-12 LR (Boscoso) + + + AW159 Wildcat ASW + AW159 ワイルドキャット ASW + AW159 와일드캣 ASW + AW159 Wildcat ASW + AW159 Wildcat ASW + AW159 Wildcat ASW + AW159 Wildcat ASW + + + AW159 Wildcat ASW (Unarmed) + AW159 ワイルドキャット ASW (非武装) + AW159 와일드캣 ASW (비무장) + AW159 Wildcat ASW (Unbewaffnet) + AW159 Wildcat ASW (Disarmato) + AW159 Wildcat ASW (non armé) + AW159 Wildcat ASW (Desarmado) + + + H225 Super Puma (Transport) + H225 シュペル ピューマ (輸送型) + H225 슈퍼 퓨마 (비무장) + H225 Super Puma (Transport) + H225 Super Puma (Trasporto) + H225 Super Puma (Transport ) + H225 Super Puma (Transporte) + + + H225 Super Puma (Civilian) + H225 シュペル ピューマ (民生型) + H225 슈퍼 퓨마 (비무장) + H225 Super Puma (Zivil) + H225 Super Puma (Civile) + H225 Super Puma (Civil) + H225 Super Puma (Civil) + + + H215 Super Puma (Transport) + H215 シュペル ピューマ (輸送型) + H215 슈퍼 퓨마 (비무장) + H215 Super Puma (Transport) + H215 Super Puma (Trasporto) + H215 Super Puma (Transport) + H215 Super Puma (Transporte) + + + H215 Super Puma (Civilian) + H215 シュペル ピューマ (民生型) + H215 슈퍼 퓨마 (비무장) + H215 Super Puma (Zivil) + H215 Super Puma (Civile) + H215 Super Puma (Civil) + H215 Super Puma (Civil) + + + H215 Super Puma (Unarmed) + H215 シュペル ピューマ (非武装) + H215 슈퍼 퓨마 (비무장) + H215 Super Puma (Unbewaffnet) + H215 Super Puma (Disarmato) + H215 Super Puma (non armé) + H215 Super Puma (Desarmado) + + + H225M Super Cougar SOCAT + H225M シュペル クーガー SOCAT + H225M 슈퍼 쿠거 SOCAT + H225M Super Cougar SOCAT + H225M Super Cougar 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 SOCAT + H225M Super Cougar SOCAT + + + H225M Super Cougar + H225M シュペル クーガー + H225M 슈퍼 쿠거 + H225M Super Cougar + H225M Super Cougar + H225M Super Cougar + H225M Super Cougar + + + H225 Super Puma SAR + H225 シュペル ピューマ 捜索救難型 + H225 슈퍼 퓨마 SAR + H225 Super Puma SAR + H225 Super Puma SAR + H225 Super Puma SAR + H225 Super Puma SAR + + + H225M Super Cougar (Unarmed) + H225M シュペル クーガー (非武装) + H225M Super Cougar (Unbewaffnet) + H225M Super Cougar (Disarmato) + H225M 슈퍼 쿠거 (비무장) + H225M Super Cougar (Non armé) + H225M Super Cougar (Desarmado) + + + HEMTT Fire Truck + HEMTT anti-incendie + HEMTT (wersja pożarnicza) + HEMTT-Löschfahrzeug + HEMTT (camión de bomberos) + Пожарная машина HEMTT + HEMTT 消防卡车 + HEMTT contra incêndio + HEMTT 消防車 + HEMTT Autobotte + HEMTT 소방트럭 + + + Typhoon Water + タイフーン 給水 + 타이푼 급수 + Typhoon Water + Typhoon Acqua + Typhoon Water + Typhoon Water + + + Ram 1500 + ラム 1500 + 램 1500 + Ram 1500 + Ram 1500 + Ram 1500 + Ram 1500 + + + Ram 1500 (Fuel) + ラム 1500 (燃料) + 램 1500 (연료) + Ram 1500 (Treibstoff) + Ram 1500 (Carburante) + Ram 1500 (Carburant) + Ram 1500 (Combustible) + + + Ram 1500 (Services) + ラム 1500 (サービス) + 램 1500 (서비스) + Ram 1500 (Pannenhilfe) + Ram 1500 (Servizi) + Ram 1500 (Dépannage) + Ram 1500 (Servicios) + + + Ram 1500 (Repair) + ラム 1500 (修理) + 램 1500 (정비) + Ram 1500 (Instandsetzung) + Ram 1500 (Riparazioni) + Ram 1500 (Réparation) + Ram 1500 (Reparaciones) + + + Ram 1500 (Comms) + ラム 1500 (通信) + 램 1500 (통신) + Ram 1500 (Kommunikation) + Ram 1500 (Comunicazioni) + Ram 1500 (Communication) + Ram 1500 (Comunicaciones) + + + Ram 1500 (HMG) + ラム 1500 (HMG) + 램 1500 (중기관총) + Ram 1500 (HMG) + Ram 1500 (HMG) + Ram 1500 (HMG) + Ram 1500 (HMG) + + + Ram 1500 (MMG) + ラム 1500 (MMG) + 램 1500 (중형기관총) + Ram 1500 (MMG) + Ram 1500 (MMG) + Ram 1500 (MMG) + Ram 1500 (MMG) + + + Ram 1500 (MRL) + ラム 1500 (MRL) + 램 1500 (다연장로켓) + Ram 1500 (MRL) + Ram 1500 (MRL) + Ram 1500 (MRL) + Ram 1500 (MRL) + + + Ram 1500 (AA) + ラム 1500 (対空) + 램 1500 (대공) + Ram 1500 (AA) + Ram 1500 (AA) + Ram 1500 (AA) + Ram 1500 (AA) + + + Ram 1500 (Covered) + ラム 1500 (カバー) + 램 1500 (커버) + Ram 1500 (Abgedeckt) + Ram 1500 (Coperto) + Ram 1500 (couvert) + Ram 1500 (Cubierto) + + + Ram 1500 (Water) + ラム 1500 (給水) + 램 1500 (급수) + Ram 1500 (Wasser) + Ram 1500 (Acqua) + Ram 1500 (eau) + Ram 1500 (Agua) + + + RSG60 + RSG60 + RSG60 + RSG60 + RSG60 + RSG60 + RSG60 + + + AMOS Container + AMOS コンテナ + AMOS 컨테이너 + AMOS Container + AMOS Container + AMOS Container + Contenedor AMOS + + + Drone40 + ドローン40 + 드론40 + Drone40 + Drone40 + Drone40 + Drone40 + + + Drone40 Scout + ドローン40 偵察型 + 드론40 정찰 + Drone40 Scout + Drone40 Scout + Drone40 Scout + Drone40 Scout + + + Drone40 HE + ドローン40 榴弾 + 드론40 고폭 + Drone40 HE + Drone40 HE + Drone40 HE + Drone40 HE + + + Drone40 Smoke (White) + ドローン40 発煙弾 (白) + 드론40 연막 (백색) + Drone40 Smoke (Weiß) + Drone40 Smoke (Bianco) + Drone40 Fumée (Blanc) + Drone40 Humo (Blanco) + + + Drone40 Smoke (Blue) + ドローン40 発煙弾 (青) + 드론40 연막 (청색) + Drone40 Smoke (Blau) + Drone40 Smoke (Blu) + Drone40 Fumée (Bleu) + Drone40 Humo (Azul) + + + Drone40 Smoke (Red) + ドローン40 発煙弾 (赤) + 드론40 연막 (적색) + Drone40 Smoke (Rot) + Drone40 Smoke (Rosso) + Drone40 Fumée (Rouge) + Drone40 Humo (Rojo) + + + Drone40 Smoke (Green) + ドローン40 発煙弾 (緑) + 드론40 연막 (녹색) + Drone40 Smoke (Grün) + Drone40 Smoke (Verde) + Drone40 Fumée (Vert) + Drone40 Humo (Verde) + + + Drone40 Smoke (Orange) + ドローン40 発煙弾 (橙) + 드론40 연막 (주황색) + Drone40 Smoke (Orange) + Drone40 Smoke (Arancione) + Drone40 Fumée (Orange) + Drone40 Humo (Naranja) + + + diff --git a/addons/compat_rf/config.cpp b/addons/compat_rf/config.cpp new file mode 100644 index 00000000000..52ef83c1b74 --- /dev/null +++ b/addons/compat_rf/config.cpp @@ -0,0 +1,19 @@ +#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", "OverlordZorn[CVO]"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_rf/script_component.hpp b/addons/compat_rf/script_component.hpp new file mode 100644 index 00000000000..2cc45da4904 --- /dev/null +++ b/addons/compat_rf/script_component.hpp @@ -0,0 +1,6 @@ +#define COMPONENT compat_rf +#define COMPONENT_BEAUTIFIED Reaction Forces Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/compat_rhs_afrf3/CfgAmmo.hpp b/addons/compat_rhs_afrf3/CfgAmmo.hpp index 54ff3bd2c2d..11aee03d795 100644 --- a/addons/compat_rhs_afrf3/CfgAmmo.hpp +++ b/addons/compat_rhs_afrf3/CfgAmmo.hpp @@ -219,6 +219,10 @@ class CfgAmmo { EGVAR(frag,force) = 0; }; + class SmokeShell; + class rhs_ammo_rdg2_white: SmokeShell { + EGVAR(grenades,rollVectorDirAndUp)[] = {{0, 1, 0}, {0, 0, 1}}; + }; class Sh_125mm_APFSDS; class Sh_125mm_HE; diff --git a/addons/compat_rhs_afrf3/CfgVehicles.hpp b/addons/compat_rhs_afrf3/CfgVehicles.hpp index 622d764ad2d..2ba6caf56f9 100644 --- a/addons/compat_rhs_afrf3/CfgVehicles.hpp +++ b/addons/compat_rhs_afrf3/CfgVehicles.hpp @@ -60,6 +60,8 @@ class CfgVehicles { EGVAR(vehicle_damage,turretFireProb) = 0.7; EGVAR(vehicle_damage,engineFireProb) = 0.7; EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + + class EGVAR(interaction,anims); }; class rhs_infantry_msv_base; @@ -156,68 +158,186 @@ class CfgVehicles { 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 EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide { + positions[] = {{-1.1, 2, -0.3}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l2_unhide { + positions[] = {{-1.1, 1.05, -0.3}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l3_unhide { + positions[] = {{-1.1, -1.1, -0.3}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r1_unhide { + positions[] = {{1.1, 1.93, -0.3}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r2_unhide { + positions[] = {{1.1, 0.25, -0.3}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r3_unhide { + positions[] = {{1.1, -1.1, -0.3}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + }; }; 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"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_1 { camLocation[] = {-1.38184, -0.575, -0.145}; camAttach = -90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; }; - }; + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide { + positions[] = {{-1.7, 0.55, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l2_unhide { + positions[] = {{-1.7, -0.95, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l3_unhide { + positions[] = {{-1.7, -1.45, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l4_unhide { + positions[] = {{-1.7, -2.7, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r1_unhide { + positions[] = {{0.8, 1, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r2_unhide { + positions[] = {{0.8, 0.12, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r3_unhide { + positions[] = {{0.8, -0.7, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r4_unhide { + positions[] = {{0.8, -1.85, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + }; + }; 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"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_1 { camLocation[] = {0.760254, -0.459473, 0.526328}; camAttach = 90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_2 { camLocation[] = {0.770508, -1.21924, 0.526954}; camAttach = 90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_3 { camLocation[] = {-1.13, -1.2085, 0.490339}; camAttach = -90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_4 { camLocation[] = {-1.14124, -0.416992, 0.460611}; camAttach = -90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_5 { camLocation[] = {-0.932983, -0.326172, 0.647666}; camAttach = -45; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; + }; + }; + + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.45, 0, 0.25}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.45, -1.68, 0.15}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.45, -2.87, 0.15}}; + }; + class crate_l4_unhide: crate_l4_unhide { + enabled = 0; + }; + class crate_r1_unhide: crate_r1_unhide { + positions[] = {{1.1, 0.97, 0.15}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.1, -1.5, 0.15}}; + }; + class crate_r3_unhide: crate_r3_unhide { + enabled = 0; + }; + class crate_r4_unhide: crate_r4_unhide { + enabled = 0; }; }; }; @@ -226,38 +346,56 @@ class CfgVehicles { class view_0 { camLocation[] = {0.589844, -0.314941, 0.449678}; camAttach = 45; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_1 { camLocation[] = {0.809082, -0.442871, 0.276865}; camAttach = 90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_2 { camLocation[] = {0.819092, -1.24414, 0.27857}; camAttach = 90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_3 { camLocation[] = {-1.1012, -1.22461, 0.341089}; camAttach = -90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_4 { camLocation[] = {-1.11597, -0.458984, 0.307256}; camAttach = -90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_5 { camLocation[] = {-0.869995, -0.304688, 0.461181}; camAttach = -45; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; + }; + }; + + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.45, 0, 0}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.45, -1.68, 0}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.45, -2.87, 0}}; + }; + class crate_r1_unhide: crate_l3_unhide { + positions[] = {{1.1, 0.97, 0}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.1, -1.5, 0}}; }; }; }; @@ -279,11 +417,289 @@ class CfgVehicles { EGVAR(vehicle_damage,turretFireProb) = 0.5; EGVAR(vehicle_damage,engineFireProb) = 0.8; EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + + class EGVAR(interaction,anims) { + class crate_l1_unhide { + positions[] = {{-1.45, 0.5, -0.65}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l2_unhide { + positions[] = {{-1.45, -0.2, -0.65}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l3_unhide { + positions[] = {{-1.45, -1.2, -0.65}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r1_unhide { + positions[] = {{1.45, 0.6, -0.65}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r2_unhide { + positions[] = {{1.45, -0.4, -0.65}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r3_unhide { + positions[] = {{1.45, -1.2, -0.65}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + }; + }; + class rhs_bmd1_base: rhs_bmd_base {}; + class rhs_bmd1p: rhs_bmd1_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.45, 0.5, -0.8}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.45, -0.2, -0.8}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.45, -1.2, -0.8}}; + }; + class crate_r1_unhide: crate_l3_unhide { + positions[] = {{1.45, 0.6, -0.8}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.45, -0.4, -0.8}}; + }; + class crate_r3_unhide: crate_r3_unhide { + positions[] = {{1.45, -1.2, -0.8}}; + }; + }; }; + class rhs_bmd2_base: rhs_bmd_base {}; + class rhs_bmd2: rhs_bmd2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.45, 0.5, -0.8}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.45, -0.2, -0.8}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.45, -1.2, -0.8}}; + }; + class crate_r1_unhide: crate_l3_unhide { + positions[] = {{1.45, 0.6, -0.8}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.45, -0.4, -0.8}}; + }; + class crate_r3_unhide: crate_r3_unhide { + positions[] = {{1.45, -1.2, -0.8}}; + }; + }; + }; + class rhs_bmd2m: rhs_bmd2 { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.45, 0.5, -0.7}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.45, -0.2, -0.7}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.45, -1.2, -0.7}}; + }; + class crate_r1_unhide: crate_l3_unhide { + positions[] = {{1.45, 0.6, -0.7}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.45, -0.4, -0.7}}; + }; + class crate_r3_unhide: crate_r3_unhide { + positions[] = {{1.45, -1.2, -0.7}}; + }; + }; + }; + class rhs_bmp1tank_base: Tank_F { EGVAR(map,vehicleLightColor)[] = {0,1,0,0.1}; EGVAR(refuel,fuelCapacity) = 460; }; + 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 EGVAR(interaction,anims) { + class crate_l1_unhide { + positions[] = {{-1.55, 1.1, -0.55}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l2_unhide { + positions[] = {{-1.55, 0.35, -0.55}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l3_unhide { + positions[] = {{-1.55, -0.6, -0.55}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r1_unhide { + positions[] = {{1.55, 1.75, -0.55}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r2_unhide { + positions[] = {{1.55, -0.25, -0.55}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r3_unhide { + positions[] = {{1.55, -1, -0.55}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + }; + }; + class rhs_bmp1_vdv: rhs_bmp_base {}; + class rhs_bmp1d_vdv: rhs_bmp1_vdv { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_r3_unhide: crate_r3_unhide { + positions[] = {{1.5, -1.2, -0.55}}; + }; + }; + }; + class rhs_prp3_vdv: rhs_bmp1_vdv { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + enabled = 0; + }; + class crate_l2_unhide: crate_l2_unhide { + enabled = 0; + }; + class crate_l3_unhide: crate_l3_unhide { + enabled = 0; + }; + class crate_r1_unhide: crate_l3_unhide { + enabled = 0; + }; + class crate_r2_unhide: crate_r2_unhide { + enabled = 0; + }; + class crate_r3_unhide: crate_r3_unhide { + enabled = 0; + }; + }; + }; + + class rhs_bmp2e_vdv: rhs_bmp1_vdv { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.8, 1.05, -0.55}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.8, 0.35, -0.55}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.8, -0.65, -0.55}}; + }; + class crate_r1_unhide: crate_l3_unhide { + positions[] = {{1.4, 1.7, -0.55}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.4, -0.25, -0.55}}; + }; + class crate_r3_unhide: crate_r3_unhide { + positions[] = {{1.4, -1.05, -0.55}}; + }; + }; + }; + class rhs_bmp2_vdv: rhs_bmp2e_vdv { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.8, 1.2, -0.55}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.8, 0.5, -0.55}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.8, -0.5, -0.55}}; + }; + class crate_r1_unhide: crate_l3_unhide { + positions[] = {{1.4, 1.85, -0.55}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.4, -0.1, -0.55}}; + }; + class crate_r3_unhide: crate_r3_unhide { + positions[] = {{1.4, -0.9, -0.55}}; + }; + }; + }; + class rhs_bmp2e_msv: rhs_bmp2e_vdv {}; + class rhs_Ob_681_2: rhs_bmp2e_msv { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.8, 1.2, -0.55}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.8, 0.5, -0.55}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.8, -0.5, -0.55}}; + }; + class crate_r1_unhide: crate_l3_unhide { + positions[] = {{1.4, 1.85, -0.55}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.4, -0.1, -0.55}}; + }; + class crate_r3_unhide: crate_r3_unhide { + positions[] = {{1.4, -0.9, -0.55}}; + }; + }; + }; + + class rhs_brm1k_base: rhs_bmp2e_vdv { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + enabled = 0; + }; + class crate_l2_unhide: crate_l2_unhide { + enabled = 0; + }; + class crate_l3_unhide: crate_l3_unhide { + enabled = 0; + }; + class crate_r1_unhide: crate_l3_unhide { + enabled = 0; + }; + class crate_r2_unhide: crate_r2_unhide { + enabled = 0; + }; + class crate_r3_unhide: crate_r3_unhide { + enabled = 0; + }; + }; + }; + class rhs_bmp3tank_base: Tank_F { EGVAR(refuel,fuelCapacity) = 460; EGVAR(vehicle_damage,hullDetonationProb) = 0.2; @@ -293,37 +709,39 @@ class CfgVehicles { 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"}; + 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"}; + 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"}; + 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"}; + roles[] = {"cargo"}; }; }; }; + class rhs_a3spruttank_base: Tank_F { EGVAR(refuel,fuelCapacity) = 400; EGVAR(vehicle_damage,hullDetonationProb) = 0.2; @@ -334,6 +752,7 @@ class CfgVehicles { 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; @@ -344,15 +763,6 @@ class CfgVehicles { 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", @@ -434,7 +844,11 @@ class CfgVehicles { "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", - "era_31_hitpoint", "era_32_hitpoint" + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint", + "era_37_hitpoint", "era_38_hitpoint", "era_39_hitpoint", "era_40_hitpoint", "era_41_hitpoint", "era_42_hitpoint", + "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", "era_46_hitpoint", "era_47_hitpoint", "era_48_hitpoint", + "era_49_hitpoint", "era_50_hitpoint", "era_58_hitpoint", "era_59_hitpoint", "era_60_hitpoint", "era_61_hitpoint", + "era_62_hitpoint", "era_63_hitpoint", "era_64_hitpoint", "era_65_hitpoint", "era_66_hitpoint", "era_67_hitpoint" }; EGVAR(vehicle_damage,slatHitpoints)[] = { "SLAT_51_hitpoint", "SLAT_52_hitpoint", "SLAT_53_hitpoint", @@ -470,6 +884,9 @@ class CfgVehicles { "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", "era_46_hitpoint", "era_47_hitpoint", "era_48_hitpoint", "era_49_hitpoint", "era_50_hitpoint" }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "slat_51_hitpoint", "slat_52_hitpoint", "slat_53_hitpoint", "slat_54_hitpoint" + }; }; class rhs_t90am_tv: rhs_t90_tv { EGVAR(vehicle_damage,eraHitpoints)[] = { @@ -483,7 +900,7 @@ class CfgVehicles { "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", "era_46_hitpoint", "era_47_hitpoint", "era_48_hitpoint", "era_49_hitpoint", "era_50_hitpoint", "era_51_hitpoint", "era_52_hitpoint", "era_53_hitpoint", "era_54_hitpoint", "era_55_hitpoint", "era_56_hitpoint", "era_57_hitpoint", "era_58_hitpoint", "era_59_hitpoint", "era_60_hitpoint", - "era_51_hitpoint", "era_62_hitpoint", "era_63_hitpoint", "era_64_hitpoint", "era_65_hitpoint", "era_66_hitpoint" + "era_61_hitpoint", "era_62_hitpoint", "era_63_hitpoint", "era_64_hitpoint", "era_65_hitpoint", "era_66_hitpoint" }; EGVAR(vehicle_damage,slatHitpoints)[] = { "SLAT_18_hitpoint", "SLAT_19_hitpoint", "SLAT_20_hitpoint", "SLAT_21_hitpoint", @@ -492,10 +909,31 @@ class CfgVehicles { }; }; class rhs_t90sm_tv: rhs_t90am_tv { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", + "era_5_hitpoint", "era_6_hitpoint", "era_7_hitpoint", "era_8_hitpoint", + "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", + "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", + "era_21_hitpoint", "era_22_hitpoint", "era_24_hitpoint", "era_25_hitpoint", + "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", + "era_35_hitpoint", "era_36_hitpoint", "era_37_hitpoint", "era_38_hitpoint", + "era_39_hitpoint", "era_40_hitpoint", "era_41_hitpoint", "era_42_hitpoint", + "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", "era_46_hitpoint", + "era_47_hitpoint", "era_48_hitpoint", "era_49_hitpoint", "era_50_hitpoint", + "era_26_hitpoint", "era_55_hitpoint", "era_56_hitpoint", "era_57_hitpoint", + "era_58_hitpoint", "era_59_hitpoint", "era_60_hitpoint", "era_61_hitpoint", + "era_62_hitpoint", "era_63_hitpoint", "era_64_hitpoint", "era_65_hitpoint", + "era_66_hitpoint", "era_23_hitpoint" + }; EGVAR(vehicle_damage,slatHitpoints)[] = { - "SLAT_23_hitpoint", "SLAT_26_hitpoint", "SLAT_51_hitpoint", "SLAT_52_hitpoint", - "SLAT_53_hitpoint", "SLAT_54_hitpoint", "SLAT_55_hitpoint", "SLAT_56_hitpoint", - "SLAT_57_hitpoint" + "slat_23_hitpoint", "slat_26_hitpoint", "slat_51_hitpoint", + "slat_52_hitpoint", "slat_53_hitpoint", "slat_54_hitpoint", + "slat_55_hitpoint", "slat_56_hitpoint", "slat_57_hitpoint", + "slat_18_hitpoint", "slat_19_hitpoint", "slat_20_hitpoint", + "slat_21_hitpoint", "slat_22_hitpoint", "slat_24_hitpoint", + "slat_25_hitpoint" }; }; @@ -539,6 +977,35 @@ class CfgVehicles { "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint" }; }; + class rhs_t80um: rhs_t80u { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", + "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", + "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint" + }; + }; + + class rhs_t15_base; + class rhs_t15_tv: rhs_t15_base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", + "era_5_hitpoint", "era_6_hitpoint", "era_7_hitpoint", "era_8_hitpoint", + "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", + "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", + "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", + "era_29_hitpoint", "era_30_hitpoint", "era_31_hitpoint", "era_32_hitpoint", + "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint", + "era_37_hitpoint" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "slat_38_hitpoint", "slat_39_hitpoint", "slat_40_hitpoint", "slat_41_hitpoint" + }; + }; // Wirecutter Backpacks class rhs_assault_umbts; diff --git a/addons/compat_rhs_afrf3/CfgWeapons.hpp b/addons/compat_rhs_afrf3/CfgWeapons.hpp index a6def44c402..a25d1f7cd05 100644 --- a/addons/compat_rhs_afrf3/CfgWeapons.hpp +++ b/addons/compat_rhs_afrf3/CfgWeapons.hpp @@ -108,19 +108,7 @@ class CfgWeapons { EGVAR(overpressure,offset) = 1.65; }; - class H_HelmetB; - class rhs_tsh4: H_HelmetB { - HEARING_PROTECTION_VICCREW; - }; - - class rhs_6b47_bare; - class rhs_6b48: rhs_6b47_bare { - HEARING_PROTECTION_VICCREW; - }; - - class rhs_zsh7a: H_HelmetB { - HEARING_PROTECTION_VICCREW; - }; + class rhs_zsh7a; class rhs_zsh7a_alt: rhs_zsh7a { ACE_Protection = 1; }; @@ -133,22 +121,6 @@ class CfgWeapons { ACE_Protection = 1; }; - class rhs_gssh18: H_HelmetB { - HEARING_PROTECTION_EARMUFF; - }; - - class rhs_6b47; - class rhs_6b47_6m2: rhs_6b47 { - HEARING_PROTECTION_PELTOR; - }; - class rhs_6b47_6m2_1: rhs_6b47 { - HEARING_PROTECTION_PELTOR; - }; - - class rhs_6m2: H_HelmetB { - HEARING_PROTECTION_PELTOR; - }; - class rhs_weap_d81; class rhs_weap_2a70: rhs_weap_d81 { // "Low pressure" 100mm cannon EGVAR(overpressure,range) = 15; diff --git a/addons/compat_rhs_afrf3/XEH_postInit.sqf b/addons/compat_rhs_afrf3/XEH_postInit.sqf index be180179a55..e740d0d8a66 100644 --- a/addons/compat_rhs_afrf3/XEH_postInit.sqf +++ b/addons/compat_rhs_afrf3/XEH_postInit.sqf @@ -1,5 +1,7 @@ #include "script_component.hpp" +if !(["ace_nametags"] call EFUNC(common,isModLoaded)) exitWith {}; + private _russianRankIcons = [ QPATHTOEF(nametags,UI\icons_russia\private_gs.paa), QPATHTOEF(nametags,UI\icons_russia\corporal_gs.paa), diff --git a/addons/compat_rhs_afrf3/XEH_preInit.sqf b/addons/compat_rhs_afrf3/XEH_preInit.sqf index b47cf6628db..2ca4338e90c 100644 --- a/addons/compat_rhs_afrf3/XEH_preInit.sqf +++ b/addons/compat_rhs_afrf3/XEH_preInit.sqf @@ -6,4 +6,12 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +// Disable RHS' wheel replacement mechanic +if (["ace_repair"] call EFUNC(common,isModLoaded)) then { + RHS_Retread_Enabled = false; + rhs_btr70_EnableRetread = false; + rhs_TypeTirePressure = 1; + RHS_BTR_Effects_Init = true; +}; + ADDON = true; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgVehicles.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgVehicles.hpp index fd889cd096e..fb52cc6373c 100644 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgVehicles.hpp +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgVehicles.hpp @@ -5,8 +5,7 @@ class CfgVehicles { class StaticGrenadeLauncher; class rhs_SPG9_base: AT_01_base_F { - // ENABLE_CSW_ATTRIBUTE; - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = QGVAR(rhs_weap_SPG9); magazineLocation = "_target selectionPosition 'breach'"; @@ -19,15 +18,14 @@ class CfgVehicles { }; class rhs_SPG9M_base: rhs_SPG9_base { - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 1; disassembleWeapon = QGVAR(spg9m_carry); }; }; class rhs_Kornet_Base: AT_01_base_F { - // ENABLE_CSW_ATTRIBUTE; - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = QGVAR(rhs_weap_9K133_launcher); magazineLocation = "_target selectionPosition 'gun'"; @@ -40,8 +38,7 @@ class CfgVehicles { }; class rhs_Metis_Base: AT_01_base_F { - // ENABLE_CSW_ATTRIBUTE; - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = QGVAR(rhs_weap_9K115_2_launcher); magazineLocation = "_target selectionPosition 'gun'"; @@ -54,8 +51,7 @@ class CfgVehicles { }; class rhs_2b14_82mm_Base: StaticMortar { - // ENABLE_CSW_ATTRIBUTE; - class ACE_CSW { + class ace_csw { enabled = 1; magazineLocation = ""; proxyWeapon = QGVAR(rhs_weap_2b14); @@ -68,7 +64,7 @@ class CfgVehicles { }; class rhs_nsv_tripod_base: StaticMGWeapon { - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = QGVAR(rhs_weap_nsvt_effects); magazineLocation = "_target selectionPosition 'magazine'"; @@ -81,7 +77,7 @@ class CfgVehicles { }; class RHS_KORD_Base: rhs_nsv_tripod_base { - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 1; proxyWeapon = QGVAR(rhs_weap_KORD); disassembleWeapon = QGVAR(kord_carry); @@ -90,7 +86,7 @@ class CfgVehicles { }; class RHS_KORD_high_base: RHS_KORD_Base { - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 1; proxyWeapon = QGVAR(rhs_weap_KORD); disassembleWeapon = QGVAR(kord_carry); @@ -99,8 +95,7 @@ class CfgVehicles { }; class RHS_AGS30_TriPod_base: StaticGrenadeLauncher { - // ENABLE_CSW_ATTRIBUTE; - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = QGVAR(rhs_weap_AGS30); magazineLocation = "_target selectionPosition 'magazine'"; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgWeapons.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgWeapons.hpp index 1e8f4dbdfd1..e444a2aa32f 100644 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgWeapons.hpp +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgWeapons.hpp @@ -14,7 +14,7 @@ class CfgWeapons { class GVAR(2b14_carry): Launcher_Base_F { dlc = "ace"; - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 20; pickupTime = 25; @@ -40,7 +40,7 @@ class CfgWeapons { class GVAR(nsv_carry): Launcher_Base_F { dlc = "ace"; - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -64,7 +64,7 @@ class CfgWeapons { class GVAR(kord_carry): Launcher_Base_F { dlc = "ace"; - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -89,7 +89,7 @@ class CfgWeapons { class GVAR(ags30_carry): Launcher_Base_F { dlc = "ace"; - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -113,7 +113,7 @@ class CfgWeapons { class GVAR(spg9_carry): Launcher_Base_F { dlc = "ace"; - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -136,7 +136,7 @@ class CfgWeapons { }; class GVAR(spg9m_carry): GVAR(spg9_carry) { - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { class assembleTo { EGVAR(csw,spg9Tripod) = "rhs_SPG9M_MSV"; }; @@ -147,7 +147,7 @@ class CfgWeapons { class GVAR(metis_carry): Launcher_Base_F { dlc = "ace"; - class ACE_CSW { + class ace_csw { type = "mount"; deployTime = 4; pickupTime = 4; @@ -169,7 +169,7 @@ class CfgWeapons { class GVAR(kornet_carry): Launcher_Base_F { dlc = "ace"; - class ACE_CSW { + class ace_csw { type = "mount"; deployTime = 4; pickupTime = 4; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/CfgMagazines.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/CfgMagazines.hpp index 4f8e808bd59..4ad71e5e24c 100644 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/CfgMagazines.hpp +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/CfgMagazines.hpp @@ -2,7 +2,7 @@ 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); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhs_mine_tm62m); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -12,7 +12,7 @@ class CfgMagazines { }; class rhs_mine_pmn2_mag: ATMine_Range_Mag { - EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_pmn2); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhs_mine_pmn2); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -22,7 +22,7 @@ class CfgMagazines { }; class rhs_mag_mine_ptm1: ATMine_Range_Mag { - EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_ptm1); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhs_mine_ptm1); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -32,7 +32,7 @@ class CfgMagazines { }; class rhs_mag_mine_pfm1: ATMine_Range_Mag { - EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_pfm1); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhs_mine_pfm1); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -42,8 +42,7 @@ class CfgMagazines { }; class rhs_ec75_mag: ATMine_Range_Mag { - EGVAR(explosives,DelayTime) = 1; - EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_ec75); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhs_ec75); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch"}; @@ -59,27 +58,27 @@ class CfgMagazines { }; class rhs_ec75_sand_mag: rhs_ec75_mag { - EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_ec75_sand); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhs_ec75_sand); }; class rhs_ec200_mag: rhs_ec75_mag { - EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_ec200); + 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); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhs_ec200_sand); }; class rhs_ec400_mag: rhs_ec75_mag { - EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_ec400); + 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); + 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); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhs_mine_msk40p_white); class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; class Tripwire { @@ -89,19 +88,19 @@ class CfgMagazines { }; class rhs_mine_msk40p_red_mag: rhs_mine_msk40p_white_mag { - EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_msk40p_red); + 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); + 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); + 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); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhs_mine_sm320_white); class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; class Tripwire { @@ -111,15 +110,15 @@ class CfgMagazines { }; class rhs_mine_sm320_red_mag: rhs_mine_sm320_white_mag { - EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_sm320_red); + 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); + 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); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhs_mine_ozm72_a); class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; class Tripwire { @@ -129,12 +128,11 @@ class CfgMagazines { }; class rhs_mine_ozm72_b_mag: rhs_mine_ozm72_a_mag { - EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_ozm72_b); + 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); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhs_mine_ozm72_c); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"Command", "MK16_Transmitter"}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/CfgWeapons.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/CfgWeapons.hpp new file mode 100644 index 00000000000..04edf4d754f --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/CfgWeapons.hpp @@ -0,0 +1,28 @@ +class CfgWeapons { + class H_HelmetB; + class rhs_tsh4: H_HelmetB { + HEARING_PROTECTION_VICCREW; + }; + class rhs_zsh7a: H_HelmetB { + HEARING_PROTECTION_VICCREW; + }; + class rhs_gssh18: H_HelmetB { + HEARING_PROTECTION_EARMUFF; + }; + class rhs_6m2: H_HelmetB { + HEARING_PROTECTION_PELTOR; + }; + + class rhs_6b47; + class rhs_6b47_6m2: rhs_6b47 { + HEARING_PROTECTION_PELTOR; + }; + class rhs_6b47_6m2_1: rhs_6b47 { + HEARING_PROTECTION_PELTOR; + }; + + class rhs_6b47_bare; + class rhs_6b48: rhs_6b47_bare { + HEARING_PROTECTION_VICCREW; + }; +}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/config.cpp new file mode 100644 index 00000000000..4a8056bf0c3 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" +#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" + +class CfgPatches { + class SUBADDON { + addonRootClass = QUOTE(COMPONENT); + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhs_main_loadorder", + "ace_hearing" + }; + skipWhenMissingDependencies = 1; + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/script_component.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/script_component.hpp new file mode 100644 index 00000000000..8edb825af34 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT hearing +#define SUBCOMPONENT_BEAUTIFIED Hearing +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/CfgVehicles.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/CfgVehicles.hpp deleted file mode 100644 index 047e264c6ec..00000000000 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/CfgVehicles.hpp +++ /dev/null @@ -1,10 +0,0 @@ -class CfgVehicles { - class RHS_Ural_Support_MSV_Base_01; - class RHS_Ural_Fuel_MSV_01: RHS_Ural_Support_MSV_Base_01 { - transportFuel = 0; - }; - class rhs_kraz255b1_base; - class rhs_kraz255b1_fuel_base: rhs_kraz255b1_base { - transportFuel = 0; - }; -}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp index 5101a383a31..8e1986b65f9 100644 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp @@ -18,4 +18,4 @@ class CfgPatches { }; }; -#include "CfgVehicles.hpp" +// ADDON kept for backward compatiblity diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/CfgVehicles.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/CfgVehicles.hpp new file mode 100644 index 00000000000..48da0552b85 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/CfgVehicles.hpp @@ -0,0 +1,145 @@ +class CfgVehicles { + class Wheeled_APC_F; + class rhs_btr_base: Wheeled_APC_F { + class EGVAR(interaction,anims) { + class wheel_1_unhide { + positions[] = {{-0.8, -1.7, 0}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + class wheel_2_unhide { + positions[] = {{0.35, -2.9, -0.1}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class rhs_btr70_vmf: rhs_btr_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class wheel_1_unhide: wheel_1_unhide { + positions[] = {{-1.2, -2.6, 0.2}}; + }; + class wheel_2_unhide: wheel_2_unhide { + positions[] = {{-0.3, -3.8, 0}}; + }; + }; + }; + + class rhs_btr70_msv: rhs_btr70_vmf {}; + class rhs_btr80_msv: rhs_btr70_msv { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class wheel_1_unhide: wheel_1_unhide { + positions[] = {{-1, -2.5, 0.6}}; + }; + class wheel_2_unhide: wheel_2_unhide { + enabled = 0; + }; + }; + }; + + class Truck_F; + class rhs_truck: Truck_F { + class EGVAR(interaction,anims) { + class spare_hide { + positions[] = {"_target selectionPosition ['spare', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class rhs_gaz66_vmf: rhs_truck {}; + class rhs_gaz66_ammo_base: rhs_gaz66_vmf { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class spare_hide: spare_hide { + positions[] = {"_target selectionPosition ['spare', 'FireGeometry', 'AveragePoint']"}; + }; + }; + }; + class rhs_gaz66_repair_base: rhs_gaz66_vmf { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class spare_hide: spare_hide { + positions[] = {"_target selectionPosition ['spare', 'FireGeometry', 'AveragePoint']"}; + }; + }; + }; + class rhs_gaz66_ap2_base: rhs_gaz66_vmf { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class spare_hide: spare_hide { + positions[] = {"_target selectionPosition ['spare', 'FireGeometry', 'AveragePoint']"}; + }; + }; + }; + + class RHS_Ural_BaseTurret: Truck_F { + class EGVAR(interaction,anims) { + class spare_hide { + positions[] = {"_target selectionPosition ['spare', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class rhs_zil131_base: Truck_F { + class EGVAR(interaction,anims) { + class spare_hide { + positions[] = {"_target selectionPosition ['spare', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class rhs_kraz255_base; + class rhs_kraz255b1_base: rhs_kraz255_base { + class EGVAR(interaction,anims) { + class spare_hide { + positions[] = {"_target selectionPosition ['spare', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class O_Truck_02_covered_F; + class rhs_kamaz5350: O_Truck_02_covered_F { + class EGVAR(interaction,anims) { + class spare_hide { + positions[] = {"_target selectionPosition ['spare', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class MRAP_02_base_F; + class rhs_tigr_base: MRAP_02_base_F { + class EGVAR(interaction,anims) { + class spare_hide { + positions[] = {"_target selectionPosition ['spare', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class Offroad_01_base_f; + class RHS_UAZ_Base: Offroad_01_base_f { + class EGVAR(interaction,anims) { + class spare_hide { + positions[] = {"_target selectionPosition ['spare', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; +}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/config.cpp new file mode 100644 index 00000000000..d6d4fab1077 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/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_repair" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Dystopian", "johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/script_component.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/script_component.hpp new file mode 100644 index 00000000000..1af928486c3 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT repair +#define SUBCOMPONENT_BEAUTIFIED Repair +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_afrf3/config.cpp b/addons/compat_rhs_afrf3/config.cpp index 44fcd30fcbe..8bf56684858 100644 --- a/addons/compat_rhs_afrf3/config.cpp +++ b/addons/compat_rhs_afrf3/config.cpp @@ -1,5 +1,4 @@ #include "script_component.hpp" -#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" class CfgPatches { class ADDON { @@ -7,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"rhs_main_loadorder"}; + requiredAddons[] = {"ace_common", "rhs_main_loadorder"}; author = ECSTRING(common,ACETeam); authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "commy2", "Skengman2"}; url = ECSTRING(main,URL); diff --git a/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgVehicles.hpp b/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgVehicles.hpp index 220aec4c245..1a15fc03f40 100644 --- a/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgVehicles.hpp +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgVehicles.hpp @@ -1,8 +1,7 @@ class CfgVehicles { class StaticMGWeapon; class rhs_DSHKM_base: StaticMGWeapon { - // ENABLE_CSW_ATTRIBUTE; - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = QGVAR(rhs_weap_DSHKM); magazineLocation = "_target selectionPosition 'otocvez'"; @@ -14,7 +13,7 @@ class CfgVehicles { }; }; class rhs_DSHkM_Mini_TriPod_base: rhs_DSHKM_base { - class ACE_CSW: ACE_CSW { + 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 index 15ff9488cad..279ec98eaa4 100644 --- a/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgWeapons.hpp +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgWeapons.hpp @@ -7,7 +7,7 @@ class CfgWeapons { }; class GVAR(dshkm_carry): Launcher_Base_F { - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; diff --git a/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgAmmo.hpp b/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgAmmo.hpp index 0808c7ff1d2..458969b7c0b 100644 --- a/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgAmmo.hpp +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgAmmo.hpp @@ -1,83 +1,83 @@ class CfgAmmo { class APERSMine_Range_Ammo; class rhs_mine_a200_bz_ammo: APERSMine_Range_Ammo { - ace_explosives_defuseObjectPosition[] = {0, 0, 0.035}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.035}; }; class rhs_mine_a200_dz35_ammo: rhs_mine_a200_bz_ammo { - ace_explosives_defuseObjectPosition[] = {0, 0, 0.02}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; }; class rhs_mine_glasmine43_hz_ammo: APERSMine_Range_Ammo { - ace_explosives_defuseObjectPosition[] = {0, 0, 0.015}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.015}; }; class rhs_mine_glasmine43_bz_ammo: rhs_mine_glasmine43_hz_ammo { - ace_minedetector_detectable = 0; + EGVAR(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}; + EGVAR(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}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0.046, 0.055}; }; class rhs_mine_M3_pressure_ammo: APERSMine_Range_Ammo { - ace_explosives_defuseObjectPosition[] = {0, 0, 0.015}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.015}; }; class rhs_mine_M3_tripwire_ammo: rhs_mine_M3_pressure_ammo { - ace_explosives_defuseObjectPosition[] = {0, 0, 0.055}; + EGVAR(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}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.072}; }; class rhs_mine_M7A2_ammo: APERSMine_Range_Ammo { - ace_explosives_defuseObjectPosition[] = {0, 0, 0.067}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.067}; }; class rhs_mine_Mk2_pressure_ammo: APERSMine_Range_Ammo { - ace_explosives_defuseObjectPosition[] = {0, 0, 0.02}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; }; class rhs_mine_Mk2_tripwire_ammo: rhs_mine_Mk2_pressure_ammo { - ace_explosives_defuseObjectPosition[] = {0, 0, 0.055}; + EGVAR(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}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.03}; }; class rhs_mine_smine35_trip_ammo: rhs_mine_bounding_trigger_base { - ace_explosives_defuseObjectPosition[] = {0, 0, 0.04}; + EGVAR(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}; + EGVAR(explosives,defuseObjectPosition)[] = {-0.03, 0, 0.015}; }; class rhs_mine_smine44_press_ammo: APERSBoundingMine_Range_Ammo { - ace_explosives_defuseObjectPosition[] = {-0.02, 0, 0.02}; + EGVAR(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}; + EGVAR(explosives,defuseObjectPosition)[] = {-1, 0, 0.25}; }; class rhs_mine_stockmine43_4m_ammo: rhs_mine_stockmine43_2m_ammo { - ace_explosives_defuseObjectPosition[] = {-2, 0, 0.25}; + EGVAR(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}; + EGVAR(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 index ce882e18258..d25a27bebd8 100644 --- a/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgMagazines.hpp +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgMagazines.hpp @@ -1,7 +1,7 @@ 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"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_a200_bz"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -11,7 +11,7 @@ class CfgMagazines { }; class rhs_mine_a200_dz35_mag: rhs_mine_a200_bz_mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_a200_dz35"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_a200_dz35"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -21,7 +21,7 @@ class CfgMagazines { }; class rhs_mine_glasmine43_hz_mag: APERSMine_Range_Mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_glasmine43_hz"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_glasmine43_hz"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -31,12 +31,12 @@ class CfgMagazines { }; class rhs_mine_glasmine43_bz_mag: rhs_mine_glasmine43_hz_mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_glasmine43_bz"; + EGVAR(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"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_m2a3b_press"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -46,7 +46,7 @@ class CfgMagazines { }; class rhs_mine_m2a3b_trip_mag: rhs_mine_m2a3b_press_mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_m2a3b_trip"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_m2a3b_trip"; class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; class Tripwire { @@ -56,7 +56,7 @@ class CfgMagazines { }; class rhs_mine_m3_pressure_mag: APERSMine_Range_Mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_m3_pressure"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_m3_pressure"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -67,7 +67,7 @@ class CfgMagazines { class APERSTripMine_Wire_Mag; class rhs_mine_M3_tripwire_mag: APERSTripMine_Wire_Mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_M3_tripwire"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_M3_tripwire"; class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; class Tripwire { @@ -78,7 +78,7 @@ class CfgMagazines { class ATMine_Range_Mag; class rhs_mine_TM43_mag: ATMine_Range_Mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_TM43"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_TM43"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -88,7 +88,7 @@ class CfgMagazines { }; class rhs_mine_M7A2_mag: APERSMine_Range_Mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_M7A2"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_M7A2"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -98,7 +98,7 @@ class CfgMagazines { }; class rhs_mine_mk2_pressure_mag: APERSMine_Range_Mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_mk2_pressure"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_mk2_pressure"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -108,7 +108,7 @@ class CfgMagazines { }; class rhs_mine_Mk2_tripwire_mag: APERSTripMine_Wire_Mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_Mk2_tripwire"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_Mk2_tripwire"; class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; class Tripwire { @@ -118,7 +118,7 @@ class CfgMagazines { }; class rhs_mine_smine35_press_mag: APERSBoundingMine_Range_Mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_smine35_press"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_smine35_press"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -128,7 +128,7 @@ class CfgMagazines { }; class rhs_mine_smine35_trip_mag: rhs_mine_smine35_press_mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_smine35_trip"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_smine35_trip"; class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; class Tripwire { @@ -138,7 +138,7 @@ class CfgMagazines { }; class rhs_mine_smine44_trip_mag: APERSBoundingMine_Range_Mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_smine44_trip"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_smine44_trip"; class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; class Tripwire { @@ -148,7 +148,7 @@ class CfgMagazines { }; class rhs_mine_smine44_press_mag: rhs_mine_smine44_trip_mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_smine44_press"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_smine44_press"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -158,7 +158,7 @@ class CfgMagazines { }; class rhs_mine_stockmine43_2m_mag: APERSTripMine_Wire_Mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_stockmine43_2m"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_stockmine43_2m"; class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; class Tripwire { @@ -168,7 +168,7 @@ class CfgMagazines { }; class rhs_mine_stockmine43_4m_mag: rhs_mine_stockmine43_2m_mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_stockmine43_4m"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_mine_stockmine43_4m"; class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; class Tripwire { @@ -179,7 +179,7 @@ class CfgMagazines { class DemoCharge_Remote_Mag; class rhs_charge_M2tet_x2_mag: DemoCharge_Remote_Mag { - ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_charge_M2tet_x2"; + EGVAR(explosives,setupObject) = "ACE_Explosives_Place_rhs_charge_M2tet_x2"; class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch"}; class Timer { diff --git a/addons/compat_rhs_gref3/config.cpp b/addons/compat_rhs_gref3/config.cpp index f2e7aeacde3..84717435bed 100644 --- a/addons/compat_rhs_gref3/config.cpp +++ b/addons/compat_rhs_gref3/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"rhsgref_main_loadorder"}; + requiredAddons[] = {"ace_common", "rhsgref_main_loadorder"}; skipWhenMissingDependencies = 1; author = ECSTRING(common,ACETeam); authors[] = {"PabstMirror", "Ruthberg", "Anton"}; diff --git a/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/CfgMagazines.hpp b/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/CfgMagazines.hpp index c004f584467..e7c00c95d2b 100644 --- a/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/CfgMagazines.hpp +++ b/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/CfgMagazines.hpp @@ -3,22 +3,22 @@ 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); + 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); + 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); + 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); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhssaf_mine_mrud_d); class ACE_Triggers { SupportedTriggers[] = {"Command", "MK16_Transmitter"}; class Command { @@ -29,7 +29,7 @@ class CfgMagazines { }; class rhssaf_mine_pma3_mag: ATMine_Range_Mag { - EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhssaf_mine_pma3); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhssaf_mine_pma3); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -39,7 +39,7 @@ class CfgMagazines { }; class rhssaf_mine_tma4_mag: ATMine_Range_Mag { - EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhssaf_mine_tma4); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhssaf_mine_tma4); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -51,9 +51,8 @@ class CfgMagazines { 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); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhssaf_tm100); class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter"}; class Timer { @@ -67,10 +66,10 @@ class CfgMagazines { }; class rhssaf_tm200_mag: rhssaf_tm100_mag { - EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhssaf_tm200); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhssaf_tm200); }; class rhssaf_tm500_mag: rhssaf_tm100_mag { - EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhssaf_tm500); + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhssaf_tm500); }; }; diff --git a/addons/compat_rhs_saf3/config.cpp b/addons/compat_rhs_saf3/config.cpp index 75ee4f55307..71340640ce3 100644 --- a/addons/compat_rhs_saf3/config.cpp +++ b/addons/compat_rhs_saf3/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"rhssaf_main_loadorder"}; + requiredAddons[] = {"ace_common", "rhssaf_main_loadorder"}; skipWhenMissingDependencies = 1; author = ECSTRING(common,ACETeam); authors[] = {}; diff --git a/addons/compat_rhs_usf3/CfgMagazineWells.hpp b/addons/compat_rhs_usf3/CfgMagazineWells.hpp deleted file mode 100644 index 01223ec141b..00000000000 --- a/addons/compat_rhs_usf3/CfgMagazineWells.hpp +++ /dev/null @@ -1,11 +0,0 @@ -class CfgMagazineWells { - class ace_hellfire_K { - ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_k)}; - }; - class ace_hellfire_N { - ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_n)}; - }; - class ace_hellfire_L { - ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_l)}; - }; -}; diff --git a/addons/compat_rhs_usf3/CfgMagazines.hpp b/addons/compat_rhs_usf3/CfgMagazines.hpp index f11dad081cc..471b345dcd7 100644 --- a/addons/compat_rhs_usf3/CfgMagazines.hpp +++ b/addons/compat_rhs_usf3/CfgMagazines.hpp @@ -38,21 +38,4 @@ class cfgMagazines { EGVAR(overpressure,range) = 0; EGVAR(overpressure,damage) = 0; }; - - class rhs_mag_AGM114K_2; - class GVAR(pylon_mag_2rnd_hellfire_k): rhs_mag_AGM114K_2 { - displayName = "2x AGM-114K [ACE]"; - pylonWeapon = "ace_hellfire_launcher"; - ammo = "ACE_Hellfire_AGM114K"; - }; - class GVAR(pylon_mag_2rnd_hellfire_n): rhs_mag_AGM114K_2 { - displayName = "2x AGM-114N [ACE]"; - pylonWeapon = "ace_hellfire_launcher_N"; - ammo = "ACE_Hellfire_AGM114N"; - }; - class GVAR(pylon_mag_2rnd_hellfire_l): rhs_mag_AGM114K_2 { - displayName = "2x AGM-114L [ACE]"; - pylonWeapon = "ace_hellfire_launcher_L"; - ammo = "ACE_Hellfire_AGM114L"; - }; }; diff --git a/addons/compat_rhs_usf3/CfgVehicles.hpp b/addons/compat_rhs_usf3/CfgVehicles.hpp index 0593c5a868a..3933e543ecf 100644 --- a/addons/compat_rhs_usf3/CfgVehicles.hpp +++ b/addons/compat_rhs_usf3/CfgVehicles.hpp @@ -43,8 +43,7 @@ class CfgVehicles { EGVAR(refuel,fuelCapacity) = 302; }; - class Truck_F; - class Truck_01_base_F: Truck_F {}; + class Truck_01_base_F; class rhsusf_fmtv_base: Truck_01_base_F { EGVAR(refuel,fuelCapacity) = 219; }; @@ -55,8 +54,7 @@ class CfgVehicles { 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_usarmy_wd; class rhsusf_M977A4_AMMO_usarmy_wd: rhsusf_M977A4_usarmy_wd { EGVAR(rearm,defaultSupply) = 1200; }; diff --git a/addons/compat_rhs_usf3/CfgWeapons.hpp b/addons/compat_rhs_usf3/CfgWeapons.hpp index 46ac7e56ba3..50b09c760f9 100644 --- a/addons/compat_rhs_usf3/CfgWeapons.hpp +++ b/addons/compat_rhs_usf3/CfgWeapons.hpp @@ -206,170 +206,7 @@ class CfgWeapons { EGVAR(overpressure,offset) = 0.9; }; - // Fast Helmets - class rhsusf_opscore_01; - class rhsusf_opscore_ut_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_aor1_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_aor1_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_bk_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_fg_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_fg_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_fg_pelt_cam: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_paint_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_paint_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_paint_pelt_nsw_cam: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_aor2_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_aor2_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_ut_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_ut_pelt_cam: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_ut_pelt_nsw_cam: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mc_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mc_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_cover; - class rhsusf_opscore_mc_cover_pelt_nsw: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mc_cover_pelt: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mc_cover_pelt_cam: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_rg_cover_pelt: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_coy_cover_pelt: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mar_01; - class rhsusf_opscore_mar_ut_pelt: rhsusf_opscore_mar_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mar_fg_pelt: rhsusf_opscore_mar_01 { - HEARING_PROTECTION_PELTOR; - }; - - // ACH Helmets - class rhsusf_ach_helmet_ocp; - class rhsusf_ach_bare_des_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_des_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_semi_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_semi_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_tan_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_tan_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_wood_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_wood_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_helmet_headset_ocp: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_helmet_headset_ess_ocp: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - - // ACVC Helmets - class rhsusf_cvc_helmet: rhsusf_opscore_01 { - HEARING_PROTECTION_VICCREW; - }; - - // MICH Helmets - class rhsusf_mich_bare; - class rhsusf_mich_bare_alt: rhsusf_mich_bare { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos; - class rhsusf_mich_bare_norotos_alt: rhsusf_mich_bare_norotos { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_arc; - class rhsusf_mich_bare_norotos_arc_alt: rhsusf_mich_bare_norotos_arc { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_semi; - class rhsusf_mich_bare_alt_semi: rhsusf_mich_bare_semi { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_semi; - class rhsusf_mich_bare_norotos_alt_semi: rhsusf_mich_bare_norotos_semi { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_arc_semi: rhsusf_mich_bare_norotos_alt_semi { - HEARING_PROTECTION_OPEN; - }; - class rhsusf_mich_bare_norotos_arc_alt_semi: rhsusf_mich_bare_norotos_arc_semi { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_tan; - class rhsusf_mich_bare_alt_tan: rhsusf_mich_bare_tan { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_tan; - class rhsusf_mich_bare_norotos_alt_tan: rhsusf_mich_bare_norotos_tan { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_arc_tan; - class rhsusf_mich_bare_norotos_arc_alt_tan: rhsusf_mich_bare_norotos_arc_tan { - HEARING_PROTECTION_PELTOR; - }; - - class rhsusf_hgu56p: rhsusf_opscore_01 { - HEARING_PROTECTION_VICCREW; - }; + class rhsusf_hgu56p; class rhsusf_hgu56p_visor: rhsusf_hgu56p { ACE_Protection = 1; }; @@ -420,13 +257,9 @@ class CfgWeapons { class rhsusf_hgu56p_mask_black_skull: rhsusf_hgu56p_visor_mask_black_skull { ACE_Protection = 0; }; - class rhsusf_ihadss: rhsusf_opscore_01 { - HEARING_PROTECTION_VICCREW; - }; class H_HelmetB; class RHS_jetpilot_usaf: H_HelmetB { ACE_Protection = 1; - HEARING_PROTECTION_VICCREW; }; }; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgVehicles.hpp index cbca20cce76..bfe157c6099 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgVehicles.hpp +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgVehicles.hpp @@ -14,7 +14,7 @@ class CfgVehicles { }; }; - class ACE_CSW { + class ace_csw { enabled = 1; magazineLocation = ""; proxyWeapon = QGVAR(rhs_mortar_81mm); @@ -28,7 +28,7 @@ class CfgVehicles { class StaticMGWeapon; class rhs_m2staticmg_base: StaticMGWeapon { - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = QGVAR(rhs_M2); magazineLocation = "_target selectionPosition 'magazine'"; @@ -41,7 +41,7 @@ class CfgVehicles { }; class RHS_M2StaticMG_MiniTripod_base: rhs_m2staticmg_base { - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 1; disassembleTurret = QEGVAR(csw,m3TripodLow); }; @@ -49,7 +49,7 @@ class CfgVehicles { class StaticGrenadeLauncher; class RHS_MK19_TriPod_base: StaticGrenadeLauncher { - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = QGVAR(rhs_MK19); magazineLocation = "_target selectionPosition 'magazine'"; @@ -63,7 +63,7 @@ class CfgVehicles { class StaticATWeapon; class RHS_TOW_TriPod_base: StaticATWeapon { - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = QGVAR(rhs_weap_TOW_Launcher_static); magazineLocation = "_target selectionPosition 'tube'"; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgWeapons.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgWeapons.hpp index d373e7fe673..b1a8bd88593 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgWeapons.hpp +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgWeapons.hpp @@ -11,7 +11,7 @@ class CfgWeapons { class GVAR(m252_carry): Launcher_Base_F { dlc = "ace"; - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 20; pickupTime = 25; @@ -37,13 +37,14 @@ class CfgWeapons { class GVAR(m2_carry): Launcher_Base_F { dlc = "ace"; - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; class assembleTo { EGVAR(csw,m3Tripod) = "RHS_M2StaticMG_WD"; EGVAR(csw,m3TripodLow) = "RHS_M2StaticMG_MiniTripod_WD"; + EGVAR(compat_spe,m3Tripod) = "RHS_M2StaticMG_MiniTripod_WD"; }; }; class WeaponSlotsInfo: WeaponSlotsInfo { @@ -62,7 +63,7 @@ class CfgWeapons { class GVAR(mk19_carry): Launcher_Base_F { dlc = "ace"; - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -86,7 +87,7 @@ class CfgWeapons { class GVAR(tow_carry): Launcher_Base_F { dlc = "ace"; - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_csw/stringtable.xml b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/stringtable.xml index bb185513a7d..bc2413a2ca8 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_csw/stringtable.xml +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/stringtable.xml @@ -10,6 +10,7 @@ [CSW] BGM-71A TOW [CSW] BGM-71A TOW [CSW] BGM-71A TOW + [CSW] BGM-71A TOW [CSW] BGM-71B TOW @@ -20,6 +21,7 @@ [CSW] BGM-71B TOW [CSW] BGM-71B TOW [CSW] BGM-71B TOW + [CSW] BGM-71B TOW [CSW] BGM-71C ITOW @@ -30,6 +32,7 @@ [CSW] BGM-71C ITOW [CSW] BGM-71C ITOW [CSW] BGM-71C ITOW + [CSW] BGM-71C ITOW [CSW] BGM-71D TOW-2 @@ -40,6 +43,7 @@ [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 @@ -50,6 +54,7 @@ [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 @@ -60,6 +65,7 @@ [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 @@ -70,6 +76,7 @@ [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 @@ -80,6 +87,7 @@ [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 @@ -90,6 +98,7 @@ [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 @@ -100,6 +109,7 @@ [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 @@ -110,6 +120,7 @@ [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 @@ -120,6 +131,7 @@ [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/CfgMagazines.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/CfgMagazines.hpp index 332c2bf1f25..aa2485dcdc2 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/CfgMagazines.hpp +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/CfgMagazines.hpp @@ -1,7 +1,6 @@ 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; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/CfgWeapons.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/CfgWeapons.hpp new file mode 100644 index 00000000000..f0571e876f7 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/CfgWeapons.hpp @@ -0,0 +1,174 @@ +class CfgWeapons { + // Fast Helmets + class rhsusf_opscore_01; + class rhsusf_opscore_ut_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor1_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor1_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_bk_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_fg_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_fg_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_fg_pelt_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_paint_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_paint_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_paint_pelt_nsw_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor2_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor2_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_ut_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_ut_pelt_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_ut_pelt_nsw_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_cover; + class rhsusf_opscore_mc_cover_pelt_nsw: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_cover_pelt: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_cover_pelt_cam: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_rg_cover_pelt: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_coy_cover_pelt: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mar_01; + class rhsusf_opscore_mar_ut_pelt: rhsusf_opscore_mar_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mar_fg_pelt: rhsusf_opscore_mar_01 { + HEARING_PROTECTION_PELTOR; + }; + + // ACH Helmets + class rhsusf_ach_helmet_ocp; + class rhsusf_ach_bare_des_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_des_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_semi_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_semi_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_tan_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_tan_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_wood_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_wood_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_helmet_headset_ocp: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_helmet_headset_ess_ocp: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + + // ACVC Helmets + class rhsusf_cvc_helmet: rhsusf_opscore_01 { + HEARING_PROTECTION_VICCREW; + }; + + // MICH Helmets + class rhsusf_mich_bare; + class rhsusf_mich_bare_alt: rhsusf_mich_bare { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos; + class rhsusf_mich_bare_norotos_alt: rhsusf_mich_bare_norotos { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_arc; + class rhsusf_mich_bare_norotos_arc_alt: rhsusf_mich_bare_norotos_arc { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_semi; + class rhsusf_mich_bare_alt_semi: rhsusf_mich_bare_semi { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_semi; + class rhsusf_mich_bare_norotos_alt_semi: rhsusf_mich_bare_norotos_semi { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_arc_semi: rhsusf_mich_bare_norotos_alt_semi { + HEARING_PROTECTION_OPEN; + }; + class rhsusf_mich_bare_norotos_arc_alt_semi: rhsusf_mich_bare_norotos_arc_semi { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_tan; + class rhsusf_mich_bare_alt_tan: rhsusf_mich_bare_tan { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_tan; + class rhsusf_mich_bare_norotos_alt_tan: rhsusf_mich_bare_norotos_tan { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_arc_tan; + class rhsusf_mich_bare_norotos_arc_alt_tan: rhsusf_mich_bare_norotos_arc_tan { + HEARING_PROTECTION_PELTOR; + }; + + class rhsusf_hgu56p: rhsusf_opscore_01 { + HEARING_PROTECTION_VICCREW; + }; + class rhsusf_ihadss: rhsusf_opscore_01 { + HEARING_PROTECTION_VICCREW; + }; + + class H_HelmetB; + class RHS_jetpilot_usaf: H_HelmetB { + HEARING_PROTECTION_VICCREW; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/config.cpp new file mode 100644 index 00000000000..e52454b1848 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" +#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" + +class CfgPatches { + class SUBADDON { + addonRootClass = QUOTE(COMPONENT); + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_hearing" + }; + skipWhenMissingDependencies = 1; + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/script_component.hpp new file mode 100644 index 00000000000..8edb825af34 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT hearing +#define SUBCOMPONENT_BEAUTIFIED Hearing +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgAmmo.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgAmmo.hpp new file mode 100644 index 00000000000..16a0628d1f1 --- /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 00000000000..e574b123a25 --- /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 00000000000..9d96974ab80 --- /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 00000000000..f460508a181 --- /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 00000000000..387de2d3ad6 --- /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 index 65ca880587f..b0df767e3a0 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/CfgAmmo.hpp +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/CfgAmmo.hpp @@ -9,9 +9,10 @@ class CfgAmmo { 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. + pitchRate = 120; // degrees per second + yawRate = 120; + stabilityCoefficient = 0.2; + bangBangGuidance = 0; canVanillaLock = 0; @@ -22,6 +23,11 @@ class CfgAmmo { defaultSeekerLockMode = "LOBL"; seekerLockModes[] = { "LOBL" }; + defaultNavigationType = "Direct"; + navigationTypes[] = { "Direct", "ZeroEffortMiss" }; + + navigationGain = 3; + seekerAngle = 180; // Angle in front of the missile which can be searched seekerAccuracy = 1; // seeker accuracy multiplier @@ -34,6 +40,19 @@ class CfgAmmo { defaultAttackProfile = "JAV_TOP"; attackProfiles[] = { "JAV_TOP", "JAV_DIR" }; useModeForAttackProfile = 1; + + class navigationStates { + class initial { + transitionCondition = QEFUNC(missileguidance,javelin_midCourseTransition); + navigationType = "Direct"; + }; + class terminal { + transitionCondition = ""; + navigationType = "ZeroEffortMiss"; + }; + // transitions from initial -> termimal + states[] = {"initial", "terminal"}; + }; }; }; }; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp index 5aaf6b4e229..10607ab6b5a 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp @@ -1,15 +1,52 @@ class CfgVehicles { - class rhsusf_M1078A1P2_B_M2_fmtv_usarmy; - class rhsusf_M1078A1R_SOV_M2_D_fmtv_socom: rhsusf_M1078A1P2_B_M2_fmtv_usarmy { - transportFuel = 0; + class rhsusf_stryker_base; + class rhsusf_stryker_m1126_base: rhsusf_stryker_base { + class EGVAR(interaction,anims) { + class Hide_FCans { + positions[] = {{-0.7, -3, -0.4}}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class rhsusf_stryker_m1127_base: rhsusf_stryker_m1126_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class Hide_FCans: Hide_FCans { + positions[] = {{-0.5, -3, -0.4}}; + }; + }; }; - class rhsusf_M977A4_usarmy_wd; - class rhsusf_M978A4_usarmy_wd: rhsusf_M977A4_usarmy_wd { - transportFuel = 0; + class rhsusf_stryker_m1126_m2_base: rhsusf_stryker_m1126_base {}; + class rhsusf_stryker_m1132_m2_base: rhsusf_stryker_m1126_m2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class Hide_FCans: Hide_FCans { + positions[] = {{-1, -4, -0.4}}; + }; + }; + }; + class rhsusf_stryker_m1134_base: rhsusf_stryker_m1126_m2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class Hide_FCans: Hide_FCans { + positions[] = {{-0.7, -3, -0.7}}; + }; + }; }; - class rhsusf_M978A4_BKIT_usarmy_wd: rhsusf_M977A4_usarmy_wd { - transportFuel = 0; + class rhsusf_m1a2tank_base; + class rhsusf_m1a2sep2_base: rhsusf_m1a2tank_base { + class EGVAR(interaction,anims) { + class fuelcans_hide { + // Rotate interactions with turret rotation + positions[] = { + "[0.23, -0.6, 0] vectorAdd ([[1.1, -3.6, 0.6], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)", + "[0.23, -0.6, 0] vectorAdd ([[-1.1, -3.6, 0.6], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)" + }; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; }; }; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_repair/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_repair/CfgVehicles.hpp new file mode 100644 index 00000000000..91bed1dc5a1 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_repair/CfgVehicles.hpp @@ -0,0 +1,127 @@ +class CfgVehicles { + class Truck_01_base_F; + class rhsusf_fmtv_base: Truck_01_base_F { + class EGVAR(interaction,anims) { + class hide_spare { + positions[] = {{1, 1.4, 0}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class rhsusf_M1078A1P2_fmtv_usarmy: rhsusf_fmtv_base {}; + class rhsusf_M1078A1P2_B_fmtv_usarmy: rhsusf_M1078A1P2_fmtv_usarmy {}; + class rhsusf_M1078A1P2_B_M2_fmtv_usarmy: rhsusf_M1078A1P2_B_fmtv_usarmy { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare: hide_spare { + positions[] = {{1, 1.4, -0.5}}; + }; + }; + }; + class rhsusf_M1078A1R_SOV_M2_D_fmtv_socom: rhsusf_M1078A1P2_B_M2_fmtv_usarmy { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare: hide_spare { + positions[] = {{1, 1, -0.5}}; + }; + }; + }; + class rhsusf_M1083A1P2_fmtv_usarmy: rhsusf_M1078A1P2_fmtv_usarmy {}; + class rhsusf_M1083A1P2_B_fmtv_usarmy: rhsusf_M1083A1P2_fmtv_usarmy {}; + class rhsusf_M1083A1P2_B_M2_fmtv_usarmy: rhsusf_M1083A1P2_B_fmtv_usarmy { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare: hide_spare { + positions[] = {{1, 1.4, -0.5}}; + }; + }; + }; + class rhsusf_M1084A1P2_fmtv_usarmy: rhsusf_M1083A1P2_fmtv_usarmy { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare: hide_spare { + positions[] = {{1, 1.8, 0}}; + }; + }; + }; + class rhsusf_M1084A1P2_B_M2_fmtv_usarmy: rhsusf_M1083A1P2_B_M2_fmtv_usarmy { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare: hide_spare { + positions[] = {{1, 1.8, -0.5}}; + }; + }; + }; + class rhsusf_M1085A1P2_B_Medical_fmtv_usarmy: rhsusf_M1083A1P2_B_fmtv_usarmy { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare: hide_spare { + positions[] = {{1, 6.1, 0}}; + }; + }; + }; + + class rhsusf_HEMTT_A4_base: Truck_01_base_F { + class EGVAR(interaction,anims) { + class hide_spare { + positions[] = {"_target selectionPosition ['sparewheel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + distance = 2.5; + }; + }; + }; + + class MRAP_01_base_F; + class rhsusf_m1151_base: MRAP_01_base_F { + class EGVAR(interaction,anims) { + class hide_spare { + positions[] = {"_target selectionPosition ['sparewheel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + // Don't inherit, as it's easier for the trenches compat + class rhsusf_M1165A1_GMV_SAG2_base: rhsusf_m1151_base { + class EGVAR(interaction,anims) { + class hide_spare { + positions[] = {"_target selectionPosition ['sparewheel_gmv', 'Geometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class rhsusf_rg33_base: MRAP_01_base_F { + class EGVAR(interaction,anims) { + class hide_spare { + positions[] = {"_target selectionPosition ['sparewheel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class rhsusf_M1239_base: MRAP_01_base_F { + class EGVAR(interaction,anims) { + class hide_spare { + positions[] = {"_target selectionPosition ['sparewheel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class rhsusf_MATV_base: MRAP_01_base_F { + class EGVAR(interaction,anims) { + class hide_spare { + positions[] = {"_target selectionPosition ['sparewheel', 'Geometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_repair/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_repair/config.cpp new file mode 100644 index 00000000000..b204f64166a --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_repair/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_repair" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_repair/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_repair/script_component.hpp new file mode 100644 index 00000000000..1af928486c3 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_repair/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT repair +#define SUBCOMPONENT_BEAUTIFIED Repair +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/CfgVehicles.hpp new file mode 100644 index 00000000000..e914b24d600 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/CfgVehicles.hpp @@ -0,0 +1,48 @@ +class CfgVehicles { + class rhsusf_stryker_base; + class rhsusf_stryker_m1126_base: rhsusf_stryker_base { + class EGVAR(interaction,anims) { + class Hide_PioKit { + positions[] = {{-1, -2.2, -0.5}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class rhsusf_stryker_m1127_base: rhsusf_stryker_m1126_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class Hide_PioKit: Hide_PioKit { + positions[] = {{-0.8, -2.2, -0.5}}; + }; + }; + }; + + class rhsusf_stryker_m1126_m2_base: rhsusf_stryker_m1126_base {}; + class rhsusf_stryker_m1132_m2_base: rhsusf_stryker_m1126_m2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class Hide_PioKit: Hide_PioKit { + positions[] = {{-1.3, -3.3, -0.5}}; + }; + }; + }; + class rhsusf_stryker_m1134_base: rhsusf_stryker_m1126_m2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class Hide_PioKit: Hide_PioKit { + positions[] = {{-1, -2.2, -0.8}}; + }; + }; + }; + + class rhsusf_m1151_base; + class rhsusf_M1165A1_GMV_SAG2_base: rhsusf_m1151_base { + class EGVAR(interaction,anims) { + class tools_hide { + positions[] = {{0.365, 1.5, -0.4}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/config.cpp new file mode 100644 index 00000000000..aea4c9daeb0 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/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_trenches" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/script_component.hpp new file mode 100644 index 00000000000..10b90eb71e5 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT trenches +#define SUBCOMPONENT_BEAUTIFIED Trenches +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/config.cpp b/addons/compat_rhs_usf3/config.cpp index 1e67b1e0075..b28a08b22e9 100644 --- a/addons/compat_rhs_usf3/config.cpp +++ b/addons/compat_rhs_usf3/config.cpp @@ -1,5 +1,4 @@ #include "script_component.hpp" -#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" class CfgPatches { class ADDON { @@ -7,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"rhsusf_main_loadorder"}; + requiredAddons[] = {"ace_common", "rhsusf_main_loadorder"}; skipWhenMissingDependencies = 1; author = ECSTRING(common,ACETeam); authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "Fyuran"}; @@ -19,7 +18,6 @@ class CfgPatches { #include "CfgAmmo.hpp" #include "CfgEventHandlers.hpp" #include "CfgMagazines.hpp" -#include "CfgMagazineWells.hpp" #include "CfgWeapons.hpp" #include "CfgVehicles.hpp" #include "CfgGlasses.hpp" diff --git a/addons/compat_sog/ACE_CSW_Groups.hpp b/addons/compat_sog/ACE_CSW_Groups.hpp index 2bc81dbb65b..a8914204398 100644 --- a/addons/compat_sog/ACE_CSW_Groups.hpp +++ b/addons/compat_sog/ACE_CSW_Groups.hpp @@ -2,7 +2,7 @@ class ACE_CSW_Groups { // --- Gun Turrets ------------------------------------------------------------- - class ace_csw_100Rnd_127x99_mag { + class EGVAR(csw,100Rnd_127x99_mag) { vn_m2_v_100_mag = 1; }; diff --git a/addons/compat_sog/CfgAmmo/explosives.hpp b/addons/compat_sog/CfgAmmo/explosives.hpp index 849f7e69480..6922962fb3e 100644 --- a/addons/compat_sog/CfgAmmo/explosives.hpp +++ b/addons/compat_sog/CfgAmmo/explosives.hpp @@ -2,16 +2,10 @@ 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; @@ -99,13 +93,7 @@ class vn_mine_punji_05_ammo: vn_mine_punji_04_ammo { }; 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')); @@ -116,50 +104,8 @@ class vn_mine_cartridge_ammo: APERSMine_Range_Ammo { 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 index d280443b6e8..6395756f640 100644 --- a/addons/compat_sog/CfgAmmo/grenades.hpp +++ b/addons/compat_sog/CfgAmmo/grenades.hpp @@ -4,6 +4,13 @@ class vn_molotov_grenade_ammo: vn_grenadehand { EGVAR(frag,enabled) = 0; }; +class vn_t67_grenade_ammo: vn_grenadehand { + EGVAR(grenades,rollVectorDirAndUp)[] = {{-1, 0, 0}, {0, 0, 1}}; +}; +class vn_chicom_grenade_ammo: vn_grenadehand { + EGVAR(grenades,rollVectorDirAndUp)[] = {{1, 0, 0}, {0, 0, 1}}; +}; + class SmokeShell; class vn_m14_grenade_ammo: SmokeShell { EGVAR(grenades,incendiary) = 1; diff --git a/addons/compat_sog/CfgEventHandlers.hpp b/addons/compat_sog/CfgEventHandlers.hpp index fc6d80fc5f9..d28b79fb991 100644 --- a/addons/compat_sog/CfgEventHandlers.hpp +++ b/addons/compat_sog/CfgEventHandlers.hpp @@ -32,6 +32,16 @@ class Extended_InitPost_EventHandlers { init = QUOTE((_this select 0) setMass 1e-12); }; }; + class Land_vn_canisterfuel_f { + class ADDON { + init = QUOTE(call (missionNamespace getVariable [ARR_2(QQEFUNC(refuel,makeJerryCan),{})])); + }; + }; + class Land_vn_fuelcan { + class ADDON { + init = QUOTE(call (missionNamespace getVariable [ARR_2(QQEFUNC(refuel,makeJerryCan),{})])); + }; + }; class vn_bicycle_base { class ADDON { init = QUOTE(call FUNC(disableCookoff)); diff --git a/addons/compat_sog/CfgMagazines/explosives.hpp b/addons/compat_sog/CfgMagazines/explosives.hpp index 7e25609fc8a..a8d6ca76bd3 100644 --- a/addons/compat_sog/CfgMagazines/explosives.hpp +++ b/addons/compat_sog/CfgMagazines/explosives.hpp @@ -6,8 +6,8 @@ class vn_mine_m18_mag: vn_magazine { displayNameShort = ""; // Every explosive inherits this and it breaks naming in the placing menu - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m18); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(m18); class ACE_Triggers { SupportedTriggers[] = {"Command", "MK16_Transmitter"}; @@ -42,7 +42,7 @@ class vn_mine_m18_fuze10_mag: vn_mine_m18_mag { // Claymore x3 (Remote) class vn_mine_m18_x3_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m18_x3); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(m18_x3); class ACE_Triggers { SupportedTriggers[] = {"Command", "MK16_Transmitter"}; @@ -65,7 +65,7 @@ class vn_mine_m18_x3_range_mag: vn_mine_m18_x3_mag { // WP Claymore (Remote) class vn_mine_m18_wp_mag: vn_mine_m18_fuze10_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m18_wp); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(m18_wp); class ACE_Triggers { SupportedTriggers[] = {"Command", "MK16_Transmitter"}; @@ -101,7 +101,7 @@ class vn_mine_m18_wp_fuze10_mag: vn_mine_m18_wp_mag { // Toe-Popper class vn_mine_m14_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m14); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(m14); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -113,7 +113,7 @@ class vn_mine_m14_mag: vn_mine_m18_mag { // Bounding Mine class vn_mine_m16_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m16); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(m16); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -125,7 +125,7 @@ class vn_mine_m16_mag: vn_mine_m18_mag { // Bounding Mine (Trip Wire 2m) class vn_mine_tripwire_m16_02_mag: vn_mine_m16_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m16_tripwire_2m); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(m16_tripwire_2m); class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; @@ -136,7 +136,7 @@ class vn_mine_tripwire_m16_02_mag: vn_mine_m16_mag { }; // 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); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(m16_tripwire_4m); class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; @@ -148,22 +148,22 @@ class vn_mine_tripwire_m16_04_mag: vn_mine_tripwire_m16_02_mag { // 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); + 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); + 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); + 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); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(satchel_remote_02); class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch"}; @@ -180,7 +180,7 @@ class vn_mine_satchel_remote_02_mag: vn_mine_m18_mag { // TM57 Anti-Tank Mine class vn_mine_tm57_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(tm57); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(tm57); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -190,7 +190,7 @@ class vn_mine_tm57_mag: vn_mine_m18_mag { // M15 Anti-Tank Mine class vn_mine_m15_mag: vn_mine_tm57_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m15); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(m15); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -202,7 +202,7 @@ class vn_mine_m15_mag: vn_mine_tm57_mag { // M112 Breaching charge class vn_mine_m112_remote_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m112); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(m112); class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch"}; @@ -221,7 +221,7 @@ class vn_mine_m112_remote_mag: vn_mine_m18_mag { // Spiked ammo box class vn_mine_ammobox_range_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(ammobox_range); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(ammobox_range); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -234,7 +234,7 @@ class vn_mine_ammobox_range_mag: vn_mine_m18_mag { // Punji large class vn_mine_punji_01_mag: vn_mine_m18_mag { useAction = 0; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(punji_01); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(punji_01); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -246,18 +246,18 @@ class vn_mine_punji_01_mag: vn_mine_m18_mag { // Punji small class vn_mine_punji_02_mag: vn_mine_punji_01_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(punji_02); + 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); + 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); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(punji_04); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -270,7 +270,7 @@ class vn_mine_punji_04_mag: vn_mine_m18_mag { // Punji side whip class vn_mine_punji_05_mag: vn_mine_punji_04_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(punji_05); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(punji_05); class ACE_Triggers: ACE_Triggers { class PressurePlate: PressurePlate { @@ -281,7 +281,7 @@ class vn_mine_punji_05_mag: vn_mine_punji_04_mag { // Bike mine (Remote) class vn_mine_bike_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(bike); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(bike); class ACE_Triggers { SupportedTriggers[] = {QGVAR(Command), QGVAR(MK16_Transmitter)}; @@ -304,7 +304,7 @@ class vn_mine_bike_range_mag: vn_mine_bike_mag { // Cartridge mine class vn_mine_cartridge_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(cartridge); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(cartridge); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -316,7 +316,7 @@ class vn_mine_cartridge_mag: vn_mine_m18_mag { // Lighter mine (Proximity) class vn_mine_lighter_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(lighter); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(lighter); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -328,7 +328,7 @@ class vn_mine_lighter_mag: vn_mine_m18_mag { // Pot mine (Remote) class vn_mine_pot_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(pot); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(pot); class ACE_Triggers { SupportedTriggers[] = {"Command", "MK16_Transmitter"}; @@ -351,7 +351,7 @@ class vn_mine_pot_range_mag: vn_mine_pot_mag { // Jerrycan mine (Remote) class vn_mine_jerrycan_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(jerrycan); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(jerrycan); class ACE_Triggers { SupportedTriggers[] = {"Command", "MK16_Transmitter"}; @@ -374,7 +374,7 @@ class vn_mine_jerrycan_range_mag: vn_mine_jerrycan_mag { // Mortar shell on a stick (Proximity) class vn_mine_mortar_range_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(mortar_range); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(mortar_range); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -386,17 +386,17 @@ class vn_mine_mortar_range_mag: vn_mine_m18_mag { // Limpet mine USA (Remote) class vn_mine_limpet_01_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(limpet_01); + 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); + 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); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(chicom_no8); class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -408,7 +408,7 @@ class vn_mine_chicom_no8_mag: vn_mine_m18_mag { // DH10 mine (Remote) class vn_mine_dh10_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(dh10); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(dh10); }; // DH10 mine (Proximity) class vn_mine_dh10_range_mag: vn_mine_dh10_mag { @@ -422,7 +422,7 @@ class vn_mine_dh10_range_mag: vn_mine_dh10_mag { // Grenade board mine (Tripwire 4m) class vn_mine_gboard_range_mag: vn_mine_m18_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(gboard); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(gboard); class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; @@ -434,10 +434,10 @@ class vn_mine_gboard_range_mag: vn_mine_m18_mag { // Satchel charge class vn_mine_satchelcharge_02_mag: vn_mine_satchel_remote_02_mag { - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(satchelcharge_02); + 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); + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(bangalore); }; diff --git a/addons/compat_sog/CfgVehicles/land.hpp b/addons/compat_sog/CfgVehicles/land.hpp index c9390265900..70b305a31d2 100644 --- a/addons/compat_sog/CfgVehicles/land.hpp +++ b/addons/compat_sog/CfgVehicles/land.hpp @@ -1,18 +1,19 @@ +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} // fuel pumps class Land_vn_commercial_base; class Land_vn_fuelstation_01_pump_f: Land_vn_commercial_base { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_vn_fuelstation_02_pump_f: Land_vn_commercial_base { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_vn_fuelstation_feed_f: Land_vn_commercial_base { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; @@ -20,13 +21,47 @@ class Land_vn_fuelstation_feed_f: Land_vn_commercial_base { // fuel objects class Land_vn_building_b_base; class Land_vn_usaf_fueltank_75_01: Land_vn_building_b_base { - transportFuel = 0; - EGVAR(refuel,hooks)[] = {{0, -0.4, -0.5}}; + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{-2.52, -2.2, -2.05}, {2.5, 0, -1.3}}; EGVAR(refuel,fuelCargo) = 2840; // 750 * 3.785 }; +class Land_vn_b_prop_fuelbladder_01: Land_vn_usaf_fueltank_75_01 { + EGVAR(refuel,hooks)[] = {{-1.75, -6.7, -1}}; + EGVAR(refuel,fuelCargo) = 3785; // 1000 * 3.785 +}; +class Land_vn_b_prop_fuelbladder_03: Land_vn_b_prop_fuelbladder_01 { + EGVAR(refuel,hooks)[] = {{-1.55, -6.5, -1}}; +}; +class Land_vn_building_industrial_base; +class Land_vn_fuel_tank_stairs: Land_vn_building_industrial_base { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{0, 0.4, -1.3}, {0, -0.4, -1.3}}; + EGVAR(refuel,fuelCargo) = 10000; // reference is B_Slingload_01_Fuel_F +}; class Land_vn_object_b_base; class Land_vn_b_prop_fueldrum_01: Land_vn_object_b_base { - transportFuel = 0; - EGVAR(refuel,hooks)[] = {{0, 0, 0.5}}; // reference is Land_FlexibleTank_01_F + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{0, 0, 0}}; EGVAR(refuel,fuelCargo) = 300; // reference is Land_FlexibleTank_01_F }; +class Land_vn_b_prop_fueldrum_02: Land_vn_b_prop_fueldrum_01 { + EGVAR(refuel,hooks)[] = {{0, -1.3, -0.15}, {2.3, 1.25, -0.15}}; + EGVAR(refuel,fuelCargo) = 14100; // (23 + 24) * 300 +}; +class vn_b_ammobox_supply_07; +class vn_b_ammobox_supply_09: vn_b_ammobox_supply_07 { // just a pallet + XEH_INHERITED; +}; +class vn_object_c_base_02; +class Land_vn_canisterfuel_f: vn_object_c_base_02 { + EGVAR(cargo,size) = 1; + EGVAR(cargo,canLoad) = 1; + EGVAR(cargo,noRename) = 1; +}; +class Land_vn_object_c_base; +class Land_vn_fuelcan: Land_vn_object_c_base { + XEH_INHERITED; + EGVAR(cargo,size) = 1; + EGVAR(cargo,canLoad) = 1; + EGVAR(cargo,noRename) = 1; +}; diff --git a/addons/compat_sog/CfgVehicles/tracked.hpp b/addons/compat_sog/CfgVehicles/tracked.hpp index e2832796a97..7adc0193c63 100644 --- a/addons/compat_sog/CfgVehicles/tracked.hpp +++ b/addons/compat_sog/CfgVehicles/tracked.hpp @@ -1,18 +1,55 @@ +// M113A1 https://man.fas.org/dod-101/sys/land/m113.htm +class Tank_F; +class APC_Tracked_01_base_F: Tank_F { + class ACE_Actions; +}; +class vn_armor_m113_base: APC_Tracked_01_base_F { + EGVAR(refuel,fuelCapacity) = 360; + class ACE_Actions: ACE_Actions { + class ACE_MainActions; + }; +}; +class vn_armor_m577_base: vn_armor_m113_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 3.5, -1]"; + }; + }; +}; + // 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; +// M48 +class vn_armor_m48_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_mainturret_backpacks { + // Rotate interactions with turret rotation + positions[] = { + "[[-1.3, -0.7, -0.4], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D", + "[[0.1, -2, -0.2], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D" + }; + items[] = {"vn_b_pack_02_02", "vn_b_pack_04_02"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; }; -// 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; +// T-54 +class vn_armor_t54_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_mainturret_backpacks { + // Rotate interactions with turret rotation + positions[] = {"[0, -0.2, 0] vectorAdd ([[-1.1, -0.85, -1.3], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)"}; + items[] = {"vn_o_pack_01", "vn_o_pack_02"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; }; // PT-76A https://en.wikipedia.org/wiki/PT-76 @@ -24,3 +61,8 @@ class vn_armor_pt76_base: vn_armor_tank_base { class vn_armor_pt76b_base: vn_armor_pt76_base { EGVAR(refuel,fuelCapacity) = 400; }; + +// Type 63 +class vn_armor_type63_base: vn_armor_tank_base { + EGVAR(refuel,fuelCapacity) = 545; +}; diff --git a/addons/compat_sog/CfgVehicles/turrets.hpp b/addons/compat_sog/CfgVehicles/turrets.hpp index 6142a018e81..928b80716a4 100644 --- a/addons/compat_sog/CfgVehicles/turrets.hpp +++ b/addons/compat_sog/CfgVehicles/turrets.hpp @@ -17,7 +17,7 @@ class vn_static_m2_high_base: StaticMGWeapon { }; }; - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = "vn_m2_v_01"; magazineLocation = "_target selectionPosition 'mg1_magazine'"; @@ -31,7 +31,7 @@ class vn_static_m2_high_base: StaticMGWeapon { // M2 Browning - Low class vn_static_m2_low_base: vn_static_m2_high_base { - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { disassembleTurret = QEGVAR(csw,m3TripodLow); }; }; @@ -45,7 +45,7 @@ class vn_static_m1919a6_base: vn_static_m2_low_base { }; }; - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 1; proxyWeapon = "vn_m1919_v_01"; magazineLocation = "_target selectionPosition 'mg1_magazine' vectorAdd [-0.3, 0, 0]"; @@ -66,7 +66,7 @@ class vn_static_m1919a4_high_base: vn_static_m1919a6_base { }; }; - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 1; proxyWeapon = "vn_m1919_v_01"; magazineLocation = "_target selectionPosition 'mg1_magazine'"; @@ -80,7 +80,7 @@ class vn_static_m1919a4_high_base: vn_static_m1919a6_base { // M1919A4 - Low class vn_static_m1919a4_low_base: vn_static_m1919a4_high_base { - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { disassembleTurret = QEGVAR(csw,m3TripodLow); }; }; @@ -93,7 +93,7 @@ class vn_static_m60_high_base: vn_static_m2_low_base { }; }; - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 1; proxyWeapon = "vn_m60_v_01"; magazineLocation = "_target selectionPosition 'mg1_trigger'"; @@ -113,7 +113,7 @@ class vn_static_m60_low_base: vn_static_m60_high_base { }; }; - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { magazineLocation = "_target selectionPosition 'mg1_otochlaven_recoil'"; disassembleTurret = QEGVAR(csw,m3TripodLow); }; @@ -131,7 +131,7 @@ class vn_static_tow_base: vn_static_at3_base { }; }; - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = "vn_missile_tow_launcher"; magazineLocation = "_target selectionPosition 'magazine'"; @@ -145,7 +145,7 @@ class vn_static_tow_base: vn_static_at3_base { // DShKM - High class vn_static_dp28_high_base: vn_static_m2_high_base { - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 0; }; }; @@ -156,7 +156,7 @@ class vn_static_dshkm_high_01_base: vn_static_dp28_high_base { }; }; - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 1; proxyWeapon = "vn_dshkm_v_01"; magazineLocation = "_target selectionPosition 'mg1_boxmag'"; @@ -170,7 +170,7 @@ class vn_static_dshkm_high_01_base: vn_static_dp28_high_base { // DShKM - High, with AA sight class vn_static_dshkm_high_02_base: vn_static_dshkm_high_01_base { - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { disassembleWeapon = QGVAR(dshkm_AA_carry); }; }; @@ -185,7 +185,7 @@ class vn_static_dshkm_low_01_base: vn_static_dshkm_high_01_base { }; }; - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { disassembleWeapon = QGVAR(dshkm_shield_carry); disassembleTurret = QEGVAR(csw,kordTripodLow); }; @@ -193,7 +193,7 @@ class vn_static_dshkm_low_01_base: vn_static_dshkm_high_01_base { // DShKM - Low class vn_static_dshkm_low_02_base: vn_static_dshkm_low_01_base { - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { disassembleWeapon = QGVAR(dshkm_carry); }; }; @@ -206,7 +206,7 @@ class vn_static_rpd_high_base: vn_static_dp28_high_base { }; }; - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 1; proxyWeapon = "vn_rpd_v_01"; magazineLocation = "_target selectionPosition 'mg1_otochlaven_recoil'"; @@ -226,7 +226,7 @@ class vn_static_pk_high_base: vn_static_rpd_high_base { }; }; - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 1; proxyWeapon = "vn_pk_v_01"; magazineLocation = "_target selectionPosition 'mg1_otochlaven_recoil'"; @@ -246,7 +246,7 @@ class vn_static_pk_low_base: vn_static_pk_high_base { }; }; - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { disassembleTurret = QEGVAR(csw,kordTripodLow); }; }; @@ -259,7 +259,7 @@ class vn_static_mg42_high_base: vn_static_rpd_high_base { }; }; - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = "vn_mg42_v_01"; magazineLocation = "_target selectionPosition 'mg1_otochlaven_recoil'"; @@ -278,7 +278,7 @@ class vn_static_mg42_low_base: vn_static_mg42_high_base { }; }; - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { disassembleTurret = ""; }; }; @@ -294,7 +294,7 @@ class vn_static_sgm_high_base: vn_static_sgm_base { }; }; - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = "vn_sgm_v_01"; magazineLocation = "_target selectionPosition 'mg1_otochlaven_recoil'"; @@ -308,7 +308,7 @@ class vn_static_sgm_high_base: vn_static_sgm_base { // SGM - Low class vn_static_sgm_low_base: vn_static_sgm_high_base { - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { disassembleWeapon = QGVAR(sgm_carry); disassembleTurret = QEGVAR(csw,kordTripodLow); }; @@ -316,25 +316,25 @@ class vn_static_sgm_low_base: vn_static_sgm_high_base { // SGM - Shield class vn_o_pl_static_sgm_low_01: vn_static_sgm_low_base { - class ACE_CSW: ACE_CSW { + 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 { + 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 { + 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 { + class ace_csw: ace_csw { disassembleWeapon = QGVAR(sgm_shield_carry); disassembleTurret = QEGVAR(csw,kordTripodLow); }; @@ -351,7 +351,7 @@ class vn_static_mk18_base: StaticCannon { }; }; - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = "vn_mk18_v_01"; magazineLocation = "_target selectionPosition 'mg1_magazine'"; @@ -378,7 +378,7 @@ class vn_static_mortar_m29_base: Mortar_01_base_F { }; }; - class ACE_CSW { + class ace_csw { enabled = 1; proxyWeapon = QGVAR(vn_mortar_m29); magazineLocation = "_target selectionPosition 'pohon'"; @@ -392,7 +392,7 @@ class vn_static_mortar_m29_base: Mortar_01_base_F { // M2 / Type 63 Mortar class vn_static_mortar_m2_base: vn_static_mortar_m29_base { - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 1; proxyWeapon = QGVAR(vn_mortar_m2); magazineLocation = "_target selectionPosition 'pohon'"; @@ -406,7 +406,7 @@ class vn_static_mortar_m2_base: vn_static_mortar_m29_base { // Type 53 Mortar class vn_static_mortar_type53_base: vn_static_mortar_m29_base { - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 1; proxyWeapon = QGVAR(vn_mortar_type53); magazineLocation = "_target selectionPosition 'pohon'"; @@ -430,7 +430,7 @@ class vn_static_h12_base: Mortar_01_base_F { }; }; - class ACE_CSW { + class ace_csw { enabled = 0; }; }; @@ -441,7 +441,7 @@ class vn_static_m45_base: vn_static_m2_high_base { EGVAR(dragging,canCarry) = 0; EGVAR(dragging,canDrag) = 0; - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 0; }; }; @@ -450,7 +450,7 @@ class vn_static_zpu4_base: vn_static_m2_high_base { EGVAR(dragging,canCarry) = 0; EGVAR(dragging,canDrag) = 0; - class ACE_CSW: ACE_CSW { + class ace_csw: ace_csw { enabled = 0; }; }; @@ -466,7 +466,7 @@ class vn_o_static_rsna75: StaticMGWeapon { }; }; - class ACE_CSW { + class ace_csw { enabled = 0; }; }; diff --git a/addons/compat_sog/CfgVehicles/wheeled.hpp b/addons/compat_sog/CfgVehicles/wheeled.hpp index 3525328d3f4..3a898519dd1 100644 --- a/addons/compat_sog/CfgVehicles/wheeled.hpp +++ b/addons/compat_sog/CfgVehicles/wheeled.hpp @@ -5,7 +5,6 @@ class vn_wheeled_m54_base: vn_wheeled_truck_base { }; class vn_wheeled_m54_cab_base; class vn_wheeled_m54_fuel_base: vn_wheeled_m54_cab_base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-1.15, -2.3, 0.28}}; EGVAR(refuel,fuelCargo) = 4542; }; @@ -25,7 +24,6 @@ class vn_wheeled_z157_base: vn_wheeled_truck_base { EGVAR(refuel,fuelCapacity) = 150; }; class vn_wheeled_z157_fuel_base: vn_wheeled_z157_base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-1.36, -3.575, -0.4}}; EGVAR(refuel,fuelCargo) = 4000; }; diff --git a/addons/compat_sog/CfgWeapons/csw.hpp b/addons/compat_sog/CfgWeapons/csw.hpp index 87b1b16c5ec..b5ca942f6e8 100644 --- a/addons/compat_sog/CfgWeapons/csw.hpp +++ b/addons/compat_sog/CfgWeapons/csw.hpp @@ -20,7 +20,7 @@ class GVAR(m2_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_m2b_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -48,7 +48,7 @@ class GVAR(m1919a4_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_m1919a4_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -76,7 +76,7 @@ class GVAR(m1919a6_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_m1919a6_ca.paa); - class ACE_CSW { + class ace_csw { type = "mount"; deployTime = 2; pickupTime = 2; @@ -100,7 +100,7 @@ class GVAR(m60_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_m60_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -128,7 +128,7 @@ class GVAR(tow_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_tow_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -155,7 +155,7 @@ class GVAR(dshkm_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_dshkm_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -183,7 +183,7 @@ class GVAR(dshkm_shield_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_dshkm_shield_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -210,7 +210,7 @@ class GVAR(dshkm_AA_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_dshkm_aa_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -237,7 +237,7 @@ class GVAR(rpd_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_rpd_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -264,7 +264,7 @@ class GVAR(pk_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_pk_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -292,7 +292,7 @@ class GVAR(mortar_m29_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_m29_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 20; pickupTime = 25; @@ -319,7 +319,7 @@ class GVAR(mg42_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_mg42_ca.paa); - class ACE_CSW { + class ace_csw { type = "mount"; deployTime = 4; pickupTime = 4; @@ -347,7 +347,7 @@ class GVAR(sgm_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_sgm_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -374,7 +374,7 @@ class GVAR(sgm_shield_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_sgm_shield_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -401,7 +401,7 @@ class GVAR(mk18_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_mk18_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 4; pickupTime = 4; @@ -430,7 +430,7 @@ class GVAR(mortar_m2_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_m2_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 20; pickupTime = 25; @@ -457,7 +457,7 @@ class GVAR(mortar_type53_carry): Launcher_Base_F { modes[] = {}; picture = QPATHTOF(UI\csw_type53_ca.paa); - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 20; pickupTime = 25; diff --git a/addons/compat_sog/compat_sog_refuel/CfgVehicles.hpp b/addons/compat_sog/compat_sog_refuel/CfgVehicles.hpp new file mode 100644 index 00000000000..c3dcfb719e5 --- /dev/null +++ b/addons/compat_sog/compat_sog_refuel/CfgVehicles.hpp @@ -0,0 +1,163 @@ +class CfgVehicles { + // Vehicle animation interactions + // BTR-40 + class vn_wheeled_car_base; + class vn_wheeled_btr40_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class refuel_can_hide { + positions[] = {{0.7, -2.35, -0.9}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class vn_wheeled_btr40_01_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class refuel_can_hide: refuel_can_hide { + positions[] = {{0.72, -2.35, -0.45}}; + }; + }; + }; + class vn_wheeled_btr40_ambulance_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class refuel_can_hide: refuel_can_hide { + positions[] = {{0.72, -2.35, -0.45}}; + }; + }; + }; + class vn_wheeled_btr40_mg_01_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class refuel_can_hide: refuel_can_hide { + positions[] = {{0.72, -2.35, -0.9}}; + }; + }; + }; + class vn_wheeled_btr40_mg_03_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class refuel_can_hide: refuel_can_hide { + positions[] = {{0.82, -2.35, -1.25}}; + }; + }; + }; + class vn_wheeled_btr40_mg_04_base: vn_wheeled_btr40_mg_01_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class refuel_can_hide: refuel_can_hide { + positions[] = {{0.72, -2.35, -1}}; + }; + }; + }; + class vn_wheeled_btr40_mg_05_base: vn_wheeled_btr40_mg_04_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class refuel_can_hide: refuel_can_hide { + positions[] = {{0.65, -2.25, -1}}; + }; + }; + }; + + // M151 + class vn_wheeled_m151_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class user_refuel_can_hide { + positions[] = {{-0.48, -1.5, -1.1}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class vn_wheeled_m151_mg_03_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_refuel_can_hide: user_refuel_can_hide { + positions[] = {{-0.75, -1.5, -1}}; + }; + }; + }; + class vn_wheeled_m151_mg_05_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_refuel_can_hide: user_refuel_can_hide { + positions[] = {{0.9, -0.1, -1.1}}; + }; + }; + }; + class vn_wheeled_m151_mg_06_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_refuel_can_hide: user_refuel_can_hide { + positions[] = {{0.3, 0.1, -1.1}}; + }; + }; + }; + class vn_wheeled_m151_01_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_refuel_can_hide: user_refuel_can_hide { + positions[] = {{-0.4, -1.5, -0.7}}; + }; + }; + }; + + // M577 + class vn_armor_m113_base; + class vn_armor_m577_base: vn_armor_m113_base { + class EGVAR(interaction,anims) { + class hide_fuel_cans { + selections[] = {"hide_fuel_cans"}; + positions[] = {{1.07, 1.05, -1}}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + // M48 + class vn_armor_tank_base; + class vn_armor_m48_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_mainturret_jerrycan { + positions[] = {"_target selectionPosition ['hide_jerrycan', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + // BTR-50PK + class vn_armor_btr50pk_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_barrels { + selections[] = {"hide_barrels"}; + positions[] = {"private _pos = _target selectionPosition 'hide_barrels'; _pos set [0, -(_pos select 0)]; _pos"}; // Mirror position to other side of vehicle + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + // PT-76 + class vn_armor_pt76_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_barrels { + selections[] = {"hide_barrels"}; + positions[] = {"private _pos = _target selectionPosition 'hide_barrels'; _pos set [0, -(_pos select 0)]; _pos"}; // Mirror position to other side of vehicle + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + // Type 63 + class vn_armor_type63_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_barrels { + selections[] = {"hide_barrels"}; + positions[] = {"private _pos = _target selectionPosition 'hide_barrels'; _pos set [0, -(_pos select 0)]; _pos"}; // Mirror position to other side of vehicle + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; +}; diff --git a/addons/compat_sog/compat_sog_refuel/config.cpp b/addons/compat_sog/compat_sog_refuel/config.cpp new file mode 100644 index 00000000000..793cf90fc4e --- /dev/null +++ b/addons/compat_sog/compat_sog_refuel/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_refuel"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_sog/compat_sog_refuel/script_component.hpp b/addons/compat_sog/compat_sog_refuel/script_component.hpp new file mode 100644 index 00000000000..af997fb8d4d --- /dev/null +++ b/addons/compat_sog/compat_sog_refuel/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT refuel +#define SUBCOMPONENT_BEAUTIFIED refuel +#include "..\script_component.hpp" diff --git a/addons/compat_sog/compat_sog_repair/CfgVehicles.hpp b/addons/compat_sog/compat_sog_repair/CfgVehicles.hpp new file mode 100644 index 00000000000..de93243251e --- /dev/null +++ b/addons/compat_sog/compat_sog_repair/CfgVehicles.hpp @@ -0,0 +1,141 @@ +class CfgVehicles { + // Vehicle animation interactions + // M39 / M54 / M49 + class vn_wheeled_truck_base; + class vn_wheeled_m54_base: vn_wheeled_truck_base { + class EGVAR(interaction,anims) { + class user_sparewheel_hide { + positions[] = {"_target selectionPosition ['hide_spare_wheel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class vn_wheeled_m54_mg_01_base: vn_wheeled_m54_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_sparewheel_hide: user_sparewheel_hide { + items[] = {"ACE_Wheel", "ACE_Wheel", "ACE_Wheel", "ACE_Wheel"}; + }; + }; + }; + + // M151 + class vn_wheeled_car_base; + class vn_wheeled_m151_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class user_sparewheel_hide { + positions[] = {"_target selectionPosition ['hide_sparewheel', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + // Dirt Ranger + class vn_wheeled_lr2a_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class hide_sparewheel { + positions[] = {"_target selectionPosition ['hide_sparewheel', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + // BTR-40 + class vn_wheeled_btr40_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class sparewheel_hide { + positions[] = {"_target selectionPosition ['hide_sparewheel', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + // M48 + class vn_armor_tank_base; + class vn_armor_m48_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_mainturret_tracks { + // Rotate interactions with turret rotation + positions[] = { + "[[1.3, 0.2, -0.5], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D", + "[[-1.3, 0.2, -0.5], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D" + }; + items[] = {"ACE_Track", "ACE_Track", "ACE_Track", "ACE_Track", "ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; + + // BTR-50PK + class vn_armor_btr50pk_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_tracks { + positions[] = {{1.35, 2.5, -0.5}}; + items[] = {"ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; + class vn_armor_btr50pk_01_base: vn_armor_btr50pk_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tracks: hide_tracks { + positions[] = {{1.35, 2.5, -0.8}}; + }; + }; + }; + + class vn_armor_btr50pk_02_base: vn_armor_btr50pk_01_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tracks: hide_tracks { + positions[] = {{1.35, 2.9, -0.8}}; + }; + }; + }; + + // T-54 + class vn_armor_t54_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_tracks { + positions[] = {{1.4, 2.1, -1.7}}; + items[] = {"ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; + + // PT-76 + class vn_armor_pt76_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_tracks { + // Rotate interactions with turret rotation + positions[] = {"[0, 0.9, 0] vectorAdd ([[-0.6, -0.9, -0.3], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)"}; + items[] = {"ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; + + // Type 63 + class vn_armor_type63_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_tracks { + // Rotate interactions with turret rotation + positions[] = {"[0, 0.7, 0] vectorAdd ([[0.4, -1.1, -0.4], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)"}; + items[] = {"ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; +}; diff --git a/addons/compat_sog/compat_sog_repair/config.cpp b/addons/compat_sog/compat_sog_repair/config.cpp new file mode 100644 index 00000000000..b2cffd8a364 --- /dev/null +++ b/addons/compat_sog/compat_sog_repair/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_repair"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_sog/compat_sog_repair/script_component.hpp b/addons/compat_sog/compat_sog_repair/script_component.hpp new file mode 100644 index 00000000000..1af928486c3 --- /dev/null +++ b/addons/compat_sog/compat_sog_repair/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT repair +#define SUBCOMPONENT_BEAUTIFIED Repair +#include "..\script_component.hpp" diff --git a/addons/compat_sog/compat_sog_trenches/CfgVehicles.hpp b/addons/compat_sog/compat_sog_trenches/CfgVehicles.hpp index bb222eaed16..bc67a39f784 100644 --- a/addons/compat_sog/compat_sog_trenches/CfgVehicles.hpp +++ b/addons/compat_sog/compat_sog_trenches/CfgVehicles.hpp @@ -60,4 +60,199 @@ class CfgVehicles { class EGVAR(compat_sog,spiderhole_03_nogeo): vn_o_vc_spiderhole_03 { scope = 1; }; + + // Vehicle animation interactions + // BTR-40 + class vn_wheeled_car_base; + class vn_wheeled_btr40_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class shovel_hide { + positions[] = {{0.95, -1.5, -0.75}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class vn_wheeled_btr40_01_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class shovel_hide: shovel_hide { + positions[] = {{0.95, -1.5, -0.3}}; + }; + }; + }; + class vn_wheeled_btr40_ambulance_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class shovel_hide: shovel_hide { + positions[] = {{0.95, -1.5, -0.3}}; + }; + }; + }; + class vn_wheeled_btr40_mg_01_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class shovel_hide: shovel_hide { + positions[] = {{0.95, -1.5, -0.8}}; + }; + }; + }; + class vn_wheeled_btr40_mg_03_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class shovel_hide: shovel_hide { + positions[] = {{1.05, -1.55, -1.1}}; + }; + }; + }; + class vn_wheeled_btr40_mg_04_base: vn_wheeled_btr40_mg_01_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class shovel_hide: shovel_hide { + positions[] = {{0.95, -1.5, -0.85}}; + }; + }; + }; + class vn_wheeled_btr40_mg_05_base: vn_wheeled_btr40_mg_04_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class shovel_hide: shovel_hide { + positions[] = {{0.9, -1.4, -0.85}}; + }; + }; + }; + + // Dirt Ranger + class vn_wheeled_lr2a_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class hide_shovel { + positions[] = {"_target selectionPosition ['hide_shovel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + + // M151 + class vn_wheeled_m151_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class user_shovel_hide { + positions[] = {{0.65, 0.2, -1.4}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class vn_wheeled_m151_mg_03_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_shovel_hide: user_shovel_hide { + positions[] = {{0.35, 0.2, -1.27}}; + }; + }; + }; + class vn_wheeled_m151_mg_05_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_shovel_hide: user_shovel_hide { + enabled = 0; + }; + }; + }; + class vn_wheeled_m151_mg_06_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_shovel_hide: user_shovel_hide { + enabled = 0; + }; + }; + }; + class vn_wheeled_m151_01_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_shovel_hide: user_shovel_hide { + positions[] = {{0.72, 0.2, -0.92}}; + }; + }; + }; + + // M113 + class APC_Tracked_01_base_F; + class vn_armor_m113_base: APC_Tracked_01_base_F { + class EGVAR(interaction,anims) { + class hide_shovel { + positions[] = {{0.2, 2.2, -0.5}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class vn_armor_m113_01_base: vn_armor_m113_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_shovel: hide_shovel {}; + }; + }; + class vn_armor_m132_base: vn_armor_m113_01_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_shovel: hide_shovel { + positions[] = {{0.2, 2.2, -0.35}}; + }; + }; + }; + + // Don't inherit, as it's easier for the refuel compat + // M577 + class vn_armor_m577_base: vn_armor_m113_base { + class EGVAR(interaction,anims) { + class hide_shovel { + positions[] = {{0.2, 5.05, -0.57}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + + // M48 + class vn_armor_tank_base; + class vn_armor_m48_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_mainturret_tools { + positions[] = {"_target selectionPosition ['hide_tools', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + + // BTR-50PK + class vn_armor_btr50pk_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_shovel { + positions[] = {"_target selectionPosition ['hide_shovel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_EntrenchingTool", "ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + + // PT-76 + class vn_armor_pt76_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_shovel { + positions[] = {"_target selectionPosition ['hide_shovel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + + // Type 63 + class vn_armor_type63_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_shovel { + positions[] = {"_target selectionPosition ['hide_shovel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; }; diff --git a/addons/compat_sog/config.cpp b/addons/compat_sog/config.cpp index 62b235773b9..04db68293cf 100644 --- a/addons/compat_sog/config.cpp +++ b/addons/compat_sog/config.cpp @@ -1,5 +1,4 @@ #include "script_component.hpp" -// ToDo: move refuel to subconfig #include "\z\ace\addons\refuel\defines.hpp" #include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" @@ -47,6 +46,8 @@ class CfgPatches { }; }; +class CBA_Extended_EventHandlers; + #include "ACE_CSW_Groups.hpp" #include "ACE_Medical_Injuries.hpp" #include "ACE_Triggers.hpp" diff --git a/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf b/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf index d2e9abdbbcb..7cac6829c55 100644 --- a/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf +++ b/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf @@ -14,8 +14,10 @@ * * Public: No */ + params ["_trap"]; -if (!(["ace_medical"] call EFUNC(common,isModLoaded))) exitWith {}; + +if !(GETEGVAR(medical,enabled,false)) exitWith {}; private _radius = getNumber (configOf _trap >> "indirectHitRange"); private _affectedUnits = _trap nearEntities ["CAManBase", _radius]; diff --git a/addons/compat_sog/functions/fnc_woundsHandlerIncendiary.sqf b/addons/compat_sog/functions/fnc_woundsHandlerIncendiary.sqf index 75ee243f082..6d3b7a86783 100644 --- a/addons/compat_sog/functions/fnc_woundsHandlerIncendiary.sqf +++ b/addons/compat_sog/functions/fnc_woundsHandlerIncendiary.sqf @@ -18,8 +18,6 @@ * Public: No */ -#define BURN_THRESHOLD 1 - params ["_unit", "_damages"]; TRACE_2("woundsHandlerIncendiary",_unit,_damages); @@ -32,9 +30,7 @@ private _fireDamage = 0; private _intensity = linearConversion [0, 20, _fireDamage, 0, 10, true]; TRACE_2("",_intensity,_fireDamage); -if (_intensity > BURN_THRESHOLD) then { - TRACE_2("Setting unit ablaze",_intensity,BURN_THRESHOLD); - ["ace_fire_burn", [_unit, _intensity]] call CBA_fnc_globalEvent; -}; +// Let fire handle if unit is set ablaze or not +[QEGVAR(fire,burn), [_unit, _intensity]] call CBA_fnc_localEvent; _this // return diff --git a/addons/compat_sog/stringtable.xml b/addons/compat_sog/stringtable.xml index 06f0827d08e..fc64aef97c6 100644 --- a/addons/compat_sog/stringtable.xml +++ b/addons/compat_sog/stringtable.xml @@ -12,6 +12,7 @@ Закопать Enterrarse Escavar + Creuser M49A2 60mm HE @@ -24,6 +25,7 @@ M49A2 60 мм ОФ M49A2 60mm HE M49A2 60mm HE + M49A2 60mm HE M302 60mm WP @@ -36,6 +38,7 @@ M302 60 мм Фосфорная M302 60mm WP M302 60mm WP + M302 60mm Phosphore Blanc M83 60mm Lume @@ -48,6 +51,7 @@ M83 60 мм Осветительная M83 60mm Iluminación M83 60mm Iluminação + M83 60 mm Eclairant M374 81mm HE @@ -60,6 +64,7 @@ M374 81 мм ОФ M374 81mm HE M374 81mm HE + M374 81mm HE M375 81mm WP @@ -72,6 +77,7 @@ M375 81 мм Фосфорная M375 81mm WP M375 81mm WP + M375 81mm Phosphore Blanc M301A3 81mm Lume @@ -84,6 +90,7 @@ M301A3 81 мм Осветительная M301A3 81mm Iluminación M301A3 81mm Iluminação + M301A3 81mm Eclairant M57 81mm Smoke @@ -96,6 +103,7 @@ M57 81 мм Дымовая M57 81mm Smoke M57 81mm Fumígena + M57 81mm Fumigène O-832D 82mm HE @@ -108,6 +116,7 @@ О-832Д 82 мм ОФ O-832D 82mm HE O-832D 82mm HE + O-832D 82mm HE D-832 82mm WP @@ -120,6 +129,7 @@ Д-832 82 мм Фосфорная D-832 82mm WP D-832 82mm WP + D-832 82mm Phosphore Blanc S-832S 82mm Lume @@ -132,6 +142,7 @@ С-832С 82 мм Осветительная S-832S 82mm Iluminación S-832S 82mm Iluminação + S-832S 82mm Eclairant [ACE] M49A2 60mm HE Box @@ -144,6 +155,7 @@ [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 @@ -156,6 +168,7 @@ [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 @@ -168,6 +181,7 @@ [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 @@ -180,6 +194,7 @@ [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 @@ -192,6 +207,7 @@ [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 @@ -204,6 +220,7 @@ [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 @@ -216,6 +233,7 @@ [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 @@ -228,6 +246,7 @@ [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 @@ -240,6 +259,7 @@ [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 @@ -252,6 +272,7 @@ [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 @@ -264,6 +285,7 @@ Выкопать паучью дыру Excavar Agujero de araña Escavar buraco de aranha + Creuser un trou d'araignée Dig Spiderhole (Angled Cover) @@ -276,6 +298,7 @@ Выкопать крытую паучью дыру 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) @@ -288,6 +311,7 @@ Выкопать двойную паучью дыру Excavar Agujero de araña (Doble) Escavar buraco de aranha (Duplo) + Creuser un trou d'araignée (double) [CSW] M1919A4 Gun Bag @@ -300,6 +324,7 @@ [CSW] Сумка с M1919A4 [CSW] M1919A4 Bolsa para arma [CSW] Bolsa para M1919A4 + [CSW] M1919A4 Gun Bag [CSW] M1919A6 Gun Bag @@ -312,6 +337,7 @@ [CSW] Сумка с M1919A6 [CSW] M1919A6 Bolsa para arma [CSW] Bolsa para M1919A6 + [CSW] M1919A6 Gun Bag [CSW] M60 Gun Bag @@ -324,6 +350,7 @@ [CSW] Сумка с M60 [CSW] M60 Bolsa para arma [CSW] Bolsa para M60 + [CSW] M60 Gun Bag [CSW] DShK (Shield) Gun Bag @@ -336,6 +363,7 @@ [CSW] Сумка с ДШК (со щитом) [CSW] DShK (Apantallada) Bolsa para arma [CSW] Bolsa para DShK (Escudo) + [CSW] DShK (Shield) Gun Bag [CSW] DShK (AA) Gun Bag @@ -348,6 +376,7 @@ [CSW] Сумка с ДШК (зенитный) [CSW] DShK (AA) Bolsa para arma [CSW] Bolsa para DShK (AA) + [CSW] DShK (AA) Gun Bag [CSW] RPD Gun Bag @@ -360,6 +389,7 @@ [CSW] Сумка с РПД [CSW] RPD Bolsa para arma [CSW] Bolsa para RPD + [CSW] RPD Gun Bag [CSW] PK Gun Bag @@ -372,6 +402,7 @@ [CSW] Сумка с ПК [CSW] PK Bolsa para arma [CSW] Bolsa para PK + [CSW] PK Sac d'armes [CSW] MG42 Gun Bag @@ -384,6 +415,7 @@ [CSW] Сумка с MG42 [CSW] MG42 Bolsa para arma [CSW] Bolsa para MG42 + [CSW] MG42 Sac d'armes [CSW] SGM Gun Bag @@ -396,6 +428,7 @@ [CSW] Сумка с СГМ [CSW] SGM Bolsa para arma [CSW] Bolsa para SGM + [CSW] SGM Sac d'armes [CSW] SGM (Shield) Gun Bag @@ -408,6 +441,7 @@ [CSW] Сумка с СГМ (со щитом) [CSW] SGM (Apantallada) Bolsa para arma [CSW] Bolsa para SGM (Escudo) + [CSW] SGM Sac d'armes (avec bouclier) [CSW] Mk18 Gun Bag @@ -420,6 +454,7 @@ [CSW] Сумка с Mk18 [CSW] Mk18 Bolsa para arma [CSW] Bolsa para Mk18 + [CSW] Mk18 Sac d'armes [CSW] M29 Mortar Tube @@ -432,6 +467,7 @@ [CSW] Сумка с миномётом M29 [CSW] M29 Tubo de Mortero [CSW] M29 Tubo de Morteiro + [CSW] Tube de mortier M29 [CSW] M2 Mortar Tube @@ -444,6 +480,7 @@ [CSW] Сумка с миномётом M2 [CSW] M2 Tubo de mortero [CSW] M2 Tubo de Morteiro + [CSW] Tube de mortier M2 [CSW] Type 53 Mortar Tube @@ -456,6 +493,7 @@ [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/CfgMagazines/csw.hpp b/addons/compat_spe/CfgMagazines/csw.hpp index 404156bd8f8..6b4c385a42a 100644 --- a/addons/compat_spe/CfgMagazines/csw.hpp +++ b/addons/compat_spe/CfgMagazines/csw.hpp @@ -2,43 +2,16 @@ 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 { +// M2 +class VehicleMagazine; +class SPE_100Rnd_127x99_M2: VehicleMagazine { ACE_isBelt = 1; }; -//MG34/42 - +// 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/CfgVehicles/wheeled.hpp b/addons/compat_spe/CfgVehicles/wheeled.hpp index 6ed68dfbdfb..f645db29e64 100644 --- a/addons/compat_spe/CfgVehicles/wheeled.hpp +++ b/addons/compat_spe/CfgVehicles/wheeled.hpp @@ -56,8 +56,12 @@ class SPE_OpelBlitz_Ammo: SPE_OpelBlitz_base { EGVAR(rearm,defaultSupply) = 1200; }; -// WHEELED - ALLIED FORCES +class SPE_OpelBlitz_Fuel: SPE_OpelBlitz_base { + EGVAR(refuel,hooks)[] = {{-0.23, -2.58, -0.59}}; + EGVAR(refuel,fuelCargo) = 2000; +}; +// WHEELED - ALLIED FORCES class SPE_US_M3_Halftrack_Ambulance: SPE_Halftrack_base { EGVAR(medical,medicClass) = 1; }; @@ -69,3 +73,69 @@ class SPE_US_M3_Halftrack_Repair: SPE_Halftrack_base { class SPE_US_M3_Halftrack_Ammo: SPE_Halftrack_base { EGVAR(rearm,defaultSupply) = 1200; }; + +class SPE_US_M3_Halftrack_Fuel: SPE_Halftrack_base { + EGVAR(refuel,hooks)[] = {{-0.23, -2.58, -0.59}}; + EGVAR(refuel,fuelCargo) = 2000; +}; + +class SPE_Car_base; +class SPE_G503_MB_base: SPE_Car_base { + class EGVAR(interaction,anims) { + class hide_musette_source { + positions[] = {{0.8, -0.97, -0.6}, {-0.8, -0.92, -0.6}}; + items[] = {"B_SPE_US_M36", "B_SPE_US_M36"}; + name = "$STR_CTH_B_SPE_US_M36"; + text = "$STR_CTH_B_SPE_US_M36"; + }; + }; +}; +class SPE_US_G503_MB_M1919_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_musette_source: hide_musette_source { + positions[] = {{0.8, -0.5, -0.6}, {-0.8, -0.45, -0.6}}; + }; + }; +}; +class SPE_US_G503_MB_M1919_Armoured_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_musette_source: hide_musette_source { + positions[] = {{0.8, -0.5, -0.6}, {-0.8, -0.45, -0.6}}; + }; + }; +}; +class SPE_US_G503_MB_M1919_PATROL_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_musette_source: hide_musette_source { + positions[] = {{0.8, -0.5, -0.6}, {-0.8, -0.45, -0.6}}; + }; + }; +}; +class SPE_US_G503_MB_M2_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_musette_source: hide_musette_source { + positions[] = {{0.8, -0.5, -0.6}, {-0.8, -0.45, -0.6}}; + }; + }; +}; +class SPE_US_G503_MB_M2_Armoured_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_musette_source: hide_musette_source { + positions[] = {{0.8, -0.5, -0.6}, {-0.8, -0.45, -0.6}}; + }; + }; +}; +class SPE_US_G503_MB_M2_PATROL_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_musette_source: hide_musette_source { + positions[] = {{0.8, -0.5, -0.6}, {-0.8, -0.45, -0.6}}; + }; + }; +}; +class SPE_G503_MB_Ambulance_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_musette_source: hide_musette_source { + positions[] = {{0.8, -0.5, -0.6}, {-0.8, -0.45, -0.6}}; + }; + }; +}; diff --git a/addons/compat_spe/compat_spe_csw/ACE_CSW_Groups.hpp b/addons/compat_spe/compat_spe_csw/ACE_CSW_Groups.hpp deleted file mode 100644 index 35758ed5333..00000000000 --- a/addons/compat_spe/compat_spe_csw/ACE_CSW_Groups.hpp +++ /dev/null @@ -1,50 +0,0 @@ -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/CfgMagazineGroups.hpp b/addons/compat_spe/compat_spe_csw/CfgMagazineGroups.hpp new file mode 100644 index 00000000000..78f6d0629dd --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/CfgMagazineGroups.hpp @@ -0,0 +1,94 @@ +class EGVAR(csw,groups) { + // --- Gun Turrets ------------------------------------------------------------- + class SPE_50Rnd_762x63 { + SPE_50Rnd_762x63 = 1; + }; + class SPE_100Rnd_762x63 { + SPE_100Rnd_762x63 = 1; + }; + + class SPE_50Rnd_762x63_M1 { + SPE_50Rnd_762x63_M1 = 1; + }; + class SPE_100Rnd_762x63_M1 { + SPE_100Rnd_762x63_M1 = 1; + }; + + class SPE_50Rnd_762x63_M2_AP { + SPE_50Rnd_762x63_M2_AP = 1; + }; + class SPE_100Rnd_762x63_M2_AP { + SPE_100Rnd_762x63_M2_AP = 1; + }; + + class SPE_50Rnd_762x63_Tracer { + SPE_50Rnd_762x63_Tracer = 1; + }; + class SPE_100Rnd_762x63_Tracer { + SPE_100Rnd_762x63_Tracer = 1; + }; + + class SPE_50Rnd_792x57 { + SPE_50Rnd_792x57 = 1; + }; + class SPE_100Rnd_792x57 { + SPE_100Rnd_792x57 = 1; + SPE_250Rnd_792x57 = 1; + }; + + class SPE_50Rnd_792x57_sS { + SPE_50Rnd_792x57_sS = 1; + }; + class SPE_100Rnd_792x57_sS { + SPE_100Rnd_792x57_sS = 1; + SPE_250Rnd_792x57_sS = 1; + }; + + class SPE_50Rnd_792x57_SMK { + SPE_50Rnd_792x57_SMK = 1; + }; + class SPE_100Rnd_792x57_SMK { + SPE_100Rnd_792x57_SMK = 1; + SPE_250Rnd_792x57_SMK = 1; + }; + + class SPE_50Rnd_792x57_Tracer { + SPE_50Rnd_792x57_Tracer = 1; + }; + class SPE_100Rnd_792x57_Tracer { + SPE_100Rnd_792x57_Tracer = 1; + }; + + // Makes it compatible with other mods' .50 BMG + class EGVAR(csw,100Rnd_127x99_mag) { + SPE_100Rnd_127x99_M2 = 1; + }; + class SPE_100Rnd_127x99_M2: EGVAR(csw,100Rnd_127x99_mag) {}; + + // --- Mortars ------------------------------------------------------------- + class SPE_1Rnd_81mmHE_M1_M43A1 { + SPE_8Rnd_81mmHE_M1_M43A1 = 1; + SPE_1Rnd_81mmHE_M1_M43A1 = 1; + }; + class SPE_1Rnd_81mmWP_M1_M57 { + SPE_8Rnd_81mmWP_M1_M57 = 1; + SPE_1Rnd_81mmWP_M1_M57 = 1; + }; + class SPE_81mm_M1_M57_SmokeShell { + SPE_8rnd_81mm_M1_M57_SmokeShell = 1; + SPE_81mm_M1_M57_SmokeShell = 1; + }; + + class SPE_1Rnd_81mm_FA_Mle_1932_HE { + SPE_8Rnd_81mm_FA_Mle_1932_HE = 1; + SPE_1Rnd_81mm_FA_Mle_1932_HE = 1; + }; + class SPE_81mm_FA_Mle_1932_Smoke { + SPE_8Rnd_81mm_FA_Mle_1932_Smoke = 1; + SPE_81mm_FA_Mle_1932_Smoke = 1; + }; + class SPE_81mm_FA_Mle_1932_Illu { + SPE_8Rnd_81mm_FA_Mle_1932_Illu = 1; + SPE_81mm_FA_Mle_1932_Illu = 1; + }; +}; diff --git a/addons/compat_spe/compat_spe_csw/CfgMagazines.hpp b/addons/compat_spe/compat_spe_csw/CfgMagazines.hpp new file mode 100644 index 00000000000..9c255c28008 --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/CfgMagazines.hpp @@ -0,0 +1,26 @@ +// In SPE 1.1.1, the tracer magazines don't have proper names +class CfgMagazines { + class SPE_50Rnd_762x63; + class SPE_50Rnd_762x63_Tracer: SPE_50Rnd_762x63 { + displayName = SUBCSTRING(50Rnd_762x63_Tracer); + displayNameShort = "$STR_A3_tracer_dns"; + }; + + class SPE_100Rnd_762x63; + class SPE_100Rnd_762x63_Tracer: SPE_100Rnd_762x63 { + displayName = SUBCSTRING(100Rnd_762x63_Tracer); + displayNameShort = "$STR_A3_tracer_dns"; + }; + + class SPE_50Rnd_792x57; + class SPE_50Rnd_792x57_Tracer: SPE_50Rnd_792x57 { + displayName = SUBCSTRING(50Rnd_792x57_Tracer); + displayNameShort = "$STR_A3_tracer_dns"; + }; + + class SPE_100Rnd_792x57; + class SPE_100Rnd_792x57_Tracer: SPE_100Rnd_792x57 { + displayName = SUBCSTRING(100Rnd_792x57_Tracer); + displayNameShort = "$STR_A3_tracer_dns"; + }; +}; diff --git a/addons/compat_spe/compat_spe_csw/CfgVehicles.hpp b/addons/compat_spe/compat_spe_csw/CfgVehicles.hpp index e0a38aa341c..30d39301f38 100644 --- a/addons/compat_spe/compat_spe_csw/CfgVehicles.hpp +++ b/addons/compat_spe/compat_spe_csw/CfgVehicles.hpp @@ -9,90 +9,267 @@ class CfgVehicles { class ACE_Actions { class ACE_MainActions; }; - class Turrets { - class MainTurret; + }; + + // --- Gun Turrets ------------------------------------------------------------- + class StaticMGWeapon: StaticWeapon {}; + class SPE_StaticMGWeapon_base: StaticMGWeapon {}; + class SPE_M2_M3: SPE_StaticMGWeapon_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + selection = "zamerny"; + }; + }; + class ace_csw { + enabled = 1; + proxyWeapon = QGVAR(M2_proxy); + magazineLocation = ""; + disassembleWeapon = "SPE_M2_50"; + disassembleTurret = QGVAR(m3Tripod); + ammoLoadTime = 10; + ammoUnloadTime = 8; + desiredAmmo = 100; + }; + }; + class SPE_M2_M3_Trench: SPE_M2_M3 { + class ace_csw: ace_csw { + disassembleWeapon = ""; + disassembleTurret = ""; }; - class UserActions; }; - // --- Mortars ----------------------------------------------------------------- - class StaticMortar: StaticWeapon { - class Turrets: Turrets { - class MainTurret: MainTurret {}; + + class SPE_M1919_M2: SPE_StaticMGWeapon_base { + class ace_csw { + enabled = 1; + proxyWeapon = QGVAR(M1919A4_proxy); + magazineLocation = "_target selectionPosition ['magazine', 'FireGeometry', 'AveragePoint']"; + disassembleWeapon = "SPE_M1919A4"; + disassembleTurret = QGVAR(m2Tripod); + ammoLoadTime = 8; + ammoUnloadTime = 6; + desiredAmmo = 100; }; }; - class SPE_StaticMortar_base: StaticMortar { - class Turrets: Turrets { - class MainTurret: MainTurret {}; + class SPE_M1919_M2_Trench_Deployed: SPE_M1919_M2 { + class ace_csw: ace_csw { + disassembleWeapon = ""; + disassembleTurret = ""; }; - class EventHandlers: EventHandlers { - class SPE_StaticWeaponsHandler { - init = ""; + }; + + + class SPE_MG42_Lafette: SPE_StaticMGWeapon_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + class GVAR(alterHeight) { + condition = "getText (configOf _target >> 'SPE_AltHeight_Tripod_Name') != '' && {[_target, true] call SPE_WEAPONS_STATIC_fnc_can_alter_height}"; + displayName = "$STR_SPE_DN_ASSETS_VEHICLES_ADJUST_TRIPOD_HEIGHT"; + statement = "[_target, getText (configOf _target >> 'SPE_AltHeight_Tripod_Name'), true] call SPE_Weapons_Static_fnc_alter_height"; + icon = "\A3\Ui_f\data\IGUI\Cfg\Actions\repair_ca.paa"; + modifierFunction = "(_this select 3) set [1, format [localize 'STR_SPE_DN_ASSETS_VEHICLES_ADJUST_TRIPOD_HEIGHT', getText (configOf _target >> 'displayName')]]"; + }; }; }; }; + class SPE_MG42_Lafette_Deployed: SPE_MG42_Lafette { + class ace_csw { + enabled = 1; + proxyWeapon = QGVAR(MG42_proxy); + magazineLocation = ""; + disassembleWeapon = "SPE_MG42"; + disassembleTurret = QGVAR(LafetteTripod); + ammoLoadTime = 7; + ammoUnloadTime = 5; + desiredAmmo = 100; + }; + }; + class SPE_MG34_Lafette_Deployed: SPE_MG42_Lafette { + class ace_csw { + enabled = 1; + proxyWeapon = QGVAR(MG34_proxy); + magazineLocation = ""; + disassembleWeapon = "SPE_MG34"; + disassembleTurret = QGVAR(LafetteTripod); + ammoLoadTime = 7; + ammoUnloadTime = 5; + desiredAmmo = 100; + }; + }; - class SPE_US_Mortar_base: SPE_StaticMortar_base {}; - class SPE_M1_81: SPE_US_Mortar_base { - class Turrets: Turrets { - class MainTurret: MainTurret { - magazines[] = {}; + class SPE_MG42_Lafette_low; + class SPE_MG42_Lafette_low_Deployed: SPE_MG42_Lafette_low { + class ace_csw { + enabled = 1; + proxyWeapon = QGVAR(MG42_proxy); + magazineLocation = ""; + disassembleWeapon = "SPE_MG42"; + disassembleTurret = QGVAR(LafetteTripodLow); + ammoLoadTime = 7; + ammoUnloadTime = 5; + desiredAmmo = 100; + }; + }; + class SPE_MG42_Lafette_trench_Deployed: SPE_MG42_Lafette_low_Deployed { + class ace_csw: ace_csw { + disassembleWeapon = ""; + disassembleTurret = ""; + }; + }; + + class SPE_MG34_Lafette_low_Deployed: SPE_MG42_Lafette_low { + class ace_csw { + enabled = 1; + proxyWeapon = QGVAR(MG34_proxy); + magazineLocation = ""; + disassembleWeapon = "SPE_MG34"; + disassembleTurret = QGVAR(LafetteTripodLow); + ammoLoadTime = 7; + ammoUnloadTime = 5; + desiredAmmo = 100; + }; + }; + class SPE_MG34_Lafette_Trench_Deployed: SPE_MG34_Lafette_low_Deployed { + class ace_csw: ace_csw { + disassembleWeapon = ""; + disassembleTurret = ""; + }; + }; + + + class SPE_MG_Bipod_base; + class SPE_M1919A6_Bipod: SPE_MG_Bipod_base { + class ace_csw { + enabled = 1; + proxyWeapon = QGVAR(M1919A6_proxy); + magazineLocation = ""; + disassembleWeapon = ""; + disassembleTurret = ""; + ammoLoadTime = 8; + ammoUnloadTime = 6; + desiredAmmo = 100; + }; + }; + + + class SPE_MG42_Bipod: SPE_MG_Bipod_base { + class ace_csw { + enabled = 1; + proxyWeapon = QGVAR(MG42_proxy); + magazineLocation = ""; + disassembleWeapon = ""; + disassembleTurret = ""; + ammoLoadTime = 7; + ammoUnloadTime = 5; + desiredAmmo = 100; + }; + }; + class SPE_MG34_Bipod: SPE_MG_Bipod_base { + class ace_csw { + enabled = 1; + proxyWeapon = QGVAR(MG34_proxy); + magazineLocation = ""; + disassembleWeapon = ""; + disassembleTurret = ""; + ammoLoadTime = 7; + ammoUnloadTime = 5; + desiredAmmo = 100; + }; + }; + + + class ThingX; + class EGVAR(csw,baseTripod): ThingX { + class ACE_Actions { + class ACE_MainActions; + }; + }; + class GVAR(m3Tripod): EGVAR(csw,baseTripod) { + scope = 2; + displayName = "$STR_DN_SPE_M3_Tripod"; + model = "\WW2\SPE_Assets_m\Vehicles\StaticWeapons_U1_m\SPE_M3_Tripod.p3d"; + picture = "\WW2\SPE_Assets_t\Weapons\Equipment_U1_t\Weapons\Launchers\Gear_M3_Tripod_X_ca.paa"; + class ace_csw { + disassembleTo = "SPE_M3_Tripod"; + }; + }; + + class GVAR(m2Tripod): EGVAR(csw,baseTripod) { + scope = 2; + displayName = "$STR_DN_SPE_M2_Tripod"; + model = "\WW2\SPE_Assets_m\Vehicles\StaticWeapons_m\SPE_M2_Tripod_Low.p3d"; + picture = "\WW2\SPE_Assets_t\Weapons\Equipment_t\Weapons\Launchers\Gear_M2_Tripod_X_ca.paa"; + class ace_csw { + disassembleTo = "SPE_M2_Tripod"; + }; + }; + + class GVAR(LafetteTripodLow): EGVAR(csw,baseTripod) { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + class GVAR(alterHeight) { + condition = "getText (configOf _target >> 'SPE_AltHeight_Tripod_Name') != '' && {[_target, true] call SPE_WEAPONS_STATIC_fnc_can_alter_height}"; + displayName = "$STR_SPE_DN_ASSETS_VEHICLES_ADJUST_TRIPOD_HEIGHT"; + statement = "[_target, getText (configOf _target >> 'SPE_AltHeight_Tripod_Name'), true] call SPE_Weapons_Static_fnc_alter_height"; + icon = "\A3\Ui_f\data\IGUI\Cfg\Actions\repair_ca.paa"; + modifierFunction = "(_this select 3) set [1, format [localize 'STR_SPE_DN_ASSETS_VEHICLES_ADJUST_TRIPOD_HEIGHT', getText (configOf _target >> 'displayName')]]"; + }; }; }; + scope = 2; + displayName = "$STR_DN_SPE_Lafette_Tripod"; + model = "\WW2\SPE_Assets_m\Vehicles\StaticWeapons_m\SPE_Lafette_Tripod_Low.p3d"; + picture = "\WW2\SPE_Assets_t\Weapons\Equipment_t\Weapons\Launchers\Gear_Lafette_Tripod_X_ca.paa"; + SPE_AltHeight_Tripod_Name = QGVAR(LafetteTripod); + class ace_csw { + disassembleTo = "SPE_Lafette_Tripod"; + }; + }; + + class GVAR(LafetteTripod): GVAR(LafetteTripodLow) { + model = "\WW2\SPE_Assets_m\Vehicles\StaticWeapons_m\SPE_Lafette_Tripod_High.p3d"; + SPE_AltHeight_Tripod_Name = QGVAR(LafetteTripodLow); + class ace_csw { + disassembleTo = "SPE_Lafette_Tripod"; + }; + }; + + // --- Mortars ----------------------------------------------------------------- + class StaticMortar: StaticWeapon {}; + class SPE_StaticMortar_base: StaticMortar {}; + class SPE_US_Mortar_base: SPE_StaticMortar_base {}; + class SPE_M1_81: SPE_US_Mortar_base { 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 { + class ace_csw { enabled = 1; - proxyWeapon = "SPE_M1_81_proxy"; + proxyWeapon = QGVAR(M1_proxy); magazineLocation = "_target selectionPosition 'usti hlavne'"; disassembleWeapon = "SPE_M1_81_Barrel"; - disassembleTurret = QGVAR(M1_81_baseplate); + disassembleTurret = QGVAR(m1Baseplate); 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 { + class ace_csw { enabled = 1; - proxyWeapon = "SPE_MLE_27_31_proxy"; + proxyWeapon = QGVAR(MLE_27_31_proxy); magazineLocation = "_target selectionPosition 'usti hlavne'"; disassembleWeapon = "SPE_MLE_27_31_Barrel"; disassembleTurret = QGVAR(MLE_27_31_baseplate); @@ -103,30 +280,9 @@ class CfgVehicles { }; 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 { + class ace_csw { enabled = 1; - proxyWeapon = "SPE_GrW278_1_proxy"; + proxyWeapon = QGVAR(GrW278_1_proxy); magazineLocation = "_target selectionPosition 'usti hlavne'"; disassembleWeapon = "SPE_GrW278_1_Barrel"; disassembleTurret = QGVAR(GrW278_baseplate); @@ -137,7 +293,15 @@ class CfgVehicles { }; - class EGVAR(csw,baseTripod); + class GVAR(m1Baseplate): 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 GVAR(MLE_27_31_baseplate): EGVAR(csw,baseTripod) { scope = 2; @@ -146,7 +310,7 @@ class CfgVehicles { 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 { + class ace_csw { disassembleTo = "SPE_MLE_27_31_Stand"; }; }; @@ -158,83 +322,8 @@ class CfgVehicles { 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 { + 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 index db090c77080..b6e71dcb6a9 100644 --- a/addons/compat_spe/compat_spe_csw/CfgWeapons.hpp +++ b/addons/compat_spe/compat_spe_csw/CfgWeapons.hpp @@ -1,43 +1,162 @@ class CfgWeapons { - class Launcher; - class Launcher_Base_F: Launcher { - class WeaponSlotsInfo; + class Launcher_Base_F; + class SPE_Slung_Static_Weapon_Base: Launcher_Base_F {}; + + // --- Vanilla Compat ------------------------------------------------------------- + class EGVAR(csw,staticHMGCarry): Launcher_Base_F { + class ace_csw { + class assembleTo { + GVAR(m3Tripod) = "B_HMG_01_F"; + }; + }; + }; + class EGVAR(csw,staticM2ShieldCarry): EGVAR(csw,staticHMGCarry) { + class ace_csw: ace_csw { + class assembleTo { + GVAR(m3Tripod) = "B_HMG_02_F"; + }; + }; }; - class SPE_Slung_Static_Weapon_Base: Launcher_Base_F {}; + class EGVAR(csw,staticGMGCarry): Launcher_Base_F { + class ace_csw { + class assembleTo { + GVAR(m3Tripod) = "B_GMG_01_F"; + }; + }; + }; + + // --- Gun Turrets ------------------------------------------------------------- + class SPE_M2_M3_Tripod; + class GVAR(M2_proxy): SPE_M2_M3_Tripod { + magazineReloadTime = 0.5; + }; + class SPE_M3_Tripod: SPE_Slung_Static_Weapon_Base { + class ace_csw { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = QGVAR(m3Tripod); + }; + }; + class SPE_M2_50: SPE_Slung_Static_Weapon_Base { + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + GVAR(m3Tripod) = "SPE_M2_M3"; + EGVAR(csw,m3TripodLow) = "SPE_M2_M3"; + }; + }; + }; + + class SPE_M1919A4_tripod; + class GVAR(M1919A4_proxy): SPE_M1919A4_tripod { + magazineReloadTime = 0.5; + }; + + class SPE_M2_Tripod: SPE_Slung_Static_Weapon_Base { + class ace_csw { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = QGVAR(m2Tripod); + }; + }; + + class SPE_LMG; + class SPE_M1919A4: SPE_LMG { + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + GVAR(m2Tripod) = "SPE_M1919_M2"; + }; + }; + }; + + class SPE_M1919A6_StaticBipod; + class GVAR(M1919A6_proxy): SPE_M1919A6_StaticBipod { + magazineReloadTime = 0.5; + }; + + class SPE_MG42_Tripod; + class GVAR(MG42_proxy): SPE_MG42_Tripod { + magazineReloadTime = 0.5; + }; + + class SPE_MG34_Tripod; + class GVAR(MG34_proxy): SPE_MG34_Tripod { + magazineReloadTime = 0.5; + }; + + class SPE_Lafette_Tripod: SPE_Slung_Static_Weapon_Base { + class ace_csw { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = QGVAR(LafetteTripodLow); + }; + }; + class SPE_MG42: SPE_LMG { + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + GVAR(LafetteTripodLow) = "SPE_MG42_Lafette_low_Deployed"; + GVAR(LafetteTripod) = "SPE_MG42_Lafette_Deployed"; + }; + }; + }; + class SPE_MG34: SPE_LMG { + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + GVAR(LafetteTripodLow) = "SPE_MG34_Lafette_low_Deployed"; + GVAR(LafetteTripod) = "SPE_MG34_Lafette_Deployed"; + }; + }; + }; + + // --- Mortars ----------------------------------------------------------------- class SPE_M1_81; - class SPE_M1_81_proxy: SPE_M1_81 { + class GVAR(M1_proxy): SPE_M1_81 { magazineReloadTime = 0.5; }; class SPE_M1_81_Stand: SPE_Slung_Static_Weapon_Base { - class ACE_CSW { + class ace_csw { type = "mount"; deployTime = 4; pickupTime = 4; - deploy = QGVAR(M1_81_baseplate); + deploy = QGVAR(m1Baseplate); }; }; class SPE_M1_81_Barrel: SPE_Slung_Static_Weapon_Base { - class ACE_CSW { + class ace_csw { type = "weapon"; - deployTime = 4; - pickupTime = 4; + deployTime = 20; + pickupTime = 25; class assembleTo { - GVAR(M1_81_baseplate) = "SPE_M1_81"; + GVAR(m1Baseplate) = "SPE_M1_81"; EGVAR(csw,mortarBaseplate) = "SPE_M1_81"; }; }; }; class SPE_MLE_27_31; - class SPE_MLE_27_31_proxy: SPE_MLE_27_31 { + class GVAR(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 { + class ace_csw { type = "mount"; deployTime = 4; pickupTime = 4; @@ -45,7 +164,7 @@ class CfgWeapons { }; }; class SPE_MLE_27_31_Barrel: SPE_Slung_Static_Weapon_Base { - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 20; pickupTime = 25; @@ -57,21 +176,20 @@ class CfgWeapons { }; class SPE_GrW278_1; - class SPE_GrW278_1_proxy: SPE_GrW278_1 { + class GVAR(GrW278_1_proxy): SPE_GrW278_1 { magazineReloadTime = 0.5; }; class SPE_GrW278_1_Stand: SPE_MLE_27_31_Stand { - class ACE_CSW { + 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 { + class ace_csw { type = "weapon"; deployTime = 20; pickupTime = 25; diff --git a/addons/compat_spe/compat_spe_csw/config.cpp b/addons/compat_spe/compat_spe_csw/config.cpp index 6ff669629bf..05627a8f6db 100644 --- a/addons/compat_spe/compat_spe_csw/config.cpp +++ b/addons/compat_spe/compat_spe_csw/config.cpp @@ -23,7 +23,22 @@ class CfgPatches { }; }; -#include "ACE_CSW_Groups.hpp" -// Todo: https://github.com/acemod/ACE3/pull/9292#discussion_r1327738181 -// #include "CfgVehicles.hpp" -// #include "CfgWeapons.hpp" +#include "CfgMagazines.hpp" +#include "CfgMagazineGroups.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" + +class CfgFunctions { + class SPE_WEAPONS_STATIC { + class SPE_Weapons_Static { + OVERWRITE_FUNC(alter_height); + OVERWRITE_FUNC(can_alter_height); + OVERWRITE_FUNC(can_assemble_weapon); + OVERWRITE_FUNC(can_disassemble_weapon); + OVERWRITE_FUNC(can_prepare_ammo); + OVERWRITE_FUNC(can_Reload); + OVERWRITE_FUNC(can_resupply_ammo); + OVERWRITE_FUNC(can_unload_ammo); + }; + }; +}; diff --git a/addons/compat_spe/compat_spe_csw/functions/fnc_alter_height.sqf b/addons/compat_spe/compat_spe_csw/functions/fnc_alter_height.sqf new file mode 100644 index 00000000000..0179c881537 --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/functions/fnc_alter_height.sqf @@ -0,0 +1,107 @@ +#include "..\script_component.hpp" +/* + * Author: Kerc (SPE), original by www.3commandobrigade.com, edited by johnb43 to be made CSW compatible + * Alters the static weapon's height. + * + * Arguments: + * 0: Static Weapon + * 1: New static weapon (i.e. the weapon to replace the current weapon) + * 2: Use ACE's progress bar (default: false) + * + * Return Value: + * None + * + * Example: + * cursorObject call SPE_Weapons_Static_fnc_can_alter_height + * + * Public: No + */ + +private _unit = call SPE_fnc_findPlayer; + +if !(alive _unit) exitWith {}; + +params ["_weaponPlatform", "_newStaticWeapon", ["_playProgressBar", false, [false]]]; + +if (_playProgressBar) exitWith { + [10 * EGVAR(csw,progressBarTimeCoefficent), [_weaponPlatform, _newStaticWeapon], { + (_this select 0) params ["_weaponPlatform", "_newStaticWeapon"]; + + [_weaponPlatform, _newStaticWeapon] call SPE_Weapons_Static_fnc_alter_height; + }, {}, LSUBLSTRING(alteringHeight), { + //IGNORE_PRIVATE_WARNING ["_player"]; + (_this select 0) params ["_weaponPlatform"]; + + _player distance _weaponPlatform <= 4 && {[_weaponPlatform, true] call SPE_Weapons_Static_fnc_can_alter_height} + }] call EFUNC(common,progressBar); +}; + +private _dir = vectorDir _weaponPlatform; +private _pos = (getPosATL _weaponPlatform) vectorAdd [0, 0, 0.1]; // 10 cm above terrain surface + +// Save state +private _magazines = magazinesAmmoFull _weaponPlatform; +private _assemblyModeIndex = _weaponPlatform getVariable QEGVAR(csw,assemblyMode); + +// Delete weapon and create new one +deleteVehicle _weaponPlatform; + +[{ + params ["_unit", "_newStaticWeapon", "_magazines", "_pos", "_dir", "_assemblyModeIndex"]; + + private _weaponPlatform = createVehicle [_newStaticWeapon, _pos, [], 0, "CAN_COLLIDE"]; + + if (!isNil "_assemblyModeIndex") then { + // Don't empty the weapon of its existing mags + _weaponPlatform setVariable [QEGVAR(csw,assemblyMode), 0, true]; + + if (_assemblyModeIndex == 0) exitWith {}; + + // Reset variable to original after initVehicle has run + [{ + (_this select 0) setVariable [QEGVAR(csw,assemblyMode), _this select 1, true]; + }, [_weaponPlatform, _assemblyModeIndex], 1.5] call CBA_fnc_waitAndExecute; + }; + + _weaponPlatform disableCollisionWith _unit; + _weaponPlatform setVectorDir _dir; + + [{ + _this remoteExecCall ["enableCollisionWith", _this]; + }, [_weaponPlatform, _unit], 0.5] call CBA_fnc_waitAndExecute; + + // Restore state + // First remove magazines that were spawned in with new weapon + { + _weaponPlatform removeMagazineTurret [_x, [0]]; + } forEach (_weaponPlatform magazinesTurret [0]); + + // Remove weapon temporarily and readd it to instantly load previous magazine + private _weapon = (_weaponPlatform weaponsTurret [0]) param [0, ""]; + + if (_weapon != "") then { + _weaponPlatform removeWeaponTurret [_weapon, [0]]; + }; + + if (_magazines isEqualTo []) exitWith {}; + + // Find loaded magazine + private _loadedIndex = _magazines findIf {_x select 2}; + + // If there was a loaded magazine, add that one first + if (_loadedIndex != -1) then { + (_magazines deleteAt _loadedIndex) params ["_magClass", "_ammoCount"]; + _weaponPlatform addMagazineTurret [_magClass, [0], _ammoCount]; + }; + + _weaponPlatform addWeaponTurret [_weapon, [0]]; + + { + _x params ["_magClass", "_ammoCount", "_loaded"]; + + // In some instances the loaded magazine is listed twice, so we skip it. + if (!_loaded) then { + _weaponPlatform addMagazineTurret [_magClass, [0], _ammoCount]; + }; + } forEach _magazines; +}, [_unit, _newStaticWeapon, _magazines, _pos, _dir, _assemblyModeIndex]] call CBA_fnc_execNextFrame; diff --git a/addons/compat_spe/compat_spe_csw/functions/fnc_can_Reload.sqf b/addons/compat_spe/compat_spe_csw/functions/fnc_can_Reload.sqf new file mode 100644 index 00000000000..c8a666753a1 --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/functions/fnc_can_Reload.sqf @@ -0,0 +1,42 @@ +#include "..\script_component.hpp" +/* + * Author: Kerc (SPE), edited by johnb43 to be made CSW compatible + * Checks if the prepped magazine for the static weapon can be loaded. + * + * Arguments: + * 0: Static Weapon + * 1: Default magazine to load (unused) (default: "") + * + * Return Value: + * If the player can load the selected ammo for the static weapon's + * + * Example: + * cursorObject call SPE_Weapons_Static_fnc_can_Reload + * + * Public: No + */ + +params ["_weaponPlatform"]; + +private _unit = call SPE_fnc_findPlayer; + +alive _unit && +{alive _weaponPlatform} && +{vehicle _unit in [_unit, _weaponPlatform]} && +{(magazines _weaponPlatform) isEqualTo []} && +{ + private _selectedMagazine = _unit getVariable ["SPE_Static_Weapon_Magazine", ""]; + + if (_selectedMagazine == "") exitWith { + false + }; + + _selectedMagazine = _selectedMagazine call EFUNC(common,getConfigName); + + if (_selectedMagazine == "") exitWith { + false + }; + + _selectedMagazine in compatibleMagazines ((_weaponPlatform weaponsTurret [0]) select 0) +} && +{CONDITION_NO_CSW(_weaponPlatform)} // CSW check diff --git a/addons/compat_spe/compat_spe_csw/functions/fnc_can_alter_height.sqf b/addons/compat_spe/compat_spe_csw/functions/fnc_can_alter_height.sqf new file mode 100644 index 00000000000..7c3f8c1f84b --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/functions/fnc_can_alter_height.sqf @@ -0,0 +1,31 @@ +#include "..\script_component.hpp" +/* + * Author: Kerc (SPE), original by www.3commandobrigade.com, edited by johnb43 to be made CSW compatible + * Checks if the static weapon's height can be adjusted. + * + * Arguments: + * 0: Static Weapon + * 1: Check for ACE CSW (default: false) + * + * Return Value: + * If the player can alter the static weapon's height + * + * Example: + * cursorObject call SPE_Weapons_Static_fnc_can_alter_height + * + * Public: No + */ + +params ["_weaponPlatform", ["_checkForCSW", false, [false]]]; + +private _unit = call SPE_fnc_findPlayer; + +alive _unit && +{alive _weaponPlatform} && +{isNull objectParent _unit} && +{crew _weaponPlatform isEqualTo []} && +{!(_weaponPlatform lockedTurret [0])} && { + // CSW check + (!_checkForCSW && {CONDITION_NO_CSW(_weaponPlatform)}) || + {_checkForCSW && {!(CONDITION_NO_CSW(_weaponPlatform))}} +} diff --git a/addons/compat_spe/compat_spe_csw/functions/fnc_can_assemble_weapon.sqf b/addons/compat_spe/compat_spe_csw/functions/fnc_can_assemble_weapon.sqf new file mode 100644 index 00000000000..60911d49fe1 --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/functions/fnc_can_assemble_weapon.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +/* + * Author: Kerc (SPE), original by www.3commandobrigade.com, edited by johnb43 to be made CSW compatible + * Determines whether the player can assemble the static weapon. + * + * Arguments: + * 0: Tripod + * 1: Weapon + * + * Return Value: + * If the player can assemble the static weapon + * + * Example: + * cursorObject call SPE_Weapons_Static_fnc_can_assemble_weapon + * + * Public: No + */ + +params ["_tripod", "_weaponComponent"]; + +private _unit = call SPE_fnc_findPlayer; + +alive _unit && +{alive _tripod} && +{isNull objectParent _unit} && +{_weaponComponent in (weapons _unit)} && +{CONDITION_NO_CSW(_tripod)} // CSW check diff --git a/addons/compat_spe/compat_spe_csw/functions/fnc_can_disassemble_weapon.sqf b/addons/compat_spe/compat_spe_csw/functions/fnc_can_disassemble_weapon.sqf new file mode 100644 index 00000000000..66a54829537 --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/functions/fnc_can_disassemble_weapon.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: Kerc (SPE), original by www.3commandobrigade.com, edited by johnb43 to be made CSW compatible + * Checks if the static weapon can be disassembled. + * + * Arguments: + * 0: Static Weapon + * + * Return Value: + * If the player can disassemble the static weapon + * + * Example: + * cursorObject call SPE_Weapons_Static_fnc_can_Reload + * + * Public: No + */ + +params ["_weaponPlatform"]; + +private _unit = call SPE_fnc_findPlayer; + +alive _unit && +{alive _weaponPlatform} && +{isNull objectParent _unit} && +{crew _weaponPlatform isEqualTo []} && +{weaponDisassemblyEnabled _unit} && +{weaponDisassemblyEnabled _weaponPlatform} && +{!(_weaponPlatform lockedTurret [0])} && +{CONDITION_NO_CSW(_weaponPlatform)} // CSW check diff --git a/addons/compat_spe/compat_spe_csw/functions/fnc_can_prepare_ammo.sqf b/addons/compat_spe/compat_spe_csw/functions/fnc_can_prepare_ammo.sqf new file mode 100644 index 00000000000..e310b2a63cb --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/functions/fnc_can_prepare_ammo.sqf @@ -0,0 +1,38 @@ +#include "..\script_component.hpp" +/* + * Author: ? (SPE), edited by johnb43 to be made CSW compatible + * Checks if the player can prepare the static weapon's ammo. + * + * Arguments: + * 0: Static Weapon + * 1: Magazine to load + * 2: If the magazine has been selected to be prepped for loading (default: false) + * + * Return Value: + * If the player can prepare the static weapon's ammo + * + * Example: + * cursorObject call SPE_Weapons_Static_fnc_can_prepare_ammo + * + * Public: No + */ + +params ["_weaponPlatform", "_ammo", ["_isSelected", false]]; + +private _unit = call SPE_fnc_findPlayer; + +alive _unit && +{alive _weaponPlatform} && +{vehicle _unit in [_unit, _weaponPlatform]} && +{ + private _defaultMags = getArray (configOf _weaponPlatform >> "Turrets" >> "MainTurret" >> "magazines"); + + if (({_x in _defaultMags} count (magazines _weaponPlatform)) > 1) exitWith { + false + }; + + private _selectedMagazine = _unit getVariable ["SPE_Static_Weapon_Magazine", ""]; + + _isSelected == (_selectedMagazine == _ammo) +} && +{CONDITION_NO_CSW(_weaponPlatform)} // CSW check diff --git a/addons/compat_spe/compat_spe_csw/functions/fnc_can_resupply_ammo.sqf b/addons/compat_spe/compat_spe_csw/functions/fnc_can_resupply_ammo.sqf new file mode 100644 index 00000000000..283c11d98d9 --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/functions/fnc_can_resupply_ammo.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +/* + * Author: Kerc (SPE), original by www.3commandobrigade.com, edited by johnb43 to be made CSW compatible + * Checks if resupply of ammo to a static weapon is available. + * + * Arguments: + * 0: Static Weapon + * 1: Default magazine to load (unused) (default: "") + * + * Return Value: + * If the player can load the static weapon's ammo + * + * Example: + * cursorObject call SPE_Weapons_Static_fnc_can_resupply_ammo + * + * Public: No + */ + +params ["_weaponPlatform"]; + +private _unit = call SPE_fnc_findPlayer; + +alive _unit && +{alive _weaponPlatform} && +{vehicle _unit in [_unit, _weaponPlatform]} && +{(_weaponPlatform magazinesTurret [[0], false]) isEqualTo []} && // Limit the reload capacity of a static weapon to 1 magazines +{CONDITION_NO_CSW(_weaponPlatform)} // CSW check diff --git a/addons/compat_spe/compat_spe_csw/functions/fnc_can_unload_ammo.sqf b/addons/compat_spe/compat_spe_csw/functions/fnc_can_unload_ammo.sqf new file mode 100644 index 00000000000..23384d29733 --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/functions/fnc_can_unload_ammo.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +/* + * Author: Kerc (SPE), original by www.3commandobrigade.com, edited by johnb43 to be made CSW compatible + * Checks if the player can unload a static weapon's magazines. + * + * Arguments: + * 0: Static Weapon + * + * Return Value: + * If the player can unload the static weapon's ammo + * + * Example: + * cursorObject call SPE_Weapons_Static_fnc_can_unload_ammo + * + * Public: No + */ + +params ["_weaponPlatform"]; + +private _unit = call SPE_fnc_findPlayer; + +alive _unit && +{alive _weaponPlatform} && +{_unit in _weaponPlatform || {isNull objectParent _unit && {(crew _weaponPlatform) isEqualTo []}}} && +{!(_weaponPlatform lockedTurret [0])} && +{(_weaponPlatform magazinesTurret [[0], false]) isNotEqualTo []} && +{CONDITION_NO_CSW(_weaponPlatform)} // CSW check diff --git a/addons/compat_spe/compat_spe_csw/script_component.hpp b/addons/compat_spe/compat_spe_csw/script_component.hpp index 1f7ace46a9e..8803d6fd261 100644 --- a/addons/compat_spe/compat_spe_csw/script_component.hpp +++ b/addons/compat_spe/compat_spe_csw/script_component.hpp @@ -1,3 +1,10 @@ #define SUBCOMPONENT csw #define SUBCOMPONENT_BEAUTIFIED Crew-Served Weapons #include "..\script_component.hpp" + +#define CONDITION_NO_CSW(var) (EGVAR(csw,ammoHandling) == 0) && {!([false, true, true, EGVAR(csw,defaultAssemblyMode)] select (var getVariable [ARR_2('EGVAR(csw,assemblyMode)',3)]))} + +#define OVERWRITE_FUNC(funcName)\ +class funcName {\ + file = QPATHTOF(DOUBLES(COMPONENT,SUBCOMPONENT)\functions\DOUBLES(fnc,funcName).sqf);\ +} diff --git a/addons/compat_spe/compat_spe_csw/stringtable.xml b/addons/compat_spe/compat_spe_csw/stringtable.xml new file mode 100644 index 00000000000..19bd37ea3c4 --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/stringtable.xml @@ -0,0 +1,35 @@ + + + + + Altering Height... + 높이 변경 중... + 高さを変更・・・ + Cambiando Altura... + + + .30-06 50Rnd Belt (M2/Tracer) + .30-06구경 스프링필드 50발 들이 벨트 (M2 훈련용/예광탄) + .30-06 50Rnd Belt (M2/Tracer) + Cinta de .30-06 50Rnd (M2/Trazadora) + + + .30-06 100Rnd Belt (M2/Tracer) + .30-06구경 스프링필드 100발 들이 벨트 (M2 훈련용/예광탄) + .30-06 100Rnd Belt (M2/Tracer) + Cinta de .30-06 100Rnd (M2/Trazadora) + + + 7.92x57 50Rnd Gurttrommel (L.S./Tracer) + 7.92x57mm 50발 들이 벨트 (L.S. 훈련용/예광탄) + 7.92x57 50Rnd Gurttrommel (L.S./Tracer) + Tambor de 7.92x57 50Rnd (L.S./Trazadora) + + + 7.92x57 100Rnd Belt (L.S./Tracer) + 7.92x57mm 100발 들이 벨트 (L.S. 훈련용/예광탄) + 7.92x57 100Rnd Belt (L.S./Tracer) + Cinta de 7.92x57 100Rnd (L.S./Trazadora) + + + diff --git a/addons/compat_spe/compat_spe_explosives/CfgMagazines.hpp b/addons/compat_spe/compat_spe_explosives/CfgMagazines.hpp index 7c1945fcb8f..810a5bc5bf1 100644 --- a/addons/compat_spe/compat_spe_explosives/CfgMagazines.hpp +++ b/addons/compat_spe/compat_spe_explosives/CfgMagazines.hpp @@ -1,9 +1,8 @@ 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); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(4LBTNT); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "FireCord", "LIB_LadungPM"}; @@ -19,9 +18,8 @@ class CfgMagazines { }; class SPE_US_TNT_half_pound_mag: SPE_Mine_Magazine { - EGVAR(explosives,DelayTime) = 1; - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(halfLBTNT); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(halfLBTNT); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "FireCord", "LIB_LadungPM"}; @@ -37,9 +35,8 @@ class CfgMagazines { }; class SPE_US_Bangalore_mag: SPE_Mine_Magazine { - EGVAR(explosives,DelayTime) = 1; - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(bangalore); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(bangalore); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "FireCord", "LIB_LadungPM"}; @@ -55,9 +52,8 @@ class CfgMagazines { }; class SPE_Ladung_Small_MINE_mag: SPE_Mine_Magazine { - EGVAR(explosives,DelayTime) = 1; - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(smallLadung); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(smallLadung); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "FireCord", "LIB_LadungPM"}; @@ -73,9 +69,8 @@ class CfgMagazines { }; class SPE_Ladung_Big_MINE_mag: SPE_Mine_Magazine { - EGVAR(explosives,DelayTime) = 1; - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(bigLadung); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(bigLadung); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "FireCord", "LIB_LadungPM"}; @@ -91,8 +86,8 @@ class CfgMagazines { }; class SPE_US_M1A1_ATMINE_mag: SPE_Mine_Magazine { - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(M1A1at); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(M1A1at); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -102,8 +97,8 @@ class CfgMagazines { }; }; class SPE_US_M3_MINE_mag: SPE_Mine_Magazine { - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(M3ap); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(M3ap); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; @@ -113,8 +108,8 @@ class CfgMagazines { }; }; class SPE_US_M3_Pressure_MINE_mag: SPE_Mine_Magazine { - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(M3Pressure); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(M3Pressure); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -125,8 +120,8 @@ class CfgMagazines { }; class SPE_Shg24x7_Improvised_Mine_mag: SPE_Mine_Magazine { - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(Shg24x7); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(Shg24x7); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -137,8 +132,8 @@ class CfgMagazines { }; class SPE_TMI_42_MINE_mag: SPE_Mine_Magazine { - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(TMI42); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(TMI42); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -149,8 +144,8 @@ class CfgMagazines { }; class SPE_SMI_35_1_MINE_mag: SPE_Mine_Magazine { - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(SMI35_1); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(SMI35_1); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; @@ -161,8 +156,8 @@ class CfgMagazines { }; class SPE_SMI_35_MINE_mag: SPE_Mine_Magazine { - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(SMI35); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(SMI35); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; @@ -173,8 +168,8 @@ class CfgMagazines { }; class SPE_SMI_35_Pressure_MINE_mag: SPE_Mine_Magazine { - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(SMI35Pressure); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(SMI35Pressure); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; @@ -185,8 +180,8 @@ class CfgMagazines { }; class SPE_STMI_MINE_mag: SPE_Mine_Magazine { - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(STMI); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(STMI); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; @@ -197,8 +192,8 @@ class CfgMagazines { }; class SPE_shumine_42_MINE_mag: SPE_Mine_Magazine { - EGVAR(explosives,Placeable) = 1; - EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(shumine42); + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEXPLOSIVES_PLACE(shumine42); useAction = 0; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; diff --git a/addons/compat_spe/compat_spe_explosives/CfgVehicles.hpp b/addons/compat_spe/compat_spe_explosives/CfgVehicles.hpp index d4d5737bb23..9137a9b802b 100644 --- a/addons/compat_spe/compat_spe_explosives/CfgVehicles.hpp +++ b/addons/compat_spe/compat_spe_explosives/CfgVehicles.hpp @@ -8,7 +8,7 @@ class CfgVehicles { // 4 Pound TNT Charge class EXPLOSIVES_PLACE(4LBTNT): EGVAR(explosives,Place) { - displayName = "4 Pound TNT Charge"; + displayName = "$STR_DN_SPE_US_TNT_4POUND"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_TNT_4pound"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -19,7 +19,7 @@ class CfgVehicles { // Half Pound TNT Charge class EXPLOSIVES_PLACE(halfLBTNT): EGVAR(explosives,Place) { - displayName = "Half Pound TNT Charge"; + displayName = "$STR_DN_SPE_US_TNT_HALF_POUND"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_TNT_Half_Pound"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -30,7 +30,7 @@ class CfgVehicles { // M1A1 Bangalore Torpedo class EXPLOSIVES_PLACE(bangalore): EGVAR(explosives,Place) { - displayName = "M1A1 Bangalore Torpedo"; + displayName = "$STR_DN_SPE_US_BANGALORE"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Bangalore"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -41,7 +41,7 @@ class CfgVehicles { // 1 Kg Charge class EXPLOSIVES_PLACE(smallLadung): EGVAR(explosives,Place) { - displayName = "1 Kg Charge"; + displayName = "$STR_SPE_Ladung_Small"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Ladung"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -52,7 +52,7 @@ class CfgVehicles { // 3 Kg Charge class EXPLOSIVES_PLACE(bigLadung): EGVAR(explosives,Place) { - displayName = "3 Kg Charge"; + displayName = "$STR_SPE_Ladung_Big"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Ladung_Big"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -63,7 +63,7 @@ class CfgVehicles { // M1A1 AT Mine class EXPLOSIVES_PLACE(M1A1at): EGVAR(explosives,Place) { - displayName = "M1A1 AT Mine"; + displayName = "$STR_DN_SPE_US_M1A1_ATMINE"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_M1A1_AT"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -72,9 +72,9 @@ class CfgVehicles { }; }; - // M1A1 AT Mine + // Shg24x7 Improvised AT Mine class EXPLOSIVES_PLACE(Shg24x7): EGVAR(explosives,Place) { - displayName = "M1A1 AT Mine"; + displayName = "$STR_SPE_Shg24x7_Improvised_Mine"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_GER_Improvised_Mine"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -83,9 +83,9 @@ class CfgVehicles { }; }; - // M1A1 AT Mine + // TMI-42 AT Mine class EXPLOSIVES_PLACE(TMI42): EGVAR(explosives,Place) { - displayName = "M1A1 AT Mine"; + displayName = "$STR_SPE_TMI_42"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Tmi42"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -96,7 +96,7 @@ class CfgVehicles { // M3 AP Tripwire Mine class EXPLOSIVES_PLACE(M3ap): EGVAR(explosives,Place) { - displayName = "M3 AP Tripwire Mine"; + displayName = "$STR_DN_SPE_US_M3"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_M3_AP"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -107,7 +107,7 @@ class CfgVehicles { // M3 AP Mine class EXPLOSIVES_PLACE(M3Pressure): EGVAR(explosives,Place) { - displayName = "M3 AP Mine"; + displayName = "$STR_DN_SPE_US_M3_Pressure"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_M3_AP_Pressure"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -118,7 +118,7 @@ class CfgVehicles { // SMi-35 AP Mine class EXPLOSIVES_PLACE(SMI35Pressure): EGVAR(explosives,Place) { - displayName = "SMi-35 AP Mine"; + displayName = "$STR_SPE_SMI_35_Pressure"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Smi35"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -129,7 +129,7 @@ class CfgVehicles { // SMi-35 Tripwire Mine class EXPLOSIVES_PLACE(SMI35): EGVAR(explosives,Place) { - displayName = "SMi-35 Tripwire Mine"; + displayName = "$STR_SPE_SMI_35"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Smi35_1"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -140,7 +140,7 @@ class CfgVehicles { // SMi-35 Tripwire (x2) Mine class EXPLOSIVES_PLACE(SMI35_1): EGVAR(explosives,Place) { - displayName = "SMi-35 Tripwire (x2) Mine"; + displayName = "$STR_SPE_SMI_35_1"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Smi35_2"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -151,7 +151,7 @@ class CfgVehicles { // StMi Mine class EXPLOSIVES_PLACE(STMI): EGVAR(explosives,Place) { - displayName = "StMi Mine"; + displayName = "$STR_SPE_STMI"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Stmi"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -162,7 +162,7 @@ class CfgVehicles { // Schuetzenmine 42 class EXPLOSIVES_PLACE(shumine42): EGVAR(explosives,Place) { - displayName = "Schuetzenmine 42"; + displayName = "$STR_SPE_shumine42"; model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Shumine42"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { diff --git a/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp b/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp index f47d6877f7b..8819f205590 100644 --- a/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp +++ b/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp @@ -1,14 +1,57 @@ class CfgVehicles { - class SPE_Halftrack_base; - class SPE_US_M3_Halftrack_Fuel: SPE_Halftrack_base { - transportFuel = 0; - EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}}; - EGVAR(refuel,fuelCargo) = 2000; - }; - class SPE_OpelBlitz_base; - class SPE_OpelBlitz_Fuel: SPE_OpelBlitz_base { - transportFuel = 0; - EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}}; - EGVAR(refuel,fuelCargo) = 2000; + // Vehicle animation interactions + class SPE_Car_base; + class SPE_G503_MB_base: SPE_Car_base { + class EGVAR(interaction,anims) { + class hide_jerry_can_source { + positions[] = {"_target selectionPosition ['hide_jerry_can', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + class SPE_Truck_base; + class SPE_CCKW_353_Base: SPE_Truck_base { + class EGVAR(interaction,anims) { + class spare_fuel_hide_source { + positions[] = {{0.8, 1.8, -1}, {-0.8, 1.8, -1}, {0.8, 3.5, -1}, {-0.8, 3.5, -1}}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class SPE_CCKW_353_Ammo: SPE_CCKW_353_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class spare_fuel_hide_source: spare_fuel_hide_source { + positions[] = {{0.8, 1.8, -0.85}, {-0.8, 1.8, -0.85}, {0.8, 3.5, -0.85}, {-0.8, 3.5, -0.85}}; + }; + }; + }; + class SPE_CCKW_353_Repair: SPE_CCKW_353_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class spare_fuel_hide_source: spare_fuel_hide_source { + positions[] = {{0.8, 1.9, -0.85}, {-0.8, 1.9, -0.85}, {0.8, 3.6, -0.85}, {-0.8, 3.6, -0.85}}; + }; + }; + }; + class SPE_CCKW_353_Fuel: SPE_CCKW_353_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class spare_fuel_hide_source: spare_fuel_hide_source { + positions[] = {{0.8, 1.25, -0.8}, {-0.8, 1.25, -0.8}, {0.8, 2.95, -0.8}, {-0.8, 2.95, -0.8}, {0.8, -1, -0.3}, {-0.8, -1, -0.3}}; + items[] = { // 32x + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F" + }; + }; + }; }; }; diff --git a/addons/compat_spe/compat_spe_repair/CfgVehicles.hpp b/addons/compat_spe/compat_spe_repair/CfgVehicles.hpp new file mode 100644 index 00000000000..2f20e427d83 --- /dev/null +++ b/addons/compat_spe/compat_spe_repair/CfgVehicles.hpp @@ -0,0 +1,120 @@ +class CfgVehicles { + // Vehicle animation interactions + class SPE_Car_base; + class SPE_G503_MB_base: SPE_Car_base { + class EGVAR(interaction,anims) { + class hide_spare_wheel_source { + positions[] = {"_target selectionPosition ['hide_spare_wheel', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class SPE_Truck_base; + class SPE_CCKW_353_Base: SPE_Truck_base { + class EGVAR(interaction,anims) { + class spare_wheel_hide_source { + positions[] = {{-0.9, 0.35, -0.95}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class SPE_CCKW_353_Ammo: SPE_CCKW_353_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class spare_wheel_hide_source: spare_wheel_hide_source { + positions[] = {{-0.9, 0.35, -0.8}}; + }; + }; + }; + class SPE_CCKW_353_Repair: SPE_CCKW_353_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class spare_wheel_hide_source: spare_wheel_hide_source { + positions[] = {{-0.9, 0.43, -0.75}}; + }; + }; + }; + class SPE_CCKW_353_Fuel: SPE_CCKW_353_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class spare_wheel_hide_source: spare_wheel_hide_source { + positions[] = {{-0.9, -0.2, -0.7}}; + }; + }; + }; + + class SPE_R200_base: SPE_Car_base { + class EGVAR(interaction,anims) { + class hide_spare_wheel_source { + positions[] = {"_target selectionPosition ['hide_sparetire', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class SPE_Tank_base; + class SPE_M18_Hellcat_Base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class hull_armour_hide_source { + positions[] = {"_target selectionPosition ['spare_track_hull', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Track", "ACE_Track", "ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; + + class SPE_PzKpfwV_base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class spare_tracks_hide_source { + selections[] = {"spare_tracks"}; + positions[] = {"private _pos = _target selectionPosition 'spare_tracks'; _pos set [0, -(_pos select 0)]; _pos"}; // Mirror position to other side of vehicle + items[] = {"ACE_Track", "ACE_Track", "ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; + + class SPE_PzKpfwVI_H1_base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class hull_armour_hide_source { + positions[] = {{-1.3, 1.7, -0.75}, {1.1, 1.7, -0.75}, {-0.05, 2.35, -1.5}}; + items[] = {"ACE_Track", "ACE_Track", "ACE_Track", "ACE_Track", "ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + class turret_armour_hide_source { + // Rotate interactions with turret rotation + positions[] = { + "[0, -0.6, 0] vectorAdd ([[1.2, 0, -0.2], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)", + "[0, -0.6, 0] vectorAdd ([[-1.3, -0.3, -0.2], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)" + }; + items[] = {"ACE_Track", "ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; + + class SPE_Jagdpanther_G1_base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class hide_spare_tracks_left_source { + positions[] = {"private _pos = _target selectionPosition ['hide_spare_tracks_right', 'FireGeometry', 'AveragePoint']; _pos set [0, -(_pos select 0)]; _pos vectorAdd [0, 0.335, 0]"}; + items[] = {"ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + class hide_spare_tracks_right_source { + positions[] = {"_target selectionPosition ['hide_spare_tracks_right', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Track", "ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; +}; diff --git a/addons/compat_spe/compat_spe_repair/config.cpp b/addons/compat_spe/compat_spe_repair/config.cpp new file mode 100644 index 00000000000..356ef6a6be9 --- /dev/null +++ b/addons/compat_spe/compat_spe_repair/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_repair" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_spe/compat_spe_repair/script_component.hpp b/addons/compat_spe/compat_spe_repair/script_component.hpp new file mode 100644 index 00000000000..1af928486c3 --- /dev/null +++ b/addons/compat_spe/compat_spe_repair/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT repair +#define SUBCOMPONENT_BEAUTIFIED Repair +#include "..\script_component.hpp" diff --git a/addons/compat_spe/compat_spe_trenches/CfgVehicles.hpp b/addons/compat_spe/compat_spe_trenches/CfgVehicles.hpp new file mode 100644 index 00000000000..bb4b78721df --- /dev/null +++ b/addons/compat_spe/compat_spe_trenches/CfgVehicles.hpp @@ -0,0 +1,119 @@ +class CfgVehicles { + // Vehicle animation interactions + class SPE_Car_base; + class SPE_G503_MB_base: SPE_Car_base { + class EGVAR(interaction,anims) { + class hide_tools_source { + positions[] = {{-0.7, 0, -0.9}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class SPE_US_G503_MB_M1919_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools_source: hide_tools_source { + positions[] = {{-0.7, 0.45, -0.9}}; + }; + }; + }; + class SPE_US_G503_MB_M1919_Armoured_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools_source: hide_tools_source { + positions[] = {{-0.7, 0.45, -0.9}}; + }; + }; + }; + class SPE_US_G503_MB_M1919_PATROL_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools_source: hide_tools_source { + positions[] = {{-0.7, 0.45, -0.9}}; + }; + }; + }; + class SPE_US_G503_MB_M2_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools_source: hide_tools_source { + positions[] = {{-0.7, 0.45, -0.9}}; + }; + }; + }; + class SPE_US_G503_MB_M2_Armoured_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools_source: hide_tools_source { + positions[] = {{-0.7, 0.45, -0.9}}; + }; + }; + }; + class SPE_US_G503_MB_M2_PATROL_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools_source: hide_tools_source { + positions[] = {{-0.7, 0.45, -0.9}}; + }; + }; + }; + class SPE_G503_MB_Ambulance_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools_source: hide_tools_source { + positions[] = {{-0.7, 0.45, -0.9}}; + }; + }; + }; + + class SPE_R200_base: SPE_Car_base { + class EGVAR(interaction,anims) { + class hide_shovel_source { + positions[] = {{0.5, 1.2, -1.05}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + + class SPE_Tank_base; + class SPE_PzKpfwV_base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class tools_hide_source { + positions[] = {{-1.45, 0.7, -0.4}}; + items[] = {"ACE_EntrenchingTool", "ACE_wirecutter"}; + name = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + text = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + }; + }; + }; + + class SPE_PzKpfwVI_H1_base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class tools_hide_source { + positions[] = {{0, 1, -0.6}, {1.1, 0.1, -0.6}}; + items[] = {"ACE_EntrenchingTool", "ACE_wirecutter"}; + name = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + text = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + }; + }; + }; + + class SPE_StuG_III_base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class hide_tools_left_source { + positions[] = {{-1.4, -1.4, -0.7}, {-1, -2.2, -0.65}}; + items[] = {"ACE_EntrenchingTool", "ACE_wirecutter"}; + name = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + text = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + }; + }; + }; + + class SPE_Jagdpanther_G1_base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class hide_tools_left_source { + positions[] = {{-1.4, 0.5, -0.7}}; + items[] = {"ACE_EntrenchingTool", "ACE_wirecutter"}; + name = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + text = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + }; + }; + }; +}; diff --git a/addons/compat_spe/compat_spe_trenches/config.cpp b/addons/compat_spe/compat_spe_trenches/config.cpp new file mode 100644 index 00000000000..1b742b57825 --- /dev/null +++ b/addons/compat_spe/compat_spe_trenches/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_trenches" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_spe/compat_spe_trenches/script_component.hpp b/addons/compat_spe/compat_spe_trenches/script_component.hpp new file mode 100644 index 00000000000..10b90eb71e5 --- /dev/null +++ b/addons/compat_spe/compat_spe_trenches/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT trenches +#define SUBCOMPONENT_BEAUTIFIED Trenches +#include "..\script_component.hpp" diff --git a/addons/compat_spe/functions/fnc_woundsHandlerIncendiary.sqf b/addons/compat_spe/functions/fnc_woundsHandlerIncendiary.sqf index aa282e9be84..d2b0cb165c8 100644 --- a/addons/compat_spe/functions/fnc_woundsHandlerIncendiary.sqf +++ b/addons/compat_spe/functions/fnc_woundsHandlerIncendiary.sqf @@ -18,8 +18,6 @@ * Public: No */ -#define BURN_THRESHOLD 1 - params ["_unit", "_damages"]; TRACE_2("woundsHandlerIncendiary",_unit,_damages); @@ -32,9 +30,7 @@ private _fireDamage = 0; private _intensity = linearConversion [0, 20, _fireDamage, 0, 10, true]; TRACE_2("",_intensity,_fireDamage); -if (_intensity > BURN_THRESHOLD) then { - TRACE_2("Setting unit ablaze",_intensity,BURN_THRESHOLD); - ["ace_fire_burn", [_unit, _intensity]] call CBA_fnc_globalEvent; -}; +// Let fire handle if unit is set ablaze or not +[QEGVAR(fire,burn), [_unit, _intensity]] call CBA_fnc_localEvent; _this // return diff --git a/addons/compat_ws/CfgVehicles.hpp b/addons/compat_ws/CfgVehicles.hpp new file mode 100644 index 00000000000..98dc922d982 --- /dev/null +++ b/addons/compat_ws/CfgVehicles.hpp @@ -0,0 +1,27 @@ +class CfgVehicles { + // Vehicle animation interactions + // Easier to not inherit + class Offroad_01_base_lxWS; + class Offroad_01_armor_base_lxWS: Offroad_01_base_lxWS { + class EGVAR(interaction,anims) { + class HideBackpacks { + positions[] = {{-1.15, -1.17, -0.66}, {1.05, -1.17, -0.66}, {1.05, -2.52, -0.66}}; + items[] = {"B_TacticalPack_blk", "B_TacticalPack_blk", "B_Carryall_khk", "B_Carryall_khk"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; + + class Offroad_01_AT_lxWS; + class Offroad_01_armor_AT_lxWS: Offroad_01_AT_lxWS { + class EGVAR(interaction,anims) { + class HideBackpacks { + positions[] = {{-1.15, -1.27, -0.66}, {1.05, -1.27, -0.66}, {1.05, -2.62, -0.66}}; + items[] = {"B_TacticalPack_blk", "B_TacticalPack_blk", "B_Carryall_khk", "B_Carryall_khk"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; +}; diff --git a/addons/compat_ws/CfgWeapons.hpp b/addons/compat_ws/CfgWeapons.hpp index 30e6882b08e..a8b27fb1f3b 100644 --- a/addons/compat_ws/CfgWeapons.hpp +++ b/addons/compat_ws/CfgWeapons.hpp @@ -37,6 +37,11 @@ class CfgWeapons { ACE_twistDirection = 1; }; + class arifle_SLR_V_lxWS; + class arifle_SLR_Para_lxWS: arifle_SLR_V_lxWS { + ACE_barrelLength = 266.7; + }; + // Velko R4/R5 class arifle_Velko_base_lxWS: arifle_Galat_base_lxWS { ACE_barrelLength = 460; diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp new file mode 100644 index 00000000000..5396b8f186c --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp @@ -0,0 +1,229 @@ +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); + }; + + #include "CfgVehiclesAttachments.hpp" + + // AA12 + class Weapon_Base_F; + class Weapon_sgun_aa40_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(AA40_Name); + }; + class Weapon_sgun_aa40_tan_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(AA40_Tan_Name); + }; + class Weapon_sgun_aa40_snake_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(AA40_Snake_Name); + }; + + // Galil ARM + class Weapon_arifle_Galat_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(Galat_Name); + }; + class Weapon_arifle_Galat_worn_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(Galat_Old_Name); + }; + + // GLX 160 + class Weapon_glaunch_GLX_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(GLX_Name); + }; + class Weapon_glaunch_GLX_snake_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(GLX_Snake_Name); + }; + class Weapon_glaunch_GLX_hex_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(GLX_Hex_Name); + }; + class Weapon_glaunch_GLX_ghex_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(GLX_GreenHex_Name); + }; + class Weapon_glaunch_GLX_camo_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(GLX_Camo_Name); + }; + class Weapon_glaunch_GLX_tan_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(GLX_Tan_Name); + }; + + // Mk14 Mod 1 EBR + class Weapon_srifle_EBR_blk_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(EBR_Black_Name); + }; + class Weapon_srifle_EBR_snake_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(EBR_Snake_Name); + }; + + // Vektor SS-77 + class Weapon_LMG_S77_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(S77_Name); + }; + class Weapon_LMG_S77_AAF_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(S77_AAF_Name); + }; + class Weapon_LMG_S77_Hex_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(S77_Hex_Name); + }; + class Weapon_LMG_S77_GHex_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(S77_GreenHex_Name); + }; + class Weapon_LMG_S77_Desert_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(S77_Desert_Name); + }; + + // Vektor SS-77 (Compact) + class Weapon_LMG_S77_Compact_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(S77_Compact_Name); + }; + class Weapon_LMG_S77_Compact_Snakeskin_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(S77_Compact_Snake_Name); + }; + + // FN FAL (Wood) - Closest match is the 50.00 + class Weapon_arifle_SLR_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_Wood_Name); + }; + class Weapon_arifle_SLR_GL_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_GL_Wood_Name); + }; + + // FN FAL + class Weapon_arifle_SLR_V_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_Name); + }; + class Weapon_arifle_SLR_V_GL_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_GL_Name); + }; + class Weapon_arifle_SLR_D_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_Desert_Name); + }; + class Weapon_arifle_SLR_V_camo_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_Camo_Name); + }; + class Weapon_arifle_SLR_Para_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_Para_Name); + }; + class Weapon_arifle_SLR_Para_snake_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_Para_Snake_Name); + }; + + // Vektor R4/R5 + class Weapon_arifle_Velko_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(Velko_R4_Name); + }; + class Weapon_arifle_VelkoR5_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(Velko_R5_Name); + }; + class Weapon_arifle_VelkoR5_GL_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(Velko_R5_GL_Name); + }; + class Weapon_arifle_VelkoR5_snake_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(Velko_R5_Snake_Name); + }; + class Weapon_arifle_VelkoR5_GL_snake_lxWS: Weapon_Base_F { + 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 Weapon_arifle_XMS_Base_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_Name); + }; + class Weapon_arifle_XMS_Base_khk_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_Khaki_Name); + }; + class Weapon_arifle_XMS_Base_Sand_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_Sand_Name); + }; + class Weapon_arifle_XMS_GL_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_GL_Name); + }; + class Weapon_arifle_XMS_GL_khk_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_GL_Khaki_Name); + }; + class Weapon_arifle_XMS_GL_Sand_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_GL_Sand_Name); + }; + class Weapon_arifle_XMS_Shot_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_SG_Name); + }; + class Weapon_arifle_XMS_Shot_khk_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_SG_Khaki_Name); + }; + class Weapon_arifle_XMS_Shot_Sand_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_SG_Sand_Name); + }; + class Weapon_arifle_XMS_M_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_SW_Name); + }; + class arifle_XMS_M_khk_lxWS: Weapon_Base_F { + diWeapon_splayName = SUBCSTRING(XMS_SW_Khaki_Name); + }; + class Weapon_arifle_XMS_M_Sand_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_SW_Sand_Name); + }; + + // GM6 Lynx + class Weapon_srifle_GM6_snake_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(gm6_snake_Name); + }; + + // RPG-32 + class Launcher_Base_F; + class Weapon_launch_RPG32_tan_lxWS: Launcher_Base_F { + displayName = SUBCSTRING(rpg32_tan_Name); + }; +}; diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgVehiclesAttachments.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgVehiclesAttachments.hpp new file mode 100644 index 00000000000..5dbeab9bc48 --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/CfgVehiclesAttachments.hpp @@ -0,0 +1,71 @@ +// Attachments +class Item_Base_F; +class Item_optic_arco_hex_lxWS: Item_Base_F { + displayName = SUBCSTRING(arco_hex_Name); +}; + +class Item_optic_Holosight_snake_lxWS: Item_Base_F { + displayName = SUBCSTRING(holosight_snake_Name); +}; + +class Item_optic_Holosight_smg_snake_lxWS: Item_Base_F { + displayName = SUBCSTRING(holosight_snake_smg_Name); +}; + +class Item_optic_Hamr_arid_lxWS: Item_Base_F { + displayName = SUBCSTRING(hamr_arid_Name); +}; +class Item_optic_Hamr_lush_lxWS: Item_Base_F { + displayName = SUBCSTRING(hamr_lush_Name); +}; +class Item_optic_Hamr_sand_lxWS: Item_Base_F { + displayName = SUBCSTRING(hamr_sand_Name); +}; +class Item_optic_Hamr_snake_lxWS: Item_Base_F { + displayName = SUBCSTRING(hamr_snake_Name); +}; + +class Item_optic_r1_high_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_high_black_Name); +}; +class Item_optic_r1_high_khaki_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_high_khaki_Name); +}; +class Item_optic_r1_high_sand_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_high_sand_Name); +}; +class Item_optic_r1_high_snake_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_high_snake_Name); +}; +class Item_optic_r1_high_arid_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_high_arid_Name); +}; +class Item_optic_r1_high_lush_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_high_lush_Name); +}; +class Item_optic_r1_high_black_sand_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_high_black_sand_Name); +}; + +class Item_optic_r1_low_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_low_black_Name); +}; +class Item_optic_r1_low_khaki_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_low_khaki_Name); +}; +class Item_optic_r1_low_sand_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_low_sand_Name); +}; +class Item_optic_r1_low_snake_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_low_snake_Name); +}; +class Item_optic_r1_low_arid_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_low_arid_Name); +}; +class Item_optic_r1_low_lush_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_low_lush_Name); +}; + +class Item_optic_DMS_snake_lxWS: Item_Base_F { + displayName = SUBCSTRING(dms_snake_Name); +}; diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp index c09400a03c8..b1929a49043 100644 --- a/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp +++ b/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp @@ -1,4 +1,6 @@ class CfgWeapons { + #include "CfgWeaponsAttachments.hpp" + // AA12 class sgun_aa40_base_lxWS; class sgun_aa40_lxWS: sgun_aa40_base_lxWS { @@ -99,6 +101,12 @@ class CfgWeapons { class arifle_SLR_V_camo_lxWS: arifle_SLR_V_lxWS { displayName = SUBCSTRING(SLR_Camo_Name); }; + class arifle_SLR_Para_lxWS: arifle_SLR_V_lxWS { + displayName = SUBCSTRING(SLR_Para_Name); + }; + class arifle_SLR_Para_snake_lxWS: arifle_SLR_Para_lxWS { + displayName = SUBCSTRING(SLR_Para_Snake_Name); + }; // Vektor R4/R5 class arifle_Velko_base_lxWS; @@ -156,4 +164,16 @@ class CfgWeapons { class arifle_XMS_M_Sand_lxWS: arifle_XMS_M_lxWS { displayName = SUBCSTRING(XMS_SW_Sand_Name); }; + + // GM6 Lynx + class srifle_GM6_F; + class srifle_GM6_snake_lxWS: srifle_GM6_F { + displayName = SUBCSTRING(gm6_snake_Name); + }; + + // RPG-32 + class launch_RPG32_F; + class launch_RPG32_tan_lxWS: launch_RPG32_F { + displayName = SUBCSTRING(rpg32_tan_Name); + }; }; diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgWeaponsAttachments.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgWeaponsAttachments.hpp new file mode 100644 index 00000000000..a805e82edcf --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/CfgWeaponsAttachments.hpp @@ -0,0 +1,76 @@ +// Attachments +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/config.cpp b/addons/compat_ws/compat_ws_realisticnames/config.cpp index 5c8e166e000..167e83fa356 100644 --- a/addons/compat_ws/compat_ws_realisticnames/config.cpp +++ b/addons/compat_ws/compat_ws_realisticnames/config.cpp @@ -15,7 +15,10 @@ class CfgPatches { authors[] = {"Mike"}; url = ECSTRING(main,URL); VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); }; }; #include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_ws/compat_ws_realisticnames/stringtable.xml b/addons/compat_ws/compat_ws_realisticnames/stringtable.xml index b38f1a867ea..df75c9bad8f 100644 --- a/addons/compat_ws/compat_ws_realisticnames/stringtable.xml +++ b/addons/compat_ws/compat_ws_realisticnames/stringtable.xml @@ -8,6 +8,8 @@ AA12 AA12 AA12 + AA12 + AA12 AA12 (Sand) @@ -16,14 +18,18 @@ AA12 (Sabbia) AA12 (サンド) AA12 (Песочный) + AA12 (Sable) + AA12 (Arena) AA12 (Snake) AA-12 (뱀 위장) AA12 (Schlange) AA12 (Serpe) - AA12 (ヘビ柄) + AA12 (ヘビ柄迷彩) AA12 (Змея) + AA12 (Serpiente) + AA12 (Sable) Galil ARM @@ -32,14 +38,18 @@ Galil ARM ガリル ARM Galil ARM + Galil ARM + Galil ARM Galil ARM (Old) 갈릴 ARM (낡음) Galil ARM (Alt) Galil ARM (Vecchio) - ガリル ARM (使い古し) + ガリル ARM (古びた) Galil ARM (Старый) + Galil ARM (Ancien) + Galil ARM (Vieja) GLX 160 @@ -48,14 +58,18 @@ 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 (Змея) + GLX 160 (Serpiente) + GLX 160 GLX 160 (Hex) @@ -64,6 +78,8 @@ GLX-160 (Hex) GLX 160 (六角形迷彩) GLX 160 (Гекс) + GLX 160 (Hex) + GLX 160 (Hex) GLX 160 (Green Hex) @@ -72,14 +88,18 @@ 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 (迷彩) + GLX 160 (AAF迷彩) GLX 160 (Камуфляж) + GLX 160 (Camo) + GLX 160 (Camo) GLX 160 (Sand) @@ -88,6 +108,8 @@ GLX-160 (Sabbia) GLX 160 (サンド) GLX 160 (Песочный) + GLX 160 (Sable) + GLX 160 (Arena) Mk14 Mod 1 EBR (Black) @@ -96,14 +118,18 @@ 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 (Змея) + Mk14 Mod 1 EBR (Serpiente) + Mk14 Mod 1 EBR (Serpent) Vektor SS-77 @@ -111,14 +137,18 @@ 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 (迷彩) + ヴェクター SS-77 (AAF迷彩) Vektor SS-77 (Камуфляж) + Vektor SS-77 (Camo) + Vektor SS-77 (Camo) Vektor SS-77 (Hex) @@ -127,6 +157,8 @@ Vektor SS-77 (Hex) ヴェクター SS-77 (六角形迷彩) Vektor SS-77 (гекс) + Vektor SS-77 (Hex) + Vektor SS-77 (Hex) Vektor SS-77 (Green Hex) @@ -135,6 +167,8 @@ Vektor SS-77 (Hex Verde) ヴェクター SS-77 (緑六角形迷彩) Vektor SS-77 (зеленый гекс) + Vektor SS-77 (VertHex) + Vektor SS-77 (Hex Verde) Vektor SS-77 (Desert) @@ -143,6 +177,8 @@ Vektor SS-77 (Deserto) ヴェクター SS-77 (砂漠迷彩) Vektor SS-77 (песочныйt) + Vektor SS-77 (Désert) + Vektor SS-77 (Desierto) Vektor SS-77 Compact @@ -151,30 +187,38 @@ 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 コンパクト (ヘビ柄) + ヴェクター SS-77 コンパクト (ヘビ柄迷彩) Vektor SS-77 Compact (змея) + Vektor SS-77 Compacta (Serpiente) + Vektor SS-77 Compacte (Serpent) 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 (лесной) + 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 (лесной) + FN FAL 50.00 GL (Bois) + FN FAL 50.00 GL (Madera) FN FAL 50.00 @@ -183,6 +227,8 @@ 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 @@ -191,6 +237,8 @@ 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) @@ -199,6 +247,8 @@ 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) @@ -207,14 +257,36 @@ 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 + FN FAL OSW Paracaidista + + + FN FAL OSW Para (Snake) + FN FAL OSW パラ (ヘビ柄迷彩) + FN FAL OSW 파라 (뱀 위장) + FN FAL OSW Fallschirmjäger (Schlange) + FN FAL OSW Para (Serpe) + FN FAL OSW Para (Serpent) + FN FAL OSW Paracaidista (Serpiente) Vektor R4 벡터 R4 Vektor R4 Vektor R4 - ヴェクター R5 + ヴェクター R4 Vektor R4 + Vektor R4 + Vektor R4 Vektor R5 Carbine @@ -223,6 +295,8 @@ Vektor R5 Carabina ヴェクター R5 カービン Vektor R5 Carbine + Vektor R5 Carbine + Vektor R5 Carabina Vektor R5 Carbine GL @@ -231,22 +305,28 @@ 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 カービン (ヘビ柄) + ヴェクター R5 カービン (ヘビ柄迷彩) Vektor R5 Carbine (Змея) + Vektor R5 Carabina (Serpiente) + Vektor R5 Carbine (Serpent) Vektor R5 Carbine GL (Snake) 벡터 R5 카빈 GL (뱀 위장) Vektor R5 Carbine GL (Schlange) Vektor R5 Carabina GL (Serpe) - ヴェクター R5 カービン GL (ヘビ柄) + ヴェクター R5 カービン GL (ヘビ柄迷彩) Vektor R5 Carbine GL (Змея) + Vektor R5 Carabina GL (Serpiente) + Vektor R5 Carbine GL (Serpent) XMS @@ -392,5 +472,347 @@ XMS SW (모래) XMS SW (サンド) + + GM6 Lynx (Snake) + GM6 リンクス (ヘビ柄迷彩) + GM6 링스 (뱀 위장) + GM6 Lynx (Schlange) + GM6 Lynx (Serpe) + GM6 Lynx (Serpent) + GM6 Lynx (Serpiente) + + + RPG-32 (Sand) + RPG-32 (サンド) + RPG-32 (모래) + RPG-32 (Sand) + RPG-32 (Sabbia) + RPG-32 (Sable) + RPG-32 (Arena) + + + ELCAN SpecterOS (Hex) + ELCAN SpecterOS (六角形迷彩) + 엘칸 스펙터OS (육각) + ELCAN SpecterOS (Hex) + ELCAN SpecterOS (Hex) + ELCAN SpecterOS (Hex) + ELCAN SpecterOS (Hex) + + + EOTech XPS3 (Snake) + EOTech XPS3 (ヘビ柄迷彩) + 이오텍 XPS3 (뱀 위장) + EOTech XPS3 (Schlange) + EOTech XPS3 (Serpe) + EOTech XPS3 (Serpent) + EOTech XPS3 (Serpiente) + + + EOTech XPS3 SMG (Snake) + EOTech XPS3 SMG (ヘビ柄迷彩) + 이오텍 XPS3 SMG (뱀 위장) + EOTech XPS3 SMG (Schlange) + EOTech XPS3 SMG (Serpe) + EOTech XPS3 SMG (Serpent) + EOTech XPS3 SMG (Serpiente) + + + 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 (Aride) + Leupold Mark 4 HAMR (Árida) + + + 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 (Vert) + Leupold Mark 4 HAMR (Exuberante) + + + 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 (Sable) + Leupold Mark 4 HAMR (Arena) + + + Leupold Mark 4 HAMR (Snake) + Leupold Mark 4 HAMR (ヘビ柄迷彩) + 류폴드 마크 4 HAMR (뱀 위장) + Leupold Mark 4 HAMR (Schlange) + Leupold Mark 4 HAMR (Serpe) + Leupold Mark 4 HAMR (Serpent) + Leupold Mark 4 HAMR (Serpiente) + + + 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 (Haut, Noir) + Aimpoint Micro R-1 (Alto, Negro) + + + 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 (Haut, Kaki) + Aimpoint Micro R-1 (Alto, Caqui) + + + 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 (Haut, Sable) + Aimpoint Micro R-1 (Alto, Arena) + + + 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 (Haut, Serpent) + Aimpoint Micro R-1 (Alto, Serpiente) + + + 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 (Hoch, Arid + Aimpoint Micro R-1 (Alto, Árido) + + + 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 (Haute, Vert) + Aimpoint Micro R-1 (Alto, Exuberante) + + + 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 (Haut, Noir/Sable) + Aimpoint Micro R-1 (Alto, Negro/Arena) + + + 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 (Bas, Noir) + Aimpoint Micro R-1 (Bajo, Negro) + + + 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 (Bas, Kaki) + Aimpoint Micro R-1 (Bajo, Caqui) + + + 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 ( Bas, Sable ) + Aimpoint Micro R-1 (Bajo, Arena) + + + 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 (Bas, Serpent) + Aimpoint Micro R-1 (Bajo, Serpiente) + + + 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 (Bas, Arid) + Aimpoint Micro R-1 (Bajo, Árido) + + + Aimpoint Micro R-1 (Low, Lush) + Aimpoint マイクロ R-1 (ローマウント、緑地迷彩) + 에임포인트 마이크로 R-1 (낮음, 초목) + Aimpoint Micro R-1 (Tief, Grün) + Aimpoint Micro R-1 (Basso, Verdeggiante) + Aimpoint Micro R-1 (Bas, Vert) + Aimpoint Micro R-1 (Low, Lush) + + + Burris XTR II (Snake) + Burris XTR II (ヘビ柄迷彩) + 버리스 XTR II (뱀 위장) + Burris XTR II (Schlange) + Burris XTR II (Serpe) + Burris XTR II (Serpent) + Burris XTR II (Serpiente) + + + Badger IFV (ATGM) + バジャー IFV (ATGM) + 뱃져 보병전투차 (대전차미사일) + Badger IFV (PzAbw) + Badger IFV (ATGM) + Badger IFV (ATGM) + Badger IFV (ATGM) + + + Badger IFV (Command) + バジャー IFV (指揮) + 뱃져 보병전투차 (지휘) + Badger IFV (Kommando) + Badger IFV (Comando) + Badger IFV (Commandement) + Badger IFV (Comandancia) + + + Badger IFV (Mortar) + バジャー IFV (迫撃砲) + 뱃져 보병전투차 (자주박격포) + Badger IFV (Mörser) + Badger IFV (Mortaio) + Badger IFV (mortier) + Badger IFV (Mortero) + + + KamAZ (Zu-23-2) + KamAZ (Zu-23-2) + 카마즈 (ZU-23-2) + KamAZ (Zu-23-2) + KamAZ (Zu-23-2) + KamAZ (Zu-23-2) + KamAZ (Zu-23-2) + + + KamAZ Cargo + KamAZ 貨物 + 카마즈 화물 + KamAZ Fracht + KamAZ Carico + KamAZ Cargo + KamAZ Carga + + + KamAZ Repair + KamAZ 修理 + 카마즈 정비 + KamAZ Instandsetzung + KamAZ Riparazione + KamAZ Réparation + KamAZ Reparaciones + + + KamAZ Racing + KamAZ レース仕様 + 카마즈 경주용 + KamAZ Rennlaster + KamAZ da corsa + KamAZ de course + KamAZ Carreras + + + KamAZ Ammo + KamAZ 弾薬 + 카마즈 탄약 + KamAZ Munition + KamAZ Munizioni + KamAZ Munitions + KamAZ Municiones + + + KamAZ Flatbed + KamAZ フラットベッド + 카마즈 플랫베드 + KamAZ Flachbett + KamAZ Pianale + KamAZ Flatbed + KamAZ Flatbed + + + AW101 Merlin + AW101 マーリン + AW101 멀린 + AW101 Merlin + AW101 Merlin + 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) + BM-2T Stalker (Boomerang-BM) + BM-2T Stalker (Bumerang-BM) + + + Otokar ARMA (HMG) + オトカ アルマ (HMG) + 오토카 아르마 APC (중기관총) + Otokar ARMA (HMG) + Otokar ARMA (HMG) + Otokar ARMA (HMG) + Otokar ARMA (HMG) + + + Otokar ARMA (Unarmed) + オトカ アルマ (非武装) + 오토카 아르마 APC (비무장) + Otokar ARMA (Unbewaffnet) + Otokar ARMA (Disarmato) + Otokar ARMA (non armé) + Otokar ARMA (Desarmado) + + + Ka-60 Kasatka (UP) + Ka-60 カサートカ (UP) + Ka-60 카사트카 (UP) + Ka-60 Kasatka (UP) + Ka-60 Kasatka (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) + Ka-60 Kasatka (UP, non armé) + Ka-60 Kasatka (UP, Desarmado) + diff --git a/addons/compat_ws/compat_ws_repair/CfgVehicles.hpp b/addons/compat_ws/compat_ws_repair/CfgVehicles.hpp new file mode 100644 index 00000000000..d7fcbc7cd97 --- /dev/null +++ b/addons/compat_ws/compat_ws_repair/CfgVehicles.hpp @@ -0,0 +1,34 @@ +class CfgVehicles { + // Vehicle animation interactions + class Truck_02_base_F; + class Truck_02_aa_base_lxWS: Truck_02_base_F { + class EGVAR(interaction,anims) { + class hideSpareWheel { + positions[] = {{1, 1.93, -0.85}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class Truck_02_cargo_base_lxWS: Truck_02_base_F { + class EGVAR(interaction,anims) { + class hideSpareWheel { + positions[] = {{1, 1.93, -0.35}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class Truck_02_box_base_lxWS: Truck_02_base_F { + class EGVAR(interaction,anims) { + class hideSpareWheel { + positions[] = {{1, 1.7, -0.35}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; +}; diff --git a/addons/compat_ws/compat_ws_repair/config.cpp b/addons/compat_ws/compat_ws_repair/config.cpp new file mode 100644 index 00000000000..4f37c831cb6 --- /dev/null +++ b/addons/compat_ws/compat_ws_repair/config.cpp @@ -0,0 +1,20 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"data_f_lxWS_Loadorder", "ace_repair"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_ws/compat_ws_repair/script_component.hpp b/addons/compat_ws/compat_ws_repair/script_component.hpp new file mode 100644 index 00000000000..1af928486c3 --- /dev/null +++ b/addons/compat_ws/compat_ws_repair/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT repair +#define SUBCOMPONENT_BEAUTIFIED Repair +#include "..\script_component.hpp" diff --git a/addons/compat_ws/compat_ws_vehicles/CfgVehicles.hpp b/addons/compat_ws/compat_ws_vehicles/CfgVehicles.hpp new file mode 100644 index 00000000000..ffc69d60758 --- /dev/null +++ b/addons/compat_ws/compat_ws_vehicles/CfgVehicles.hpp @@ -0,0 +1,27 @@ +class CfgVehicles { + class Car_F; + class Wheeled_APC_F: Car_F { + class Turrets { + class MainTurret; + }; + }; + class APC_Wheeled_01_base_F: Wheeled_APC_F { + class Turrets: Turrets { + class MainTurret: MainTurret {}; + }; + }; + class APC_Wheeled_01_atgm_base_lxWS: APC_Wheeled_01_base_F { + class Turrets: Turrets { + class MainTurret: MainTurret { + weapons[] = {"autocannon_40mm_CTWS", "ACE_LMG_coax_MAG58_mem3", "missiles_titan"}; // For realistic MG name + }; + }; + }; + class APC_Wheeled_01_command_base_lxWS: APC_Wheeled_01_base_F { + class Turrets: Turrets { + class MainTurret: MainTurret { + weapons[] = {"HMG_127_lxWS", "ACE_LMG_coax_MAG58_mem3"}; // For realistic MG name + }; + }; + }; +}; diff --git a/addons/compat_ws/compat_ws_vehicles/config.cpp b/addons/compat_ws/compat_ws_vehicles/config.cpp new file mode 100644 index 00000000000..07d6c1f608c --- /dev/null +++ b/addons/compat_ws/compat_ws_vehicles/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "data_f_lxWS_Loadorder", + "ace_vehicles" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_ws/compat_ws_vehicles/script_component.hpp b/addons/compat_ws/compat_ws_vehicles/script_component.hpp new file mode 100644 index 00000000000..17370c415fd --- /dev/null +++ b/addons/compat_ws/compat_ws_vehicles/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT vehicles +#define SUBCOMPONENT_BEAUTIFIED Vehicles +#include "..\script_component.hpp" diff --git a/addons/compat_ws/config.cpp b/addons/compat_ws/config.cpp index 32a3f6f73cb..54a6df99eec 100644 --- a/addons/compat_ws/config.cpp +++ b/addons/compat_ws/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"data_f_lxWS_Loadorder"}; + requiredAddons[] = {"data_f_lxWS_Loadorder", "ace_common"}; skipWhenMissingDependencies = 1; author = ECSTRING(common,ACETeam); authors[] = {"Mike"}; @@ -15,4 +15,5 @@ class CfgPatches { }; }; +#include "CfgVehicles.hpp" #include "CfgWeapons.hpp" diff --git a/addons/concertina_wire/XEH_postInit.sqf b/addons/concertina_wire/XEH_postInit.sqf index 7cb8909c817..bb3f0225344 100644 --- a/addons/concertina_wire/XEH_postInit.sqf +++ b/addons/concertina_wire/XEH_postInit.sqf @@ -10,4 +10,4 @@ GVAR(deployPFH) = -1; }; }] call CBA_fnc_addEventHandler; -[QGVAR(vehicleDamage), {_this call FUNC(vehicleDamage)}] call CBA_fnc_addEventHandler; +[QGVAR(vehicleDamage), LINKFUNC(vehicleDamage)] call CBA_fnc_addEventHandler; diff --git a/addons/concertina_wire/functions/fnc_deploy.sqf b/addons/concertina_wire/functions/fnc_deploy.sqf index 579bc73f973..b1699ffc857 100644 --- a/addons/concertina_wire/functions/fnc_deploy.sqf +++ b/addons/concertina_wire/functions/fnc_deploy.sqf @@ -22,7 +22,7 @@ params ["_wirecoil", "_unit"]; private _wireNoGeo = "ACE_ConcertinaWireNoGeo" createVehicle [0,0,0]; { _wireNoGeo animate [_x, 1]; -} count WIRE_FAST; +} forEach WIRE_FAST; GVAR(placer) = _unit; private _dir = getDir _unit; @@ -48,10 +48,10 @@ GVAR(deployPFH) = [{ private _anim = 0 max (1 - (_range / 12)); if (!(alive _unit) || _range >= 12 || (_unit getVariable [QGVAR(wireDeployed), false])) exitWith { - private _wire = "ACE_ConcertinaWire" createvehicle [0, 0, 0]; + private _wire = "ACE_ConcertinaWire" createVehicle [0, 0, 0]; { _wire animate [_x, _anim]; - } count WIRE_FAST; + } forEach WIRE_FAST; [{ params ["_args", "_idPFH"]; @@ -74,7 +74,7 @@ GVAR(deployPFH) = [{ _wireNoGeo setDir _dir; { _wireNoGeo animate [_x, _anim]; - } count WIRE_FAST; + } forEach WIRE_FAST; }, 0, [_wireNoGeo, _wireNoGeoPos, _unit]] call CBA_fnc_addPerFrameHandler; [LLSTRING(RollWire), "", ""] call EFUNC(interaction,showMouseHint); diff --git a/addons/concertina_wire/functions/fnc_dismountSuccess.sqf b/addons/concertina_wire/functions/fnc_dismountSuccess.sqf index 3a90b62a91d..d90d3931dab 100644 --- a/addons/concertina_wire/functions/fnc_dismountSuccess.sqf +++ b/addons/concertina_wire/functions/fnc_dismountSuccess.sqf @@ -20,7 +20,7 @@ params ["_wire"]; { _wire animate [_x, 1]; -} count WIRE_FAST; +} forEach WIRE_FAST; [{ params ["_args", "_idPFH"]; @@ -31,7 +31,7 @@ params ["_wire"]; private _dir = getDir _wire; private _pos = getPosASL _wire; - private _wirecoil = "ACE_ConcertinaWireCoil" createvehicle [0, 0, 0]; + private _wirecoil = "ACE_ConcertinaWireCoil" createVehicle [0, 0, 0]; deleteVehicle _wire; diff --git a/addons/concertina_wire/functions/fnc_handleDamage.sqf b/addons/concertina_wire/functions/fnc_handleDamage.sqf index 02092044ef3..f5f1177df5d 100644 --- a/addons/concertina_wire/functions/fnc_handleDamage.sqf +++ b/addons/concertina_wire/functions/fnc_handleDamage.sqf @@ -22,7 +22,7 @@ params ["_wire", "", "_damage", "_source", ""]; if (_damage < 0.5) exitWith { 0 }; -if (!(isNull _source)) then { +if (!isNull _source) then { _wire setVariable [QGVAR(lastDamager), _source]; }; diff --git a/addons/concertina_wire/stringtable.xml b/addons/concertina_wire/stringtable.xml index 0ea44fc063f..603cc5a7a85 100644 --- a/addons/concertina_wire/stringtable.xml +++ b/addons/concertina_wire/stringtable.xml @@ -30,7 +30,7 @@ Concertina wire coil Bobina de arame farpado 鉄条網コイル - 코일형 철조망 + 윤형철조망 鐵絲網捲 铁丝网卷 Bıçaklı Tel Rulo diff --git a/addons/cookoff/ACE_Settings.hpp b/addons/cookoff/ACE_Settings.hpp index ba4447dba99..37594bed51b 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 c1671777054..a328451a7b8 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 2b58daa3043..f973ef40261 100644 --- a/addons/cookoff/CfgEden.hpp +++ b/addons/cookoff/CfgEden.hpp @@ -1,28 +1,27 @@ - class Cfg3DEN { class Object { class AttributeCategories { class ace_attributes { class Attributes { - class GVAR(enable) { - property = QGVAR(enable); + class GVAR(enable) { // setting was previously GVAR(enable), so maintain for backwards compatiblity with missions + property = QGVAR(enable); // same as above control = "Checkbox"; - displayName = CSTRING(enable_hd_name); - tooltip = CSTRING(enable_hd_tooltip); - expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};); + displayName = CSTRING(enableFire_name); + tooltip = CSTRING(enableFire_tooltip); + expression = QUOTE(if (!_value) then {_this setVariable [ARR_3('%s',_value,true)]}); typeName = "BOOL"; condition = "objectVehicle"; - defaultValue = QUOTE((GETMVAR(QGVAR(enable),0)) in [ARR_2(1,2)]); + defaultValue = QUOTE(GETMVAR(QGVAR(enableFire),true)); }; class GVAR(enableAmmoCookoff) { property = QGVAR(enableAmmoCookoff); control = "Checkbox"; displayName = CSTRING(enableAmmoCookoff_name); tooltip = CSTRING(enableAmmoCookoff_tooltip); - expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};); + expression = QUOTE(if (!_value) then {_this setVariable [ARR_3('%s',_value,true)]}); typeName = "BOOL"; condition = "objectHasInventoryCargo"; - defaultValue = QUOTE(if (_this isKindOf 'ReammoBox_F') then { GETMVAR(QGVAR(enableAmmobox),true) } else { GETMVAR(QGVAR(enableAmmoCookoff),true) };); + defaultValue = QUOTE(if (_this isKindOf 'ReammoBox_F') then {GETMVAR(QGVAR(enableAmmobox),true)} else {GETMVAR(QGVAR(enableAmmoCookoff),true)}); }; }; }; diff --git a/addons/cookoff/CfgEventHandlers.hpp b/addons/cookoff/CfgEventHandlers.hpp index 6c29240403a..f6503c2479b 100644 --- a/addons/cookoff/CfgEventHandlers.hpp +++ b/addons/cookoff/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); diff --git a/addons/cookoff/CfgSFX.hpp b/addons/cookoff/CfgSFX.hpp index 0d670ead863..24329862fc7 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 index 742fb589d94..70d752d6138 100644 --- a/addons/cookoff/CfgSounds.hpp +++ b/addons/cookoff/CfgSounds.hpp @@ -45,7 +45,7 @@ class CfgSounds { 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_far_1) { + 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) { diff --git a/addons/cookoff/CfgVehicles.hpp b/addons/cookoff/CfgVehicles.hpp index 78cbd0c6234..4451d120802 100644 --- a/addons/cookoff/CfgVehicles.hpp +++ b/addons/cookoff/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CfgVehicles { class Sound; class GVAR(Sound_low): Sound { @@ -7,7 +6,6 @@ class CfgVehicles { scope = 1; sound = QGVAR(CookOff_low); }; - class GVAR(Sound_mid): GVAR(Sound_low) { sound = QGVAR(CookOff_mid); }; @@ -17,47 +15,14 @@ class CfgVehicles { class Tank; class Tank_F: Tank { - GVAR(ammoLocation) = "HitHull"; GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"}; - GVAR(probability) = 0.5; - }; - class MBT_02_base_F: Tank_F { - GVAR(ammoLocation) = "HitTurret"; }; class Car_F; class Wheeled_APC_F: Car_F { - GVAR(ammoLocation) = "HitHull"; GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"}; - GVAR(probability) = 0.8; - // big explosions for wheeled APCs (same as for tanks) + // Big explosions for wheeled APCs (same as for tanks) explosionEffect = "FuelExplosionBig"; }; - - - class MRAP_01_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class MRAP_02_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class MRAP_03_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class Quadbike_01_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,1,0}; - }; - - class Truck_F; - class Truck_02_base_F: Truck_F { - GVAR(engineSmokeOffset)[] = {0,-2.6,-0.1}; - }; - - class Truck_02_MRL_base_F: Truck_02_base_F { - GVAR(engineSmokeOffset)[] = {0,0.3,-0.1}; - }; }; diff --git a/addons/cookoff/XEH_PREP.hpp b/addons/cookoff/XEH_PREP.hpp index 2cd87efaa7c..94059089535 100644 --- a/addons/cookoff/XEH_PREP.hpp +++ b/addons/cookoff/XEH_PREP.hpp @@ -1,10 +1,12 @@ - -PREP(handleDamageBox); -PREP(engineFire); -PREP(cookOff); -PREP(smoke); -PREP(cookOffEffect); -PREP(cookOffBox); -PREP(detonateAmmunition); +PREP(cookOffBoxLocal); +PREP(cookOffBoxServer); +PREP(cookOffLocal); +PREP(cookOffServer); +PREP(detonateAmmunitionServer); +PREP(detonateAmmunitionServerLoop); +PREP(engineFireLocal); +PREP(engineFireServer); PREP(getVehicleAmmo); +PREP(handleDamageBox); PREP(isMagazineFlare); +PREP(smoke); diff --git a/addons/cookoff/XEH_postInit.sqf b/addons/cookoff/XEH_postInit.sqf index b33723619e0..63e1486c82b 100644 --- a/addons/cookoff/XEH_postInit.sqf +++ b/addons/cookoff/XEH_postInit.sqf @@ -1,63 +1,64 @@ #include "script_component.hpp" -[QGVAR(engineFire), FUNC(engineFire)] call CBA_fnc_addEventHandler; -[QGVAR(cookOff), { - params ["_vehicle"]; - if (local _vehicle) then { - _this call FUNC(cookOff); - }; -}] call CBA_fnc_addEventHandler; -[QGVAR(cookOffEffect), FUNC(cookOffEffect)] call CBA_fnc_addEventHandler; -[QGVAR(smoke), FUNC(smoke)] call CBA_fnc_addEventHandler; -[QGVAR(cookOffBox), FUNC(cookOffBox)] call CBA_fnc_addEventHandler; - -// handle cleaning up effects when vehicle is deleted mid-cookoff -[QGVAR(addCleanupHandlers), { - params ["_vehicle"]; - - // Don't add a new EH if cookoff is run multiple times - if ((_vehicle getVariable [QGVAR(deletedEH), -1]) == -1) then { - private _deletedEH = _vehicle addEventHandler ["Deleted", { - params ["_vehicle"]; +[QGVAR(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; + +if (isServer) then { + [QGVAR(cookOffBoxServer), LINKFUNC(cookOffBoxServer)] call CBA_fnc_addEventHandler; + [QGVAR(cookOffServer), LINKFUNC(cookOffServer)] call CBA_fnc_addEventHandler; + [QGVAR(detonateAmmunitionServer), LINKFUNC(detonateAmmunitionServer)] call CBA_fnc_addEventHandler; + [QGVAR(engineFireServer), LINKFUNC(engineFireServer)] call CBA_fnc_addEventHandler; +}; - [QGVAR(cleanupEffects), [_vehicle]] call CBA_fnc_localEvent; - }]; +// 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; - _vehicle setVariable [QGVAR(deletedEH), _deletedEH]; - }; -}] call CBA_fnc_addEventHandler; +["ReammoBox_F", "Deleted", { + { + deleteVehicle _x; + } forEach ((_this select 0) getVariable [QGVAR(effects), []]); +}, true, [], true] call CBA_fnc_addClassEventHandler; +// Raised when the flames have subsided or after the ammo of a box has finished cooking off [QGVAR(cleanupEffects), { - params ["_vehicle", ["_effects", []]]; + params ["_object"]; - _effects = _effects + (_vehicle getVariable [QGVAR(effects), []]); - if (_effects isNotEqualTo []) then { - { deleteVehicle _x } count _effects; - }; + { + deleteVehicle _x; + } forEach (_object getVariable [QGVAR(effects), []]); + + _object setVariable [QGVAR(effects), nil]; }] call CBA_fnc_addEventHandler; +// Ammo box damage handling ["ReammoBox_F", "init", { - (_this select 0) addEventHandler ["HandleDamage", { - if ((_this select 0) getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmobox)]) then { - _this call FUNC(handleDamageBox); - }; - }]; -}, nil, nil, true] call CBA_fnc_addClassEventHandler; + // Calling this function inside curly brackets allows the usage of "exitWith", which would be broken with "HandleDamage" otherwise + (_this select 0) addEventHandler ["HandleDamage", {_this call FUNC(handleDamageBox)}]; +}, true, [], true] call CBA_fnc_addClassEventHandler; + +// Vehicle ammo cook-off (secondary explosions) +["AllVehicles", "Killed", { + if (!GVAR(enableAmmoCookoff) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; -// secondary explosions -["AllVehicles", "killed", { params ["_vehicle", "", "", "_useEffects"]; - if ( - _useEffects && - _vehicle getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmoCookoff)] - ) then { - if (GVAR(ammoCookoffDuration) == 0) exitWith {}; - ([_vehicle] call FUNC(getVehicleAmmo)) params ["_mags", "_total"]; - - private _delay = (random MAX_AMMO_DETONATION_START_DELAY) max MIN_AMMO_DETONATION_START_DELAY; - [FUNC(detonateAmmunition), [_vehicle, _mags, _total], _delay] call CBA_fnc_waitAndExecute; + + if (_useEffects && {_vehicle getVariable [QGVAR(enableAmmoCookoff), true]}) then { + // We don't need to pass source and instigator, as vehicle is already dead + [QGVAR(detonateAmmunitionServer), [ + _vehicle, + false, + objNull, + objNull, + random [MIN_AMMO_DETONATION_START_DELAY, (MIN_AMMO_DETONATION_START_DELAY + MAX_AMMO_DETONATION_START_DELAY) / 2, MAX_AMMO_DETONATION_START_DELAY] + ]] call CBA_fnc_serverEvent; }; -}, nil, ["Man","StaticWeapon"]] call CBA_fnc_addClassEventHandler; +}, true, ["CAManBase", "StaticWeapon"], true] call CBA_fnc_addClassEventHandler; if (hasInterface) then { // Plays a sound locally, so that different sounds can be used for various distances @@ -68,7 +69,7 @@ if (hasInterface) then { private _distance = _object distance (positionCameraToWorld [0, 0, 0]); - TRACE_3("",_object,_sound,_maxDistance); + TRACE_2("",_object,_sound); // 3 classes of distances: close, mid and far, each having different sound files private _classDistance = switch (true) do { @@ -94,6 +95,6 @@ if (hasInterface) then { if (!fileExists _sound) exitWith {}; // Obeys speed of sound and takes doppler effects into account - playSound3D [_sound, objNull, insideBuilding _object >= 0.5, getPosASL _object, _volume, _pitch + (random 0.2) - 0.1, _maxDistance, 0, true]; + 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/functions/fnc_cookOff.sqf b/addons/cookoff/functions/fnc_cookOff.sqf deleted file mode 100644 index 57cde71682d..00000000000 --- a/addons/cookoff/functions/fnc_cookOff.sqf +++ /dev/null @@ -1,129 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Start a cook-off in the given vehicle. - * - * Arguments: - * 0: Vehicle - * 1: Intensity of fire - * - * Return Value: - * None - * - * Example: - * [(vehicle player), 3] call ace_cookoff_fnc_cookOff - * - * Public: No - */ - -params ["_vehicle", "_intensity", ["_instigator", objNull], ["_smokeDelayEnabled", true], ["_ammoDetonationChance", 0], ["_detonateAfterCookoff", false], ["_fireSource", ""], ["_canRing", true], ["_maxIntensity", MAX_COOKOFF_INTENSITY, [0]], ["_canJet", true, [true]]]; - -if (GVAR(enable) == 0) exitWith {}; -if !(GVAR(enableFire)) exitWith {}; -if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] in [0, false]) exitWith {}; -// exit if cook-off enabled only for players and no players in vehicle crew found -if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] isEqualTo 1 && {fullCrew [_vehicle, "", false] findIf {isPlayer (_x select 0)} == -1}) exitWith {}; - - -TRACE_2("cooking off",_vehicle,_intensity); -TRACE_8("",_instigator,_smokeDelayEnabled,_ammoDetonationChance,_detonateAfterCookoff,_fireSource,_canRing,_maxIntensity,_canJet); - -if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {}; -_vehicle setVariable [QGVAR(isCookingOff), true, true]; - -[QGVAR(addCleanupHandlers), [_vehicle]] call CBA_fnc_globalEvent; - -// limit maximum value of intensity to prevent very long cook-off times -_intensity = _intensity min _maxIntensity; - -private _config = configOf _vehicle; -private _positions = getArray (_config >> QGVAR(cookoffSelections)) select {(_vehicle selectionPosition _x) isNotEqualTo [0,0,0]}; - -if (_positions isEqualTo []) then { - WARNING_1("no valid selection for cookoff found. %1",typeOf _vehicle); - { - private _pos = _vehicle selectionPosition _x; - if (_pos isEqualTo [0, 0, 0]) exitWith {}; - _positions pushBack _x; - } forEach DEFAULT_COMMANDER_HATCHES; - - if (_positions isEqualTo []) then { - _positions pushBack "#noselection"; - }; -}; - -private _delay = 0; -if (_smokeDelayEnabled) then { - _delay = SMOKE_TIME + random SMOKE_TIME; -}; -[QGVAR(smoke), [_vehicle, _positions]] call CBA_fnc_globalEvent; - -[{ - params ["_vehicle", "_positions", "_intensity", "_ammoDetonationChance", "_detonateAfterCookoff", "_instigator", "_fireSource", "_canRing", "_canJet"]; - _vehicle setVariable [QGVAR(intensity), _intensity]; - private _smokeEffects = _vehicle getVariable [QGVAR(effects), []]; - - [{ - params ["_args", "_pfh"]; - _args params ["_vehicle", "_positions", "_ammoDetonationChance", "_detonateAfterCookoff", "_instigator", "_fireSource", "_canRing", "_canJet", "_smokeEffects"]; - private _intensity = _vehicle getVariable [QGVAR(intensity), 0]; - if (isNull _vehicle || {_intensity <= 1}) exitWith { - [QGVAR(cleanupEffects), [_vehicle, _smokeEffects]] call CBA_fnc_globalEvent; - _vehicle setVariable [QGVAR(isCookingOff), false, true]; - [_pfh] call CBA_fnc_removePerFrameHandler; - - if (GVAR(destroyVehicleAfterCookoff) || _detonateAfterCookoff) then { - _vehicle setDamage [1, true]; - }; - }; - - private _lastFlameTime = _vehicle getVariable [QGVAR(lastFlame), 0]; - private _nextFlameTime = _vehicle getVariable [QGVAR(nextFlame), 0]; - - // Wait until we are ready for the next flame - // dt = Tcurrent - Tlast - // dt >= Tnext - if ((CBA_missionTime - _lastFlameTime) >= _nextFlameTime) then { - private _ring = (0.2 > random 1); - if (!_ring && _intensity >= 2) then { - _ring = (0.7 > random 1); - }; - - if !(_canRing) then { - _ring = false; - }; - - private _time = linearConversion [0, 10, _intensity, 3, 20] + random COOKOFF_TIME; - - if (_fireSource isEqualTo "") then { - _fireSource = selectRandom _positions; - }; - - [QGVAR(cookOffEffect), [_vehicle, _canJet, _ring, _time, _fireSource, _intensity]] call CBA_fnc_globalEvent; - - _intensity = _intensity - (0.5 max random 1); - _vehicle setVariable [QGVAR(intensity), _intensity]; - _vehicle setVariable [QGVAR(lastFlame), CBA_missionTime]; - _vehicle setVariable [QGVAR(nextFlame), _time + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES)]; - - { - [QEGVAR(fire,burn), [_x, _intensity * 1.5, _instigator]] call CBA_fnc_globalEvent; - } forEach crew _vehicle - }; - - if (_ammoDetonationChance > random 1) then { - private _lastExplosiveDetonationTime = _vehicle getVariable [QGVAR(lastExplosiveDetonation), 0]; - private _nextExplosiveDetonation = _vehicle getVariable [QGVAR(nextExplosiveDetonation), 0]; - - if ((CBA_missionTime - _lastExplosiveDetonationTime) > _nextExplosiveDetonation) then { - if (_fireSource isEqualTo "") then { - _fireSource = selectRandom _positions; - }; - createVehicle ["ACE_ammoExplosionLarge", (_vehicle modelToWorld (_vehicle selectionPosition _fireSource)), [], 0 , "CAN_COLLIDE"]; - - _vehicle setVariable [QGVAR(lastExplosiveDetonation), CBA_missionTime]; - _vehicle setVariable [QGVAR(nextExplosiveDetonation), random 60]; - }; - }; - }, 0.25, [_vehicle, _positions, _ammoDetonationChance, _detonateAfterCookoff, _instigator, _fireSource, _canRing, _canJet, _smokeEffects]] call CBA_fnc_addPerFrameHandler -}, [_vehicle, _positions, _intensity, _ammoDetonationChance, _detonateAfterCookoff, _instigator, _fireSource, _canRing, _canJet], _delay] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_cookOffBox.sqf b/addons/cookoff/functions/fnc_cookOffBox.sqf deleted file mode 100644 index 8b8e60891cf..00000000000 --- a/addons/cookoff/functions/fnc_cookOffBox.sqf +++ /dev/null @@ -1,74 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: KoffeinFlummi, commy2, kymckay - * Start a cook-off in the given ammo box. - * - * Arguments: - * 0: Ammo box - * - * Return Value: - * None - * - * Example: - * [_box] call ace_cookoff_fnc_cookOffBox - * - * Public: No - */ - -params ["_box"]; - -if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {}; -_box setVariable [QGVAR(isCookingOff), true]; - -if (local _box) then { - [QGVAR(cookOffBox), _box] call CBA_fnc_globalEvent; -}; - -[{ - params ["_box"]; - - // Box will start smoking - private _smoke = "#particlesource" createVehicleLocal [0,0,0]; - _smoke setParticleClass "AmmoSmokeParticles2"; - _smoke attachTo [_box, [0,0,0]]; - - private _effects = [_smoke]; - - if (isServer) then { - private _sound = createSoundSource ["Sound_Fire", position _box, [], 0]; - _effects pushBack _sound; - }; - - [{ - params ["_box", "_effects"]; - - // These functions are smart and do all the cooking off work - if (local _box) then { - if (GVAR(ammoCookoffDuration) == 0) exitWith {}; - ([_box] call FUNC(getVehicleAmmo)) params ["_mags", "_total"]; - [_box, _mags, _total] call FUNC(detonateAmmunition); - - // This shit is busy being on fire, magazines aren't accessible/usable - clearMagazineCargoGlobal _box; - }; - - // Light the fire (also handles lighting) - private _fire = "#particlesource" createVehicleLocal [0,0,0]; - _fire setParticleClass "AmmoBulletCore"; - _fire attachTo [_box, [0,0,0]]; - - _effects pushBack _fire; - - [{ - params ["_box", "_effects"]; - - { - deleteVehicle _x; - } forEach _effects; - - if (local _box) then { - _box setDamage 1; - }; - }, [_box, _effects], COOKOFF_TIME_BOX] call CBA_fnc_waitAndExecute; // TODO: Change so that box is alive until no ammo left, with locality in mind - }, [_box, _effects], SMOKE_TIME] call CBA_fnc_waitAndExecute; -}, _box, IGNITE_TIME] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf b/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf new file mode 100644 index 00000000000..8285104daf8 --- /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 00000000000..10d57876a72 --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffBoxServer.sqf @@ -0,0 +1,50 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, kymckay, johnb43 + * Start an ammo cook-off in the given ammo box. + * + * Arguments: + * 0: Ammo box + * 1: Source (default: objNull) + * 2: Instigator (default: objNull) + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_cookoff_fnc_cookOffBoxServer + * + * Public: No + */ + +if (!isServer) exitWith {}; +if (!GVAR(enableAmmobox) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; + +params ["_box", ["_source", objNull], ["_instigator", objNull]]; + +// Make sure it's a box (important, because deleted EH is assigned to ReammoBox_F only in postInit) +if !(_box isKindOf "ReammoBox_F") exitWith {}; + +if !(_box getVariable [QGVAR(enableAmmoCookoff), true]) exitWith {}; + +// Allow only 1 cook-off per box at a time +if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {}; + +_box setVariable [QGVAR(isCookingOff), true, true]; + +private _delay = random [SMOKE_DELAY / 2, SMOKE_DELAY, SMOKE_DELAY / 2 * 3]; + +// Spawn cook-off effects on all connected machines and JIP +private _jipID = [QGVAR(cookOffBoxLocal), [ + _box, + _source, + _instigator, + CBA_missionTime + _delay // Generate a globally synced timestamp +]] call CBA_fnc_globalEventJIP; + +[_jipID, _box] call CBA_fnc_removeGlobalEventJIP; + +_box setVariable [QGVAR(cookoffBoxJipID), _jipID]; + +// API +[QGVAR(cookOffBox), [_box, _source, _instigator, _delay]] call CBA_fnc_globalEvent; diff --git a/addons/cookoff/functions/fnc_cookOffEffect.sqf b/addons/cookoff/functions/fnc_cookOffEffect.sqf deleted file mode 100644 index 44282f2f6b8..00000000000 --- a/addons/cookoff/functions/fnc_cookOffEffect.sqf +++ /dev/null @@ -1,200 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Spawn cook-off effects - * - * Arguments: - * 0: Vehicle - * 1: Spawn fire jet - * 2: Spawn fire ring - * 3: How long effect will last (Max 20 seconds) - * 4: What selection will fire originate from - * 5: Cookoff intensity value - * - * Return Value: - * None - * - * Example: - * [vehicle player, true, false, 15, "commander_turret"] call ace_cookoff_fnc_cookOffEffect - * - * Public: No - */ - -params ["_obj", "_jet", "_ring", "_time", "_fireSelection", "_intensity"]; -private _light = "#lightpoint" createVehicleLocal [0,0,0]; -_light setLightBrightness 5; -_light setLightAmbient [0.8, 0.6, 0.2]; -_light setLightColor [1, 0.5, 0.2]; -_light lightAttachObject [_obj, [0,0,0]]; -_time = 0 max (_time min 20); - -private _sound = objNull; -if (isServer) then { - // ironically biggest performance hit is this. Creating a new sound source takes up aprox 400 milliseconds. - // I dont think there is an alternative that takes into effect distance and whatever, but if you find one please fix! - if (_jet || _ring) then { - private _soundName = selectRandomWeighted [QGVAR(Sound_low), 0.1, QGVAR(Sound_mid), 0.25, QGVAR(Sound_high), 0.65]; - _sound = createSoundSource [_soundName, position _obj, [], 0]; - }; - - if (_ring) then { - private _intensity = 6; - private _radius = 1.5 * ((boundingBoxReal _obj) select 2); - [QEGVAR(fire,addFireSource), [_obj, _radius, _intensity, format [QGVAR(%1), hashValue _obj]]] call CBA_fnc_localEvent; - }; -}; - -[{ - params ["_args", "_pfh"]; - _args params ["_obj", "_jet", "_ring", "_time", "_startTime", "_light", "_fireSelection", "_sound", "_intensity"]; - private _elapsedTime = CBA_missionTime - _startTime; - if (_elapsedTime >= _time) exitWith { - deleteVehicle _light; - deleteVehicle _sound; - if (isServer) then { - [QEGVAR(fire,removeFireSource), [format [QGVAR(%1), hashValue _obj]]] call CBA_fnc_localEvent; - }; - [_pfh] call CBA_fnc_removePerFrameHandler; - }; - private _factor = (1 + (_elapsedTime / 2) min 2); - private _flameSize = 1.5; - - if (_elapsedTime > (_time * (3 / 4))) then { - _factor = _factor * linearConversion [_time * (3 / 4), _time, _elapsedTime, 1, 0.5]; - }; - - _light setLightBrightness 5 * (_factor / 5); - - if (_jet) then { - private _particlePosition = (_obj selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, 0]; - - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", - "Billboard", - 1, - (0.1 + (random 0.2)) * _factor, - _particlePosition, - [0, 0, 15 * (_factor / 2)], - 0, - 10, - 7.9, - 0.075, - [1.25 * _factor, 2.5 * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], - 1, - 0, - "", - "", - _obj - ]; - - // make flame push object into ground to make effect seem more "alive" - if (!isGamePaused && { local _obj }) then { - private _force = [0, 0, _factor * -(0.5 min random 1.5) * (0.3 min random 1)] vectorMultiply getMass _obj; - _obj addForce [_force, vectorUpVisual _obj]; - }; - }; - - if (_ring) then { - private _ringOrigin = (_obj selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, -1]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [0, 20 * (_factor / 2), 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [0, -20 * (_factor / 2), 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [20 * (_factor / 2), 0, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - [-0.1 + random 0.2, -0.1 + random 0.2, -1], - [-20 * (_factor / 2), 0, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - private _dir = 20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [_dir, _dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - _dir = -20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [_dir, _dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - _dir = 20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [_dir, -_dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - _dir = 20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [-_dir, _dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - }; - - (getVehicleTIPars _obj) params ["_tiEngine", "_tiWheels", "_tiWeapon"]; - _obj setVehicleTIPars [ - // formula is designed to have the temperature ramp up quickly and then level out - (_tiEngine + (_intensity * 0.01))/1.005, - (_tiWheels + (_intensity * 0.004))/1.002, // wheels//tracks are further away from burning parts - (_tiWeapon + (_intensity * 0.01))/1.005 - ]; - -}, 0, [_obj, _jet, _ring, _time, CBA_missionTime, _light, _fireSelection, _sound, _intensity]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_cookOffLocal.sqf b/addons/cookoff/functions/fnc_cookOffLocal.sqf new file mode 100644 index 00000000000..4c61a4e5a63 --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffLocal.sqf @@ -0,0 +1,226 @@ +#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]; + private _dir = 20 * (_factor / 2); + + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [0, _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 + ]; + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [0, -_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 + ]; + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [_dir, 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, + _ringOrigin, + [-_dir, 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, + _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 + ]; + + 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 + ]; + + 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 + ]; + + 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 00000000000..d1e5347be5e --- /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, _delayBetweenSmokeAndFire, _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 cc39ff43cf7..00000000000 --- a/addons/cookoff/functions/fnc_detonateAmmunition.sqf +++ /dev/null @@ -1,132 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Glowbal - * Detonates ammunition from a vehicle until no ammo left - * - * Arguments: - * 0: vehicle - * 1: Ammo Array - * - 0: Magazine Classname - * - 1: Ammo Count - * 2: Total Ammo Count - * - * Return Value: - * None - * - * Example: - * [_vehicle, magazinesAmmo _vehicle] call ace_cookoff_fnc_detonateAmmunition - * - * Public: No - */ - -params ["_vehicle", "_magazines", "_totalAmmo"]; - -if (GVAR(enable) == 0) exitWith {}; -if !(GVAR(enableAmmoCookoff)) exitWith {}; - -if (isNull _vehicle) exitWith {}; // vehicle got deleted -if (_magazines isEqualTo []) exitWith {}; // nothing to detonate anymore -if (underwater _vehicle) exitWith {}; - -private _magazineIndex = floor random(count _magazines); -private _magazine = _magazines select _magazineIndex; -_magazine params ["_magazineClassname", "_amountOfMagazines"]; - -if (_amountOfMagazines < 0) exitWith { - ERROR_1("mag with no ammo - %1",_magazine); -}; -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; -_simType = toLower _simType; -switch (_simType) do { - case ("shotbullet"): { - [QGVAR(playCookoffSound), [_vehicle, _simType]] call CBA_fnc_globalEvent; - if (random 1 < 0.6) then { - [_vehicle, _ammo, _speed, true] call _spawnProjectile; - }; - }; - case ("shotshell"): { - [QGVAR(playCookoffSound), [_vehicle, _simType]] call CBA_fnc_globalEvent; - if (random 1 < 0.15) then { - [_vehicle, _ammo, _speed, true] call _spawnProjectile; - }; - }; - case ("shotgrenade"): { - if (random 1 < 0.9) then { - _speed = 0; - }; - [_vehicle, _ammo, _speed, random 1 < 0.5] call _spawnProjectile; - }; - case ("shotrocket"); - case ("shotmissile"); - case ("shotsubmunitions"): { - if (random 1 < 0.1) then { - [QGVAR(playCookoffSound), [_vehicle, _simType]] call CBA_fnc_globalEvent; - [_vehicle, _ammo, _speed, random 1 < 0.3] call _spawnProjectile; - } else { - createvehicle ["ACE_ammoExplosionLarge", (_vehicle modelToWorld _effect2pos), [], 0 , "CAN_COLLIDE"]; - }; - }; - case ("shotmine"); - case ("shotdirectionalbomb"): { - 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"]; - }; - }; - }; - case ("shotilluminating"): { - 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; diff --git a/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf b/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf new file mode 100644 index 00000000000..43ac730e09d --- /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 00000000000..946cb4f7d8f --- /dev/null +++ b/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf @@ -0,0 +1,172 @@ +#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 = toLowerANSI 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 ["_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 { + triggerAmmo _projectile; + }; +}; + +switch (_simType) do { + case "shotbullet": { + [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; + + if (random 1 < 0.6) then { + true call _fnc_spawnProjectile; + }; + }; + case "shotshell": { + [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; + + if (random 1 < 0.15) then { + true call _fnc_spawnProjectile; + }; + }; + case "shotgrenade": { + if (random 1 < 0.9) then { + _speed = 0; + }; + + (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; + + (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 { + // _speed should be 0, but as it doesn't fly away, no need to set _speed + false call _fnc_spawnProjectile; + }; + }; + case "shotilluminating": { + if (random 1 < 0.15) then { + (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 118537b30a3..00000000000 --- a/addons/cookoff/functions/fnc_engineFire.sqf +++ /dev/null @@ -1,51 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: KoffeinFlummi, commy2 - * Start fire in engine block of a car. - * - * Arguments: - * 0: Vehicle - * - * Return Value: - * None - * - * Example: - * (vehicle player) call ace_cookoff_fnc_engineFire - * - * Public: No - */ - -params ["_vehicle"]; - -if (_vehicle getVariable [QGVAR(isEngineSmoking), false]) exitWith {}; -_vehicle setVariable [QGVAR(isEngineSmoking), true]; - -if (local _vehicle) then { - [QGVAR(engineFire), _vehicle] call CBA_fnc_globalEvent; -}; - -private _offset = getArray (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(engineSmokeOffset)); - -if (_offset isEqualTo []) then { - _offset = [0,0,0]; -}; - -private _position = [ - 0, - (boundingBoxReal _vehicle select 1 select 1) - 2, - (boundingBoxReal _vehicle select 0 select 2) + 2 -] vectorAdd _offset; - -private _smoke = "#particlesource" createVehicleLocal [0,0,0]; -_smoke setParticleClass "ObjectDestructionSmoke1_2Smallx"; -_smoke attachTo [_vehicle, _position]; - -[{ - (_this select 0) params ["_vehicle", "_smoke", "_time"]; - - if (isNull _vehicle || {!alive _vehicle} || {_vehicle getHitPointDamage "HitEngine" < 0.9} || {CBA_missionTime > _time}) then { - deleteVehicle _smoke; - _vehicle setVariable [QGVAR(isEngineSmoking), false]; - [_this select 1] call CBA_fnc_removePerFrameHandler; - }; -}, 5, [_vehicle, _smoke, CBA_missionTime + 240]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_engineFireLocal.sqf b/addons/cookoff/functions/fnc_engineFireLocal.sqf new file mode 100644 index 00000000000..5960a518ce7 --- /dev/null +++ b/addons/cookoff/functions/fnc_engineFireLocal.sqf @@ -0,0 +1,85 @@ +#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 = if (_hitPoints isNotEqualTo []) then { + (_hitPoints select 0) findIf {_x == "hitengine"} + } else { + -1 + }; + + // 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 00000000000..0d435029b8c --- /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 f6be84c1f90..35ca6fae263 100644 --- a/addons/cookoff/functions/fnc_getVehicleAmmo.sqf +++ b/addons/cookoff/functions/fnc_getVehicleAmmo.sqf @@ -1,65 +1,76 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Gets all magazines inside of a vehicle. + * Gets all magazines inside of an object. * * Arguments: - * 0: Vehicle + * 0: Object * * Return Value: - * 0: Ammo Array - * - 0: Magazine Classname - * - 1: Ammo Count - * 1: Total Ammo Count + * 0: Ammo array + * - 0: Magazine classname + * - 1: Ammo count + * - 2: If a projectile should be spawned upon detonation + * 1: Total ammo count * * Example: - * [vehicle player] call ace_cookoff_fnc_getVehicleAmmo + * cursorObject call ace_cookoff_fnc_getVehicleAmmo * * Public: No */ -params ["_vehicle"]; -TRACE_1("getVehicleAmmo",_vehicle); +params ["_object"]; +TRACE_1("getVehicleAmmo",_object); private _ammoToDetonate = []; private _totalAmmo = 0; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgAmmo = configFile >> "CfgAmmo"; +private _ammo = ""; // Get ammo from turrets { - _x params ["_mag", "_turret", "_count"]; - // if the turret is an FFV seat, it takes magazines from the soldier - if (_count > 0) then { - if (_mag call FUNC(isMagazineFlare)) then {continue}; - private _ammo = getText (configFile >> "CfgMagazines" >> _mag >> "ammo"); - private _model = getText (configFile >> "CfgAmmo" >> _ammo >> "model"); - if (_model == "\A3\weapons_f\empty") exitWith {TRACE_3("skipping",_mag,_ammo,_model);}; - _ammoToDetonate pushBack [_mag, _count]; + // If the turret is an FFV seat, it takes magazines from the soldier + _x params ["_magazine", "", "_count"]; + + if (_count > 0 && {!(_magazine call FUNC(isMagazineFlare))}) then { + _ammo = getText (_cfgMagazines >> _magazine >> "ammo"); + + if (getText (_cfgAmmo >> _ammo >> "model") == "\A3\weapons_f\empty") then { + TRACE_2("skipping",_magazine,_ammo); + + continue; + }; + + _ammoToDetonate pushBack [_magazine, _count, true]; _totalAmmo = _totalAmmo + _count; }; -} forEach (magazinesAllTurrets [_vehicle, true]); +} forEach (magazinesAllTurrets [_object, true]); // Get ammo from cargo space { - _x params ["_mag", "_count"]; - if (_count > 0) then { - if (_mag call FUNC(isMagazineFlare)) then {continue}; - _ammoToDetonate pushBack [_mag, _count]; + _x params ["_magazine", "_count"]; + + if (_count > 0 && {!(_magazine call FUNC(isMagazineFlare))}) then { + _ammoToDetonate pushBack [_magazine, _count, random 1 < 0.5]; _totalAmmo = _totalAmmo + _count; }; -} forEach (magazinesAmmoCargo _vehicle); +} forEach (magazinesAmmoCargo _object); // Get ammo from transportAmmo / ace_rearm -private _vehCfg = configOf _vehicle; +private _configVehicle = configOf _object; +private _configSupply = (getNumber (_configVehicle >> "transportAmmo")) max (getNumber (_configVehicle >> QEGVAR(rearm,defaultSupply))); -private _configSupply = (getNumber (_vehCfg >> "transportAmmo")) max (getNumber (_vehCfg >> QEGVAR(rearm,defaultSupply))); -if (_vehicle getVariable [QEGVAR(rearm,isSupplyVehicle), (_configSupply > 0)]) then { - TRACE_1("transportAmmo vehicle - adding virtual ammo",typeOf _vehicle); +if (_object getVariable [QEGVAR(rearm,isSupplyVehicle), _configSupply > 0]) then { + TRACE_1("transportAmmo vehicle - adding virtual ammo",typeOf _object); - _ammoToDetonate pushBack ["2000Rnd_65x39_belt", 2000]; + _ammoToDetonate pushBack ["2000Rnd_65x39_belt", 2000, false]; _totalAmmo = _totalAmmo + 2000; - _ammoToDetonate pushBack ["20Rnd_105mm_HEAT_MP", 100]; + + _ammoToDetonate pushBack ["20Rnd_105mm_HEAT_MP", 100, true]; _totalAmmo = _totalAmmo + 100; - _ammoToDetonate pushBack ["SatchelCharge_Remote_Mag", 10]; + + _ammoToDetonate pushBack ["SatchelCharge_Remote_Mag", 10, true]; _totalAmmo = _totalAmmo + 10; }; diff --git a/addons/cookoff/functions/fnc_handleDamageBox.sqf b/addons/cookoff/functions/fnc_handleDamageBox.sqf index dfc5cb7267c..2d55db0fd02 100644 --- a/addons/cookoff/functions/fnc_handleDamageBox.sqf +++ b/addons/cookoff/functions/fnc_handleDamageBox.sqf @@ -1,13 +1,13 @@ #include "..\script_component.hpp" /* - * Author: KoffeinFlummi, commy2 - * Handles all incoming damage for boxi + * Author: KoffeinFlummi, commy2, johnb43 + * Handles all incoming damage for boxes. * * Arguments: * HandleDamage EH * * Return Value: - * Damage to be inflicted. + * Damage to be inflicted (can be nil) * * Example: * _this call ace_cookoff_fnc_handleDamageBox @@ -15,58 +15,48 @@ * Public: No */ -params ["_vehicle", "", "_damage", "_source", "_ammo", "_hitIndex", "_shooter"]; +// If cookoff for boxes is disabled, exit +if (!GVAR(enableAmmobox) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; -// it's already dead, who cares? -if (damage _vehicle >= 1) exitWith {}; +params ["_box", "", "_damage", "_source", "_ammo", "", "_instigator", "_hitPoint"]; -// If cookoff is disabled exit -if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] in [0, false]) exitWith {}; +if (!local _box) exitWith {}; -// get hitpoint name -private _hitpoint = "#structural"; +// If it's already dead, ignore +if (!alive _box) exitWith {}; -if (_hitIndex != -1) then { - _hitpoint = toLower ((getAllHitPointsDamage _vehicle param [0, []]) select _hitIndex); -}; +if !(_box getVariable [QGVAR(enableAmmoCookoff), true]) exitWith {}; + +if !(_hitPoint == "" && {_damage > 0.5}) exitWith {}; // "" means structural damage -// get change in damage -private _oldDamage = 0; +private _ammoConfig = _ammo call CBA_fnc_getObjectConfig; -if (_hitpoint isEqualTo "#structural") then { - _oldDamage = damage _vehicle; +// Catch fire when hit by an explosive or incendiary round +if ((getNumber (_ammoConfig >> "explosive") >= 0.5) || {getNumber (_ammoConfig >> QEGVAR(vehicle_damage,incendiary)) > random 1}) then { + [QGVAR(cookOffBoxServer), [_box, _source, _instigator]] call CBA_fnc_serverEvent; } else { - _oldDamage = _vehicle getHitIndex _hitIndex; -}; + // There is a small chance of cooking a box off if it's shot by tracer ammo + if (random 1 >= _damage * 0.05) exitWith {}; -if (_hitpoint == "#structural" && _damage > 0.5) then { - // Almost always catch fire when hit by an explosive - if (IS_EXPLOSIVE_AMMO(_ammo)) then { - _vehicle call FUNC(cookOffBox); + // Need magazine to check for tracers + private _magazine = if (_source == _instigator) then { + currentMagazine _source } else { - // Need magazine to check for tracers - private _mag = ""; - if (_source == _shooter) then { - _mag = currentMagazine _source; - } else { - _mag = _source currentMagazineTurret ([_shooter] call CBA_fnc_turretPath); - }; - private _magCfg = configFile >> "CfgMagazines" >> _mag; + _source currentMagazineTurret (_source unitTurret _instigator) + }; - // 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); - }; - }; + 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 -} else { - _damage }; + +// Prevent destruction, let cook-off handle it if necessary +_damage min 0.89 diff --git a/addons/cookoff/functions/fnc_isMagazineFlare.sqf b/addons/cookoff/functions/fnc_isMagazineFlare.sqf index b6c8a604be3..f856b21a9a4 100644 --- a/addons/cookoff/functions/fnc_isMagazineFlare.sqf +++ b/addons/cookoff/functions/fnc_isMagazineFlare.sqf @@ -1,24 +1,22 @@ #include "..\script_component.hpp" /* * Author: Cyruz - * Checks if the magazine has ammo which is a flare + * Checks if the magazine's ammo are flares. * * Arguments: * 0: Magazine * * Return Value: - * 0: If magazine is type of flare + * If magazine is type of flare * * Example: - * ["3Rnd_UGL_FlareWhite_F"] call ace_cookoff_fnc_isMagazineFlare + * "3Rnd_UGL_FlareWhite_F" call ace_cookoff_fnc_isMagazineFlare * * Public: No */ params ["_magazine"]; -private _ammo = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); -private _intensity = getNumber (configFile >> "CfgAmmo" >> _ammo >> "intensity"); -private _flare = getNumber (configFile >> "CfgAmmo" >> _ammo >> QEGVAR(grenades,flare)); +private _configAmmo = configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); -_intensity != 0 || _flare == 1 +getNumber (_configAmmo >> "intensity") != 0 || {getNumber (_configAmmo >> QEGVAR(grenades,flare)) == 1} diff --git a/addons/cookoff/functions/fnc_smoke.sqf b/addons/cookoff/functions/fnc_smoke.sqf index ce50043413f..94055041de7 100644 --- a/addons/cookoff/functions/fnc_smoke.sqf +++ b/addons/cookoff/functions/fnc_smoke.sqf @@ -5,7 +5,7 @@ * * Arguments: * 0: Vehicle - * 1. Selections for smoke to come out of (default: []) + * 1: Selections for smoke to come out of * * Return Value: * None @@ -16,12 +16,11 @@ * Public: No */ -params ["_vehicle", ["_positions", []]]; +params ["_vehicle", "_selections"]; -private _turretConfig = [_vehicle, [0]] call CBA_fnc_getTurret; -private _positionBarrelEnd = getText (_turretConfig >> "gunBeg"); +private _positionBarrelEnd = getText ([_vehicle, [0]] call CBA_fnc_getTurret >> "gunBeg"); -// smoke out of cannon and hatches +// Smoke out of cannon and hatches private _smokeBarrel = "#particlesource" createVehicleLocal [0, 0, 0]; _smokeBarrel setParticleClass "MediumDestructionSmoke"; _smokeBarrel attachTo [_vehicle, [0, 0, 0], _positionBarrelEnd]; @@ -29,10 +28,10 @@ _smokeBarrel attachTo [_vehicle, [0, 0, 0], _positionBarrelEnd]; private _effects = [_smokeBarrel]; { - private _position = [0, -2, 0]; - - if (_x isNotEqualTo "#noselection") then { - _position = _vehicle selectionPosition _x; + private _position = if (_x != "#noselection") then { + _vehicle selectionPosition _x + } else { + [0, -2, 0] }; private _smoke = "#particlesource" createVehicleLocal [0, 0, 0]; @@ -40,6 +39,6 @@ private _effects = [_smokeBarrel]; _smoke attachTo [_vehicle, _position]; _effects pushBack _smoke; -} forEach _positions; +} forEach _selections; _vehicle setVariable [QGVAR(effects), _effects]; diff --git a/addons/cookoff/initSettings.inc.sqf b/addons/cookoff/initSettings.inc.sqf index 8912636fd6a..c7f1be8ffde 100644 --- a/addons/cookoff/initSettings.inc.sqf +++ b/addons/cookoff/initSettings.inc.sqf @@ -1,69 +1,71 @@ [ - QGVAR(enable), "LIST", - [LSTRING(enable_hd_name), LSTRING(enable_hd_tooltip)], + QGVAR(enableFire), + "CHECKBOX", + [LSTRING(enableFire_name), LSTRING(enableFire_tooltip)], LSTRING(category_displayName), - [[0, 1, 2], ["STR_A3_OPTIONS_DISABLED", ELSTRING(common,playerOnly), ELSTRING(common,playersAndAI)], 2], - true, // isGlobal - {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + true, + 1 ] call CBA_fnc_addSetting; [ - QGVAR(enableFire), "CHECKBOX", - [LSTRING(enableFire_name), LSTRING(enableFire_tooltip)], + 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), - true, // default value - true, // isGlobal - {[QGVAR(enableFire), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + [0, 10, 1, 2], + 1 ] call CBA_fnc_addSetting; [ - QGVAR(destroyVehicleAfterCookoff), "CHECKBOX", + QGVAR(destroyVehicleAfterCookoff), + "CHECKBOX", [LSTRING(destroyVehicleAfterCookoff_name), LSTRING(destroyVehicleAfterCookoff_tooltip)], LSTRING(category_displayName), - false, // default value - true, // isGlobal - {[QGVAR(destroyVehicleAfterCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + false, + 1 ] call CBA_fnc_addSetting; [ - QGVAR(enableAmmoCookoff), "CHECKBOX", + QGVAR(enableAmmoCookoff), + "CHECKBOX", [LSTRING(enableAmmoCookoff_name), LSTRING(enableAmmoCookoff_tooltip)], LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(enableAmmoCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + true, + 1 ] call CBA_fnc_addSetting; [ - QGVAR(enableAmmobox), "CHECKBOX", + 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 + true, + 1 ] call CBA_fnc_addSetting; [ - QGVAR(ammoCookoffDuration), "SLIDER", + 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 + [0, 10, 1, 2], + 1 ] call CBA_fnc_addSetting; [ - QGVAR(probabilityCoef), "SLIDER", - [LSTRING(probabilityCoef_name), LSTRING(probabilityCoef_tooltip)], + QGVAR(removeAmmoDuringCookoff), + "CHECKBOX", + [LSTRING(removeAmmoDuringCookoff_name), LSTRING(removeAmmoDuringCookoff_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 + true, + 1 ] call CBA_fnc_addSetting; diff --git a/addons/cookoff/script_component.hpp b/addons/cookoff/script_component.hpp index d41b8f675c3..bf8fd62dd5c 100644 --- a/addons/cookoff/script_component.hpp +++ b/addons/cookoff/script_component.hpp @@ -16,14 +16,12 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define IS_EXPLOSIVE_AMMO(ammo) (getNumber (ammo call CBA_fnc_getObjectConfig >> "explosive") > 0.5) - // Stages of cookoff in order (in seconds) -// Should be no un-synced randomness in these as the effects must be ran on each client -#define IGNITE_TIME 3 -#define SMOKE_TIME 10.5 +// Should be no un-synced randomness in these as the effects must be run on each client +#define SMOKE_DELAY 10.5 +#define DETONATION_DELAY 3 #define COOKOFF_TIME 14 // Cook off time should be 20s at most due to length of sound files -#define COOKOFF_TIME_BOX 82.5 // Cook off time for boxes should be significant to allow time for ammo to burn +#define ENGINE_FIRE_TIME 240 #define MIN_TIME_BETWEEN_FLAMES 5 #define MAX_TIME_BETWEEN_FLAMES 15 #define MAX_TIME_BETWEEN_AMMO_DET 25 @@ -32,9 +30,6 @@ #define MIN_AMMO_DETONATION_START_DELAY 1 // Min time to wait before a vehicle's ammo starts to cookoff #define MAX_AMMO_DETONATION_START_DELAY 6 // Max time to wait before a vehicle's ammo starts to cookoff -// Delay between flame effect for players in a cooking off vehicle -#define FLAME_EFFECT_DELAY 0.4 - // Common commander hatch defines for default vehicles #define DEFAULT_COMMANDER_HATCHES ["osa_poklop_commander", "hatch_commander_axis"] diff --git a/addons/cookoff/stringtable.xml b/addons/cookoff/stringtable.xml index 5f764a24b76..5cfd4d738c4 100644 --- a/addons/cookoff/stringtable.xml +++ b/addons/cookoff/stringtable.xml @@ -2,13 +2,13 @@ - ACE Cook off + ACE Cook-off ACE Detonación inducida por calor - ACE Detonazione Munizioni + ACE Esplosioni di Munizioni ACE 殉爆效果 ACE 殉爆效果 ACE 誘爆 - ACE 쿡오프 + ACE 유폭 ACE Durchzündung ACE Auto-inflammation ACE Samozapłon @@ -16,159 +16,69 @@ ACE Cook off ACE Vznícení munice - - Damage handling and turret effects - Daño y efectos de torreta - Schadensberechnung und Geschützturmeffekte - 損傷処理と砲塔の効果 - Обработка урона и эффектов срыва башни - Manipulação de dano e efeitos de torre - Dégâts et effets de tourelle - 傷害控制及炮塔效果 - 损坏处理和炮塔效果 - Gestione danni ed effetti torretta - Poškodit ovládání a efekty věže - Obsługa obrażeń i efekty wieży - 피해량 조절 및 포탑에 효과 부여 - - - Changes damage handling for cook off and turret explosion effects - Cambia el daño de la detonación inducida por calor y los efectos de la explosión de la torreta - Ändert die Schadensberechnung für die Durchzündung und die Explosionseffekte des Geschützturmes - 誘爆の損傷処理と砲塔の爆発効果を変更します。 - Изменяет обработку урона для возгорания и эффекта срыва башни - Modifica a manipulação de dano para o cozinhamento de munição e efeitos de explosão da torre - Modifie la gestion des dégâts pour l'auto-inflammation et les effets d'explosion de tourelle. - 更改殉爆以及炮塔爆炸之傷害控制 - 改变殉爆和炮塔爆炸的损坏处理效果 - Modifica la gestione dei danni per l'esplosione di munizioni e gli effetti di esplosione della torretta - Změní poškození ovládání a efekty výbuchu veže - Zmienia obsługę obrażeń podczas samozapłonu i eksplozji wieży - 쿡오프로 인해 피해량의 변화와 포탑 터짐현상을 결정합니다. - - - 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. - Habilita la detonación inducida por calor en las cajas de munición - 弾薬箱が誘爆するようになります。 - Ermöglicht Durchzündung von Munitionskisten. - 탄약 상자에 쿡오프 현상을 적용합니다. - Aktywuje samozapłon skrzyń z amunicją - Permet l'auto-inflammation des caisses de munitions. - Abilita l'esplosione di casse di munizioni distrutte. - 開啟彈藥箱殉爆效果 - 开启弹药箱殉爆效果 - Активирует детонацию ящиков с боеприпасами - Permitir que caixas de munição cozinhem. - Zapíná vznícení munice v krabicích. - - - Enable Ammunition cook off - Habilitar la detonación inducida por calor en la munición - 弾薬の誘爆を有効化 - Durchzündung für Munition ermöglichen - 탄약 쿡오프 현상 활성화 - Aktywuj samozapłon amunicji - Auto-inflammation des munitions - Abilita Esplosione Munizioni - 開啟彈藥殉爆效果 - 开启弹药殉爆效果 - Разрешить детонацию боекомплекта - Permitir cozinhar munição - Povolit vznícení munice + + Enable vehicle cook-off fire + 車両の誘爆火災を有効化 + Вкл. возгорание техники + 차량 유폭 화재를 활성화합니다 + Abilita incendio dei veicoli + Aktiviert Fahrzeug Munitionsbrand + Permettre l'incendie du véhicule + Habilitar incendio en vehículos a causa de la detonación inducida por calor - - Enables Ammunition cook off. Fires ammunition projectiles while vehicle is on fire and has ammunition. - Habilita la detonación inducida por calor en la munición. Dispara proyectiles de munición mientras el vehículo está ardiendo y tiene munición - 弾薬が誘爆します。車両が燃えると、搭載している弾薬が激しく燃え上がります。 - Ermöglicht Durchzündung von Munition. Feuert Projektile der Munition ab, solange das Fahrzeug brennt und Munition besitzt. - Aktywuje samozapłon amunicji. Wystrzeliwuje pociski podczas gdy pojazd płonie i posiada amunicję. - Permet l'auto-inflammation des munitions. Tire des projectiles tant que le véhicule est en feu et contient des munitions. - Abilita l'esplosione di munizioni. Spara proiettili di munizioni quando il veicolo va a fuoco e contiene ancora munizioni. - 開啟彈藥殉爆效果。當一台載有彈藥的載具起火時, 將會有殉爆的效果 - 开启弹药殉爆效果。当一台载有弹药的载具起火时,将会有殉爆的效果。 - 쿡오프 현상을 활성화 합니다. 이것은 탄약에 불이 붙어 있는 동안 주변에 발사체를 발사합니다. - Активирует детонацию боекомплекта в горящей технике. - Permite que a munição cozinhe. Dispara projéteis de munição enquanto o veículo está em chamas e tem munição. - Zapíná vznícení munice. Vystřeluje projektily po dobu kdy vozidlo hoří a má munici. + + Enables 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. + Permet d'obtenir des effets de feu de véhicule à partir de munitions qui explosent.\nCela n'inclut pas les effets d'explosion. + Habilita los efectos del incendio en vehículos por la detonación inducida por calor.\nEsto no incluye las detonaciones de munición. - - Ammunition cook off duration - Duración de la detonación inducida por calor de la munición - Munitionsdurchzündungsdauer - Czas trwania samozapłonu amunicji - 弾薬の誘爆持続時間 - Durée d'auto-inflammation des munitions - Durata Esplosione Munizioni - 彈藥殉爆效果持續時間 - 弹药殉爆效果持续时间 - 쿡오프 지속 시간 - Длительность детонации боеприпасов - Duração do cozinhamento de munição - Doba trvání vznícení munice + + Vehicle cook-off fire duration multiplier + 車両の誘爆火災の持続時間倍率 + Увел. продолжительности горения техники + 차량 유폭 화재 지속 시간 계수 + Coefficiente di durata incendio dei veicoli + Fahrzeugbrand Dauer-Multiplikator + Coefficient de durée d'incendie du véhicule + Multiplicador de la duración del incendio en vehículos por la detonación inducida por calor - - Multiplier for how long cook off lasts [Setting to 0 will disable ammo cookoff] - Multiplicador de cuanto dura la detonación inducida por calor [Ponerlo a cero la deshabilita] - Faktor für die Munitionsdurchzündungsdauer [0 zum Deaktivieren] - Multiplicateur permettant de régler la durée durant laquelle les munitions continuent d'exploser [Une valeur de 0 désactive l'auto-inflammation]. - Mnożnik decydujący jak długo ma trwać samozapłon amunicji [Ustawienie na 0 spowoduje wyłącznie samozapłonu] - 誘爆の持続時間を乗数で設定します。[0 に設定で誘爆を無効化] - Moltiplicatore della durata delle esplosioni di munizioni [Se impostato su 0 disabiliterà le esplosioni delle munizioni] - 設定彈藥殉爆效果會持續多久時間 [輸入0來關閉殉爆效果] - 设定弹药殉爆效果会持续多久时间 [输入0来关闭殉爆效果] - 쿡오프 지속 시간의 배수 [0 이면 비활성] - Множитель длительности детонации [0 - отключает детонацию боеприпасов] - Multiplicação da duração do cozinhamento [0 faz com que o cozinhamento seja desativado] - Multiplikátor doby trvání vznícení munice [Nastavte 0 pro vypnutí vznícení munice] + + Multiplier for how long 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. + Coefficient de durée des feux de véhicules.\nLa valeur 0 désactive les feux de véhicules. + Multiplicador de la duración del incendio en vehículos por la detonación inducida por calor.\nEstablecerlo a 0 deshabilita el incendio a causa de la detonación inducida por calor. - Cook-off probability coefficient - Coeficiente de probabilidad de detonación inducida por calor - 誘爆の可能性係数 - Coefficiente Probabilità Esplosione - Faktor für Wahrscheinlichkeit der Durchzündung - 殉爆發生機率係數 - 殉爆发生机率系数 - Coefficient de probabilité d'auto-inflammation - Współczynnik prawdopodobieństwa samozapłonu - Коэф. вероятности детонации - Probabilidade de Cozinhar - Koeficient pravděpodobnosti vznícení munice - 쿡오프 발생 확률 계수 + Vehicle cook-off fire probability multiplier + 車両の誘爆火災の可能性倍率 + Возможность усиления пожара при детонации техники + 차량 유폭 화재 확률 계수 + Probabilità di incendio dei veicoli + Fahrzeug Munitionsbrand Wahrscheinlichkeit-Multiplikator + Probabilité d'incendies de véhicules + Multiplicador de la probabilidad de incendio a causa de la detonación inducida por calor - Multiplier for cook-off probability. Higher value results in higher cook-off probability - Multiplicador de probabilidad de detonación inducida por calor. Valores más altos producen mayor probabilidad - 誘爆する可能性の乗数。高い値では誘爆する可能性が高まります。 - Moltiplicatore per la probabilità dell'esplosione di munizioni. Un valore più alto aumenta la probabilità. - Faktor für Wahrscheinlichkeit der Durchzündung. Ein höherer Wert führt zu höherer Durchzündungswahrscheinlichkeit. - 調整殉爆發生機率係數。值越高代表越容易發生殉爆 - 调整殉爆发生机率系数。值越高代表越容易发生殉爆。 - Multiplicateur de probabilité de l'auto-inflammation. Plus la valeur est élevée, plus la probabilité de combustion est grande. - Mnożnik prawdopodobieństwa samozapłonu. Większa wartość oznacza większe prawdopodobieństwo samozapłonu - Множитель коэффициента вероятности детонации. Чем выше значение, тем выше вероятность - Multiplicador para a chance de cozinhamento. Valores mais altos aumentam as chances de ocorrer. - Multiplikátor pro pravděpodobnost vznícení munice. Vyšší hodnota znamená vyšší šanci vznícení munice. - 쿡오프가 일어날 확률에 계수를 곱합니다. 더 큰 숫자는 더 높은 확률의 쿡오프를 일으킵니다. + Multiplier for vehicle cook-off fire probability. Higher value results in higher cook-off fire 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. + Coefficient de probabilité des incendies de véhicules.\nLes valeurs élevées augmentent la probabilité des incendies.\nLa valeur 0 désactive les incendies de véhicules. + Multiplicador de la probabilidad de incendio a causa de la detonación inducida por calor. Valores más altos resultan en mayor probabilidad de incendio a causa de la detonación inducida por calor.\nEstablecerlo a 0 deshabilita el incendio a causa de la detonación inducida por calor. - Destroy Vehicles After Cook-off - 쿡오프 후 차량 파괴 + Destroy vehicles after cook-off + 유폭 후 차량 파괴 殉爆发生后摧毁载具 Уничтожать технику после детонации Destruir vehículos tras la detonación inducida por calor @@ -181,40 +91,102 @@ 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 Cook-Off Vehicle Fire - 誘爆火災を有効化 - Véhicules - Feu durant l'auto-inflammation - Вкл. горение техники от детонации - Aktiviert das in Brand setzen des Fahrzeugs während des Durchzündens der Munition - Abilita incendiamento veicoli - Włącz pożar pojazdu podczas samozapłonu - 启用殉爆载具火灾 - 차량 쿡오프 화재 활성화 - Habilitar incendio a causa de la detonación inducida por calor - Ativar incêndio de veículo durante cozinhamento + + Enable vehicle ammo cook-off + 車両弾薬の誘爆を有効化 + Вкл. детонацию боеприпасов в технике. + 차량 내 탄약 유폭 활성화 + Abilita esplosioni delle munizioni dei veicoli + Aktiviert Fahrzeug Munitionsdurchzündung + Permet l'explosion des munitions des véhicules + Habilitar detonación inducida por calor de la munición del vehículo - - Whether or not vehicles will catch on fire during cook-off - 誘爆により車両が炎上するかどうかを設定します。 - Définit si les véhicules prennent feu durant l'auto-inflammation de leurs munitions. - Будет ли техника гореть при детонации боеприпасов - Ob Fahrzeuge in Brand gesetzt werden, während deren Munition durchzündet. - Determina se veicoli cominceranno a bruciare se le loro munizioni esplodono. - Określa, czy pojazdy zapalą się podczas samozapłonu ich amunicji. - 车辆在殉爆过程中是否会起火 - 쿡오프가 일어나면 차량에 불이 붙습니다. - Define si los vehículos salen ardiendo despues de una detonación inducida por calor. - Define se os veículos pegarão fogo durante o cozinhamento. + + 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. + Permet l'explosion des munitions du véhicule. Tire des morceaux de munitions si le véhicule a encore des munitions restantes.\nIl n'y a pas d'effets de feu. + Habilita la detonación inducida por calor de la munición del vehículo. Dispara la munición del vehículo mientras el vehículo disponga de munición restante.\nEsto no incluye los efectos a causa de incendio. + + + 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. + Permet l'explosion des caisses de munitions.\nN'inclut pas les effets de feu. + Habilita la detonación inducida por calor de las cajas de munición.\nEsto no incluye los efectos a causa de incendio. + + + Ammo cook-off duration multiplier + 弾薬の誘爆の持続時間倍率 + Увеличение продолжительности детонации боеприпасов. + 탄약 유폭 시간 계수 + Coefficiente di durata esplisioni di munizioni + Fahrzeug Munitionsdurchzündung Dauer-Multiplikator + Coefficient de durée d'explosion des munitions + Multiplicador de la duración de la detonación inducida por calor de la munición + + + 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. + Coefficient de durée d'explosion des munitions pour les véhicules et les caisses.\nLa valeur 0 désactive les explosions des véhicules et des caisses. + Multiplicador de la duración de la detonación inducida por calor de la munición, tanto para los vehículos como para las cajas de munición.\nEstablecerlo a 0 deshabilita la detonación inducida por calor tanto para los vehículos como para las cajas de munición. + + + 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. + Elimina la munición cuando se produce la detonación inducida por calor. diff --git a/addons/csw/Cfg3den.hpp b/addons/csw/Cfg3den.hpp deleted file mode 100644 index 5d15e19d6b8..00000000000 --- a/addons/csw/Cfg3den.hpp +++ /dev/null @@ -1,43 +0,0 @@ -class ctrlCombo; -class Cfg3DEN { - class Attributes { - class Default; - class Title: Default { - class Controls { - class Title; - }; - }; - class Combo: Title { - class Controls: Controls { - class Title: Title {}; - class Value; - }; - }; - class GVAR(assemblyModeControl): Combo { - class Controls: Controls { - class Title: Title {}; - class Value: Value { - class Items { - class Disable { - text = "$STR_DISABLED"; - value = 0; - }; - class Enable { - text = "$STR_CONFIG_JOYSTICK_ENABLED"; - value = 1; - }; - class EnableAndEmpty { - text = CSTRING(eden_enableAndEmpty); - value = 2; - }; - class Default { - text = "$STR_VEHICLE_DEFAULT"; - value = 3; - default = 1; - }; - }; - }; - }; - }; - }; -}; diff --git a/addons/csw/CfgMagazines.hpp b/addons/csw/CfgMagazines.hpp index 86ad73c58fc..2466bbe6967 100644 --- a/addons/csw/CfgMagazines.hpp +++ b/addons/csw/CfgMagazines.hpp @@ -58,6 +58,7 @@ class CfgMagazines { class GVAR(20Rnd_20mm_G_belt): 40Rnd_20mm_G_belt { author = ECSTRING(common,ACETeam); displayName = CSTRING(GMGBelt_displayName); + descriptionShort = CSTRING(GMGBelt_descriptionShort); model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; picture = QPATHTOF(UI\ammoBox_50bmg_ca.paa); type = 256; diff --git a/addons/csw/CfgVehicles.hpp b/addons/csw/CfgVehicles.hpp index 424289c077d..724d5ed513e 100644 --- a/addons/csw/CfgVehicles.hpp +++ b/addons/csw/CfgVehicles.hpp @@ -138,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); @@ -198,7 +197,6 @@ class CfgVehicles { class GMG_TriPod; class GMG_01_base_F: GMG_TriPod { - // ENABLE_CSW_ATTRIBUTE; class ADDON { enabled = 1; proxyWeapon = QGVAR(GMG_20mm); // Weapon Proxy (Shorter Reload Time) [CfgWeapons] @@ -232,7 +230,6 @@ class CfgVehicles { class AT_01_base_F: StaticMGWeapon { - // ENABLE_CSW_ATTRIBUTE; class ADDON { enabled = 1; proxyWeapon = QGVAR(Titan_AT_Static); @@ -246,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] @@ -262,7 +258,6 @@ class CfgVehicles { class StaticMortar: StaticWeapon {}; class Mortar_01_base_F: StaticMortar { - // ENABLE_CSW_ATTRIBUTE; class ADDON { enabled = 1; magazineLocation = ""; diff --git a/addons/csw/XEH_postInit.sqf b/addons/csw/XEH_postInit.sqf index 87196f33772..419e7013809 100644 --- a/addons/csw/XEH_postInit.sqf +++ b/addons/csw/XEH_postInit.sqf @@ -8,18 +8,32 @@ GVAR(vehicleMagCache) = createHashMap; // 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; +// Also triggered at mission start ["CBA_SettingChanged", { GVAR(quickmountEnabled) = ( missionNamespace getVariable [QEGVAR(quickmount,enabled), false] && {(missionNamespace getVariable [QEGVAR(quickmount,enableMenu), -1]) in [1,3]} ); + + // Do not allow no ammo handling when advanced assembly is enabled + // Reason: When using advanced assembly, the amount of ammo is not stored anywhere, so when you reassemble a static, it will spawn full ammo + if (GVAR(defaultAssemblyMode) && GVAR(ammoHandling) == 0) then { + if (isServer) then { + [QGVAR(ammoHandling), 2, 2, "server"] call CBA_settings_fnc_set; + }; + + // Notify everyone about change + [QEGVAR(common,displayTextStructured), [composeText [ + lineBreak, + parseText format [ + "%1", format ["%1 requires %2 to be set higher than 0.", QGVAR(defaultAssemblyMode), QGVAR(ammoHandling)] + ], + lineBreak, + parseText format ["%1", "No mission restart is required."] + ], 4]] call CBA_fnc_localEvent; + }; }] call CBA_fnc_addEventHandler; // Event handlers: diff --git a/addons/csw/config.cpp b/addons/csw/config.cpp index 98abcea5c02..aab2b0416f2 100644 --- a/addons/csw/config.cpp +++ b/addons/csw/config.cpp @@ -15,7 +15,6 @@ class CfgPatches { }; }; -#include "Cfg3den.hpp" #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" diff --git a/addons/csw/dev/checkStaticWeapons.sqf b/addons/csw/dev/checkStaticWeapons.sqf index 7d9917daa71..137dc953341 100644 --- a/addons/csw/dev/checkStaticWeapons.sqf +++ b/addons/csw/dev/checkStaticWeapons.sqf @@ -16,7 +16,7 @@ private _inherited = []; private _config = _x; private _configEnabled = (getNumber (_config >> QUOTE(ADDON) >> "enabled")) == 1; if (_configEnabled) then { - private _configExplicit = (count configProperties [_config, "configName _x == 'ace_csw'", false]) == 1; + private _configExplicit = (count configProperties [_config, toString {configName _x == QUOTE(ADDON)}, false]) == 1; if (_configExplicit) then { _explicitBases pushBack (configName _config); _inherited pushBack []; @@ -43,8 +43,8 @@ private _inherited = []; INFO("------ Logging static magazines with no carry version -------"); private _hash = createHashMap; -// private _logAll = true; // logs all possible weapon magazines (even if not used in a static weapon) -private _logAll = false; +private _logAll = false; // logs all possible weapon magazines (even if not used in a static weapon) when set to true + { private _vehicleType = configName _x; private _turretConfig = [_vehicleType, [0]] call CBA_fnc_getTurret; diff --git a/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf b/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf index 5230fccf521..f3a6bbde5f9 100644 --- a/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf +++ b/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf @@ -1,11 +1,11 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Helper function for ace_rearm; Gets magazines that should be loaded by csw + * Helper function for ace_rearm; Gets magazines that should be loaded by csw. * * Arguments: - * 0: Vehicle - * 1: Specific Turret or pass bool to check all turrets (default: true) + * 0: CSW + * 1: Specific Turret or pass bool to check all turrets (default: true) * * Return Value: * [0: compatible veh mags, 1: carry mags] diff --git a/addons/csw/functions/fnc_ai_handleFired.sqf b/addons/csw/functions/fnc_ai_handleFired.sqf index d92e517091b..4a6615f4043 100644 --- a/addons/csw/functions/fnc_ai_handleFired.sqf +++ b/addons/csw/functions/fnc_ai_handleFired.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Handles AI Fired EH + * Handles AI Fired EH. * * Arguments: * Fired EH @@ -12,6 +12,8 @@ * Public: No */ +if (GVAR(ammoHandling) != 2) exitWith {}; + params ["_vehicle", "_weapon", "", "", "", "_magazine", "", "_gunner"]; TRACE_4("firedEH:",_vehicle,_weapon,_magazine,_gunner); diff --git a/addons/csw/functions/fnc_ai_handleGetIn.sqf b/addons/csw/functions/fnc_ai_handleGetIn.sqf index f14a4ccbc7a..bbbddaf537f 100644 --- a/addons/csw/functions/fnc_ai_handleGetIn.sqf +++ b/addons/csw/functions/fnc_ai_handleGetIn.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Author: Grim - * Handles AI GetIn on an empty weapon + * Author: LinkIsGrim + * Handles AI GetIn on an empty CSW. * * Arguments: * GetIn EH @@ -12,6 +12,8 @@ * Public: No */ +if (GVAR(ammoHandling) != 2) exitWith {}; + params ["_vehicle", "", "_gunner"]; TRACE_2("getInEH:",_vehicle,_gunner); diff --git a/addons/csw/functions/fnc_ai_reload.sqf b/addons/csw/functions/fnc_ai_reload.sqf index d472233bcfa..288d718a2f7 100644 --- a/addons/csw/functions/fnc_ai_reload.sqf +++ b/addons/csw/functions/fnc_ai_reload.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* - * Author: PabstMirror, modified by Grim - * Handles AI reloading + * Author: PabstMirror, LinkIsGrim + * Handles AI reloading. * * Arguments: - * 0: Static Weapon + * 0: CSW * 1: Gunner * 2: Weapon * 3: Magazine (default: "") @@ -15,7 +15,7 @@ * Public: No */ -params ["_staticWeapon", "_gunner", "_weapon", ["_magazine", ""]]; +params ["_vehicle", "_gunner", "_weapon", ["_magazine", ""]]; private _turretPath = [_gunner] call EFUNC(common,getTurretIndex); private _reloadSource = objNull; @@ -24,7 +24,7 @@ private _reloadNeededAmmo = -1; private _cfgMagGroups = configFile >> QGVAR(groups); -private _nearSupplies = [_gunner] + ((_staticWeapon nearSupplies 10) select { +private _nearSupplies = [_gunner] + ((_vehicle nearSupplies 10) select { isNull (group _x) || {!([_x] call EFUNC(common,isPlayer)) && {[side group _gunner, side group _x] call BIS_fnc_sideIsFriendly}} }); @@ -40,7 +40,7 @@ private _nearSupplies = [_gunner] + ((_staticWeapon nearSupplies 10) select { } forEach ((magazineCargo _xSource) select {isClass (_cfgMagGroups >> _x)}); TRACE_2("",_xSource,_cswMagazines); - private _compatibleMags = [_weapon] call CBA_fnc_compatibleMagazines; + private _compatibleMags = compatibleMagazines _weapon; if (_magazine != "") then { _compatibleMags insert [0, [_magazine]]; }; @@ -49,7 +49,7 @@ private _nearSupplies = [_gunner] + ((_staticWeapon nearSupplies 10) select { private _xWeaponMag = _x; { if ((getNumber (_cfgMagGroups >> _x >> _xWeaponMag)) == 1) then { - private _loadInfo = [_staticWeapon, _turretPath, _x, _xSource] call FUNC(reload_canLoadMagazine); + private _loadInfo = [_vehicle, _turretPath, _x, _xSource] call FUNC(reload_canLoadMagazine); if (_loadInfo select 0) then { _reloadMag = _x; _reloadSource = _xSource; @@ -81,16 +81,16 @@ if (_bestAmmoToSend == -1) exitWith {ERROR("No ammo");}; [_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"); +if (!isNull(configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime")) then { + _timeToLoad = getNumber(configOf _vehicle >> 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);}; + params ["_vehicle", "_turretPath", "_gunner", "_reloadMag", "_bestAmmoToSend"]; + if ((!alive _vehicle) || {!alive _gunner} || {(_vehicle distance _gunner) > 10}) exitWith {TRACE_1("invalid state",_this);}; // Reload the static weapon - TRACE_5("calling addTurretMag event",_staticWeapon,_turretPath,_gunner,_reloadMag,_bestAmmoToSend); + TRACE_5("calling addTurretMag event",_vehicle,_turretPath,_gunner,_reloadMag,_bestAmmoToSend); [QGVAR(addTurretMag), _this] call CBA_fnc_globalEvent; -}, [_staticWeapon, _turretPath, _gunner, _reloadMag, _bestAmmoToSend], _timeToLoad] call CBA_fnc_waitAndExecute; +}, [_vehicle, _turretPath, _gunner, _reloadMag, _bestAmmoToSend], _timeToLoad] call CBA_fnc_waitAndExecute; diff --git a/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf b/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf index 57f2ce2bc8d..12d00ca44e9 100644 --- a/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf @@ -1,14 +1,14 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Checks if you can deploy a weapon on the tripod + * Checks if you can deploy a weapon on the tripod. * * Arguments: - * 0: Target Tripod - * 0: Player + * 0: Target + * 1: Player * * Return Value: - * Wether or not you can deploy the weapon + * Whether or not you can deploy the weapon * * Example: * [cursorObject, player] call ace_csw_fnc_assemble_canDeployWeapon @@ -16,9 +16,11 @@ * 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)) != "" || + {(getText (configFile >> "CfgWeapons" >> primaryWeapon _player >> QUOTE(ADDON) >> "assembleTo" >> typeOf _target)) != ""} +} diff --git a/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf b/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf index 40c6b527d39..3228373b401 100644 --- a/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf @@ -1,25 +1,23 @@ #include "..\script_component.hpp" /* * Author: tcvm - * If the CSW is mounted or in use this will not allow you to dismount the weapon + * If the CSW is mounted or in use this will not allow you to dismount the weapon. * * Arguments: - * 0: Static Weapon + * 0: CSW * * Return Value: - * Can Dismount + * Can dismount weapon * * Example: - * [cursorObject] call ace_csw_fnc_assemble_canPickupWeapon + * cursorObject call ace_csw_fnc_assemble_canPickupWeapon * * Public: No */ -params ["_staticWeapon"]; +params ["_vehicle"]; // 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??? +private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select (_vehicle getVariable [QGVAR(assemblyMode), 3]); -_assemblyMode && {_notCrewed || _deadCrew} +_assemblyMode && {alive _vehicle} && {((crew _vehicle) 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 9c2f3ef725c..e0a058a1af0 100644 --- a/addons/csw/functions/fnc_assemble_deployTripod.sqf +++ b/addons/csw/functions/fnc_assemble_deployTripod.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Deploys the tripod + * Deploys the tripod. * * Arguments: * 0: Unit @@ -10,7 +10,7 @@ * None * * Example: - * [player] call ace_csw_fnc_assemble_deployTripod + * player call ace_csw_fnc_assemble_deployTripod * * Public: No */ @@ -19,30 +19,48 @@ params ["_player"]; TRACE_1("assemble_deployTripod",_player); + // Save magazines and attachments (handle loaded launchers which can become csw like CUP Metis) + private _secondaryWeaponInfo = (getUnitLoadout _player) select 1; + private _secondaryWeaponClassname = _secondaryWeaponInfo deleteAt 0; + + // Remove empty entries + _secondaryWeaponInfo = _secondaryWeaponInfo select {_x isNotEqualTo "" && {_x isNotEqualTo []}}; + // Remove the tripod from the launcher slot - private _secondaryWeaponClassname = secondaryWeapon _player; - // handle loaded launchers which can become csw like CUP Metis - private _secondaryWeaponMagazine = secondaryWeaponMagazine _player param [0, ""]; - _player removeWeaponGlobal (secondaryWeapon _player); + _player removeWeaponGlobal _secondaryWeaponClassname; private _onFinish = { params ["_args"]; - _args params ["_player", "_secondaryWeaponClassname", "_secondaryWeaponMagazine"]; - TRACE_3("deployTripod finish",_player,_secondaryWeaponClassname,_secondaryWeaponMagazine); + _args params ["_player", "_secondaryWeaponClassname", "_secondaryWeaponInfo"]; + TRACE_3("deployTripod finish",_player,_secondaryWeaponClassname,_secondaryWeaponInfo); - private _tripodClassname = getText(configFile >> "CfgWeapons" >> _secondaryWeaponClassname >> QUOTE(ADDON) >> "deploy"); + private _tripodClassname = getText (configFile >> "CfgWeapons" >> _secondaryWeaponClassname >> QUOTE(ADDON) >> "deploy"); // Create a tripod private _cswTripod = createVehicle [_tripodClassname, [0, 0, 0], [], 0, "NONE"]; // Because the tripod can be a "full weapon" we disable any data that will allow it to be loaded _cswTripod setVariable [QGVAR(assemblyMode), 2, true]; // Explicitly set enabled&unload assembly mode and broadcast - if (_secondaryWeaponMagazine isNotEqualTo "") then { - _cswTripod setVariable [QGVAR(secondaryWeaponMagazine), _secondaryWeaponMagazine]; - }; - if (!GVAR(defaultAssemblyMode)) then { - [_cswTripod, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + + 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]; }; + // Disable vanilla assembly until FUNC(initVehicle) runs and sets the definite value + [_cswTripod, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + private _posATL = _player getRelPos [2, 0]; _posATL set [2, ((getPosATL _player) select 2) + 0.5]; @@ -65,15 +83,18 @@ private _onFailure = { params ["_args"]; - _args params ["_player", "_secondaryWeaponClassname", "_secondaryWeaponMagazine"]; - TRACE_3("deployTripod failure",_player,_secondaryWeaponClassname,_secondaryWeaponMagazine); + _args params ["_player", "_secondaryWeaponClassname", "_secondaryWeaponInfo"]; + TRACE_3("deployTripod failure",_player,_secondaryWeaponClassname,_secondaryWeaponInfo); - _player addWeaponGlobal _secondaryWeaponClassname; - if (_secondaryWeaponMagazine isNotEqualTo "") then { - _player addWeaponItem [_secondaryWeaponClassname, _secondaryWeaponMagazine, true]; - }; + // Add tripod back + [_player, _secondaryWeaponClassname] call CBA_fnc_addWeaponWithoutItems; + + // Add all attachments back + { + _player addWeaponItem [_secondaryWeaponClassname, _x, true]; + } forEach _secondaryWeaponInfo; }; - private _deployTime = getNumber(configFile >> "CfgWeapons" >> _secondaryWeaponClassname >> QUOTE(ADDON) >> "deployTime"); - [TIME_PROGRESSBAR(_deployTime), [_player, _secondaryWeaponClassname, _secondaryWeaponMagazine], _onFinish, _onFailure, localize LSTRING(PlaceTripod_progressBar)] call EFUNC(common,progressBar); + private _deployTime = getNumber (configFile >> "CfgWeapons" >> _secondaryWeaponClassname >> QUOTE(ADDON) >> "deployTime"); + [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 772cad65d4c..a0cdc102ca8 100644 --- a/addons/csw/functions/fnc_assemble_deployWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_deployWeapon.sqf @@ -1,39 +1,59 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Deploys the current CSW + * Deploys the current CSW. * * Arguments: - * 0: Unit + * 0: Target + * 1: Player + * 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 }; - TRACE_3("assemble_deployWeapon_carryWeaponClassname",_tripod,_player,_carryWeaponClassname); + params ["_tripod", "_player"]; private _tripodClassname = typeOf _tripod; - _player removeWeaponGlobal _carryWeaponClassname; + private _assembledClassname = getText (configFile >> "CfgWeapons" >> secondaryWeapon _player >> QUOTE(ADDON) >> "assembleTo" >> _tripodClassname); + private _index = 1; + + if (_assembledClassname == "") then { + _assembledClassname = getText (configFile >> "CfgWeapons" >> primaryWeapon _player >> QUOTE(ADDON) >> "assembleTo" >> _tripodClassname); + _index = 0; + }; - 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);}; + // Save magazines and attachments (handle loaded launchers which can become csw like CUP Metis) + private _carryWeaponInfo = (getUnitLoadout _player) select _index; + private _carryWeaponClassname = _carryWeaponInfo deleteAt 0; + + // Remove empty entries + _carryWeaponInfo = _carryWeaponInfo select {_x isNotEqualTo "" && {_x isNotEqualTo []}}; + + TRACE_3("assemble_deployWeapon_carryWeaponClassname",_tripod,_player,_carryWeaponClassname); + + _player removeWeaponGlobal _carryWeaponClassname; + + private _deployTime = getNumber (configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "deployTime"); + TRACE_4("",_carryWeaponClassname,_tripodClassname,_assembledClassname,_deployTime); private _onFinish = { params ["_args"]; - _args params ["_tripod", "_player", "_assembledClassname"]; + _args params ["_tripod", "_player", "_assembledClassname", "_tripodClassname", "_carryWeaponClassname", "_carryWeaponInfo"]; TRACE_3("deployWeapon finish",_tripod,_player,_assembledClassname); + private _secondaryWeaponMagazines = _tripod getVariable [QGVAR(secondaryWeaponMagazines), []]; + private _tripodPos = getPosATL _tripod; private _tripodDir = getDir _tripod; deleteVehicle _tripod; @@ -41,13 +61,30 @@ _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", "_componentClasses", "_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 - if (!GVAR(defaultAssemblyMode)) then { - [_csw, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + _csw setVariable [QGVAR(componentClasses), _componentClasses, true]; + + { + // 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]; }; + + // Disable vanilla assembly until FUNC(initVehicle) runs and sets the definite value + [_csw, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + _csw setDir _tripodDir; _csw setPosATL _tripodPos; if ((_tripodPos select 2) < 0.5) then { @@ -55,22 +92,29 @@ }; [QGVAR(deployWeaponSucceeded), [_csw]] call CBA_fnc_localEvent; TRACE_2("csw placed",_csw,_assembledClassname); - }, [_assembledClassname, _tripodDir, _tripodPos]] call CBA_fnc_execNextFrame; + }, [_assembledClassname, [_tripodClassname, _carryWeaponClassname], _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, _tripodClassname, _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 85b13464156..f3f1fd7bfcb 100644 --- a/addons/csw/functions/fnc_assemble_deployWeaponModifier.sqf +++ b/addons/csw/functions/fnc_assemble_deployWeaponModifier.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Modifies interaction for deploying weapon + * Modifies interaction for deploying weapon. * * Arguments: * 0: Target @@ -20,9 +20,14 @@ params ["_target", "_player", "", "_actionData"]; -private _carryWeaponClassname = secondaryWeapon _player; -private _assembleTo = (getText(configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "assembleTo" >> (typeOf _target))); -private _icon = getText (configFile >> "CfgVehicles" >> _assembleTo >> "picture"); -TRACE_2("",_assembleTo,_icon); +private _tripodClassname = typeOf _target; +private _assembledClassname = getText (configFile >> "CfgWeapons" >> secondaryWeapon _player >> QUOTE(ADDON) >> "assembleTo" >> _tripodClassname); + +if (_assembledClassname == "") then { + _assembledClassname = getText (configFile >> "CfgWeapons" >> primaryWeapon _player >> QUOTE(ADDON) >> "assembleTo" >> _tripodClassname); +}; + +private _icon = getText (configFile >> "CfgVehicles" >> _assembledClassname >> "picture"); +TRACE_2("",_assembledClassname,_icon); _actionData set [2, _icon]; diff --git a/addons/csw/functions/fnc_assemble_pickupTripod.sqf b/addons/csw/functions/fnc_assemble_pickupTripod.sqf index d85f9a3f831..c09400a87f6 100644 --- a/addons/csw/functions/fnc_assemble_pickupTripod.sqf +++ b/addons/csw/functions/fnc_assemble_pickupTripod.sqf @@ -1,17 +1,17 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Picks up the tripod and adds it to the player launcher slot + * Picks up the tripod and adds it to the player launcher slot. * * Arguments: * 0: Tripod - * 1: Unit + * 1: Player * * Return Value: * None * * Example: - * [tripod, player] call ace_csw_fnc_assemble_pickupTripod + * [cursorObject, player] call ace_csw_fnc_assemble_pickupTripod * * Public: No */ @@ -20,27 +20,55 @@ params ["_tripod", "_player"]; TRACE_2("assemble_pickupTripod",_tripod,_player); - private _tripodClassname = getText(configOf _tripod >> QUOTE(ADDON) >> "disassembleTo"); - private _pickupTime = getNumber(configFile >> "CfgWeapons" >> _tripodClassname >> QUOTE(ADDON) >> "pickupTime"); + private _tripodClassname = getText (configOf _tripod >> QUOTE(ADDON) >> "disassembleTo"); + private _pickupTime = getNumber (configFile >> "CfgWeapons" >> _tripodClassname >> QUOTE(ADDON) >> "pickupTime"); private _onFinish = { params ["_args"]; _args params ["_tripod", "_player", "_tripodClassname"]; TRACE_3("assemble_pickupTripod finish",_tripod,_player,_tripodClassname); + // Save tripod position before it's deleted + private _tripodPos = getPosATL _tripod; + + // Eject dead units (all crew are dead at this point, otherwise condition would have failed), but ignore UAV units + { + if (unitIsUAV _x) then { + _tripod deleteVehicleCrew _x; + } else { + moveOut _x; + }; + } forEach (crew _tripod); + deleteVehicle _tripod; - _player addWeaponGlobal _tripodClassname; + [_player, "PutDown"] call EFUNC(common,doGesture); + + // If the player has space, give it to him + if ((alive _player) && {(secondaryWeapon _player) == ""}) exitWith { + [_player, _tripodClassname] call CBA_fnc_addWeaponWithoutItems; + }; + + // Try to find existing weapon holders + private _weaponHolder = nearestObject [_tripodPos, "WeaponHolder"]; + + // If there are none or too far away, make a new one + if (isNull _weaponHolder || {_tripodPos distance _weaponHolder > 2}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", [0, 0, 0], [], 0, "CAN_COLLIDE"]; + _weaponHolder setDir random [0, 180, 360]; + _weaponHolder setVehiclePosition [_tripodPos, [], 0, "CAN_COLLIDE"]; // Places object on surface below + }; + + _weaponHolder addWeaponCargoGlobal [_tripodClassname, 1]; }; private _condition = { params ["_args"]; - _args params ["_tripod", "_player"]; - - !(isNull _tripod) && { (secondaryWeapon _player) isEqualTo "" } + _args params ["_tripod"]; + _tripod call FUNC(canPickupTripod) }; TRACE_3("",_pickupTime,typeOf _tripod,_tripodClassname); - [TIME_PROGRESSBAR(_pickupTime), [_tripod, _player, _tripodClassname], _onFinish, {}, localize LSTRING(PickupTripod_progressBar), _condition] call EFUNC(common,progressBar); + [TIME_PROGRESSBAR(_pickupTime), [_tripod, _player, _tripodClassname], _onFinish, {}, LLSTRING(PickupTripod_progressBar), _condition] call EFUNC(common,progressBar); }, _this] call CBA_fnc_execNextFrame; diff --git a/addons/csw/functions/fnc_assemble_pickupWeapon.sqf b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf index 440fd31cc0b..023143710b6 100644 --- a/addons/csw/functions/fnc_assemble_pickupWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf @@ -1,60 +1,76 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Dismounts the weapon from the tripod and drops its backpack beside + * Dismounts the weapon from the tripod and drops its backpack beside. * * Arguments: - * 0: Static Weapon + * 0: CSW + * 1: Player * * Return Value: * None * * Example: - * [weapon] call ace_csw_fnc_assemble_pickupWeapon + * [cursorObject, player] call ace_csw_fnc_assemble_pickupWeapon * * Public: No */ [{ - params ["_staticWeapon", "_player"]; - TRACE_2("assemble_pickupWeapon",_staticWeapon,_player); - - private _onDisassembleFunc = getText(configOf _staticWeapon >> QUOTE(ADDON) >> "disassembleFunc"); - private _carryWeaponClassname = getText(configOf _staticWeapon >> QUOTE(ADDON) >> "disassembleWeapon"); - private _turretClassname = getText(configOf _staticWeapon >> QUOTE(ADDON) >> "disassembleTurret"); - private _pickupTime = getNumber(configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "pickupTime"); - TRACE_4("",typeOf _staticWeapon,_carryWeaponClassname,_turretClassname,_pickupTime); - if (!isClass (configFile >> "CfgWeapons" >> _carryWeaponClassname)) exitWith {ERROR_1("bad weapon classname [%1]",_carryWeaponClassname);}; + params ["_vehicle", "_player"]; + TRACE_2("assemble_pickupWeapon",_vehicle,_player); + + private _weaponConfig = configOf _vehicle >> QUOTE(ADDON); + private _componentClasses = _vehicle getVariable QGVAR(componentClasses); + + (if (!isNil "_componentClasses") then { + _componentClasses + } else { + [getText (_weaponConfig >> "disassembleTurret"), getText (_weaponConfig >> "disassembleWeapon")] + }) params ["_turretClassname", "_carryWeaponClassname"]; + + if (!isClass (configFile >> "CfgWeapons" >> _carryWeaponClassname)) exitWith { + ERROR_1("bad weapon classname [%1]",_carryWeaponClassname); + }; + // Turret classname can equal nothing if the deploy bag is the "whole" weapon. e.g Kornet, Metis, other ATGMs - if ((_turretClassname isNotEqualTo "") && {!isClass (configFile >> "CfgVehicles" >> _turretClassname)}) exitWith {ERROR_1("bad turret classname [%1]",_turretClassname);}; + if ((_turretClassname != "") && {!isClass (configFile >> "CfgVehicles" >> _turretClassname)}) exitWith { + ERROR_1("bad turret classname [%1]",_turretClassname); + }; + + private _onDisassembleFunc = getText (_weaponConfig >> "disassembleFunc"); + + private _pickupTime = getNumber (configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "pickupTime"); + TRACE_4("",typeOf _vehicle,_carryWeaponClassname,_turretClassname,_pickupTime); private _onFinish = { params ["_args"]; - _args params ["_staticWeapon", "_player", "_carryWeaponClassname", "_turretClassname", "_onDisassembleFunc"]; - TRACE_4("disassemble finish",_staticWeapon,_player,_carryWeaponClassname,_turretClassname); + _args params ["_vehicle", "_player", "_carryWeaponClassname", "_turretClassname", "_onDisassembleFunc"]; + TRACE_4("disassemble finish",_vehicle,_player,_carryWeaponClassname,_turretClassname); - private _weaponPos = getPosATL _staticWeapon; - _weaponPos set [2, (_weaponPos select 2) + 0.1]; - private _weaponDir = getDir _staticWeapon; + private _weaponPos = (getPosATL _vehicle) vectorAdd [0, 0, 0.1]; + private _weaponDir = getDir _vehicle; - private _carryWeaponMag = ""; - private _carryWeaponMags = getArray (configFile >> "CfgWeapons" >> _carryWeaponClassname >> "magazines") apply {toLower _x}; + private _carryWeaponMag = []; + private _carryWeaponMags = compatibleMagazines _carryWeaponClassname; LOG("remove ammo"); { _x params ["_xMag", "", "_xAmmo"]; if (_xAmmo == 0) then {continue}; private _carryMag = _xMag call FUNC(getCarryMagazine); - if (_carryWeaponMag isEqualTo "" && {toLower _carryMag in _carryWeaponMags}) then { + if (_carryWeaponMag isEqualTo [] && {_carryMag in _carryWeaponMags}) then { TRACE_3("Adding mag to secondary weapon",_xMag,_xAmmo,_carryMag); - _carryWeaponMag = _carryMag; - DEC(_xAmmo); + _carryWeaponMag = [_carryMag, _xAmmo]; + + // Do not return this magazine, as it will be put into the weapon + continue; }; if ((_xAmmo > 0) && {_carryMag != ""}) then { TRACE_2("Removing ammo",_xMag,_carryMag); [_player, _carryMag, _xAmmo] call FUNC(reload_handleReturnAmmo); }; - } forEach (magazinesAllTurrets _staticWeapon); + } forEach (magazinesAllTurrets _vehicle); if (_turretClassname isNotEqualTo "") then { private _cswTripod = createVehicle [_turretClassname, [0, 0, 0], [], 0, "NONE"]; @@ -66,39 +82,66 @@ _cswTripod setVelocity [0, 0, -0.05]; _cswTripod setVectorUp (surfaceNormal _weaponPos); }, [_cswTripod, _weaponDir, _weaponPos]] call CBA_fnc_execNextFrame; - [_cswTripod, _staticWeapon] call (missionNamespace getVariable _onDisassembleFunc); + [_cswTripod, _vehicle] call (missionNamespace getVariable _onDisassembleFunc); }; [{ - params ["_player", "_weaponPos", "_carryWeaponClassname", "_carryWeaponMag"]; - if ((alive _player) && {(secondaryWeapon _player) == ""}) exitWith { - _player addWeapon _carryWeaponClassname; - if (_carryWeaponMag isNotEqualTo "") then { + params ["_player", "_weaponPos", "_carryWeaponClassname", "_carryWeaponMag", "_turretClassname"]; + + private _carryWeaponType = _carryWeaponClassname call EFUNC(common,getWeaponType); + + if !(_carryWeaponType in [1, 2]) exitWith { + ERROR_1("bad carry weapon type [%1]",_carryWeaponClassname); + + if (_carryWeaponMag isEqualTo []) exitWith {}; + + // Return the ammo, so it doesn't vanish + [_player, _carryWeaponMag select 0, _carryWeaponMag select 1] call FUNC(reload_handleReturnAmmo); + }; + + // Give the weapon to the player if possible + if ((alive _player) && {([primaryWeapon _player, secondaryWeapon _player] select (_carryWeaponType - 1)) == ""}) exitWith { + [_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]; - if (_carryWeaponMag isEqualTo "") then { - _weaponHolder addWeaponCargoGlobal [_carryWeaponClassname, 1]; + _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 { + _vehicle deleteVehicleCrew _x; } else { - _weaponHolder addWeaponWithAttachmentsCargoGlobal [[_carryWeaponClassname, "", "", "", [_carryWeaponMag, 1], [], ""], 1]; + moveOut _x; }; - }, [_player, _weaponPos, _carryWeaponClassname, _carryWeaponMag]] call CBA_fnc_execNextFrame; + } forEach (crew _vehicle); - LOG("delete weapon"); - deleteVehicle _staticWeapon; + deleteVehicle _vehicle; LOG("end"); }; private _condition = { params ["_args"]; - _args params ["_staticWeapon"]; - ((crew _staticWeapon) isEqualTo []) && (alive _staticWeapon) + _args params ["_vehicle"]; + + _vehicle 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), [_vehicle, _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 index 8969758e4d4..9eb7f0a133a 100644 --- a/addons/csw/functions/fnc_canDeployTripod.sqf +++ b/addons/csw/functions/fnc_canDeployTripod.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Checks if the unit can deploy a tripod + * Checks if the player can deploy the tripod. * * Arguments: - * 0: Unit + * 0: Player * * Return Value: * Can deploy @@ -15,8 +15,8 @@ * Public: No */ -params ["_unit"]; +params ["_player"]; -private _secondaryWeapon = secondaryWeapon _unit; +private _secondaryWeapon = secondaryWeapon _player; _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 16446c4fb23..9e017c16ef0 100644 --- a/addons/csw/functions/fnc_canGetIn.sqf +++ b/addons/csw/functions/fnc_canGetIn.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Checks if it's possible to get in the CSW + * Checks if it's possible to get in the CSW. * * Arguments: - * 0: Vehicle + * 0: CSW * * Return Value: * None diff --git a/addons/csw/functions/fnc_canPickupTripod.sqf b/addons/csw/functions/fnc_canPickupTripod.sqf index 0a9f0f5f90f..bf25b5a9e87 100644 --- a/addons/csw/functions/fnc_canPickupTripod.sqf +++ b/addons/csw/functions/fnc_canPickupTripod.sqf @@ -1,21 +1,20 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Checks if the unit can pickup the tripod + * Checks if the player can pickup the tripod. * * Arguments: * 0: Tripod - * 1: Unit * * Return Value: * Can pickup * * Example: - * [cursorObject, player] call ace_csw_fnc_canPickupTripod + * cursorObject call ace_csw_fnc_canPickupTripod * * Public: No */ -params ["_tripod", "_unit"]; +params ["_tripod"]; -((secondaryWeapon _unit) == "") && {alive _tripod} // return +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 index 81e07c6f103..3d94ca2fe1c 100644 --- a/addons/csw/functions/fnc_getCarryMagazine.sqf +++ b/addons/csw/functions/fnc_getCarryMagazine.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror, Dystopian - * Gets magazine that the player can carry, suitable to vehicle magazine + * Gets magazine that the player can carry, suitable to vehicle magazine. * * Arguments: * 0: Vehicle Magazine diff --git a/addons/csw/functions/fnc_getLoadActions.sqf b/addons/csw/functions/fnc_getLoadActions.sqf index 456362a3b68..59b368b3686 100644 --- a/addons/csw/functions/fnc_getLoadActions.sqf +++ b/addons/csw/functions/fnc_getLoadActions.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Gets sub actions for what the unit can load into the CSW + * Gets sub actions for what the player can load into the CSW. * * Arguments: - * 0: Vehicle + * 0: CSW * 1: Unit * * Return Value: @@ -32,10 +32,11 @@ private _condition = { params ["_target", "_player", "_args"]; _args params ["_carryMag", "_turretPath", "", "_magSource"]; - ([_target, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) select 0 + [_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew) && + {([_target, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) select 0} }; -private _cfgMagazines = configFile >> "CfgMagazines"; // micro-optimization +private _cfgMagazines = configFile >> "CfgMagazines"; // Micro-optimization private _actions = []; { _x params ["_carryMag", "", "_loadInfo"]; @@ -44,9 +45,9 @@ private _actions = []; private _displayName = getText (_cfgMagazines >> _carryMag >> "displayName"); private _picture = getText (_cfgMagazines >> _carryMag >> "picture"); private _text = if (_isBeltLinking) then { - format [localize LSTRING(actionLink), _displayName]; + format [LLSTRING(actionLink), _displayName]; } else { - format [localize LSTRING(loadX), _displayName]; + format [LLSTRING(loadX), _displayName]; }; private _action = [format ["load_%1", _forEachIndex], _text, _picture, _statement, _condition, {}, _x] call EFUNC(interact_menu,createAction); diff --git a/addons/csw/functions/fnc_getUnloadActions.sqf b/addons/csw/functions/fnc_getUnloadActions.sqf index 32d9cc091a2..1c7b629ebcc 100644 --- a/addons/csw/functions/fnc_getUnloadActions.sqf +++ b/addons/csw/functions/fnc_getUnloadActions.sqf @@ -23,20 +23,22 @@ private _statement = { TRACE_5("starting unload",_target,_turretPath,_player,_carryMag,_vehMag); private _timeToUnload = 1; - if (!isNull (configOf _target >> QUOTE(ADDON) >> "ammoUnloadTime")) then { - _timeToUnload = getNumber (configOf _target >> QUOTE(ADDON) >> "ammoUnloadTime"); + private _config = configOf _target >> QUOTE(ADDON) >> "ammoUnloadTime"; + if (!isNull _config) then { + _timeToUnload = getNumber _config; }; [ TIME_PROGRESSBAR(_timeToUnload), [_target, _turretPath, _player, _carryMag, _vehMag], { + //IGNORE_PRIVATE_WARNING ["_player"]; (_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")], + format [LLSTRING(unloadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")], {(_this select 0) call FUNC(reload_canUnloadMagazine)}, ["isNotInside"] ] call EFUNC(common,progressBar); @@ -45,7 +47,9 @@ private _statement = { private _condition = { params ["_target", "_player", "_args"]; _args params ["_vehMag", "_turretPath", "_carryMag"]; - [_target, _turretPath, _player, _carryMag, _vehMag] call FUNC(reload_canUnloadMagazine) + + [_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew) && + {[_target, _turretPath, _player, _carryMag, _vehMag] call FUNC(reload_canUnloadMagazine)} }; private _actions = []; diff --git a/addons/csw/functions/fnc_initVehicle.sqf b/addons/csw/functions/fnc_initVehicle.sqf index ed882e435c0..1c4660260fd 100644 --- a/addons/csw/functions/fnc_initVehicle.sqf +++ b/addons/csw/functions/fnc_initVehicle.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Initializes CSW systems on vehicle + * Initializes CSW systems on vehicle. * * Arguments: * 0: Vehicle @@ -34,30 +34,33 @@ if (_configEnabled && {GVAR(ammoHandling) == 2}) then { }; 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]; + +if (_vehicle turretLocal [0]) then { + // Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default] + private _assemblyModeIndex = _vehicle getVariable [QGVAR(assemblyMode), 3]; + private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select _assemblyModeIndex; + + TRACE_2("turretLocal",_vehicle,_assemblyMode); + + // If turret is local, handle unloading mags and proxy weapons + if (_configEnabled) then { + TRACE_2("config enabled",_vehicle,_assemblyMode); + 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]); + if (!_assemblyMode) exitWith {}; + + [_vehicle, _emptyWeapon] call FUNC(staticWeaponInit_unloadExtraMags); + }; + + if (_assemblyConfig) then { 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 + // Disable vanilla assembly if assemblyMode enabled + // Need to wait to allow setting object vars during assembly, but since this function runs 1 second after vehicle init, it can run immediately + [_vehicle, "disableWeaponAssembly", QUOTE(ADDON), _assemblyMode] call EFUNC(common,statusEffect_set); + }; }; // Add interactions for players @@ -66,7 +69,7 @@ if (hasInterface && {!(_typeOf in GVAR(initializedStaticTypes))}) then { 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); + 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); }; @@ -78,7 +81,7 @@ if (hasInterface && {!(_typeOf in GVAR(initializedStaticTypes))}) then { 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 = { + private _childrenCode = { BEGIN_COUNTER(getActions); // can remove for final release private _ret = (call FUNC(getLoadActions)) + (call FUNC(getUnloadActions)); END_COUNTER(getActions); @@ -86,17 +89,25 @@ if (hasInterface && {!(_typeOf in GVAR(initializedStaticTypes))}) then { }; 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); + private _ammoAction = [QGVAR(magazine), LLSTRING(AmmoHandling_displayName), "", {}, _condition, _childrenCode, [], _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); + private _ammoAction = [QGVAR(magazine), LLSTRING(AmmoHandling_displayName), "", {}, _condition, _childrenCode] 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); + + // Replace existing check ammo interaction with one that takes into account if the magazine actions are available + private _checkAmmoAction = [QEGVAR(reload,CheckAmmo), LELSTRING(reload,checkAmmo), "", EFUNC(reload,checkAmmo), { + if !((GVAR(ammoHandling) == 0) && {!([false, true, true, GVAR(defaultAssemblyMode)] select (_target getVariable [QGVAR(assemblyMode), 3]))}) exitWith { false }; + _this call EFUNC(reload,canCheckAmmo) + }] call EFUNC(interact_menu,createAction); + [_typeOf, 0, ["ACE_MainActions"], _checkAmmoAction] call EFUNC(interact_menu,addActionToClass); + + // Add another check ammo action to the ammo handling point + _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 fedd1d412b3..47897c43c22 100644 --- a/addons/csw/functions/fnc_proxyWeapon.sqf +++ b/addons/csw/functions/fnc_proxyWeapon.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: tcvm, PabstMirror - * Handles the use of proxy weapons to bypass engine reload times + * Handles the use of proxy weapons to fix engine-reload times. * * Arguments: - * 0: Vehicle + * 0: CSW * 1: Turret * 2: Proxy weapon needed * 2: Weapon should be emptied @@ -21,6 +21,11 @@ params ["_vehicle", "_turret", "_needed", "_emptyWeapon"]; TRACE_4("proxyWeapon",_vehicle,_turret,_needed,_emptyWeapon); +// addWeaponTurret/removeWeaponTurret need to be executed where turret is local +if !(_vehicle turretLocal _turret) exitWith { + WARNING_2("[%1]'s turret [%2] isn't local, skipping proxy weapon change",_vehicle,_turret); +}; + if (_vehicle getVariable [format [QGVAR(proxyHandled_%1), _turret], false]) exitWith { TRACE_1("already handled",typeOf _vehicle); }; private _proxyWeapon = getText (configOf _vehicle >> QUOTE(ADDON) >> "proxyWeapon"); diff --git a/addons/csw/functions/fnc_reload_canLoadMagazine.sqf b/addons/csw/functions/fnc_reload_canLoadMagazine.sqf index 70c673299af..d4049706bdb 100644 --- a/addons/csw/functions/fnc_reload_canLoadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_canLoadMagazine.sqf @@ -1,16 +1,16 @@ #include "..\script_component.hpp" /* - * Author: PabstMirror &tcvm - * Tests if unit can load a magazine into a static weapon. + * Author: PabstMirror, tcvm + * Tests if unit can load a magazine into a CSW. * * Arguments: - * 0: Static Weapon + * 0: CSW * 1: Turret Path * 2: Carryable Magazine - * 3: Supplier + * 3: Supplier (default: objNull) * * Return Value: - * [CanLoad, LoadedMag, AmmoNeeded, IsBeltLinking] + * [Can Load , Loaded Mag , Ammo Needed , Is Belt Linking ] * * Example: * [cursorObject, [0], "ACE_csw_100Rnd_127x99_mag_red", player] call ace_csw_fnc_reload_canLoadMagazine @@ -28,7 +28,7 @@ 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 + {!((_magSource isKindOf "Bag_Base") || {_magSource isKindOf "ContainerSupply"})} && // Hacky workaround for magazines within dropped backpacks { ((_vehicle distance _magSource) > 10) || {((magazineCargo _magSource) findIf {_x == _carryMag}) == -1} @@ -42,7 +42,7 @@ 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 (_cfgMagazinesCarryMag >> "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; @@ -62,7 +62,7 @@ scopeName "main"; }; private _maxMagazineAmmo = _desiredAmmo min getNumber (_cfgMagazines >> _xMag >> "count"); if (_xAmmo >= _maxMagazineAmmo) exitWith { - [false, _loadedMag, -6, false] breakOut "main"; // Already at capicity + [false, _loadedMag, -6, false] breakOut "main"; // Already at capacity }; _ammoNeeded = _maxMagazineAmmo - _xAmmo; _isBeltLinking = true; diff --git a/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf b/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf index 4e03625a294..d7899e655a6 100644 --- a/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Tests if unit can unload a magazine from a static weapon. + * Tests if unit can unload a magazine from a CSW. * * Arguments: - * 0: Static Weapon + * 0: CSW * 1: Turret Path * 2: Player * 3: Carryable Magazine diff --git a/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf index 933625fb890..861f70350d1 100644 --- a/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf +++ b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf @@ -1,15 +1,15 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Gets magazines that the player is carrying that can be loaded into the static weapon + * Gets nearby magazines that can be loaded into the CSW. * * Arguments: - * 0: Vehicle - * 1: Player + * 0: CSW + * 1: Unit * * Return Value: * Mags - * [Carry Magazine , Turret Path , Load Info , Magazine Source ] + * [Carry Magazine , Turret Path , Load Info , Magazine Source ] * * Example: * [cursorObject, player] call ace_csw_fnc_reload_getLoadableMagazines @@ -70,7 +70,7 @@ private _return = []; ) exitWith { _return pushBack [_carryMag, _turretPath, _loadInfo, _magSource]; }; - } forEach ([_weapon] call CBA_fnc_compatibleMagazines); + } forEach (compatibleMagazines _weapon); } forEach _availableMagazines; } forEach (_vehicle weaponsTurret _turretPath); } forEach (allTurrets _vehicle); diff --git a/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf b/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf index 6b5b77efeec..24d21534ee2 100644 --- a/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf +++ b/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf @@ -4,7 +4,7 @@ * Finds the best vehicle magazines to create from a carryable magazine for a given weapon. * * Arguments: - * 0: Vehicle + * 0: CSW * 1: Turret * 2: Magazine that is carryable * @@ -37,7 +37,7 @@ private _bestMagCount = -1; _bestMagCount = _xAmmo; }; }; - } forEach (getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines")); + } forEach (compatibleMagazines _weapon); } forEach (_vehicle weaponsTurret _turret); TRACE_3("best fit",_desiredAmmo,_bestMag,_bestMagCount); diff --git a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf index e5aa51d3429..389ae699a4a 100644 --- a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf @@ -1,16 +1,16 @@ #include "..\script_component.hpp" /* * Author: tcvm, PabstMirror - * Handles adding ammo to a turret - * Called from a global event but only runs where turret is local + * Handles adding ammo to a turret. + * Called from a global event but only runs where turret is local. * * Arguments: - * 0: Static Weapon + * 0: CSW * 1: Turret Path * 2: Source of magazine * 3: Vehicle Magazine * 4: Ammo in magazine - * 5: Unit or object to return ammo to + * 5: Unit or object to return ammo to (default: Source of magazine) * * Return Value: * None @@ -21,11 +21,12 @@ * Public: No */ -params ["_vehicle", "_turret", "_magSource", "_carryMag", "_ammoReceived", ["_returnTo", _magSource]]; +params ["_vehicle", "_turret", "_magSource", "_carryMag", "_ammoReceived"]; +private _returnTo = param [5, _magSource]; TRACE_6("reload_handleAddTurretMag",_vehicle,_turret,_magSource,_carryMag,_ammoReceived,_returnTo); TRACE_2("",local _vehicle,_vehicle turretLocal _turret); -if (!(_vehicle turretLocal _turret)) exitWith {}; +if !(_vehicle turretLocal _turret) exitWith {}; ([_vehicle, _turret, _carryMag] call FUNC(reload_canLoadMagazine)) params ["_canAdd", "_loadedMag", "_neededAmmo", "_isBeltLinking"]; TRACE_4("canLoad",_canAdd,_loadedMag,_neededAmmo,_isBeltLinking); diff --git a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf index 59d948ba279..dccc9b16d4c 100644 --- a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf @@ -1,13 +1,13 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Handles removing ammo from a turret - * Called from a global event but only runs where turret is local + * Handles removing ammo from a turret. + * Called from a global event but only runs where turret is local. * * Arguments: - * 0: Static Weapon + * 0: CSW * 1: Turret Path - * 2: Magainze Unit Can Carry + * 2: Magazine Unit Can Carry * 3: Magazine To Remove From Static * 4: Unit or container to unload to * @@ -24,7 +24,7 @@ params ["_vehicle", "_turretPath", "_carryMag", "_vehMag", "_unloadTo"]; TRACE_5("removeTurretMag EH",_vehicle,_turretPath,_carryMag,_vehMag,_unloadTo); TRACE_3("",local _vehicle,_vehicle turretLocal _turretPath,local _unloadTo); -if (!(_vehicle turretLocal _turretPath)) exitWith {}; +if !(_vehicle turretLocal _turretPath) exitWith {}; private _magsInWeapon = []; // Check how much ammo it has now: { diff --git a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf index da8383b6085..009a39c0d10 100644 --- a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf +++ b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Author: tcvm and PabstMirror - * Handles returned ammo (either from unloading or leftovers from linking) + * Author: tcvm, PabstMirror + * Handles returned ammo (either from unloading or leftovers from linking). * * Arguments: * 0: Man or Vehicle @@ -18,13 +18,15 @@ */ params ["_unloadTo", "_carryMag", "_ammo"]; -TRACE_3("reload_handleReturnAmmo",_unloadTo,_carryMag,_ammo); +TRACE_4("reload_handleReturnAmmo",_unloadTo,typeOf _unloadTo,_carryMag,_ammo); private _carryMaxAmmo = getNumber (configFile >> "CfgMagazines" >> _carryMag >> "count"); private _fullMagazines = floor (_ammo / _carryMaxAmmo); private _bulletsRemaining = _ammo % _carryMaxAmmo; -if (_unloadTo isKindOf "CaManBase") then { +private _unloadToUnit = _unloadTo isKindOf "CAManBase"; + +if (_unloadToUnit) then { while {(_fullMagazines > 0) && {[_unloadTo, _carryMag] call CBA_fnc_canAddItem}} do { _unloadTo addMagazine [_carryMag, _carryMaxAmmo]; _fullMagazines = _fullMagazines - 1; @@ -37,19 +39,21 @@ if (_unloadTo isKindOf "CaManBase") then { if ((_fullMagazines == 0) && {_bulletsRemaining == 0}) exitWith {}; -// Try to use existing container -private _container = _unloadTo getVariable [QGVAR(container), objNull]; -if ((_container distance _unloadTo) > 10) then { _container = objNull; }; -if (isNull _container) then { - _container = (nearestObjects [_unloadTo, [QGVAR(ammo_holder), "GroundWeaponHolder"], 10]) param [0, objNull]; +// Try to use object inventory or existing container +private _container = [_unloadTo, objNull] select _unloadToUnit; +if ((maxLoad _container) isEqualTo 0) then { + _container = _unloadTo getVariable [QGVAR(container), objNull]; + if ((_container distance _unloadTo) > 10) then { _container = objNull; }; + if (isNull _container) then { + _container = (nearestObjects [_unloadTo, [["GroundWeaponHolder"], [QGVAR(ammo_holder)]] select GVAR(handleExtraMagazinesType), 10]) param [0, objNull]; + }; }; - if (isNull _container) then { // Create ammo storage container private _weaponRelPos = _unloadTo getRelPos RELATIVE_DIRECTION(270); _weaponRelPos set [2, ((getPosATL _unloadTo) select 2) + 0.05]; - _container = createVehicle [["GroundWeaponHolder", QGVAR(ammo_holder)] select GVAR(handleExtraMagazinesType), [0, 0, 0], [], 0, "NONE"]; + _container = createVehicle [["GroundWeaponHolder", QGVAR(ammo_holder)] select GVAR(handleExtraMagazinesType), [0, 0, 0], [], 0, "CAN_COLLIDE"]; _unloadTo setVariable [QGVAR(container), _container, true]; _container setDir random [0, 180, 360]; _container setPosATL _weaponRelPos; @@ -59,7 +63,7 @@ if (isNull _container) then { TRACE_2("Creating NEW Container",_container,_weaponRelPos); }; -TRACE_3("adding to container",_container,_fullMagazines,_bulletsRemaining); +TRACE_4("adding to container",_container,typeOf _container,_fullMagazines,_bulletsRemaining); if (_fullMagazines > 0) then { _container addMagazineAmmoCargo [_carryMag, _fullMagazines, _carryMaxAmmo]; diff --git a/addons/csw/functions/fnc_reload_loadMagazine.sqf b/addons/csw/functions/fnc_reload_loadMagazine.sqf index 9526b5adb8b..a5a3e07c06e 100644 --- a/addons/csw/functions/fnc_reload_loadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_loadMagazine.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Loads a magazine into a static weapon from a magazine carried by or next to the player. + * Loads a magazine into a CSW from a magazine carried by or next to the player. * * Arguments: - * 0: Vehicle + * 0: CSW * 1: Turret * 2: Unit Carried Magazine * 3: Magazine source @@ -23,11 +23,12 @@ params ["_vehicle", "_turret", "_carryMag", "_magSource", "_unit"]; TRACE_5("loadMagazine",_vehicle,_turret,_carryMag,_magSource,_unit); private _timeToLoad = 1; -if (!isNull(configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime")) then { - _timeToLoad = getNumber(configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime"); +private _config = configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime"; +if (!isNull _config) then { + _timeToLoad = getNumber _config; }; -private _displayName = format [localize LSTRING(loadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")]; +private _displayName = format [LLSTRING(loadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")]; private _onFinish = { (_this select 0) params ["_vehicle", "_turret", "_carryMag", "_magSource", "_unit"]; @@ -47,12 +48,23 @@ private _onFinish = { }; } forEach (if (_magSource isKindOf "CAManBase") then {magazinesAmmo _magSource} else {magazinesAmmoCargo _magSource}); - if (_bestAmmoToSend == -1) exitWith {ERROR_2("No ammo [%1 - %2]?",_xMag,_bestAmmoToSend);}; + if (_bestAmmoToSend == -1) exitWith {ERROR_2("No ammo [%1 - %2]?",_carryMag,_bestAmmoToSend);}; [_magSource, _carryMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine); if (_bestAmmoToSend == 0) exitWith {}; - TRACE_6("calling addTurretMag event",_vehicle,_turret,_magSource,_carryMag,_bestAmmoToSend,_unit); - [QGVAR(addTurretMag), [_vehicle, _turret, _magSource, _carryMag, _bestAmmoToSend, _unit]] call CBA_fnc_globalEvent; + // Workaround for removeSpecificMagazine and WeaponHolders being deleted when empty, give back to the unit if the weapon holder was deleted + // TODO: Pass type and position of deleted object to create a new one + // TODO: Use '_magSource getEntityInfo 14' in 2.18 and the isSetForDeletion flag to execute in same frame + [{ + params ["_magSource", "_unit", "_args"]; + + if (isNull _magSource) then { + _args pushBack _unit; + }; + + TRACE_1("calling addTurretMag event",_args); + [QGVAR(addTurretMag), _args] call CBA_fnc_globalEvent; + }, [_magSource, _unit, [_vehicle, _turret, _magSource, _carryMag, _bestAmmoToSend]]] call CBA_fnc_execNextFrame; }; diff --git a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf index 23155ead0bd..975d5dbb9c2 100644 --- a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf +++ b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf @@ -1,11 +1,11 @@ #include "..\script_component.hpp" /* * Author: tcvm, PabstMirror - * Dumps ammo to container + * Dumps ammo to container. * * Arguments: - * 0: Weapon - * 1: Using advanced assembly + * 0: CSW + * 1: Empty weapon * * Return Value: * None @@ -16,11 +16,10 @@ * Public: No */ -params ["_staticWeapon", "_assemblyMode", "_emptyWeapon"]; -TRACE_3("staticWeaponInit_unloadExtraMags",_staticWeapon,_assemblyMode,_emptyWeapon); -if (!_assemblyMode) exitWith {}; +params ["_vehicle", "_emptyWeapon"]; +TRACE_2("staticWeaponInit_unloadExtraMags",_vehicle,_emptyWeapon); -private _desiredAmmo = getNumber (configOf _staticWeapon >> QUOTE(ADDON) >> "desiredAmmo"); +private _desiredAmmo = getNumber (configOf _vehicle >> QUOTE(ADDON) >> "desiredAmmo"); private _storeExtraMagazines = GVAR(handleExtraMagazines); if (_emptyWeapon) then { _desiredAmmo = 0; @@ -56,31 +55,57 @@ private _containerMagazineCount = []; } else { if ((_xMag select [0,4]) != "fake") then { WARNING_1("Unable to unload [%1] - No matching carry mag",_xMag); }; }; -} forEach (magazinesAllTurrets _staticWeapon); +} forEach (magazinesAllTurrets _vehicle); TRACE_1("Remove all loaded magazines",_magsToRemove); { - _staticWeapon removeMagazinesTurret _x; + [QEGVAR(common,removeMagazinesTurret), [_vehicle, _x select 0, _x select 1], _vehicle, _x select 1] call CBA_fnc_turretEvent; + if ((_loadedMagazineInfo select [0,2]) isEqualTo _x) then { TRACE_1("Re-add the starting mag",_loadedMagazineInfo); - _staticWeapon addMagazineTurret _loadedMagazineInfo; + + [QEGVAR(common,addMagazineTurret), [_vehicle, _loadedMagazineInfo], _vehicle, _x select 1] call CBA_fnc_turretEvent; }; } forEach _magsToRemove; -if (_staticWeapon getVariable [QGVAR(secondaryWeaponMagazine), ""] isNotEqualTo "") then { - private _secondaryWeaponMagazine = _staticWeapon getVariable QGVAR(secondaryWeaponMagazine); - private _turret = allTurrets _staticWeapon param [0, []]; - private _vehicleMag = [_staticWeapon, _turret, _secondaryWeaponMagazine] call FUNC(reload_getVehicleMagazine); - TRACE_3("Re-add previous mag",_secondaryWeaponMagazine,_turret,_vehicleMag); - if (!isClass (configFile >> "CfgMagazines" >> _vehicleMag)) exitWith {}; - _staticWeapon addMagazineTurret [_vehicleMag, _turret, 1]; - _staticWeapon setVariable [QGVAR(secondaryWeaponMagazine), nil]; +private _secondaryWeaponMagazines = _vehicle getVariable [QGVAR(secondaryWeaponMagazines), []]; + +if (_secondaryWeaponMagazines isNotEqualTo []) then { + // Check if the static weapon can take magazines + private _turret = (allTurrets _vehicle) param [0, []]; + private _compatibleMagazinesTurret = flatten ((_vehicle weaponsTurret _turret) apply {compatibleMagazines _x}); + private _container = objNull; + + { + private _vehicleMag = [_vehicle, _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 { + [QEGVAR(common,addMagazineTurret), [_vehicle, [_vehicleMag, _turret, _x select 1]], _vehicle, _turret] call CBA_fnc_turretEvent; + } else { + // Find a suitable container to place items in if necessary + if (isNull _container) then { + _container = (nearestObjects [_vehicle, ["GroundWeaponHolder"], 10]) param [0, objNull]; + + // Create ammo storage container + if (isNull _container) then { + _container = createVehicle ["GroundWeaponHolder", getPosATL _vehicle, [], 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; + + _vehicle setVariable [QGVAR(secondaryWeaponMagazines), nil, true]; }; if (_storeExtraMagazines) then { TRACE_1("saving extra mags to container",_containerMagazineCount); { - [_staticWeapon, _x, _containerMagazineCount select _forEachIndex] call FUNC(reload_handleReturnAmmo); + [_vehicle, _x, _containerMagazineCount select _forEachIndex] call FUNC(reload_handleReturnAmmo); } forEach _containerMagazineClassnames; }; diff --git a/addons/csw/initSettings.inc.sqf b/addons/csw/initSettings.inc.sqf index de3976896be..4a58ed80b03 100644 --- a/addons/csw/initSettings.inc.sqf +++ b/addons/csw/initSettings.inc.sqf @@ -1,61 +1,53 @@ -private _categoryArray = [format ["ACE %1", localize LSTRING(DisplayName)]]; +private _categoryArray = [format ["ACE %1", LLSTRING(DisplayName)]]; [ - QGVAR(defaultAssemblyMode), "CHECKBOX", + 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 + 1 // isGlobal ] call CBA_fnc_addSetting; [ - QGVAR(handleExtraMagazines), "CHECKBOX", + 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 + 1 // isGlobal ] call CBA_fnc_addSetting; [ - QGVAR(handleExtraMagazinesType), "LIST", + 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 + 1 // isGlobal ] call CBA_fnc_addSetting; [ - QGVAR(ammoHandling), "LIST", + 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 + 1 // isGlobal ] call CBA_fnc_addSetting; [ - QGVAR(progressBarTimeCoefficent), "SLIDER", + 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 + [0, 2, 1, 2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + 1 // isGlobal ] call CBA_fnc_addSetting; [ - QGVAR(dragAfterDeploy), "CHECKBOX", + QGVAR(dragAfterDeploy), + "CHECKBOX", [LSTRING(dragAfterDeploy_displayName), LSTRING(dragAfterDeploy_description)], - _categoryArray, - false, // default value - false, // isGlobal - {[QGVAR(dragAfterDeploy), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + _categoryArray ] call CBA_fnc_addSetting; diff --git a/addons/csw/script_config_macros_csw.hpp b/addons/csw/script_config_macros_csw.hpp index 1a0e1b3be54..6701159f294 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 b6f8ecb47e2..5d11773490b 100644 --- a/addons/csw/stringtable.xml +++ b/addons/csw/stringtable.xml @@ -179,7 +179,7 @@ Scorta di munizioni 탄약 보관 Magazyn amunicji - 弾薬の格納場所 + 弾薬保管位置 弹药存储 Хранилище боеприпасов Almacenamiento de munición @@ -192,7 +192,7 @@ Determina se ulteriori caricatori verranno stoccati sul suolo o in una cassa di munizioni. 여분의 탄약을 지면 또는 탄약 상자에 넣을 지 결정합니다. Decyduje, czy dodatkowe magazynki przechowywane są na ziemi, czy w skrzynce z amunicją. - 追加の弾倉を地面に配置するか、弾薬箱内に保管するかを設定します。 + 追加の弾倉を地面に直接配置するか、弾薬箱内に保管するかを設定します。 设置多余的弹夹是存放在地面上还是弹药箱内 Определяет будут ли дополнительные магазины лежать на земле или внутри хранилища Determina si los cargadores extra son almacenados en el suelo o en una caja de munición @@ -263,7 +263,7 @@ インタラクションの所要時間係数 互動時間係數 交互时间系数 - Coefficente per il tempo di interazione + Coefficiente per il tempo di interazione Koeficient času interakce Współczynnik czasu interakcji Coeficiente de tiempo de interacción @@ -672,6 +672,22 @@ [CSW] Лента 20-мм гранат для ст. гранатомёта [CSW] 20mm 고속유탄발사기 탄띠 + + Caliber: 20 mm<br/>Rounds: 20<br />Used in: Grenade Launcher + 口徑:20 mm<br/>個數:20<br />用於:榴彈發射器 + Calibre : 20 mm<br/>Munitions : 20<br />Application : lance-grenades + Calibre: 20 mm<br/>Cargas: 20<br />Se usa en: lanzagranadas + Calibro: 20 mm<br/>Munizioni: 20<br />Si usa in: lanciagranate + Kaliber: 20 mm<br/>Naboje: 20<br />Używane w: granatniku + Калибр: 20 мм<br/>Кол-во: 20<br />Применение: гранатомет + Kaliber: 20 mm<br/>Patronen: 20<br />Eingesetzt von: Granatenwerfer + Ráže: 20 mm<br/>Munice: 20<br />Použití: Granátomet + Calibre: 20 mm<br/>Balas: 20<br />Uso em: Lança-granadas + 구경: 20mm<br />탄 수: 20<br />사용 가능: 유탄발사기 + 口径:20 毫米<br/>容弹量:20<br />用于:枪榴弹发射器 + 口径:20 mm <br/>弾薬:20<br />使用:グレネードランチャー + Kalibre: 20 mm<br/>Mermi: 20<br />Kullanıldığı Yer: Bombaatar + M3 Tripod Trípode M3 @@ -1120,5 +1136,22 @@ [CSW] Сумка с СПГ-9М орудием [CSW] SPG-9M 발사기 가방 + + + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[班组\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + diff --git a/addons/dagr/XEH_postInit.sqf b/addons/dagr/XEH_postInit.sqf index 6996ced7f21..34dc9818437 100644 --- a/addons/dagr/XEH_postInit.sqf +++ b/addons/dagr/XEH_postInit.sqf @@ -30,4 +30,4 @@ GVAR(vectorConnected) = false; GVAR(noVectorData) = true; GVAR(vectorGrid) = "00000000"; -[QEGVAR(vector,rangefinderData), FUNC(handleRangeFinderData)] call CBA_fnc_addEventHandler; +[QEGVAR(vector,rangefinderData), LINKFUNC(handleRangeFinderData)] call CBA_fnc_addEventHandler; diff --git a/addons/dagr/functions/fnc_menuInit.sqf b/addons/dagr/functions/fnc_menuInit.sqf index fc05185638f..b7433b92aae 100644 --- a/addons/dagr/functions/fnc_menuInit.sqf +++ b/addons/dagr/functions/fnc_menuInit.sqf @@ -584,7 +584,7 @@ GVAR(menuRun) = true; }; GVAR(tmpUpdateRate) = 0.1 max GVAR(tmpUpdateRate) min 2.0; if (!GVAR(busy)) then { - (__dsp displayCtrl __mainText) ctrlSetText (Str(GVAR(tmpUpdateRate) * 1000) + "ms"); + (__dsp displayCtrl __mainText) ctrlSetText (str(GVAR(tmpUpdateRate) * 1000) + "ms"); (__dsp displayCtrl __F1) ctrlSetText "Save"; (__dsp displayCtrl __F3) ctrlSetText "Cancel"; }; diff --git a/addons/dagr/functions/fnc_outputData.sqf b/addons/dagr/functions/fnc_outputData.sqf index b7064ce248a..646f56d1c88 100644 --- a/addons/dagr/functions/fnc_outputData.sqf +++ b/addons/dagr/functions/fnc_outputData.sqf @@ -17,7 +17,7 @@ 135471 cutRsc ["DAGR_DISPLAY", "plain down"]; -#define __display (uiNameSpace getVariable "DAGR_DISPLAY") +#define __display (uiNamespace getVariable "DAGR_DISPLAY") #define __gridControl (__display displayCtrl 266851) #define __speedControl (__display displayCtrl 266852) @@ -62,7 +62,7 @@ GVAR(outputPFH) = [{ }; // Time - private _dagrTime = [daytime, "HH:MM"] call bis_fnc_timeToString; + private _dagrTime = [dayTime, "HH:MM"] call bis_fnc_timeToString; // Output __gridControl ctrlSetText _dagrGrid; diff --git a/addons/dagr/functions/fnc_outputVector.sqf b/addons/dagr/functions/fnc_outputVector.sqf index e9bd0ea6c38..816ed2e4b23 100644 --- a/addons/dagr/functions/fnc_outputVector.sqf +++ b/addons/dagr/functions/fnc_outputVector.sqf @@ -17,7 +17,7 @@ 135471 cutRsc ["DAGR_DISPLAY", "plain down"]; -#define __display (uiNameSpace getVariable "DAGR_DISPLAY") +#define __display (uiNamespace getVariable "DAGR_DISPLAY") #define __gridControl (__display displayCtrl 266851) #define __speedControl (__display displayCtrl 266858) @@ -36,7 +36,7 @@ if (_lazPosX < 0) then { _lazPosX = _lazPosX + 99999;}; if (_lazPosY < 0) then {_lazPosY = _lazPosY + 99999;}; // Find laser position -private _xGrid = toArray Str(round _lazPosX); +private _xGrid = toArray str(round _lazPosX); while {count _xGrid < 5} do { _xGrid = [48] + _xGrid; @@ -45,7 +45,7 @@ _xGrid resize 4; _xGrid = toString _xGrid; _xGrid = parseNumber _xGrid; -private _yGrid = toArray Str(round _lazPosY); +private _yGrid = toArray str(round _lazPosY); while {count _yGrid < 5} do { _yGrid = [48] + _yGrid; }; @@ -54,17 +54,17 @@ _yGrid = toString _yGrid; _yGrid = parseNumber _yGrid; private _xCoord = switch true do { - case (_xGrid >= 1000): { "" + Str(_xGrid) }; - case (_xGrid >= 100): { "0" + Str(_xGrid) }; - case (_xGrid >= 10): { "00" + Str(_xGrid) }; - default { "000" + Str(_xGrid) }; + case (_xGrid >= 1000): { "" + str(_xGrid) }; + case (_xGrid >= 100): { "0" + str(_xGrid) }; + case (_xGrid >= 10): { "00" + str(_xGrid) }; + default { "000" + str(_xGrid) }; }; private _yCoord = switch true do { - case (_yGrid >= 1000): { "" + Str(_yGrid) }; - case (_yGrid >= 100): { "0" + Str(_yGrid) }; - case (_yGrid >= 10): { "00" + Str(_yGrid) }; - default { "000" + Str(_yGrid) }; + case (_yGrid >= 1000): { "" + str(_yGrid) }; + case (_yGrid >= 100): { "0" + str(_yGrid) }; + case (_yGrid >= 10): { "00" + str(_yGrid) }; + default { "000" + str(_yGrid) }; }; private _dagrGrid = _xCoord + " " + _yCoord; @@ -74,7 +74,7 @@ private _elevation = floor ((_lazPosZ) + EGVAR(common,mapAltitude)); private _dagrElevation = str _elevation + "m"; // Time -private _dagrTime = [daytime, "HH:MM"] call bis_fnc_timeToString; +private _dagrTime = [dayTime, "HH:MM"] call bis_fnc_timeToString; // Bearing private _bearing = GVAR(LAZHEADING); diff --git a/addons/dagr/functions/fnc_outputWP.sqf b/addons/dagr/functions/fnc_outputWP.sqf index 27944f0bb91..bf25118c9ea 100644 --- a/addons/dagr/functions/fnc_outputWP.sqf +++ b/addons/dagr/functions/fnc_outputWP.sqf @@ -17,7 +17,7 @@ 135471 cutRsc ["DAGR_DISPLAY", "plain down"]; -#define __display (uiNameSpace getVariable "DAGR_DISPLAY") +#define __display (uiNamespace getVariable "DAGR_DISPLAY") #define __gridControl (__display displayCtrl 266851) #define __speedControl (__display displayCtrl 266858) @@ -47,18 +47,18 @@ GVAR(outputPFH) = [{ private _xGrid2 = floor (DAGR_WP_INFO / 10000); private _yGrid2 = DAGR_WP_INFO - _xGrid2 * 10000; - _xCoord2 = switch true do { - case (_xGrid2 >= 1000): { "" + Str(_xGrid2) }; - case (_xGrid2 >= 100): { "0" + Str(_xGrid2) }; - case (_xGrid2 >= 10): { "00" + Str(_xGrid2) }; - default { "000" + Str(_xGrid2) }; + private _xCoord2 = switch true do { + case (_xGrid2 >= 1000): { "" + str(_xGrid2) }; + case (_xGrid2 >= 100): { "0" + str(_xGrid2) }; + case (_xGrid2 >= 10): { "00" + str(_xGrid2) }; + default { "000" + str(_xGrid2) }; }; - _yCoord2 = switch true do { - case (_yGrid2 >= 1000): { "" + Str(_yGrid2) }; - case (_yGrid2 >= 100): { "0" + Str(_yGrid2) }; - case (_yGrid2 >= 10): { "00" + Str(_yGrid2) }; - default { "000" + Str(_yGrid2) }; + private _yCoord2 = switch true do { + case (_yGrid2 >= 1000): { "" + str(_yGrid2) }; + case (_yGrid2 >= 100): { "0" + str(_yGrid2) }; + case (_yGrid2 >= 10): { "00" + str(_yGrid2) }; + default { "000" + str(_yGrid2) }; }; _dagrGrid2 = _xCoord2 + " " + _yCoord2; diff --git a/addons/dagr/stringtable.xml b/addons/dagr/stringtable.xml index 32510520021..621440ffbac 100644 --- a/addons/dagr/stringtable.xml +++ b/addons/dagr/stringtable.xml @@ -59,7 +59,7 @@ Defense Advanced GPS Receiver Defense Advanced GPS Receiver Defense Advanced GPS Receiver - 国防のための高度なGPS受信機 (Defense Advanced GPS Receiver) + 国防のための高機能なGPS受信機 (Defense Advanced GPS Receiver) 국방 고급위성항법시스템 수신기 軍用高級防禦GPS接收器 军用高级防御 GPS 接收器 diff --git a/addons/disarming/XEH_postInit.sqf b/addons/disarming/XEH_postInit.sqf index 6944f8b146a..5b123af297a 100644 --- a/addons/disarming/XEH_postInit.sqf +++ b/addons/disarming/XEH_postInit.sqf @@ -1,4 +1,4 @@ #include "script_component.hpp" -[QGVAR(dropItems), FUNC(eventTargetStart)] call CBA_fnc_addEventHandler; -[QGVAR(debugCallback), FUNC(eventCallerFinish)] call CBA_fnc_addEventHandler; +[QGVAR(dropItems), LINKFUNC(eventTargetStart)] call CBA_fnc_addEventHandler; +[QGVAR(debugCallback), LINKFUNC(eventCallerFinish)] call CBA_fnc_addEventHandler; diff --git a/addons/disarming/functions/fnc_disarmDropItems.sqf b/addons/disarming/functions/fnc_disarmDropItems.sqf index 26e00dfa5f7..c95647b82ab 100644 --- a/addons/disarming/functions/fnc_disarmDropItems.sqf +++ b/addons/disarming/functions/fnc_disarmDropItems.sqf @@ -30,7 +30,7 @@ private _fncSumArray = { }; //Sanity Checks -if (!([_target] call FUNC(canBeDisarmed))) exitWith { +if !([_target] call FUNC(canBeDisarmed)) exitWith { [_caller, _target, "Debug: Cannot disarm target"] call FUNC(eventTargetFinish); }; if (_doNotDropAmmo && {({_x in _listOfItemsToRemove} count (magazines _target)) > 0}) exitWith { @@ -50,7 +50,7 @@ if (!_doNotDropAmmo) then { if ((_x getVariable [QGVAR(disarmUnit), objNull]) == _target) exitWith { _holder = _x; }; - } count ((getpos _target) nearObjects [DISARM_CONTAINER, 3]); + } forEach ((getPos _target) nearObjects [DISARM_CONTAINER, 3]); }; //Create a new weapon holder @@ -74,7 +74,6 @@ if (_holder getVariable [QGVAR(holderInUse), false]) exitWith { }; _holder setVariable [QGVAR(holderInUse), true]; - //Remove Magazines private _targetMagazinesStart = magazinesAmmo _target; private _holderMagazinesStart = magazinesAmmoCargo _holder; @@ -96,13 +95,13 @@ if (({((_x select 0) in _listOfItemsToRemove) && {(getNumber (configFile >> "Cfg [_caller, _target, "Debug: Didn't Remove Magazines"] call FUNC(eventTargetFinish); }; //Verify holder has mags unit had -if (!([_targetMagazinesStart, _targetMagazinesEnd, _holderMagazinesStart, _holderMagazinesEnd] call FUNC(verifyMagazinesMoved))) then { +if !([_targetMagazinesStart, _targetMagazinesEnd, _holderMagazinesStart, _holderMagazinesEnd] call FUNC(verifyMagazinesMoved)) then { _holder setVariable [QGVAR(holderInUse), false]; [_caller, _target, "Debug: Crate Magazines not in holder"] call FUNC(eventTargetFinish); }; //Remove Items, Assigned Items and NVG -private _holderItemsStart = getitemCargo _holder; +private _holderItemsStart = getItemCargo _holder; private _targetItemsStart = (assignedItems _target) + (items _target) - (weapons _target); if ((headgear _target) != "") then {_targetItemsStart pushBack (headgear _target);}; if ((goggles _target) != "") then {_targetItemsStart pushBack (goggles _target);}; @@ -132,7 +131,7 @@ private _addToCrateCount = []; _holder addItemCargoGlobal [(_addToCrateClassnames select _forEachIndex), (_addToCrateCount select _forEachIndex)]; } forEach _addToCrateClassnames; -private _holderItemsEnd = getitemCargo _holder; +private _holderItemsEnd = getItemCargo _holder; private _targetItemsEnd = (assignedItems _target) + (items _target) - (weapons _target); if ((headgear _target) != "") then {_targetItemsEnd pushBack (headgear _target);}; if ((goggles _target) != "") then {_targetItemsEnd pushBack (goggles _target);}; @@ -173,7 +172,7 @@ if (_holderIsEmpty) then { private _needToRemoveWeapon = ({_x in _listOfItemsToRemove} count (weapons _target)) > 0; private _needToRemoveMagazines = ({_x in _listOfItemsToRemove} count (magazines _target)) > 0; - private _needToRemoveBackpack = ((backPack _target) != "") && {(backPack _target) in _listOfItemsToRemove}; + private _needToRemoveBackpack = ((backpack _target) != "") && {(backpack _target) in _listOfItemsToRemove}; private _needToRemoveVest = ((vest _target) != "") && {(vest _target) in _listOfItemsToRemove}; private _needToRemoveUniform = ((uniform _target) != "") && {(uniform _target) in _listOfItemsToRemove}; @@ -193,7 +192,7 @@ if (_holderIsEmpty) then { } forEach (magazines _target); //Drop backpack (Keeps variables for ACRE/TFR) - if (_needToRemoveBackpack) then {_target action ["DropBag", _holder, (backPack _target)];}; + if (_needToRemoveBackpack) then {_target action ["DropBag", _holder, (backpack _target)];}; } else { [_pfID] call CBA_fnc_removePerFrameHandler; @@ -238,7 +237,7 @@ if (_holderIsEmpty) then { [_caller, _target, "Debug: Drop Actions Timeout"] call FUNC(eventTargetFinish); }; //If target lost disarm status: - if (!([_target] call FUNC(canBeDisarmed))) exitWith { + if !([_target] call FUNC(canBeDisarmed)) exitWith { _holder setVariable [QGVAR(holderInUse), false]; [_caller, _target, "Debug: Target cannot be disarmed"] call FUNC(eventTargetFinish); }; diff --git a/addons/disarming/functions/fnc_eventTargetStart.sqf b/addons/disarming/functions/fnc_eventTargetStart.sqf index 7173f66a76d..a7154ce2e4c 100644 --- a/addons/disarming/functions/fnc_eventTargetStart.sqf +++ b/addons/disarming/functions/fnc_eventTargetStart.sqf @@ -32,7 +32,7 @@ private _itemsToAdd = []; } forEach _listOfObjectsToRemove; { - if (!(_x in _listOfObjectsToRemove)) then { + if !(_x in _listOfObjectsToRemove) then { _listOfObjectsToRemove pushBack _x; }; } forEach _itemsToAdd; diff --git a/addons/disarming/functions/fnc_openDisarmDialog.sqf b/addons/disarming/functions/fnc_openDisarmDialog.sqf index a3762aec9f4..0054cc09fde 100644 --- a/addons/disarming/functions/fnc_openDisarmDialog.sqf +++ b/addons/disarming/functions/fnc_openDisarmDialog.sqf @@ -16,11 +16,14 @@ * * Public: No */ + params ["_caller", "_target"]; -#define DEFUALTPATH "\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa" + +#define DEFAULTPATH "\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa" + //Sanity Checks if (_caller != ACE_player) exitWith {ERROR("Player isn't caller?");}; -if (!([_player, _target] call FUNC(canPlayerDisarmUnit))) exitWith {ERROR("Can't Disarm Unit");}; +if !([_caller, _target] call FUNC(canPlayerDisarmUnit)) exitWith {ERROR("Can't Disarm Unit");}; if (dialog) then {ERROR("Dialog open when trying to open disarm dialog"); closeDialog 0;}; disableSerialization; @@ -74,8 +77,8 @@ GVAR(disarmTarget) = _target; private _rankPicture = _display displayCtrl 1203; //Show rank and name (just like BIS's inventory) - private _icon = format [DEFUALTPATH, toLower (rank _target)]; - if (_icon isEqualTo DEFUALTPATH) then {_icon = ""}; + private _icon = format [DEFAULTPATH, toLowerANSI (rank _target)]; + if (_icon isEqualTo DEFAULTPATH) then {_icon = ""}; _rankPicture ctrlSetText _icon; _playerName ctrlSetText ([GVAR(disarmTarget), false, true] call EFUNC(common,getName)); @@ -93,7 +96,7 @@ GVAR(disarmTarget) = _target; if ((_x getVariable [QGVAR(disarmUnit), objNull]) == _target) exitWith { _holder = _x; }; - } count ((getpos _target) nearObjects [DISARM_CONTAINER, 3]); + } forEach ((getPos _target) nearObjects [DISARM_CONTAINER, 3]); //If a holder exists, show it's inventory if (!isNull _holder) then { diff --git a/addons/disarming/gui_disarm.hpp b/addons/disarming/gui_disarm.hpp index 4c8ce53e6c0..b6afa26551d 100644 --- a/addons/disarming/gui_disarm.hpp +++ b/addons/disarming/gui_disarm.hpp @@ -7,13 +7,13 @@ class RscActiveText; class RscListBox; //Use the definese from -#define X_BIS(num) (num * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)) -#define Y_BIS(num) (num * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)) -#define W_BIS(num) (num * (((safezoneW / safezoneH) min 1.2) / 40)) -#define H_BIS(num) (num * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)) +#define X_BIS(num) (num * (((safeZoneW / safeZoneH) min 1.2) / 40) + (safeZoneX + (safeZoneW - ((safeZoneW / safeZoneH) min 1.2))/2)) +#define Y_BIS(num) (num * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25) + (safeZoneY + (safeZoneH - (((safeZoneW / safeZoneH) min 1.2) / 1.2))/2)) +#define W_BIS(num) (num * (((safeZoneW / safeZoneH) min 1.2) / 40)) +#define H_BIS(num) (num * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)) -#define X_MAKEITBIGGA(num) (num * (safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2)) -#define Y_MAKEITBIGGA(num) (num * (safeZoneH / 30) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2)) +#define X_MAKEITBIGGA(num) (num * (safeZoneH / 40) + (safeZoneX + (safeZoneW - safeZoneH)/2)) +#define Y_MAKEITBIGGA(num) (num * (safeZoneH / 30) + (safeZoneY + (safeZoneH - (safeZoneH / 1.2))/2)) #define W_MAKEITBIGGA(num) (num * (safeZoneH / 40)) #define H_MAKEITBIGGA(num) (num * (safeZoneH / 30)) @@ -140,9 +140,9 @@ class GVAR(remoteInventory) { }; class GroundContainer: RscListBox { idc = 632; - sizeEx = "0.8 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - sizeEx2 = "0.8 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - rowHeight = "1.75 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + sizeEx = "0.8 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; + sizeEx2 = "0.8 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; + rowHeight = "1.75 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; canDrag = 0; colorText[] = {1,1,1,1}; colorBackground[] = {0,0,0,0}; diff --git a/addons/dogtags/CfgEventHandlers.hpp b/addons/dogtags/CfgEventHandlers.hpp index 2a3f71f852d..f6503c2479b 100644 --- a/addons/dogtags/CfgEventHandlers.hpp +++ b/addons/dogtags/CfgEventHandlers.hpp @@ -3,11 +3,13 @@ class Extended_PreStart_EventHandlers { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; + class Extended_PreInit_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; + class Extended_PostInit_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); diff --git a/addons/dogtags/CfgVehicles.hpp b/addons/dogtags/CfgVehicles.hpp index cc564106998..56be52b53e2 100644 --- a/addons/dogtags/CfgVehicles.hpp +++ b/addons/dogtags/CfgVehicles.hpp @@ -4,7 +4,7 @@ class CfgVehicles { class ACE_Actions { class ACE_Dogtag { displayName = CSTRING(itemName); - condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeDogtag)); + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canCheckDogtag)); statement = ""; exceptions[] = {"isNotSwimming", "isNotInside"}; showDisabled = 0; diff --git a/addons/dogtags/CfgWeapons.hpp b/addons/dogtags/CfgWeapons.hpp index 0f795d8d08d..ac73ee68f74 100644 --- a/addons/dogtags/CfgWeapons.hpp +++ b/addons/dogtags/CfgWeapons.hpp @@ -16,8 +16,8 @@ class CfgWeapons { author = ECSTRING(common,ACETeam); scope = 0; displayName = CSTRING(itemName); - model = QUOTE(PATHTOF(data\ace_dogtag.p3d)); - picture = QUOTE(PATHTOF(data\dogtagSingle.paa)); + model = QPATHTOF(data\ace_dogtag.p3d); + picture = QPATHTOF(data\dogtagSingle.paa); class ItemInfo: CBA_MiscItem_ItemInfo { mass = 0; //too small to for 1 ? }; diff --git a/addons/dogtags/XEH_PREP.hpp b/addons/dogtags/XEH_PREP.hpp index 59176001399..9ff33a26a2a 100644 --- a/addons/dogtags/XEH_PREP.hpp +++ b/addons/dogtags/XEH_PREP.hpp @@ -1,15 +1,11 @@ - PREP(addDogtagActions); -PREP(addDogtagItem); PREP(bloodType); PREP(canCheckDogtag); PREP(canTakeDogtag); PREP(checkDogtag); -PREP(checkDogtagItem); +PREP(disableFactionDogtags); PREP(getDogtagData); PREP(getDogtagItem); -PREP(sendDogtagData); PREP(showDogtag); PREP(ssn); PREP(takeDogtag); -PREP(disableFactionDogtags); diff --git a/addons/dogtags/XEH_postInit.sqf b/addons/dogtags/XEH_postInit.sqf index f683f6f2530..ab4daf6e29e 100644 --- a/addons/dogtags/XEH_postInit.sqf +++ b/addons/dogtags/XEH_postInit.sqf @@ -1,19 +1,100 @@ #include "script_component.hpp" -[QGVAR(showDogtag), DFUNC(showDogtag)] call CBA_fnc_addEventHandler; -[QGVAR(sendDogtagData), DFUNC(sendDogtagData)] call CBA_fnc_addEventHandler; -[QGVAR(getDogtagItem), DFUNC(getDogtagItem)] call CBA_fnc_addEventHandler; -[QGVAR(addDogtagItem), DFUNC(addDogtagItem)] call CBA_fnc_addEventHandler; +if (hasInterface || isServer) then { + [QGVAR(broadcastDogtagInfo), { + GVAR(dogtagsData) set _this; + + if (isNil "CBA_fnc_renameInventoryItem") exitWith {}; // requires https://github.com/CBATeam/CBA_A3/pull/1329 + params ["_item", "_dogTagData"]; + private _name = _dogtagData param [0, ""]; -// Add actions and event handlers only if ace_medical is loaded + // If data doesn't exist or body has no name, set name as "unknown" + if (_name == "") then { + _name = LELSTRING(common,unknown); + }; + + _name = [LLSTRING(itemName), ": ", _name] joinString ""; + [_item, _name] call CBA_fnc_renameInventoryItem; + }] call CBA_fnc_addEventHandler; + + if (isServer) then { + // Sync dogtag data from server to client + [QGVAR(requestSyncDogtagDataJIP), { + params ["_clientOwner"]; + + { + [QGVAR(broadcastDogtagInfo), [_x, _y], _clientOwner] call CBA_fnc_ownerEvent; + } forEach GVAR(dogtagsData); + }] call CBA_fnc_addEventHandler; + + [QGVAR(getDogtagItem), LINKFUNC(getDogtagItem)] call CBA_fnc_addEventHandler; + } else { + // To be here, hasInterface must be true + [QGVAR(requestSyncDogtagDataJIP), clientOwner] call CBA_fnc_serverEvent; + }; +}; + +if (hasInterface) then { + // If the arsenal is loaded, show the custom names for dog tags when in the arsenal + if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(arsenal,rightPanelFilled), { + params ["_display", "_leftPanelIDC", "_rightPanelIDC"]; + + if !(_leftPanelIDC in [2010, 2012, 2014] && {_rightPanelIDC == 38}) exitWith {}; + + private _rightPanel = _display displayCtrl 15; + private _cfgWeapons = configFile >> "CfgWeapons"; + + TRACE_1("passed",_rightPanel); + + for "_i" from 0 to (lnbSize _rightPanel select 0) - 1 do { + private _item = _rightPanel lnbData [_i, 0]; + + if (_item isKindOf ["ACE_dogtag", _cfgWeapons]) then { + private _name = (GVAR(dogtagsData) getOrDefault [_item, []]) param [0, ""]; + + // If data doesn't exist or body has no name, set name as "unknown" + if (_name == "") then { + _name = LELSTRING(common,unknown); + }; + + _rightPanel lnbSetText [[_i, 1], [LLSTRING(itemName), ": ", _name] joinString ""]; + }; + }; + }] call CBA_fnc_addEventHandler; + }; + + // Add context menu option + [ + "ACE_dogtag", + ["GROUND", "CARGO", "CONTAINER"], + LLSTRING(checkItem), + nil, + QPATHTOF(data\dogtag_icon_ca.paa), + [ + {true}, + {true} + ], + { + [GVAR(dogtagsData) getOrDefault [_this select 2, []]] call FUNC(showDogtag); + + false + } + ] call CBA_fnc_addItemContextMenuOption; +}; + +// Add actions and event handlers only if ace_medical is enabled // - Adding actions via config would create a dependency -if (["ace_medical"] call EFUNC(common,isModLoaded)) then { +["CBA_settingsInitialized", { + if !(GETEGVAR(medical,enabled,false)) exitWith {}; + if (hasInterface) then { + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; private _checkTagAction = [ "ACE_CheckDogtag", - format ["%1: %2", localize LSTRING(itemName), localize LSTRING(checkDogtag)], + format ["%1: %2", LLSTRING(itemName), LLSTRING(checkDogtag)], QPATHTOF(data\dogtag_icon_ca.paa), - {[_player,_target] call FUNC(checkDogtag)}, + {[_player, _target] call FUNC(checkDogtag)}, {!isNil {_target getVariable QGVAR(dogtagData)}} ] call EFUNC(interact_menu,createAction); @@ -21,9 +102,9 @@ if (["ace_medical"] call EFUNC(common,isModLoaded)) then { private _takeTagAction = [ "ACE_TakeDogtag", - format ["%1: %2", localize LSTRING(itemName), localize LSTRING(takeDogtag)], + format ["%1: %2", LLSTRING(itemName), LLSTRING(takeDogtag)], QPATHTOF(data\dogtag_icon_ca.paa), - {[_player,_target] call FUNC(takeDogtag)}, + {[_player, _target] call FUNC(takeDogtag)}, {(!isNil {_target getVariable QGVAR(dogtagData)}) && {((_target getVariable [QGVAR(dogtagTaken), objNull]) != _target)}} ] call EFUNC(interact_menu,createAction); @@ -33,46 +114,19 @@ if (["ace_medical"] call EFUNC(common,isModLoaded)) then { if (isServer) then { ["ace_placedInBodyBag", { params ["_target", "_bodyBag", "_isGrave"]; + if (_isGrave) exitWith {}; TRACE_2("ace_placedInBodyBag eh",_target,_bodyBag); - private _dogTagData = [_target] call FUNC(getDogtagData); - _bodyBag setVariable [QGVAR(dogtagData), _dogTagData, true]; + private _dogtagData = _target call FUNC(getDogtagData); + _bodyBag setVariable [QGVAR(dogtagData), _dogtagData, true]; if ((_target getVariable [QGVAR(dogtagTaken), objNull]) == _target) then { _bodyBag setVariable [QGVAR(dogtagTaken), _bodyBag, true]; }; }] call CBA_fnc_addEventHandler; }; -}; - -// If the arsenal is loaded, show the custom names for dog tags when in the arsenal -if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { - [QEGVAR(arsenal,rightPanelFilled), { - params ["_display", "_leftPanelIDC", "_rightPanelIDC"]; - - if (_leftPanelIDC in [2010, 2012, 2014] && {_rightPanelIDC == 38}) then { - LOG("passed"); - private _rightPanel = _display displayCtrl 15; - private _allDogtags = missionNamespace getVariable [QGVAR(allDogtags), []]; - private _allDogtagsData = missionNamespace getVariable [QGVAR(allDogtagDatas), []]; - private _cfgWeapons = configFile >> "CfgWeapons"; - private _item = ""; - private _dogtagData = []; - - for "_i" from 0 to (lnbSize _rightPanel select 0) - 1 do { - _item = _rightPanel lnbData [_i, 0]; - - if (_item isKindOf ["ACE_dogtag", _cfgWeapons]) then { - _dogtagData = _allDogtagsData param [_allDogtags find _item, []]; - - // If data doesn't exist, put name as "unknown" - _rightPanel lnbSetText [[_i, 1], [LLSTRING(itemName), ": ", _dogtagData param [0, LELSTRING(common,unknown)]] joinString ""]; - }; - }; - }; - }] call CBA_fnc_addEventHandler; -}; +}] call CBA_fnc_addEventHandler; -// Disable dogtags for civilians +// Disable dog tags for civilians "CIV_F" call FUNC(disableFactionDogtags); diff --git a/addons/dogtags/XEH_preInit.sqf b/addons/dogtags/XEH_preInit.sqf index 5ad43b02291..482551de0ad 100644 --- a/addons/dogtags/XEH_preInit.sqf +++ b/addons/dogtags/XEH_preInit.sqf @@ -6,6 +6,14 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -GVAR(disabledFactions) = [] call CBA_fnc_createNamespace; +GVAR(disabledFactions) = createHashMap; + +if (hasInterface || isServer) then { + GVAR(dogtagsData) = createHashMap; + + if (!isServer) exitWith {}; + + GVAR(idCounter) = 0; +}; ADDON = true; diff --git a/addons/dogtags/functions/fnc_addDogtagActions.sqf b/addons/dogtags/functions/fnc_addDogtagActions.sqf index 7c7a2e5e8f9..310cbc3f340 100644 --- a/addons/dogtags/functions/fnc_addDogtagActions.sqf +++ b/addons/dogtags/functions/fnc_addDogtagActions.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL, mharis001 - * Returns children actions for checking dogtags in player's inventory. + * Returns children actions for checking dog tags in the player's inventory. * * Arguments: * 0: Player @@ -10,7 +10,7 @@ * Actions * * Example: - * [_player] call ace_dogtags_fnc_addDogtagActions + * player call ace_dogtags_fnc_addDogtagActions * * Public: No */ @@ -18,17 +18,27 @@ params ["_player"]; private _fnc_getActions = { + //IGNORE_PRIVATE_WARNING ["_player"]; private _actions = []; private _cfgWeapons = configFile >> "CfgWeapons"; { private _config = _cfgWeapons >> _x; - if (getNumber (_config >> QGVAR(tagID)) > 0) then { - private _displayName = getText (_config >> "displayName"); - private _picture = getText (_config >> "picture"); - private _action = [_x, _displayName, _picture, FUNC(checkDogtagItem), {true}, {}, _x] call EFUNC(interact_menu,createAction); - _actions pushBack [_action, [], _player]; + if (getNumber (_config >> QGVAR(tagID)) > 0) then { + _actions pushBack [ + [ + _x, + getText (_config >> "displayName"), + getText (_config >> "picture"), + {[GVAR(dogtagsData) getOrDefault [_this select 2, []]] call FUNC(showDogtag)}, + {true}, + {}, + _x + ] call EFUNC(interact_menu,createAction), + [], + _player + ]; }; } forEach (_player call EFUNC(common,uniqueItems)); diff --git a/addons/dogtags/functions/fnc_addDogtagItem.sqf b/addons/dogtags/functions/fnc_addDogtagItem.sqf deleted file mode 100644 index 970bb1926e0..00000000000 --- a/addons/dogtags/functions/fnc_addDogtagItem.sqf +++ /dev/null @@ -1,31 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: SzwedzikPL - * Adds dogtag item to unit (triggered by server). - * - * Arguments: - * 0: Item class - * 1: Dogtag data - * - * Return Value: - * None - * - * Example: - * ["itemClass", ["name", "610-27-5955", "A POS"]] call ace_dogtags_fnc_addDogtagItem - * - * Public: No - */ - -params ["_item", "_dogtagData"]; - -if (_item == "") exitWith {}; - -[ace_player, _item] call CBA_fnc_addItem; - -_dogtagData params ["_nickName"]; -private _displayText = format [localize LSTRING(takeDogtagSuccess), _nickName]; - -// display message -[{ - [_this, 2.5] call EFUNC(common,displayTextStructured); -}, _displayText, DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/dogtags/functions/fnc_bloodType.sqf b/addons/dogtags/functions/fnc_bloodType.sqf index 5e03c586fa8..53b60073709 100644 --- a/addons/dogtags/functions/fnc_bloodType.sqf +++ b/addons/dogtags/functions/fnc_bloodType.sqf @@ -1,16 +1,16 @@ #include "..\script_component.hpp" /* * Author: commy2 - * Reports a blood type depending on the units name. + * Reports a blood type depending on the unit's name. * * Arguments: - * 0: Name of a unit + * 0: Unit name * * Return Value: * A random blood type * * Example: - * _bloodType = ["name"] call ace_dogtags_fnc_bloodType + * "name" call ace_dogtags_fnc_bloodType * * Public: No */ diff --git a/addons/dogtags/functions/fnc_canCheckDogtag.sqf b/addons/dogtags/functions/fnc_canCheckDogtag.sqf index 399ad5db252..a5ed987fc0f 100644 --- a/addons/dogtags/functions/fnc_canCheckDogtag.sqf +++ b/addons/dogtags/functions/fnc_canCheckDogtag.sqf @@ -1,26 +1,26 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Checks if dogtag can be checked. + * Checks if the target's dog tag can be checked by the unit. * * Arguments: - * 0: Player + * 0: Player (not used) * 1: Target * * Return Value: - * True if dogtag can be checked + * If dog tag can be checked * * Example: - * _canCheck = [player, unit] call ace_dogtags_fnc_canCheckDogtag + * [player, cursorObject] call ace_dogtags_fnc_canCheckDogtag * * Public: No */ -params ["_player", "_target"]; +params ["", "_target"]; if (isNull _target) exitWith {false}; -// check if disabled for faction -if ([GVAR(disabledFactions) getVariable faction _target] param [0, false]) exitWith {false}; +// Check if disabled for faction +if ((faction _target) in GVAR(disabledFactions)) exitWith {false}; -(!alive _target) || {_target getVariable ["ACE_isUnconscious", false]} +!(_target call EFUNC(common,isAwake)) diff --git a/addons/dogtags/functions/fnc_canTakeDogtag.sqf b/addons/dogtags/functions/fnc_canTakeDogtag.sqf index 7ae38f7c410..c56db0b8933 100644 --- a/addons/dogtags/functions/fnc_canTakeDogtag.sqf +++ b/addons/dogtags/functions/fnc_canTakeDogtag.sqf @@ -1,17 +1,17 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Checks if dogtag can be taken. + * Checks if the target's dog tag can be taken by the unit. * * Arguments: * 0: Player * 1: Target * * Return Value: - * True if dogtag can be taken + * If dog tag can be taken * * Example: - * _canTake = [player, unit] call ace_dogtags_fnc_canTakeDogtag + * [player, cursorObject] call ace_dogtags_fnc_canTakeDogtag * * Public: No */ @@ -20,7 +20,10 @@ params ["_player", "_target"]; if (isNull _target) exitWith {false}; -// check if disabled for faction -if ([GVAR(disabledFactions) getVariable faction _target] param [0, false]) exitWith {false}; +// Check if disabled for faction +if ((faction _target) in GVAR(disabledFactions)) exitWith {false}; -(!alive _target) || {_target getVariable ["ACE_isUnconscious", false]} +// CBA_fnc_canAddItem doesn't account for mass 0 items and unit not having any containers +!(_target call EFUNC(common,isAwake)) && {(uniform _player + vest _player + backpack _player) != ""} && {[_player, "ACE_dogtag_1"] call CBA_fnc_canAddItem} +// Todo: Use code below in 2.18 +// _player canAdd ["ACE_dogtag_1", 1, true] diff --git a/addons/dogtags/functions/fnc_checkDogtag.sqf b/addons/dogtags/functions/fnc_checkDogtag.sqf index dcceb8c2c0b..4b2f2d533f2 100644 --- a/addons/dogtags/functions/fnc_checkDogtag.sqf +++ b/addons/dogtags/functions/fnc_checkDogtag.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Checks unit dogtag. + * Checks the unit's dog tag. * * Arguments: * 0: Player @@ -11,17 +11,17 @@ * None * * Example: - * [player, unit] call ace_dogtags_fnc_checkDogtag + * [player, cursorObject] call ace_dogtags_fnc_checkDogtag * * Public: No */ params ["_player", "_target"]; -// animation +// Animation _player call EFUNC(common,goKneeling); -// sound +// Sound private _position = _target modelToWorldWorld (_target selectionPosition "neck"); playSound3D [ @@ -34,10 +34,8 @@ playSound3D [ 50 ]; -// display dogtag +// Display dog tag private _doubleTags = (_target getVariable [QGVAR(dogtagTaken), objNull]) != _target; -private _dogTagData = [_target] call FUNC(getDogTagData); +private _dogtagData = _target call FUNC(getDogtagData); -[{ - [QGVAR(showDogtag), _this] call CBA_fnc_localEvent; -}, [_dogTagData, _doubleTags], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; +[LINKFUNC(showDogtag), [_dogtagData, _doubleTags], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/dogtags/functions/fnc_checkDogtagItem.sqf b/addons/dogtags/functions/fnc_checkDogtagItem.sqf deleted file mode 100644 index 09526d83ed8..00000000000 --- a/addons/dogtags/functions/fnc_checkDogtagItem.sqf +++ /dev/null @@ -1,22 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: SzwedzikPL - * Check dogtag self menu action. - * - * Arguments: - * 0: Player - * 1: Target - * 2: Item class - * - * Return Value: - * None - * - * Example: - * [player, unit, "itemClass"] call ace_dogtags_fnc_checkDogtagItem - * - * Public: No - */ - -params ["_player", "_target", "_item"]; - -[QGVAR(sendDogtagData), [_player, _item]] call CBA_fnc_serverEvent; diff --git a/addons/dogtags/functions/fnc_disableFactionDogtags.sqf b/addons/dogtags/functions/fnc_disableFactionDogtags.sqf index f1ea5f5c065..b1ac145d9a0 100644 --- a/addons/dogtags/functions/fnc_disableFactionDogtags.sqf +++ b/addons/dogtags/functions/fnc_disableFactionDogtags.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: commy2 - * Disable this faction from using dogtags. + * Disables this faction from using dog tags. * * Arguments: * 0: Faction @@ -17,4 +17,9 @@ params [["_faction", "", [""]]]; -GVAR(disabledFactions) setVariable [_faction, true]; +_faction = configName (configFile >> "CfgFactionClasses" >> _faction); + +// Faction doesn't exist +if (_faction == "") exitWith {}; + +GVAR(disabledFactions) set [_faction, true]; diff --git a/addons/dogtags/functions/fnc_getDogtagData.sqf b/addons/dogtags/functions/fnc_getDogtagData.sqf index 6a850543fc2..4aaf930fa21 100644 --- a/addons/dogtags/functions/fnc_getDogtagData.sqf +++ b/addons/dogtags/functions/fnc_getDogtagData.sqf @@ -1,19 +1,19 @@ #include "..\script_component.hpp" /* * Author: esteldunedain - * Get unit dogtag data. + * Gets unit's dog tag data. * * Arguments: * 0: Target * * Return Value: - * Dogtag Data + * Dog tag Data * 0: Name * 1: SSN * 2: Blood Type * * Example: - * _dogtagData = [unit, player] call ace_dogtags_fnc_getDogtagData + * player call ace_dogtags_fnc_getDogtagData * * Public: No */ @@ -21,17 +21,20 @@ params ["_target"]; // Check if the data was already created -private _dogTagData = _target getVariable QGVAR(dogtagData); -if (!isNil "_dogTagData") exitWith {_dogTagData}; +private _dogtagData = _target getVariable QGVAR(dogtagData); + +if (!isNil "_dogtagData") exitWith {_dogtagData}; // Create dog tag data once for the unit: nickname, code (eg. 135-13-900) and blood type private _targetName = [_target, false, true] call EFUNC(common,getName); -private _dogTagData = [ +private _dogtagData = [ _targetName, _targetName call FUNC(ssn), _targetName call FUNC(bloodType) ]; + // Store it -_target setVariable [QGVAR(dogtagData), _dogTagData, true]; -_dogTagData +_target setVariable [QGVAR(dogtagData), _dogtagData, true]; + +_dogtagData diff --git a/addons/dogtags/functions/fnc_getDogtagItem.sqf b/addons/dogtags/functions/fnc_getDogtagItem.sqf index 04112bcc940..4f8cc94cc76 100644 --- a/addons/dogtags/functions/fnc_getDogtagItem.sqf +++ b/addons/dogtags/functions/fnc_getDogtagItem.sqf @@ -1,7 +1,8 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Server: creates new dogtag item and send it to client. + * Server: Creates a new dog tag item and sends it to client. + * It broacasts the dog tag info to all machines with interfaces. * * Arguments: * 0: Player @@ -11,29 +12,37 @@ * None * * Example: - * [player, unit] call ace_dogtags_fnc_getDogtagItem + * [player, cursorObject] call ace_dogtags_fnc_getDogtagItem * * Public: No */ -if(!isServer) exitWith {}; +if (!isServer) exitWith {}; params ["_player", "_target"]; TRACE_2("getDogtagItem",_player,_target); -private _allDogtags = missionNamespace getVariable [QGVAR(allDogtags), []]; -private _allDogtagDatas = missionNamespace getVariable [QGVAR(allDogtagDatas), []]; +GVAR(idCounter) = GVAR(idCounter) + 1; -private _nextID = count _allDogtags + 1; - -if (_nextID > 999) exitWith {ERROR("Ran out of IDs");}; +if (GVAR(idCounter) > 999) exitWith {ERROR("Ran out of IDs");}; private _dogTagData = [_target] call FUNC(getDogTagData); -private _item = format ["ACE_dogtag_%1", _nextID]; -_allDogtags pushBack _item; -_allDogtagDatas pushBack _dogTagData; +private _item = format ["ACE_dogtag_%1", GVAR(idCounter)]; + +// Broadcast data globally, so that clients can use it where needed +[QGVAR(broadcastDogtagInfo), [_item, _dogTagData]] call CBA_fnc_globalEvent; + +// Dog tags have no mass, so no need to check if it can fit in container, but check if unit has an inventory at all +[_player, _item, true] call CBA_fnc_addItem; + +private _name = _dogtagData param [0, ""]; -missionNamespace setVariable [QGVAR(allDogtags), _allDogtags]; -missionNamespace setVariable [QGVAR(allDogtagDatas), _allDogtagDatas]; +// If data doesn't exist or body has no name, set name as "unknown" +if (_name == "") then { + _name = LELSTRING(common,unknown); +}; -[QGVAR(addDogtagItem), [_item, _dogTagData], [_player]] call CBA_fnc_targetEvent; +// Display message +[{ + [QEGVAR(common,displayTextStructured), [_this select 0, 2.5], _this select 1] call CBA_fnc_targetEvent; +}, [format [LLSTRING(takeDogtagSuccess), _name], _player], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/dogtags/functions/fnc_sendDogtagData.sqf b/addons/dogtags/functions/fnc_sendDogtagData.sqf deleted file mode 100644 index 2351e611665..00000000000 --- a/addons/dogtags/functions/fnc_sendDogtagData.sqf +++ /dev/null @@ -1,33 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: SzwedzikPL - * Server: returns to client data on given dogtag. - * - * Arguments: - * 0: Player - * 1: Target - * - * Return Value: - * None - * - * Example: - * [player, unit] call ace_dogtags_fnc_sendDogtagData - * - * Public: No - */ - -if (!isServer) exitWith {}; - -params ["_target", "_item"]; -TRACE_2("sendDogtagData",_target,_item); - -private _allDogtags = missionNameSpace getVariable [QGVAR(allDogtags), []]; -private _allDogtagDatas = missionNameSpace getVariable [QGVAR(allDogtagDatas), []]; - -private _dogtagData = []; -private _index = _allDogtags find _item; -if (_index >= 0) then { - _dogtagData = _allDogtagDatas select _index; -}; - -[QGVAR(showDogtag), [_dogtagData], [_target]] call CBA_fnc_targetEvent; diff --git a/addons/dogtags/functions/fnc_showDogtag.sqf b/addons/dogtags/functions/fnc_showDogtag.sqf index 4865ff7de20..5de9a9fc62a 100644 --- a/addons/dogtags/functions/fnc_showDogtag.sqf +++ b/addons/dogtags/functions/fnc_showDogtag.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Shows dogtag. + * Shows dog tag. * * Arguments: - * 0: Dogtag data + * 0: Dog tag data * 1: Display as double tag * * Return Value: @@ -27,9 +27,17 @@ if (_doubleTags) then { } else { (QGVAR(tag) call BIS_fnc_rscLayer) cutRsc [QGVAR(singleTag), "PLAIN", 1, true]; }; -private _display = uiNamespace getvariable [QGVAR(tag), displayNull]; -if(isNull _display) exitWith {}; + +private _display = uiNamespace getVariable [QGVAR(tag), displayNull]; + +if (isNull _display) exitWith {}; private _control = _display displayCtrl 1001; -_dogtagData params ["_nickName", "_code", "_bloodType"]; -_control ctrlSetStructuredText parseText format ["%1
%2
%3", toUpper _nickName, _code, _bloodType]; +_dogtagData params ["_name", "_code", "_bloodType"]; + +// If data doesn't exist or body has no name, set name as "unknown" +if (_name == "") then { + _name = LELSTRING(common,unknown); +}; + +_control ctrlSetStructuredText parseText format ["%1
%2
%3", toUpper _name, _code, _bloodType]; diff --git a/addons/dogtags/functions/fnc_ssn.sqf b/addons/dogtags/functions/fnc_ssn.sqf index 0ba3499c0b0..794422ddd11 100644 --- a/addons/dogtags/functions/fnc_ssn.sqf +++ b/addons/dogtags/functions/fnc_ssn.sqf @@ -1,16 +1,16 @@ #include "..\script_component.hpp" /* * Author: kymckay - * Reports a social security number generated from the units name. + * Reports a social security number generated from the unit's name. * * Arguments: - * 0: Name of a unit + * 0: Unit name * * Return Value: * A random three/two/four format social security number * * Example: - * _ssn = ["AAA"] call ace_dogtags_fnc_ssn + * "name" call ace_dogtags_fnc_ssn * * Public: No */ @@ -18,19 +18,20 @@ params ["_name"]; private _chars = toArray _name; -private _length = count _chars; + // Warning, for strings containing non-latin characters, `_count _name` != `_count _chars` +private _length = count _chars; _chars pushBack _length; _length = _length + 1; private _remainder = 0; -private _nums = [0,0,0,0,0,0,0,0,0]; +private _nums = [0, 0, 0, 0, 0, 0, 0, 0, 0]; for "_index" from 0 to (8 max _length) do { private _inputChar = _chars select (_index % _length); - _nums set [(_index % 9), ((_nums select (_index % 9)) + _inputChar + _remainder) % 10]; + _nums set [_index % 9, ((_nums select (_index % 9)) + _inputChar + _remainder) % 10]; _remainder = (_inputChar + _remainder) % 256; }; -([_nums select [0,3],_nums select [3,2], _nums select [5,4]] apply { _x joinString "" }) joinString "-" +([_nums select [0, 3], _nums select [3, 2], _nums select [5, 4]] apply { _x joinString "" }) joinString "-" diff --git a/addons/dogtags/functions/fnc_takeDogtag.sqf b/addons/dogtags/functions/fnc_takeDogtag.sqf index 1972c91ee09..b374c271219 100644 --- a/addons/dogtags/functions/fnc_takeDogtag.sqf +++ b/addons/dogtags/functions/fnc_takeDogtag.sqf @@ -1,8 +1,8 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * If dogtag is not already taken triggers event on server. - * If dogtag already taken displays info about it. + * If the dog tag hasn't already been taken, it triggers an event on the server. + * If the dog tag has already been taken, it displays info about it. * * Arguments: * 0: Player @@ -12,17 +12,17 @@ * None * * Example: - * [player, unit] call ace_dogtags_fnc_takeDogtag + * [player, cursorObject] call ace_dogtags_fnc_takeDogtag * * Public: No */ params ["_player", "_target"]; -// animation +// Animation _player call EFUNC(common,goKneeling); -// sound +// Sound private _position = _target modelToWorldWorld (_target selectionPosition "neck"); playSound3D [ @@ -35,12 +35,11 @@ playSound3D [ 50 ]; -// display message +// Display message if ((_target getVariable [QGVAR(dogtagTaken), objNull]) == _target) then { - [{ - [_this, 2.5] call EFUNC(common,displayTextStructured); - }, localize LSTRING(dogtagAlreadyTaken), DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; + [EFUNC(common,displayTextStructured), [LLSTRING(dogtagAlreadyTaken), 2.5], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; } else { _target setVariable [QGVAR(dogtagTaken), _target, true]; + [QGVAR(getDogtagItem), [_player, _target]] call CBA_fnc_serverEvent; }; diff --git a/addons/dogtags/stringtable.xml b/addons/dogtags/stringtable.xml index d48fcac9cef..ff0af0db4e9 100644 --- a/addons/dogtags/stringtable.xml +++ b/addons/dogtags/stringtable.xml @@ -6,14 +6,14 @@ Nieśmiertelnik Жетон Identifikační známka - 認識票 + ドッグタグ Erkennungsmarke 군번줄 Plaque d'identification Piastrina 兵籍牌 兵籍牌 - Dog Tag + Chapa de Identificação Placa de identidad Künye @@ -22,14 +22,14 @@ Sprawdź nieśmiertelnik Проверить жетон Zkontrolovat známku - 認識票を確認 + ドッグタグを確認 Erkennungsmarke prüfen 군번줄 확인 Vérifier la plaque d'identification Controlla Piastrina 檢查兵籍牌 检查兵籍牌 - Verificar Dog Tag + Verificar chapa de identificação Verificar placa de identidad Künyeyi Kontrol Et @@ -54,7 +54,7 @@ Zabierz Взять Vezmi - 取る + 拾う Nehmen 회수 Prendre @@ -66,47 +66,47 @@ Al - Dogtag taken from %1... + Dog Tag taken from %1... Zabrałeś nieśmiertelnik %1... Жетон снят с %1... Sebral jsem známku od %1... - %1 から認識票を取っています・・・ + %1 からドッグタグを回収しています・・・ Erkennungsmarke von %1 genommen... %1(으)로부터 군번줄을 회수했습니다... Plaque d'identification prise sur %1... Piastrina presa da %1... 從%1身上拿取兵籍牌... 从%1身上拿取兵籍牌... - Dogtag pego de %1... + Chapa de identificação pega de %1... Tomada placa de identidad de %1... Künye %1 kişisinden alındı - Somebody else has already taken the dogtag... + Somebody else has already taken the Dog Tag... Ktoś już zabrał ten nieśmiertelnik... Кто-то уже забрал жетон... Někdo jiný už vzal identifikační známku... - 誰かが既に認識票を取ったようだ・・・ + 既に誰かがドッグタグを回収したようだ・・・ Jemand anderes hat bereits die Erkennungsmarke genommen... 누군가 이미 군번줄을 회수해갔습니다... Quelqu'un d'autre a déjà pris la plaque d'identification... Qualcun altro ha già preso la piastrina... 已經有人把他的兵籍牌拿走了... 已经有人把他的兵籍牌拿走了... - Alguém já pegou essa dogtag... + Alguém já pegou essa chapa de identificação... Alguien más ha tomado la placa de identidad Başka biri zaten künyeyi almış - Onscreen display for checking dogtags + Onscreen display for checking Dog Tags Anzeige um Erkennungsmarke zu überprüfen 在畫面中顯示檢查兵籍牌 在画面中显示检查兵籍牌 - 確認中の認識票を画面上に表示します + 確認中のドッグタグを画面上に表示します Indicatore su schermo per il controllo delle piastrine Wyświetlacz ekranowy dla sprawdzania nieśmiertelników Экран для проверки жетонов - Tela de Exibição para verificar dogtags + Tela de exibição para verificar chapas de identificação Visualización en pantalla de placa de identidad Affichage à l'écran pour le contrôle des plaques. Okno na obrazovce pro kontrolu známek diff --git a/addons/dragging/CfgVehicles.hpp b/addons/dragging/CfgVehicles.hpp index 395133e9464..bd9758447bf 100644 --- a/addons/dragging/CfgVehicles.hpp +++ b/addons/dragging/CfgVehicles.hpp @@ -3,6 +3,9 @@ class CBA_Extended_EventHandlers; class CfgVehicles { + class C_man_1; + class GVAR(clone): C_man_1 {}; + // Static weapons class LandVehicle; class StaticWeapon: LandVehicle { diff --git a/addons/dragging/XEH_PREP.hpp b/addons/dragging/XEH_PREP.hpp index 0861c9533d2..aeba3135ab5 100644 --- a/addons/dragging/XEH_PREP.hpp +++ b/addons/dragging/XEH_PREP.hpp @@ -5,6 +5,8 @@ PREP(canDrop_carry); PREP(canRun_carry); PREP(carryObject); PREP(carryObjectPFH); +PREP(createClone); +PREP(deleteClone); PREP(dragObject); PREP(dragObjectPFH); PREP(dropObject); diff --git a/addons/dragging/XEH_postInit.sqf b/addons/dragging/XEH_postInit.sqf index ae277bf4d24..48655c5833a 100644 --- a/addons/dragging/XEH_postInit.sqf +++ b/addons/dragging/XEH_postInit.sqf @@ -1,9 +1,62 @@ // by PabstMirror, commy2 #include "script_component.hpp" +[QGVAR(moveCorpse), { + params ["_corpse", "_dir", "_posATL"]; + + if (isNull _corpse) exitWith {}; + + // Check if the corpse is already close to the target + // If so, don't teleport + if ((getPosATL _corpse) distance _posATL > 0.25) then { + // Set direction before position + _corpse setDir _dir; + + // Bring corpse back to clone's position + _corpse setPosATL _posATL; + }; + + // Sync the corpse with its position + [{ + _this awake true; + + [{ + _this awake false; + }, _this] call CBA_fnc_execNextFrame; + }, _corpse] call CBA_fnc_execNextFrame; + + // Allow the corpse to be synced for JIP players + if (isServer) exitWith { + GVAR(movedCorpses) pushBackUnique _corpse; + }; +}] call CBA_fnc_addEventHandler; + if (isServer) then { // Release object on disconnection. Function is identical to killed addMissionEventHandler ["HandleDisconnect", LINKFUNC(handleKilled)]; + + GVAR(movedCorpses) = []; + + ["CAManBase", "Deleted", { + GVAR(movedCorpses) deleteAt (GVAR(movedCorpses) find (_this select 0)); + }, true, [], true] call CBA_fnc_addClassEventHandler; + + [QGVAR(disableSyncMovedCorpseOnJIP), { + params ["_corpse"]; + + GVAR(movedCorpses) deleteAt (GVAR(movedCorpses) find _corpse); + }] call CBA_fnc_addEventHandler; + + // Sync position of dead corpse for JIP unit (prevents weird invisible hitboxes on corpses) + [QGVAR(requestSyncMovedCorpsesJIP), { + params ["_clientOwner"]; + + { + [QGVAR(moveCorpse), [_x, getDir _x, getPosATL _x], _clientOwner] call CBA_fnc_ownerEvent; + } forEach GVAR(movedCorpses); + }] call CBA_fnc_addEventHandler; +} else { + [QGVAR(requestSyncMovedCorpsesJIP), clientOwner] call CBA_fnc_serverEvent; }; if (!hasInterface) exitWith {}; @@ -20,6 +73,11 @@ if (isNil QGVAR(maxWeightCarryRun)) then { GVAR(maxWeightCarryRun) = 50; }; +// Extended EH doesn't fire for dead units, so add interactions manually +{ + _x call FUNC(initPerson); +} forEach allDeadMen; + ["isNotDragging", {!((_this select 0) getVariable [QGVAR(isDragging), false])}] call EFUNC(common,addCanInteractWithCondition); ["isNotCarrying", {!((_this select 0) getVariable [QGVAR(isCarrying), false])}] call EFUNC(common,addCanInteractWithCondition); @@ -57,6 +115,14 @@ if (isNil QGVAR(maxWeightCarryRun)) then { // Display event handler ["MouseZChanged", {(_this select 1) call FUNC(handleScrollWheel)}] call CBA_fnc_addDisplayHandler; +// Handle local effect commands for clones +[QGVAR(setCloneFace), { + params ["_clone", "_corpse"]; + + _clone setFace face _corpse; + _clone setMimic "unconscious"; +}] call CBA_fnc_addEventHandler; + // Handle surrendering and handcuffing ["ace_captiveStatusChanged", { params ["_unit", "_state"]; @@ -70,6 +136,9 @@ if (isNil QGVAR(maxWeightCarryRun)) then { [QGVAR(startCarry), LINKFUNC(startCarryLocal)] call CBA_fnc_addEventHandler; [QGVAR(startDrag), LINKFUNC(startDragLocal)] call CBA_fnc_addEventHandler; +[QGVAR(setCarryable), LINKFUNC(setCarryable)] call CBA_fnc_addEventHandler; +[QGVAR(setDraggable), LINKFUNC(setDraggable)] call CBA_fnc_addEventHandler; + [QGVAR(carryingContainerClosed), { params ["_container", "_owner"]; TRACE_2("carryingContainerClosed EH",_container,_owner); diff --git a/addons/dragging/functions/fnc_canCarry.sqf b/addons/dragging/functions/fnc_canCarry.sqf index be3015868b5..a38f37a02ee 100644 --- a/addons/dragging/functions/fnc_canCarry.sqf +++ b/addons/dragging/functions/fnc_canCarry.sqf @@ -18,7 +18,10 @@ params ["_unit", "_target"]; -if !(alive _target && {_target getVariable [QGVAR(canCarry), false]} && {isNull objectParent _target}) exitWith {false}; +private _alive = alive _target; +private _isPerson = _target isKindOf "CAManBase"; + +if !((_alive || _isPerson) && {_target getVariable [QGVAR(canCarry), false]} && {isNull objectParent _target}) exitWith {false}; if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false}; @@ -26,18 +29,19 @@ if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false}; // 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}; +// Units need to be unconscious or limping; Units also need to not be in ragdoll if alive, as that causes desync issues +if (_isPerson) exitWith { + ((!_alive) && {missionNamespace getVariable [QGVAR(canMoveDead), true]}) || + {(isAwake _target) && // not ragdolled if alive + {!(_target call EFUNC(common,isAwake)) || + {_target getHitPointDamage "HitLegs" >= 0.5}}} +}; + // Static weapons need to be empty for carrying (ignore UAV AI) if (_target isKindOf "StaticWeapon") exitWith { (crew _target) findIf {!unitIsUAV _x} == -1 }; -// Units need to be unconscious or limping; Units also need to not be in ragdoll, as that causes desync issues -if (_target isKindOf "CAManBase") exitWith { - 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 diff --git a/addons/dragging/functions/fnc_canDrag.sqf b/addons/dragging/functions/fnc_canDrag.sqf index 586e23feaf8..2616d6d1447 100644 --- a/addons/dragging/functions/fnc_canDrag.sqf +++ b/addons/dragging/functions/fnc_canDrag.sqf @@ -18,22 +18,26 @@ params ["_unit", "_target"]; -if !(alive _target && {_target getVariable [QGVAR(canDrag), false]} && {isNull objectParent _target}) exitWith {false}; +private _alive = alive _target; +private _isPerson = _target isKindOf "CAManBase"; + +if !((_alive || _isPerson) && {_target getVariable [QGVAR(canDrag), false]} && {isNull objectParent _target}) exitWith {false}; if !([_unit, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; +// Units need to be unconscious or limping; Units also need to not be in ragdoll if alive, as that causes desync issues +if (_isPerson) exitWith { + ((!_alive) && {missionNamespace getVariable [QGVAR(canMoveDead), true]}) || + {(isAwake _target) && // not ragdolled if alive + {!(_target call EFUNC(common,isAwake)) || + {_target getHitPointDamage "HitLegs" >= 0.5}}} +}; + // Static weapons need to be empty for dragging (ignore UAV AI) if (_target isKindOf "StaticWeapon") exitWith { (crew _target) findIf {!unitIsUAV _x} == -1 }; -// Units need to be unconscious or limping; Units also need to not be in ragdoll, as that causes desync issues -if (_target isKindOf "CAManBase") exitWith { - 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 diff --git a/addons/dragging/functions/fnc_carryObject.sqf b/addons/dragging/functions/fnc_carryObject.sqf index dfff18a3c0b..d765020f96e 100644 --- a/addons/dragging/functions/fnc_carryObject.sqf +++ b/addons/dragging/functions/fnc_carryObject.sqf @@ -19,6 +19,12 @@ params ["_unit", "_target"]; TRACE_2("params",_unit,_target); +// If in ViV cargo, unload it first +// Warn user if it failed to unload (shouldn't happen) +if (!isNull isVehicleCargo _target && {!(objNull setVehicleCargo _target)}) then { + WARNING_1("ViV Unload Failed %1",_target); +}; + // Get attachTo offset and direction private _position = _target getVariable [QGVAR(carryPosition), [0, 0, 0]]; private _direction = _target getVariable [QGVAR(carryDirection), 0]; @@ -42,9 +48,6 @@ if (_target isKindOf "CAManBase") then { [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), [ _unit, "DefaultAction", @@ -53,21 +56,21 @@ _unit setVariable [QGVAR(releaseActionID), [ ] call EFUNC(common,addActionEventHandler)]; // Add anim changed EH -[_unit, "AnimChanged", FUNC(handleAnimChanged), [_unit]] call CBA_fnc_addBISEventHandler; +[_unit, "AnimChanged", LINKFUNC(handleAnimChanged), [_unit]] call CBA_fnc_addBISEventHandler; // Prevent UAVs from firing private _UAVCrew = _target call EFUNC(common,getVehicleUAVCrew); if (_UAVCrew isNotEqualTo []) then { { - _target deleteVehicleCrew _x; + [_x, true] call EFUNC(common,disableAiUAV); } forEach _UAVCrew; - _target setVariable [QGVAR(isUAV), true, true]; + _target setVariable [QGVAR(isUAV), _UAVCrew, true]; }; // Check everything -[FUNC(carryObjectPFH), 0.5, [_unit, _target, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(carryObjectPFH), 0.5, [_unit, _target, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; -// Reset current dragging height -GVAR(currentHeightChange) = 0; +// API +[QGVAR(startedCarry), [_unit, _target]] call CBA_fnc_localEvent; diff --git a/addons/dragging/functions/fnc_carryObjectPFH.sqf b/addons/dragging/functions/fnc_carryObjectPFH.sqf index b73ff972619..a615d282521 100644 --- a/addons/dragging/functions/fnc_carryObjectPFH.sqf +++ b/addons/dragging/functions/fnc_carryObjectPFH.sqf @@ -35,15 +35,35 @@ if !(_unit getVariable [QGVAR(isCarrying), false]) exitWith { _idPFH call CBA_fnc_removePerFrameHandler; }; -// Drop if the crate is destroyed OR target moved away from carrier (weapon disassembled) OR carrier starts limping -if !(alive _target && {_unit distance _target <= 10} && {_unit getHitPointDamage "HitLegs" < 0.5}) exitWith { - TRACE_2("dead/distance",_unit,_target); +// Drop if the target is destroyed +if (!alive _target) exitWith { + TRACE_2("dead",_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); - }; + [_unit, _target] call FUNC(dropObject_carry); + + _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); @@ -53,8 +73,8 @@ if !(alive _target && {_unit distance _target <= 10} && {_unit getHitPointDamage _idPFH call CBA_fnc_removePerFrameHandler; }; -// Drop static if crew is in it (UAV crew deletion may take a few frames) -if (_target isKindOf "StaticWeapon" && {(crew _target) isNotEqualTo []} && {!(_target getVariable [QGVAR(isUAV), false])}) then { +// Drop static if either non-UAV crew or new UAV crew is in it (ignore saved UAV crew) +if (_target isKindOf "StaticWeapon" && {((crew _target) - (_target getVariable [QGVAR(isUAV), []])) isNotEqualTo []}) exitWith { TRACE_2("static weapon crewed",_unit,_target); [_unit, _target] call FUNC(dropObject_carry); @@ -71,7 +91,7 @@ private _previousHint = _unit getVariable [QGVAR(hint), []]; if (_previousHint isEqualType "") exitWith {}; // Mouse hint -private _hintLMB = LLSTRING(Drop); +private _hintLMB = LELSTRING(common,Drop); private _cursorObject = cursorObject; if ( diff --git a/addons/dragging/functions/fnc_createClone.sqf b/addons/dragging/functions/fnc_createClone.sqf new file mode 100644 index 00000000000..6cb4aa0ec69 --- /dev/null +++ b/addons/dragging/functions/fnc_createClone.sqf @@ -0,0 +1,101 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut, johnb43 + * Creates a draggable / carryable clone of a dead unit. + * + * Arguments: + * 0: Unit dragging/carrying + * 1: Dead unit + * + * Return Value: + * Cloned unit + * + * Example: + * [player, cursorObject] call ace_dragging_fnc_createClone; + * + * Public: No + */ + +params ["_unit", "_target"]; + +// Don't sync corpse when a player joins in progress until the corpse is in its proper position +[QGVAR(disableSyncMovedCorpseOnJIP), _target] call CBA_fnc_serverEvent; + +private _posATL = getPosATL _target; + +// Create clone +private _clone = createVehicle [[configOf _target >> QGVAR(cloneClass), "TEXT", QGVAR(clone)] call CBA_fnc_getConfigEntry, _posATL, [], 0, "CAN_COLLIDE"]; + +// Claim the clone +[_unit, _clone] call EFUNC(common,claim); + +// Move unit -10 m below terrain in order to hide it and remove its inventory access +_posATL set [2, -10]; + +// Corpse is desynced, but it doesn't matter here +_target setPosATL _posATL; + +// Hide unit until it can be moved below terrain +private _isObjectHidden = isObjectHidden _target; + +if (!_isObjectHidden) then { + [QEGVAR(common,hideObjectGlobal), [_target, true]] call CBA_fnc_serverEvent; +}; + +// Prevents unit from falling when below terrain +private _simulationEnabled = simulationEnabled _target; + +if (_simulationEnabled) then { + [QEGVAR(common,enableSimulationGlobal), [_target, false]] call CBA_fnc_serverEvent; +}; + +private _isInRemainsCollector = isInRemainsCollector _target; + +// Make sure corpse isn't deleted by engine's garbage collector +if (_isInRemainsCollector) then { + removeFromRemainsCollector [_target]; +}; + +// Make sure clone has the same wound textures as the corpse +_clone setDamage ((damage _target) min 0.99); // Don't kill the clone + +{ + _clone setHitPointDamage [_x, (_target getHitPointDamage _x) min 0.99]; +} forEach ["HitHead", "HitBody", "HitHands", "HitLegs"]; // Relevant hitpoints + +// Disable all damage +_clone allowDamage false; +_clone setVariable [QGVAR(original), [_target, _isInRemainsCollector, _isObjectHidden, _simulationEnabled], true]; + +[_clone, _target call CBA_fnc_getLoadout] call CBA_fnc_setLoadout; + +// Sets the facial expression +[[QGVAR(setCloneFace), [_clone, _target]] call CBA_fnc_globalEventJIP, _clone] call CBA_fnc_removeGlobalEventJIP; + +// API +[QGVAR(cloneCreated), [_clone, _target]] call CBA_fnc_localEvent; + +[{ + params ["_clone", "_target"]; + + // Remove clone from all zeuses + if (["ace_zeus"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(zeus,removeObjects), [[_clone]]] call CBA_fnc_serverEvent; + }; + + // Release claim on corpse + [objNull, _target] call EFUNC(common,claim); +}, [_clone, _target], 0.25] call CBA_fnc_waitAndExecute; + +// Save which curators had this object as editable +if (["ace_zeus"] call EFUNC(common,isModLoaded)) then { + private _objectCurators = objectCurators _target; + + _target setVariable [QGVAR(objectCurators), _objectCurators, true]; + + if (_objectCurators isEqualTo []) exitWith {}; + + [QEGVAR(zeus,removeObjects), [[_target], _objectCurators]] call CBA_fnc_serverEvent; +}; + +_clone diff --git a/addons/dragging/functions/fnc_deleteClone.sqf b/addons/dragging/functions/fnc_deleteClone.sqf new file mode 100644 index 00000000000..148b88a3a31 --- /dev/null +++ b/addons/dragging/functions/fnc_deleteClone.sqf @@ -0,0 +1,80 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut, johnb43 + * Drops a draggable / carryable clone of a dead unit. + * + * Arguments: + * 0: Unit dragging / carrying + * 1: Clone + * 2: If unit is in building + * + * Return Value: + * Original unit + * + * Example: + * [player, cursorObject, false] call ace_dragging_fnc_deleteClone; + * + * Public: No + */ + +params ["_unit", "_clone", "_inBuilding"]; + +(_clone getVariable [QGVAR(original), []]) params [ + ["_target", objNull], + ["_isInRemainsCollector", true], + ["_isObjectHidden", false], + ["_simulationEnabled", true] +]; + +// API +[QGVAR(cloneDeleted), [_clone, _target]] call CBA_fnc_localEvent; + +// Check if unit was deleted +if (!isNull _target) then { + private _posATL = getPosATL _clone; + + if (_inBuilding) then { + _posATL = _posATL vectorAdd [0, 0, 0.05]; + }; + + // Make sure position isn't underground + if (_posATL select 2 < 0.05) then { + _posATL set [2, 0.05]; + }; + + // Move the unit globally (important, as it desyncs the corpse position otherwise) + [QGVAR(moveCorpse), [_target, getDir _unit + 180, _posATL]] call CBA_fnc_globalEvent; + + // Unhide unit + if (!_isObjectHidden) then { + [QEGVAR(common,hideObjectGlobal), [_target, false]] call CBA_fnc_serverEvent; + }; + + // Enable simulation again + if (_simulationEnabled) then { + [QEGVAR(common,enableSimulationGlobal), [_target, true]] call CBA_fnc_serverEvent; + }; + + // Detach first to prevent objNull in attachedObjects + detach _clone; + deleteVehicle _clone; + + // Get which curators had this object as editable + if (["ace_zeus"] call EFUNC(common,isModLoaded)) then { + private _objectCurators = _target getVariable [QGVAR(objectCurators), []]; + + if (_objectCurators isEqualTo []) exitWith {}; + + [QEGVAR(zeus,addObjects), [[_target], _objectCurators]] call CBA_fnc_serverEvent; + }; + + if (_isInRemainsCollector) then { + addToRemainsCollector [_target]; + }; +} else { + // Detach first to prevent objNull in attachedObjects + detach _clone; + deleteVehicle _clone; +}; + +_target diff --git a/addons/dragging/functions/fnc_dragObject.sqf b/addons/dragging/functions/fnc_dragObject.sqf index ddad0ad7bb2..3169db26795 100644 --- a/addons/dragging/functions/fnc_dragObject.sqf +++ b/addons/dragging/functions/fnc_dragObject.sqf @@ -19,6 +19,12 @@ params ["_unit", "_target"]; TRACE_2("params",_unit,_target); +// If in ViV cargo, unload it first +// Warn user if it failed to unload (shouldn't happen) +if (!isNull isVehicleCargo _target && {!(objNull setVehicleCargo _target)}) then { + WARNING_1("ViV Unload Failed %1",_target); +}; + // Get attachTo offset and direction. private _position = _target getVariable [QGVAR(dragPosition), [0, 0, 0]]; private _direction = _target getVariable [QGVAR(dragDirection), 0]; @@ -43,9 +49,6 @@ if (_target isKindOf "CAManBase") then { [_target, "AinjPpneMrunSnonWnonDb_still", 0] call EFUNC(common,doAnimation); }; -_unit setVariable [QGVAR(isDragging), true, true]; -_unit setVariable [QGVAR(draggedObject), _target, true]; - // Add drop action GVAR(unit) = _unit; @@ -54,10 +57,10 @@ GVAR(releaseActionID) = [0xF1, [false, false, false], { }, "keydown", "", false, 0] call CBA_fnc_addKeyHandler; // Show mouse hint -["", LLSTRING(Drop)] call EFUNC(interaction,showMouseHint); +["", LELSTRING(common,Drop)] call EFUNC(interaction,showMouseHint); // Block firing -if !(GVAR(dragAndFire)) then { +if (!GVAR(dragAndFire)) then { _unit setVariable [QGVAR(blockFire), [ _unit, "DefaultAction", {true}, @@ -66,23 +69,24 @@ if !(GVAR(dragAndFire)) then { }; // Add anim changed EH -[_unit, "AnimChanged", FUNC(handleAnimChanged), [_unit]] call CBA_fnc_addBISEventHandler; +[_unit, "AnimChanged", LINKFUNC(handleAnimChanged), [_unit]] call CBA_fnc_addBISEventHandler; // Prevent UAVs from firing private _UAVCrew = _target call EFUNC(common,getVehicleUAVCrew); + if (_UAVCrew isNotEqualTo []) then { { - _target deleteVehicleCrew _x; + [_x, true] call EFUNC(common,disableAiUAV); } forEach _UAVCrew; - _target setVariable [QGVAR(isUAV), true, true]; + _target setVariable [QGVAR(isUAV), _UAVCrew, true]; }; // Check everything -[FUNC(dragObjectPFH), 0.5, [_unit, _target, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; - -// Reset current dragging height. -GVAR(currentHeightChange) = 0; +[LINKFUNC(dragObjectPFH), 0.5, [_unit, _target, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; // Fixes not being able to move when in combat pace [_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + +// API +[QGVAR(startedDrag), [_unit, _target]] call CBA_fnc_localEvent; diff --git a/addons/dragging/functions/fnc_dragObjectPFH.sqf b/addons/dragging/functions/fnc_dragObjectPFH.sqf index a2895f42162..13400aa349f 100644 --- a/addons/dragging/functions/fnc_dragObjectPFH.sqf +++ b/addons/dragging/functions/fnc_dragObjectPFH.sqf @@ -31,23 +31,28 @@ if !(_unit getVariable [QGVAR(isDragging), false]) exitWith { _idPFH call CBA_fnc_removePerFrameHandler; }; -// Drop if the crate is destroyed OR (target moved away from carrier (weapon disasembled)) -if (!alive _target || {_unit distance _target > 10}) then { - TRACE_2("dead/distance",_unit,_target); +// Drop if the target is destroyed +if (!alive _target) exitWith { + TRACE_2("dead",_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); - }; + [_unit, _target] call FUNC(dropObject); + + _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" && {(crew _target) isNotEqualTo []} && {!(_target getVariable [QGVAR(isUAV), false])}) then { +// Drop static if either non-UAV crew or new UAV crew is in it (ignore saved UAV crew) +if (_target isKindOf "StaticWeapon" && {((crew _target) - (_target getVariable [QGVAR(isUAV), []])) isNotEqualTo []}) exitWith { TRACE_2("static weapon crewed",_unit,_target); [_unit, _target] call FUNC(dropObject); @@ -57,3 +62,8 @@ if (_target isKindOf "StaticWeapon" && {(crew _target) isNotEqualTo []} && {!(_t _idPFH call CBA_fnc_removePerFrameHandler; }; + +// Clones can die of drowning if oxygen is under 0.5, so refill their oxygen from time to time +if (_target isKindOf QGVAR(clone) && {getOxygenRemaining _target < 0.8}) then { + _target setOxygenRemaining 1; +}; diff --git a/addons/dragging/functions/fnc_dropObject.sqf b/addons/dragging/functions/fnc_dropObject.sqf index debe7571018..049f8228168 100644 --- a/addons/dragging/functions/fnc_dropObject.sqf +++ b/addons/dragging/functions/fnc_dropObject.sqf @@ -26,14 +26,20 @@ if (!isNil QGVAR(releaseActionID)) then { }; // Stop blocking -if !(GVAR(dragAndFire)) then { +if (!GVAR(dragAndFire)) then { [_unit, "DefaultAction", _unit getVariable [QGVAR(blockFire), -1]] call EFUNC(common,removeActionEventHandler); }; private _inBuilding = _unit call FUNC(isObjectOnObject); +private _isClone = _target isKindOf QGVAR(clone); + +// Drop cloned dead units +if (_isClone) then { + _target = [_unit, _target, _inBuilding] call FUNC(deleteClone); +}; // Play release animation -if !(_unit getVariable ["ACE_isUnconscious", false]) then { +if (_unit call EFUNC(common,isAwake)) then { [_unit, "released"] call EFUNC(common,doGesture); }; @@ -57,7 +63,7 @@ _unit removeWeapon "ACE_FakePrimaryWeapon"; [_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); // Prevent object from flipping inside buildings -if (_inBuilding) then { +if (_inBuilding && {!_isClone}) then { _target setPosASL (getPosASL _target vectorAdd [0, 0, 0.05]); TRACE_2("setPos",getPosASL _unit,getPosASL _target); }; @@ -80,14 +86,16 @@ if (_unit getVariable ["ACE_isUnconscious", false]) then { [_unit, "unconscious", 2] call EFUNC(common,doAnimation); }; -// Recreate UAV crew (add a frame delay or this may cause the vehicle to be moved to [0,0,0]) -if (_target getVariable [QGVAR(isUAV), false]) then { - [{ - params ["_target"]; - if (!alive _target) exitWith {}; - TRACE_2("restoring uav crew",_target,getPosASL _target); - createVehicleCrew _target; - }, [_target]] call CBA_fnc_execNextFrame; +// Reenable UAV crew +private _UAVCrew = _target getVariable [QGVAR(isUAV), []]; + +if (_UAVCrew isNotEqualTo []) then { + // Reenable AI + { + [_x, false] call EFUNC(common,disableAiUAV); + } forEach _UAVCrew; + + _target setVariable [QGVAR(isUAV), nil, true]; }; // Fixes not being able to move when in combat pace @@ -99,3 +107,6 @@ private _mass = _target getVariable [QGVAR(originalMass), 0]; if (_mass != 0) then { [QEGVAR(common,setMass), [_target, _mass]] call CBA_fnc_globalEvent; // Force global sync }; + +// API +[QGVAR(stoppedDrag), [_unit, _target]] call CBA_fnc_localEvent; diff --git a/addons/dragging/functions/fnc_dropObject_carry.sqf b/addons/dragging/functions/fnc_dropObject_carry.sqf index f3f15fac141..525a150bcff 100644 --- a/addons/dragging/functions/fnc_dropObject_carry.sqf +++ b/addons/dragging/functions/fnc_dropObject_carry.sqf @@ -25,6 +25,12 @@ TRACE_1("params",_this); _unit setVariable [QGVAR(releaseActionID), nil]; private _inBuilding = _unit call FUNC(isObjectOnObject); +private _isClone = _target isKindOf QGVAR(clone); + +// Drop cloned dead units +if (_isClone) then { + _target = [_unit, _target, _inBuilding] call FUNC(deleteClone); +}; // Prevent collision damage [QEGVAR(common,fixCollision), _unit] call CBA_fnc_localEvent; @@ -44,7 +50,7 @@ if (_tryLoad && {!(_target isKindOf "CAManBase")} && {["ace_cargo"] call EFUNC(c // Fix anim when aborting carrying persons if (_target isKindOf "CAManBase" || {animationState _unit in CARRY_ANIMATIONS}) then { - if (vehicle _unit == _unit && {!(_unit getVariable ["ACE_isUnconscious", false])}) then { + if (isNull objectParent _unit && {_unit call EFUNC(common,isAwake)}) then { [_unit, "", 2] call EFUNC(common,doAnimation); }; @@ -59,11 +65,12 @@ if (_target isKindOf "CAManBase" || {animationState _unit in CARRY_ANIMATIONS}) _unit removeWeapon "ACE_FakePrimaryWeapon"; // Reselect weapon and re-enable sprint -private _previousWeaponIndex = _unit getVariable [QGVAR(previousWeapon), -1]; -_unit setVariable [QGVAR(previousWeapon), nil, true]; +private _previousWeaponState = _unit getVariable QGVAR(previousWeapon); -if (_previousWeaponIndex != -1) then { - _unit action ["SwitchWeapon", _unit, _unit, _previousWeaponIndex]; +if (!isNil "_previousWeaponState") then { + _unit selectWeapon _previousWeaponState; + + _unit setVariable [QGVAR(previousWeapon), nil, true]; }; [_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); @@ -71,8 +78,9 @@ if (_previousWeaponIndex != -1) then { [_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); // Prevent object from flipping inside buildings -if (_inBuilding) then { +if (_inBuilding && {!_isClone}) then { _target setPosASL (getPosASL _target vectorAdd [0, 0, 0.05]); + TRACE_2("setPos",getPosASL _unit,getPosASL _target); }; _unit setVariable [QGVAR(isCarrying), false, true]; @@ -86,14 +94,16 @@ if !(_target isKindOf "CAManBase") then { [QEGVAR(common,fixFloating), _target, _target] call CBA_fnc_targetEvent; }; -// Recreate UAV crew (add a frame delay or this may cause the vehicle to be moved to [0,0,0]) -if (_target getVariable [QGVAR(isUAV), false]) then { - [{ - params ["_target"]; - if (!alive _target) exitWith {}; - TRACE_2("restoring uav crew",_target,getPosASL _target); - createVehicleCrew _target; - }, [_target]] call CBA_fnc_execNextFrame; +// Reenable UAV crew +private _UAVCrew = _target getVariable [QGVAR(isUAV), []]; + +if (_UAVCrew isNotEqualTo []) then { + // Reenable AI + { + [_x, false] call EFUNC(common,disableAiUAV); + } forEach _UAVCrew; + + _target setVariable [QGVAR(isUAV), nil, true]; }; // Reset mass @@ -114,11 +124,17 @@ if (_loadCargo) then { private _vehicles = [_cursorObject, 0, true] call EFUNC(common,nearestVehiclesFreeSeat); if ([_cursorObject] isEqualTo _vehicles) then { - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [_unit, _target, _cursorObject] call EFUNC(medical_treatment,loadUnit); } else { [_unit, _target, _cursorObject] call EFUNC(common,loadPerson); }; + + // Repurpose variable for flag used in event below + _loadCargo = true; }; }; }; + +// API +[QGVAR(stoppedCarry), [_unit, _target, _loadCargo]] call CBA_fnc_localEvent; diff --git a/addons/dragging/functions/fnc_getWeight.sqf b/addons/dragging/functions/fnc_getWeight.sqf index f6b93feca0a..f6cb4661659 100644 --- a/addons/dragging/functions/fnc_getWeight.sqf +++ b/addons/dragging/functions/fnc_getWeight.sqf @@ -11,7 +11,7 @@ * Weight * * Example: - * [cursorTarget] call ace_dragging_fnc_getWeight + * cursorTarget call ace_dragging_fnc_getWeight * * Public: No */ @@ -23,19 +23,20 @@ if (GVAR(weightCoefficient) == 0) exitWith {0}; private _weight = loadAbs _object; -if !(GVAR(skipContainerWeight)) then { +if (!GVAR(skipContainerWeight)) then { // Add the mass of the object itself // getMass handles PhysX mass, this should be 0 for SupplyX containers and WeaponHolders // Use originalMass in case we're checking weight for a carried object - _weight = _weight + ((_object getVariable [QGVAR(originalMass), getMass _object])); + _weight = _weight + (_object getVariable [QGVAR(originalMass), getMass _object]); }; -// Contents of backpacks get counted twice (https://github.com/acemod/ACE3/pull/8457#issuecomment-1062522447 and https://feedback.bistudio.com/T167469) -// This is a workaround until that is fixed on BI's end -{ - _x params ["", "_container"]; - _weight = _weight - (loadAbs _container); -} forEach (everyContainer _object); +// Fixed in https://feedback.bistudio.com/T167469 on 2.16 profiling branch and for 2.18 stable +if ((productVersion select 3) < 152017) then { + { + _x params ["", "_container"]; + _weight = _weight - (loadAbs _container); + } forEach (everyContainer _object); +}; // Mass in Arma isn't an exact amount but rather a volume/weight value // This attempts to work around that by making it a usable value (sort of) diff --git a/addons/dragging/functions/fnc_handleAnimChanged.sqf b/addons/dragging/functions/fnc_handleAnimChanged.sqf index 24b8f582057..49ccc18d3f1 100644 --- a/addons/dragging/functions/fnc_handleAnimChanged.sqf +++ b/addons/dragging/functions/fnc_handleAnimChanged.sqf @@ -5,7 +5,7 @@ * * Arguments: * 0: Unit - * 1: Animaion + * 1: Animation * * Return Value: * None @@ -17,6 +17,7 @@ */ params ["_unit", "_anim"]; +//IGNORE_PRIVATE_WARNING ["_thisArgs", "_thisID"]; _thisArgs params ["_realUnit"]; TRACE_4("params",_unit,_anim,_realUnit,_thisID); diff --git a/addons/dragging/functions/fnc_handleScrollWheel.sqf b/addons/dragging/functions/fnc_handleScrollWheel.sqf index 8b522e34bc0..065701bbd44 100644 --- a/addons/dragging/functions/fnc_handleScrollWheel.sqf +++ b/addons/dragging/functions/fnc_handleScrollWheel.sqf @@ -27,7 +27,7 @@ private _carriedItem = _unit getVariable [QGVAR(carriedObject), objNull]; // Disabled for persons if (_carriedItem isKindOf "CAManBase") exitWith {false}; -if !(CBA_events_control) then { +if (!CBA_events_control) then { // Raise/lower // Move carried item 15 cm per scroll interval _scrollAmount = _scrollAmount * 0.15; @@ -42,7 +42,7 @@ if !(CBA_events_control) then { // 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); + private _selectionPosition = _unit worldToModel (ASLToAGL getPosWorld _carriedItem); _selectionPosition = _selectionPosition vectorAdd _positionChange; _carriedItem attachTo [_unit, _selectionPosition]; diff --git a/addons/dragging/functions/fnc_resumeCarry.sqf b/addons/dragging/functions/fnc_resumeCarry.sqf index 233d60e298b..e7cdeb5dc6d 100644 --- a/addons/dragging/functions/fnc_resumeCarry.sqf +++ b/addons/dragging/functions/fnc_resumeCarry.sqf @@ -17,7 +17,7 @@ params ["_unit"]; -// If not dragging, don't do anything +// If not carrying, don't do anything if !(_unit getVariable [QGVAR(isCarrying), false]) exitWith {}; // If action is already present, don't add it again diff --git a/addons/dragging/functions/fnc_resumeDrag.sqf b/addons/dragging/functions/fnc_resumeDrag.sqf index d0fea988fb8..7ae7c1a8f3c 100644 --- a/addons/dragging/functions/fnc_resumeDrag.sqf +++ b/addons/dragging/functions/fnc_resumeDrag.sqf @@ -29,4 +29,4 @@ GVAR(releaseActionID) = [0xF1, [false, false, false], { }, "keydown", "", false, 0] call CBA_fnc_addKeyHandler; // Show mouse hint -["", LLSTRING(Drop)] call EFUNC(interaction,showMouseHint); +["", LELSTRING(common,Drop)] call EFUNC(interaction,showMouseHint); diff --git a/addons/dragging/functions/fnc_setCarryable.sqf b/addons/dragging/functions/fnc_setCarryable.sqf index 60b9854f419..757f7baa045 100644 --- a/addons/dragging/functions/fnc_setCarryable.sqf +++ b/addons/dragging/functions/fnc_setCarryable.sqf @@ -5,21 +5,52 @@ * * Arguments: * 0: Object - * 1: True to enable carrying, false to disable + * 1: True to enable carrying, false to disable (default: false) * 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) + * 5: Apply globally (default: false) * * Return Value: * None * * Example: - * [cursorTarget, 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 */ -params ["_object", "_enableCarry", "_position", "_direction", ["_ignoreWeightCarry", false, [false]]]; +params [ + ["_object", objNull, [objNull]], + ["_enableCarry", false, [false]], + "_position", + "_direction", + ["_ignoreWeightCarry", false, [false]], + ["_global", false, [false]] +]; + +if (isNull _object) exitWith {}; + +if (!isNil "_position" && {!(_position isEqualType []) || {!(_position isEqualTypeArray [0, 0, 0])}}) exitWith { + ERROR_2("setCarryable: Bad position parameter [%1] for [%2], should be a 3D position or nil",_position,_object); +}; + +if (!isNil "_direction" && {!(_direction isEqualType 0)}) exitWith { + ERROR_2("setCarryable: Bad direction parameter [%1] for [%2], should be a number or nil",_direction,_object); +}; + +// Handle global here +if (_global) exitWith { + private _jipID = format [QGVAR(carrying_%1), hashValue _object]; + [QGVAR(setCarryable), [_object, _enableCarry, _position, _direction, _ignoreWeightCarry], _jipID] call CBA_fnc_globalEventJIP; + + // Remove from JIP queue if object is deleted + if !(_object getVariable [QGVAR(setCarryableRemoveJip), false]) then { + [_jipID, _object] call CBA_fnc_removeGlobalEventJIP; + + _object setVariable [QGVAR(setCarryableRemoveJip), true, true]; + }; +}; if (isNil "_position") then { _position = _object getVariable [QGVAR(carryPosition), [0, 1, 1]]; @@ -56,6 +87,7 @@ GVAR(initializedClasses_carry) = _initializedClasses; private _icon = [QPATHTOF(UI\icons\box_carry.paa), QPATHTOF(UI\icons\person_carry.paa)] select (_object isKindOf "CAManBase"); +//IGNORE_PRIVATE_WARNING ["_target", "_player"]; private _carryAction = [ QGVAR(carry), LLSTRING(Carry), @@ -68,7 +100,7 @@ private _carryAction = [ private _dropAction = [ QGVAR(drop_carry), - LLSTRING(Drop), + LELSTRING(common,Drop), "", { [_player, _target] call FUNC(dropObject_carry) @@ -78,3 +110,5 @@ private _dropAction = [ [_type, 0, ["ACE_MainActions"], _carryAction] call EFUNC(interact_menu,addActionToClass); [_type, 0, [], _dropAction] call EFUNC(interact_menu,addActionToClass); + +nil // return diff --git a/addons/dragging/functions/fnc_setDraggable.sqf b/addons/dragging/functions/fnc_setDraggable.sqf index e024ec5be29..ebec7d64267 100644 --- a/addons/dragging/functions/fnc_setDraggable.sqf +++ b/addons/dragging/functions/fnc_setDraggable.sqf @@ -5,21 +5,52 @@ * * Arguments: * 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) + * 1: True to enable dragging, false to disable (default: false) + * 2: Position offset for attachTo command (default: [0, 1.5, 0]) + * 3: Direction in degrees to rotate the object after attachTo (default: 0) * 4: Override weight limit (default: false) + * 5: Apply globally (default: false) * * Return Value: * None * * Example: - * [cursorTarget, 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 */ -params ["_object", "_enableDrag", "_position", "_direction", ["_ignoreWeightDrag", false, [false]]]; +params [ + ["_object", objNull, [objNull]], + ["_enableDrag", false, [false]], + "_position", + "_direction", + ["_ignoreWeightDrag", false, [false]], + ["_global", false, [false]] +]; + +if (isNull _object) exitWith {}; + +if (!isNil "_position" && {!(_position isEqualType []) || {!(_position isEqualTypeArray [0, 0, 0])}}) exitWith { + ERROR_2("setDraggable: Bad position parameter [%1] for [%2], should be a 3D position or nil",_position,_object); +}; + +if (!isNil "_direction" && {!(_direction isEqualType 0)}) exitWith { + ERROR_2("setDraggable: Bad direction parameter [%1] for [%2], should be a number or nil",_direction,_object); +}; + +// Handle global here +if (_global) exitWith { + private _jipID = format [QGVAR(dragging_%1), hashValue _object]; + [QGVAR(setDraggable), [_object, _enableDrag, _position, _direction, _ignoreWeightDrag], _jipID] call CBA_fnc_globalEventJIP; + + // Remove from JIP queue if object is deleted + if !(_object getVariable [QGVAR(setDraggableRemoveJip), false]) then { + [_jipID, _object] call CBA_fnc_removeGlobalEventJIP; + + _object setVariable [QGVAR(setDraggableRemoveJip), true, true]; + }; +}; if (isNil "_position") then { _position = _object getVariable [QGVAR(dragPosition), [0, 1.5, 0]]; @@ -56,6 +87,7 @@ GVAR(initializedClasses) = _initializedClasses; private _icon = [QPATHTOF(UI\icons\box_drag.paa), QPATHTOF(UI\icons\person_drag.paa)] select (_object isKindOf "CAManBase"); +//IGNORE_PRIVATE_WARNING ["_target", "_player"]; private _dragAction = [ QGVAR(drag), LLSTRING(Drag), @@ -68,7 +100,7 @@ private _dragAction = [ private _dropAction = [ QGVAR(drop), - LLSTRING(Drop), + LELSTRING(common,Drop), "", { [_player, _target] call FUNC(dropObject); @@ -78,3 +110,5 @@ private _dropAction = [ [_type, 0, ["ACE_MainActions"], _dragAction] call EFUNC(interact_menu,addActionToClass); [_type, 0, [], _dropAction] call EFUNC(interact_menu,addActionToClass); + +nil // return diff --git a/addons/dragging/functions/fnc_startCarry.sqf b/addons/dragging/functions/fnc_startCarry.sqf index 3e2cc17efde..99652fc263d 100644 --- a/addons/dragging/functions/fnc_startCarry.sqf +++ b/addons/dragging/functions/fnc_startCarry.sqf @@ -15,6 +15,7 @@ * * Public: No */ + params ["_unit", "_target"]; // Try to claim the object diff --git a/addons/dragging/functions/fnc_startCarryLocal.sqf b/addons/dragging/functions/fnc_startCarryLocal.sqf index 15101e29508..cf17dfb311d 100644 --- a/addons/dragging/functions/fnc_startCarryLocal.sqf +++ b/addons/dragging/functions/fnc_startCarryLocal.sqf @@ -31,6 +31,9 @@ if !(_target getVariable [QGVAR(ignoreWeightCarry), false]) then { // Exit if object weight is over global var value if (_weight > GETMVAR(ACE_maxWeightCarry,1E11)) exitWith { + // Release claim on object + [objNull, _target, true] call EFUNC(common,claim); + [LLSTRING(UnableToDrag)] call EFUNC(common,displayTextStructured); }; @@ -38,6 +41,11 @@ private _timer = CBA_missionTime + 5; // Handle objects vs. persons if (_target isKindOf "CAManBase") then { + // Create clone for dead units + if (!alive _target) then { + _target = [_unit, _target] call FUNC(createClone); + }; + private _primaryWeapon = primaryWeapon _unit; // Add a primary weapon if the unit has none @@ -46,8 +54,8 @@ if (_target isKindOf "CAManBase") then { _primaryWeapon = "ACE_FakePrimaryWeapon"; }; - // Select primary, otherwise the drag animation actions don't work - _unit selectWeapon _primaryWeapon; + // Select primary, otherwise the carry animation actions don't work + _unit selectWeapon _primaryWeapon; // This turns off lasers/lights // Move a bit closer and adjust direction when trying to pick up a person [QEGVAR(common,setDir), [_target, getDir _unit + 180], _target] call CBA_fnc_targetEvent; @@ -59,10 +67,11 @@ if (_target isKindOf "CAManBase") then { _timer = CBA_missionTime + 10; } else { // Select no weapon and stop sprinting - private _previousWeaponIndex = [_unit] call EFUNC(common,getFiremodeIndex); - _unit setVariable [QGVAR(previousWeapon), _previousWeaponIndex, true]; + if (currentWeapon _unit != "") then { + _unit setVariable [QGVAR(previousWeapon), (weaponState _unit) select [0, 3], true]; - _unit action ["SwitchWeapon", _unit, _unit, 299]; + _unit action ["SwitchWeapon", _unit, _unit, 299]; + }; [_unit, "AmovPercMstpSnonWnonDnon", 0] call EFUNC(common,doAnimation); @@ -78,10 +87,10 @@ if (_target isKindOf "CAManBase") then { // Prevents dragging and carrying at the same time _unit setVariable [QGVAR(isCarrying), true, true]; -// Required for aborting animation +// Required for aborting (animation & keybind) _unit setVariable [QGVAR(carriedObject), _target, true]; -[FUNC(startCarryPFH), 0.2, [_unit, _target, _timer]] call CBA_fnc_addPerFrameHandler; +[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; @@ -90,3 +99,6 @@ if (_mass > 1) then { _target setVariable [QGVAR(originalMass), _mass, true]; [QEGVAR(common,setMass), [_target, 1e-12]] call CBA_fnc_globalEvent; // Force global sync }; + +// API +[QGVAR(setupCarry), [_unit, _target]] call CBA_fnc_localEvent; diff --git a/addons/dragging/functions/fnc_startCarryPFH.sqf b/addons/dragging/functions/fnc_startCarryPFH.sqf index ca34275a2c7..aefe6d76fcb 100644 --- a/addons/dragging/functions/fnc_startCarryPFH.sqf +++ b/addons/dragging/functions/fnc_startCarryPFH.sqf @@ -32,9 +32,9 @@ if !(_unit getVariable [QGVAR(isCarrying), false]) exitWith { _idPFH call CBA_fnc_removePerFrameHandler; }; -// Same as dragObjectPFH, checks if object is deleted or dead OR (target moved away from carrier (weapon disasembled)) -if (!alive _target || {_unit distance _target > 10}) then { - TRACE_4("dead/distance",_unit,_target,_timeOut,CBA_missionTime); +// Drop if the target is destroyed, if the target moved away from carrier (e.g. weapon disassembled) or if the carrier starts limping +if !(alive _target && {_unit distance _target <= 10} && {_unit getHitPointDamage "HitLegs" < 0.5}) exitWith { + TRACE_4("dead/distance/limping",_unit,_target,_timeOut,CBA_missionTime); [_unit, _target] call FUNC(dropObject_carry); _idPFH call CBA_fnc_removePerFrameHandler; @@ -42,7 +42,7 @@ if (!alive _target || {_unit distance _target > 10}) then { // Handle persons vs. objects if (_target isKindOf "CAManBase") then { - // Drop if in timeout + // Carry person after timeout (animation takes a long time to finish) if (CBA_missionTime > _timeOut) exitWith { TRACE_4("Start carry person",_unit,_target,_timeOut,CBA_missionTime); [_unit, _target] call FUNC(carryObject); @@ -50,13 +50,12 @@ if (_target isKindOf "CAManBase") then { _idPFH call CBA_fnc_removePerFrameHandler; }; } else { - // Drop if in timeout + // Timeout: Drop target. CBA_missionTime, because anim length is linked to ingame time if (CBA_missionTime > _timeOut) exitWith { TRACE_4("timeout",_unit,_target,_timeOut,CBA_missionTime); - _idPFH call CBA_fnc_removePerFrameHandler; + [_unit, _target] call FUNC(dropObject_carry); - private _draggedObject = _unit getVariable [QGVAR(draggedObject), objNull]; - [_unit, _draggedObject] call FUNC(dropObject_carry); + _idPFH call CBA_fnc_removePerFrameHandler; }; // Wait for the unit to stand up diff --git a/addons/dragging/functions/fnc_startDrag.sqf b/addons/dragging/functions/fnc_startDrag.sqf index 8dd6db6dee5..d65f218acd7 100644 --- a/addons/dragging/functions/fnc_startDrag.sqf +++ b/addons/dragging/functions/fnc_startDrag.sqf @@ -15,6 +15,7 @@ * * Public: No */ + params ["_unit", "_target"]; // Try to claim the object diff --git a/addons/dragging/functions/fnc_startDragLocal.sqf b/addons/dragging/functions/fnc_startDragLocal.sqf index b656c8ce5a7..f0468f133ba 100644 --- a/addons/dragging/functions/fnc_startDragLocal.sqf +++ b/addons/dragging/functions/fnc_startDragLocal.sqf @@ -31,19 +31,25 @@ if !(_target getVariable [QGVAR(ignoreWeightDrag), false]) then { // Exit if object weight is over global var value if (_weight > GETMVAR(ACE_maxWeightDrag,1E11)) exitWith { + // Release claim on object + [objNull, _target, true] call EFUNC(common,claim); + [LLSTRING(UnableToDrag)] call EFUNC(common,displayTextStructured); }; private _primaryWeapon = primaryWeapon _unit; // Add a primary weapon if the unit has none -if !(GVAR(dragAndFire)) then { +if (!GVAR(dragAndFire)) then { if (_primaryWeapon == "") then { _unit addWeapon "ACE_FakePrimaryWeapon"; _primaryWeapon = "ACE_FakePrimaryWeapon"; }; - _unit selectWeapon _primaryWeapon; + // Keep the laser/light on if the weapon is already selected + if (currentWeapon _unit != _primaryWeapon) then { + _unit selectWeapon _primaryWeapon; + }; } else { // Making sure the unit is holding a primary weapon or handgun private _handgunWeapon = handgunWeapon _unit; @@ -84,6 +90,11 @@ if !(_unit call EFUNC(common,isSwimming)) then { // Move a bit closer and adjust direction when trying to pick up a person if (_target isKindOf "CAManBase") then { + // Create clone for dead units + if (!alive _target) then { + _target = [_unit, _target] call FUNC(createClone); + }; + [QEGVAR(common,setDir), [_target, getDir _unit + 180], _target] call CBA_fnc_targetEvent; _target setPosASL (getPosASL _unit vectorAdd (vectorDir _unit vectorMultiply 1.5)); @@ -93,7 +104,10 @@ if (_target isKindOf "CAManBase") then { // Prevents dragging and carrying at the same time _unit setVariable [QGVAR(isDragging), true, true]; -[FUNC(startDragPFH), 0.2, [_unit, _target, CBA_missionTime + 5]] call CBA_fnc_addPerFrameHandler; +// Required for aborting (keybind) +_unit setVariable [QGVAR(draggedObject), _target, 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; @@ -102,3 +116,6 @@ if (_mass > 1) then { _target setVariable [QGVAR(originalMass), _mass, true]; [QEGVAR(common,setMass), [_target, 1e-12]] call CBA_fnc_globalEvent; // Force global sync }; + +// API +[QGVAR(setupDrag), [_unit, _target]] call CBA_fnc_localEvent; diff --git a/addons/dragging/functions/fnc_startDragPFH.sqf b/addons/dragging/functions/fnc_startDragPFH.sqf index 07dfe2064f7..e1cf75b38e0 100644 --- a/addons/dragging/functions/fnc_startDragPFH.sqf +++ b/addons/dragging/functions/fnc_startDragPFH.sqf @@ -32,22 +32,20 @@ if !(_unit getVariable [QGVAR(isDragging), false]) exitWith { _idPFH call CBA_fnc_removePerFrameHandler; }; -// Same as dragObjectPFH, checks if object is deleted, dead or target moved away from carrier (e.g. weapon disassembled) -if (!alive _target || {_unit distance _target > 10}) then { +// Drop if the target is destroyed or if the target moved away from carrier (e.g. weapon disassembled) +if (!alive _target || {_unit distance _target > 10}) exitWith { TRACE_4("dead/distance",_unit,_target,_timeOut,CBA_missionTime); [_unit, _target] call FUNC(dropObject); _idPFH call CBA_fnc_removePerFrameHandler; }; -// Timeout: Do nothing, quit. CBA_missionTime, because anim length is linked to ingame time +// Timeout: Drop target. CBA_missionTime, because anim length is linked to ingame time if (CBA_missionTime > _timeOut) exitWith { TRACE_4("timeout",_unit,_target,_timeOut,CBA_missionTime); - _idPFH call CBA_fnc_removePerFrameHandler; + [_unit, _target] call FUNC(dropObject); - // Drop if in timeout - private _draggedObject = _unit getVariable [QGVAR(draggedObject), objNull]; - [_unit, _draggedObject] call FUNC(dropObject); + _idPFH call CBA_fnc_removePerFrameHandler; }; // Unit is ready to start dragging diff --git a/addons/dragging/initKeybinds.inc.sqf b/addons/dragging/initKeybinds.inc.sqf index a8792f35763..b7c3a2ace00 100644 --- a/addons/dragging/initKeybinds.inc.sqf +++ b/addons/dragging/initKeybinds.inc.sqf @@ -19,6 +19,7 @@ }; private _cursorObject = cursorObject; + if (_cursorObject isKindOf "CaManBase" && {unitIsUAV _cursorObject}) then { _cursorObject = vehicle _cursorObject }; if (isNull _cursorObject || {(_cursorObject distance _player) > 2.6}) exitWith {false}; if !([_player, _cursorObject] call FUNC(canDrag)) exitWith {false}; @@ -48,6 +49,7 @@ }; private _cursorObject = cursorObject; + if (_cursorObject isKindOf "CaManBase" && {unitIsUAV _cursorObject}) then { _cursorObject = vehicle _cursorObject }; if (isNull _cursorObject || {(_cursorObject distance _player) > 2.6}) exitWith {false}; if !([_player, _cursorObject] call FUNC(canCarry)) exitWith {false}; diff --git a/addons/dragging/initSettings.inc.sqf b/addons/dragging/initSettings.inc.sqf index 039327330d7..37feef4cbc4 100644 --- a/addons/dragging/initSettings.inc.sqf +++ b/addons/dragging/initSettings.inc.sqf @@ -21,7 +21,7 @@ [LSTRING(allowRunWithLightweight_DisplayName), LSTRING(allowRunWithLightweight_Description)], LLSTRING(SettingsName), true, - true + 1 ] call CBA_fnc_addSetting; [ @@ -30,5 +30,5 @@ [LSTRING(skipContainerWeight_DisplayName), LSTRING(skipContainerWeight_Description)], LLSTRING(SettingsName), false, - true + 1 ] call CBA_fnc_addSetting; diff --git a/addons/dragging/stringtable.xml b/addons/dragging/stringtable.xml index 7cf53ba55c6..c2f96ce55ac 100644 --- a/addons/dragging/stringtable.xml +++ b/addons/dragging/stringtable.xml @@ -167,6 +167,7 @@ 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. @@ -178,6 +179,7 @@ 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 @@ -189,10 +191,11 @@ 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. @@ -200,6 +203,7 @@ Défini si le poids d'un objet est ajouté aux calculs du poids. Determina se o peso do objeto é adicionado aos cálculos de peso. Определяет, добавляется ли вес объекта при расчете веса. + Determina si el peso del objeto es añadido en los cálculos de peso. Max Weight Coefficient @@ -210,6 +214,7 @@ Maximaler Gewichtskoeffizient 最大重量係数 Максимальный коэффициент веса + Máximo Coeficiente de Peso Modifies weight limit calculations. Set to 0 to ignore. @@ -220,6 +225,7 @@ Ä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 f736e8451ba..3a5a4a1ed6d 100644 --- a/addons/dragon/CfgAmmo.hpp +++ b/addons/dragon/CfgAmmo.hpp @@ -1,3 +1,4 @@ +class ace_missileguidance_type_Dragon; class CfgAmmo { class ammo_Penetrator_Base; class M_Scalpel_AT; @@ -37,39 +38,7 @@ class CfgAmmo { EGVAR(vehicle_damage,incendiary) = 1.0; - class ace_missileguidance { - minDeflection = 0; - maxDeflection = 0; - incDeflection = 0; - - canVanillaLock = 0; - - // Guidance type for munitions - defaultSeekerType = "SACLOS"; - seekerTypes[] = { "SACLOS" }; - - defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = { "LOAL", "LOBL" }; - - seekLastTargetPos = 0; - seekerAngle = 30; - seekerAccuracy = 1; - - seekerMinRange = 65; - seekerMaxRange = 1000; - - correctionDistance = 30; - missileLeadDistance = 0; - offsetFromCrosshair[] = { 0, 0, 0 }; - - serviceInterval = 0.33; // how many seconds between pops - serviceCharges = 32; // how many charges are in this missile - serviceChargeAcceleration = 6.5; - dragonSpeed = 100; // meters per second - - defaultAttackProfile = "DRAGON"; - attackProfiles[] = {"DRAGON"}; - }; + class ace_missileguidance: ace_missileguidance_type_Dragon {}; }; class GVAR(super): GVAR(dragonBase) { @@ -79,33 +48,11 @@ class CfgAmmo { submunitionParentSpeedCoef = 0; submunitionInitialOffset[] = { 0, 0, -0.2 }; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance { enabled = 1; - - // Guidance type for munitions - defaultSeekerType = "SACLOS"; - seekerTypes[] = { "SACLOS" }; - - defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = { "LOAL", "LOBL" }; - - seekLastTargetPos = 0; - seekerAngle = 30; - seekerAccuracy = 1; - seekerMinRange = 30; seekerMaxRange = 1500; - - correctionDistance = 30; - missileLeadDistance = 0; - - serviceInterval = 0.33; // how many seconds between pops serviceCharges = 60; // how many charges are in this missile - serviceChargeAcceleration = 6.5; - dragonSpeed = 100; // meters per second - - defaultAttackProfile = "DRAGON"; - attackProfiles[] = {"DRAGON"}; }; }; diff --git a/addons/dragon/CfgVehicles.hpp b/addons/dragon/CfgVehicles.hpp index 13441c6c26a..9cc60771b51 100644 --- a/addons/dragon/CfgVehicles.hpp +++ b/addons/dragon/CfgVehicles.hpp @@ -107,7 +107,7 @@ class CfgVehicles { soundGetIn[] = {"A3\sounds_f\dummysound",0.00031622776,1,5}; armorStructural = 10.0; - class ACE_CSW { + class ace_csw { disassembleTo = QGVAR(super); }; diff --git a/addons/dragon/CfgWeapons.hpp b/addons/dragon/CfgWeapons.hpp index 9cb58e2c1f4..0bdd53e34f2 100644 --- a/addons/dragon/CfgWeapons.hpp +++ b/addons/dragon/CfgWeapons.hpp @@ -19,7 +19,7 @@ class CfgWeapons { descriptionShort = CSTRING(dragonDescription); scope = 2; - class ACE_CSW { + class ace_csw { type = "mount"; deployTime = 2; pickupTime = 2; @@ -75,7 +75,7 @@ class CfgWeapons { opticsZoomMin = 0.055; opticsZoomMax = 0.055; scope = 2; - class ACE_CSW { + class ace_csw { type = "weapon"; deployTime = 2; pickupTime = 1; diff --git a/addons/dragon/XEH_postInit.sqf b/addons/dragon/XEH_postInit.sqf index 0305fe772a9..2360a5bd971 100644 --- a/addons/dragon/XEH_postInit.sqf +++ b/addons/dragon/XEH_postInit.sqf @@ -6,7 +6,7 @@ ["vehicle", { params ["","_vehicle"]; TRACE_2("vehicle change",_vehicle,typeOf _vehicle); - if (!(_vehicle isKindOf QGVAR(staticBase))) exitWith {}; + if !(_vehicle isKindOf QGVAR(staticBase)) exitWith {}; _vehicle animate ["rest_rotate", 0]; @@ -14,7 +14,7 @@ [GVAR(pfID)] call CBA_fnc_removePerFrameHandler; private _lastView = cameraView; - if (!(_lastView in ["INTERNAL", "EXTERNAL"])) then { _lastView == "INTERNAL"; }; + if !(_lastView in ["INTERNAL", "EXTERNAL"]) then { _lastView == "INTERNAL"; }; GVAR(pfID) = [{ params ["_args"]; diff --git a/addons/dragon/functions/fnc_attackProfile_DRAGON.sqf b/addons/dragon/functions/fnc_attackProfile_DRAGON.sqf index 58e3844c882..6642d7d7de0 100644 --- a/addons/dragon/functions/fnc_attackProfile_DRAGON.sqf +++ b/addons/dragon/functions/fnc_attackProfile_DRAGON.sqf @@ -23,7 +23,7 @@ _attackProfileStateParams params ["_maxCorrectableDistance", "_wireCut", "_seeke private _projectilePos = getPosASL _projectile; private _distanceToProjectile = (getPosASL _shooter) vectorDistanceSqr _projectilePos; -private _retPos = _projectilePos vectorAdd (AGLtoASL (_projectile vectorModelToWorld [0, 50, 0])); +private _retPos = _projectilePos vectorAdd (AGLToASL (_projectile vectorModelToWorld [0, 50, 0])); // _shooter returns the vehicle that shot it. If the launcher dies, the wire would probably be cut so assume it if ((_distanceToProjectile > _seekerMaxRangeSqr) || _wireCut || { !alive _shooter }) exitWith { diff --git a/addons/dragon/functions/fnc_onFired.sqf b/addons/dragon/functions/fnc_onFired.sqf index 4228f5dff0e..5e56a045081 100644 --- a/addons/dragon/functions/fnc_onFired.sqf +++ b/addons/dragon/functions/fnc_onFired.sqf @@ -15,6 +15,8 @@ * * Public: No */ +#define DEFAULT_CORRECTION_DISTANCE 2 + params ["_firedEH", "", "", "_seekerParams", "_stateParams"]; _firedEH params ["_shooter","_weapon","","","","","_projectile"]; _stateParams params ["", "", "_attackProfileStateParams"]; diff --git a/addons/dragon/functions/fnc_sightAttach.sqf b/addons/dragon/functions/fnc_sightAttach.sqf index 76ad9c33565..de085942b7d 100644 --- a/addons/dragon/functions/fnc_sightAttach.sqf +++ b/addons/dragon/functions/fnc_sightAttach.sqf @@ -21,7 +21,7 @@ params ["_target", "_unit", ["_event", false]]; TRACE_3("sightAttach",_target,_unit,_event); if (_event isEqualTo true) then { // this is actually needed as 3rd arg may not be bool - if (!(_target turretLocal [0])) exitWith {}; + if !(_target turretLocal [0]) exitWith {}; _target setVariable [QGVAR(sightAttached), true, true]; _target animate ["optic_hide", 0]; _target addWeapon QGVAR(superStatic); diff --git a/addons/dragon/functions/fnc_sightDetach.sqf b/addons/dragon/functions/fnc_sightDetach.sqf index c9d03e22e64..a5ac159a335 100644 --- a/addons/dragon/functions/fnc_sightDetach.sqf +++ b/addons/dragon/functions/fnc_sightDetach.sqf @@ -23,7 +23,7 @@ params ["_target", "_unit", ["_event", false]]; TRACE_3("sightDetach",_target,_unit,_event); if (_event isEqualTo true) then { // this is actually needed as 3rd arg may not be bool - if (!(_target turretLocal [0])) exitWith {}; + if !(_target turretLocal [0]) exitWith {}; _target setVariable [QGVAR(sightAttached), false, true]; _target animate ["optic_hide", 1]; _target removeWeapon QGVAR(superStatic); diff --git a/addons/explosives/ACE_Arsenal_Stats.hpp b/addons/explosives/ACE_Arsenal_Stats.hpp index 821ac65bfd1..c2c33b7f0a7 100644 --- a/addons/explosives/ACE_Arsenal_Stats.hpp +++ b/addons/explosives/ACE_Arsenal_Stats.hpp @@ -7,7 +7,7 @@ class EGVAR(arsenal,stats) { 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); + condition = QUOTE(getNumber (_this select 1 >> QQGVAR(detonator)) > 0); tabs[] = {{}, {7}}; }; }; diff --git a/addons/explosives/ACE_Triggers.hpp b/addons/explosives/ACE_Triggers.hpp index 27d63a736dd..a94ad95eaa4 100644 --- a/addons/explosives/ACE_Triggers.hpp +++ b/addons/explosives/ACE_Triggers.hpp @@ -18,7 +18,7 @@ class ACE_Triggers { isAttachable = 1; displayName = CSTRING(clacker_displayName); picture = QPATHTOF(Data\UI\Clacker.paa); - onPlace = QUOTE(_this call FUNC(AddClacker);false); + onPlace = QUOTE(_this call FUNC(addClacker); false); requires[] = {"ACE_Clacker"}; }; class MK16_Transmitter: Command { @@ -37,7 +37,7 @@ class ACE_Triggers { isAttachable = 1; displayName = CSTRING(cellphone_displayName); picture = QPATHTOF(Data\UI\Cellphone_UI.paa); - onPlace = QUOTE(_this call FUNC(addCellphoneIED);false); + onPlace = QUOTE(_this call FUNC(addCellphoneIED); false); requires[] = {"ACE_Cellphone"}; }; class PressurePlate { diff --git a/addons/explosives/CfgAmmo.hpp b/addons/explosives/CfgAmmo.hpp index c02885362ee..bfe48d8fa9e 100644 --- a/addons/explosives/CfgAmmo.hpp +++ b/addons/explosives/CfgAmmo.hpp @@ -3,47 +3,41 @@ class CfgAmmo { class Default; class TimeBombCore: Default { - GVAR(DefuseTime) = 5; + GVAR(defuseTime) = 5; }; - /* - class BoundingMineCore: TimeBombCore; - class BoundingMineBase: BoundingMineCore; - class APERSBoundingMine_Range_Ammo: BoundingMineBase; - class MineCore: TimeBombCore; - class MineBase: MineCore; - class APERSMine_Range_Ammo: MineBase; - class ATMine_Range_Ammo: MineBase; - - class DirectionalBombCore: TimeBombCore; - class DirectionalBombBase: DirectionalBombCore; - - class SLAMDirectionalMine_Wire_Ammo: DirectionalBombBase; - - class PipeBombCore: TimeBombCore; - class PipeBombBase: PipeBombCore; - */ // GVAR(size) = 0; is small size // GVAR(size) = 1; is large size - class DirectionalBombBase; - class ClaymoreDirectionalMine_Remote_Ammo: DirectionalBombBase { + class ClaymoreDirectionalMine_Remote_Ammo; + class ACE_ClaymoreDirectionalMine_Remote_Ammo: ClaymoreDirectionalMine_Remote_Ammo { // Wrapper class to avoid unintentional changes to third-party mods. Ref #10105 GVAR(magazine) = "ClaymoreDirectionalMine_Remote_Mag"; - GVAR(Explosive) = "ClaymoreDirectionalMine_Remote_Ammo_Scripted"; GVAR(size) = 0; GVAR(defuseObjectPosition)[] = {0, 0, 0.038}; soundActivation[] = {"", 0, 0, 0}; soundDeactivation[] = {"", 0, 0, 0}; + + // Reduce vanilla damage, so that it doesn't destroy buildings + hit = 10; + indirectHit = 10; }; - // class ClaymoreDirectionalMine_Remote_Ammo_Scripted: ClaymoreDirectionalMine_Remote_Ammo {}; + class DirectionalBombBase; class APERSTripMine_Wire_Ammo: DirectionalBombBase { GVAR(defuseObjectPosition)[] = {-1.415, 0, 0.12}; GVAR(size) = 0; }; + class APERSBoundingMine_Range_Ammo; + class ACE_APERSBoundingMine_Range_Ammo: APERSBoundingMine_Range_Ammo { + // Reduce vanilla damage, so that it doesn't destroy buildings + hit = 10; + indirectHit = 10; + CraterEffects = "MineCrater"; + }; + class ACE_FlareTripMine_Wire_Ammo: APERSTripMine_Wire_Ammo { SoundSetExplosion[] = {}; - defaultMagazine = "ACE_FlareTripMine_Mag"; //Mag that gets dropped after defuse + defaultMagazine = "ACE_FlareTripMine_Mag"; // Mag that gets dropped after defuse hit = 0; indirectHit = 0; indirectHitRange = 0; @@ -65,9 +59,16 @@ class CfgAmmo { GVAR(size) = 0; }; + // More sensitive pressure-fuze for the Vanilla AT Mine. + class MineBase; + class ATMine_Range_Ammo: MineBase { + mineTrigger = "ACE_TankTriggerLight"; + }; + // "The SLAM has an anti-tamper feature that is only active in the bottom- and side-attack modes." class SLAMDirectionalMine_Wire_Ammo: DirectionalBombBase { indirectHitRange = 20; + explosionAngle = 60; GVAR(explodeOnDefuseChance) = 1; GVAR(magazine) = "SLAMDirectionalMine_Wire_Mag"; GVAR(size) = 0; @@ -83,16 +84,17 @@ class CfgAmmo { class ACE_SLAMDirectionalMine_Magnetic_Ammo: SLAMDirectionalMine_Wire_Ammo { mineTrigger = "ACE_MagneticTrigger"; GVAR(explodeOnDefuseChance) = 1; - explosionAngle = 360; - indirectHitRange = 1; + explosionAngle = 60; + hit = 3000; + indirectHit = 3000; + indirectHitRange = 10; mineInconspicuousness = 25; icon = "iconExplosiveGP"; }; - class PipeBombBase; - class DemoCharge_Remote_Ammo: PipeBombBase { + class DemoCharge_Remote_Ammo; + class ACE_DemoCharge_Remote_Ammo: DemoCharge_Remote_Ammo { GVAR(magazine) = "DemoCharge_Remote_Mag"; - GVAR(Explosive) = "DemoCharge_Remote_Ammo_Scripted"; // can probably remove as base ammo now has triggerWhenDestroyed GVAR(size) = 0; GVAR(defuseObjectPosition)[] = {0.07, 0, 0.055}; soundActivation[] = {"", 0, 0, 0}; @@ -101,16 +103,14 @@ class CfgAmmo { indirectHit = 500; indirectHitRange = 7; }; + class PipeBombBase; class SatchelCharge_Remote_Ammo: PipeBombBase { GVAR(magazine) = "SatchelCharge_Remote_Mag"; - GVAR(Explosive) = "SatchelCharge_Remote_Ammo_Scripted"; // can probably remove as base ammo now has triggerWhenDestroyed GVAR(size) = 0; GVAR(defuseObjectPosition)[] = {0.1, 0.1, 0.05}; soundActivation[] = {"", 0, 0, 0}; soundDeactivation[] = {"", 0, 0, 0}; }; - // class DemoCharge_Remote_Ammo_Scripted: DemoCharge_Remote_Ammo {}; - // class SatchelCharge_Remote_Ammo_Scripted: SatchelCharge_Remote_Ammo {}; class IEDUrbanBig_Remote_Ammo: PipeBombBase { triggerWhenDestroyed = 1; @@ -168,10 +168,9 @@ class CfgAmmo { mineTrigger = "RangeTriggerShort"; }; - // Orange DLC: + // Orange DLC class APERSMineDispenser_Ammo: PipeBombBase { GVAR(magazine) = "APERSMineDispenser_Mag"; - GVAR(Explosive) = "APERSMineDispenser_Ammo_Scripted"; // triggerWhenDestroyed = 1; GVAR(size) = 0; GVAR(defuseObjectPosition)[] = {0.0, -0.05, 0.15}; }; @@ -181,7 +180,6 @@ class CfgAmmo { GVAR(size) = 0; GVAR(defuseObjectPosition)[] = {0, 0, 0.15}; }; - class MineBase; class UnderwaterMine_Range_Ammo: MineBase { GVAR(size) = 1; }; diff --git a/addons/explosives/CfgEventHandlers.hpp b/addons/explosives/CfgEventHandlers.hpp index ae0e5fe5410..fe3119a580b 100644 --- a/addons/explosives/CfgEventHandlers.hpp +++ b/addons/explosives/CfgEventHandlers.hpp @@ -9,6 +9,7 @@ class Extended_PreInit_EventHandlers { init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; + class Extended_PostInit_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); @@ -26,6 +27,7 @@ class Extended_Take_EventHandlers { GVAR(takeHandler) = QUOTE(call FUNC(onInventoryChanged)); }; }; + class Extended_Put_EventHandlers { class CAManBase { GVAR(takeHandler) = QUOTE([ARR_3(_this select 1,_this select 0,_this select 2)] call FUNC(onInventoryChanged)); @@ -42,4 +44,9 @@ class Extended_Init_EventHandlers { class ACE_Explosives_Place_SLAM { ADDON = QUOTE(params ['_mine']; if (local _mine) then {_mine setCenterOfMass [ARR_3(0,-0.035,0.05)]; _mine setMass 5}); }; + class ACE_ModuleMine_SLAMBottomMine { + class ADDON { + init = QUOTE(params ['_mine']; if (local _mine) then { [ARR_2({_this call CALLSTACK(BIS_fnc_setPitchBank)},[ARR_3(_mine,MINE_PITCH_UP,0)])] call CBA_fnc_execNextFrame }); + }; + }; }; diff --git a/addons/explosives/CfgMagazines.hpp b/addons/explosives/CfgMagazines.hpp index 7bb2c6ff02d..71e374be1d5 100644 --- a/addons/explosives/CfgMagazines.hpp +++ b/addons/explosives/CfgMagazines.hpp @@ -1,10 +1,9 @@ class CfgMagazines { class CA_Magazine; class ATMine_Range_Mag: CA_Magazine { - GVAR(Placeable) = 1; useAction = 0; - GVAR(SetupObject) = "ACE_Explosives_Place_ATMine"; // CfgVehicle class for setup object. - GVAR(DelayTime) = 2.5; + GVAR(placeable) = 1; + GVAR(setupObject) = "ACE_Explosives_Place_ATMine"; // CfgVehicle class for setup object class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -13,7 +12,7 @@ class CfgMagazines { }; }; class APERSBoundingMine_Range_Mag: ATMine_Range_Mag { - GVAR(SetupObject) = "ACE_Explosives_Place_APERSBoundingMine"; + GVAR(setupObject) = "ACE_Explosives_Place_APERSBoundingMine"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -22,7 +21,7 @@ class CfgMagazines { }; }; class APERSMine_Range_Mag: ATMine_Range_Mag { - GVAR(SetupObject) = "ACE_Explosives_Place_APERSMine"; + GVAR(setupObject) = "ACE_Explosives_Place_APERSMine"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { @@ -31,7 +30,7 @@ class CfgMagazines { }; }; class APERSTripMine_Wire_Mag: ATMine_Range_Mag { - GVAR(SetupObject) = "ACE_Explosives_Place_APERSTripwireMine"; + GVAR(setupObject) = "ACE_Explosives_Place_APERSTripwireMine"; class ACE_Triggers { SupportedTriggers[] = {"Tripwire"}; class Tripwire; @@ -40,17 +39,16 @@ class CfgMagazines { class ACE_FlareTripMine_Mag: APERSTripMine_Wire_Mag { author = ECSTRING(common,aceteam); ammo = "ACE_FlareTripMine_Wire_Ammo"; - GVAR(SetupObject) = "ACE_Explosives_Place_APERSTripwireMine"; + GVAR(setupObject) = "ACE_Explosives_Place_APERSTripwireMine"; displayName = CSTRING(TripFlare_Name); descriptionShort = CSTRING(TripFlare_Description); class Library {libTextDesc = CSTRING(TripFlare_Description);}; }; class ClaymoreDirectionalMine_Remote_Mag: CA_Magazine { - GVAR(Placeable) = 1; useAction = 0; - GVAR(SetupObject) = "ACE_Explosives_Place_Claymore"; - GVAR(DelayTime) = 1.5; + GVAR(placeable) = 1; + GVAR(setupObject) = "ACE_Explosives_Place_Claymore"; class ACE_Triggers { SupportedTriggers[] = {"Command", "MK16_Transmitter"}; class Command { @@ -61,10 +59,9 @@ class CfgMagazines { }; class SatchelCharge_Remote_Mag: CA_Magazine { - GVAR(Placeable) = 1; useAction = 0; - GVAR(SetupObject) = "ACE_Explosives_Place_SatchelCharge"; - GVAR(DelayTime) = 1; + GVAR(placeable) = 1; + GVAR(setupObject) = "ACE_Explosives_Place_SatchelCharge"; class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch"}; class Timer { @@ -78,19 +75,19 @@ class CfgMagazines { }; }; class DemoCharge_Remote_Mag: SatchelCharge_Remote_Mag { - GVAR(SetupObject) = "ACE_Explosives_Place_DemoCharge"; + GVAR(setupObject) = "ACE_Explosives_Place_DemoCharge"; model = "\A3\Weapons_F\explosives\c4_charge_small_d"; }; class SLAMDirectionalMine_Wire_Mag: ATMine_Range_Mag { - GVAR(SetupObject) = "ACE_Explosives_Place_SLAM"; + GVAR(setupObject) = "ACE_Explosives_Place_SLAM"; class ACE_Triggers { SupportedTriggers[] = {"IRSensor", "PressurePlate", "Timer", "Command", "MK16_Transmitter"}; class PressurePlate { displayName = CSTRING(SLAME_Magnetic); digDistance = 0; ammo = "ACE_SLAMDirectionalMine_Magnetic_Ammo"; - pitch = 90; + pitch = MINE_PITCH_UP; }; class IRSensor { displayName = CSTRING(SLAME_IRSensor); @@ -107,7 +104,7 @@ class CfgMagazines { }; class IEDUrbanBig_Remote_Mag: DemoCharge_Remote_Mag { - GVAR(SetupObject) = "ACE_Explosives_Place_IEDUrbanBig"; + GVAR(setupObject) = "ACE_Explosives_Place_IEDUrbanBig"; class ACE_Triggers { SupportedTriggers[] = {"Command", "DeadmanSwitch", "Cellphone", "PressurePlate"}; class Command { @@ -125,7 +122,7 @@ class CfgMagazines { }; }; class IEDLandBig_Remote_Mag: IEDUrbanBig_Remote_Mag { - GVAR(SetupObject) = "ACE_Explosives_Place_IEDLandBig"; + GVAR(setupObject) = "ACE_Explosives_Place_IEDLandBig"; picture = "\A3\Weapons_F\Data\UI\gear_mine_AT_CA.paa"; // Fix inconsistent picture class ACE_Triggers: ACE_Triggers { class Command: Command { @@ -139,7 +136,7 @@ class CfgMagazines { }; }; class IEDUrbanSmall_Remote_Mag: DemoCharge_Remote_Mag { - GVAR(SetupObject) = "ACE_Explosives_Place_IEDUrbanSmall"; + GVAR(setupObject) = "ACE_Explosives_Place_IEDUrbanSmall"; picture = "\A3\Weapons_F\Data\UI\gear_mine_AP_bouncing_CA.paa"; // Fix inconsistent picture class ACE_Triggers { SupportedTriggers[] = {"Command", "DeadmanSwitch", "Cellphone", "PressurePlate"}; @@ -158,7 +155,7 @@ class CfgMagazines { }; }; class IEDLandSmall_Remote_Mag: IEDUrbanSmall_Remote_Mag { - GVAR(SetupObject) = "ACE_Explosives_Place_IEDLandSmall"; + GVAR(setupObject) = "ACE_Explosives_Place_IEDLandSmall"; class ACE_Triggers: ACE_Triggers { class Command: Command { ammo = "ACE_IEDLandSmall_Command_Ammo"; @@ -174,7 +171,7 @@ class CfgMagazines { // Orange DLC: class APERSMineDispenser_Mag: SatchelCharge_Remote_Mag { - GVAR(SetupObject) = "ACE_Explosives_Place_APERSMineDispenser"; + GVAR(setupObject) = "ACE_Explosives_Place_APERSMineDispenser"; class ACE_Triggers { SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter"}; class Timer { @@ -187,7 +184,7 @@ class CfgMagazines { }; }; class TrainingMine_Mag: APERSMine_Range_Mag { - GVAR(SetupObject) = "ACE_Explosives_Place_TrainingMine"; + GVAR(setupObject) = "ACE_Explosives_Place_TrainingMine"; class ACE_Triggers { SupportedTriggers[] = {"PressurePlate"}; class PressurePlate { diff --git a/addons/explosives/CfgVehicles.hpp b/addons/explosives/CfgVehicles.hpp index 91a708beb87..bf3eb1b12bd 100644 --- a/addons/explosives/CfgVehicles.hpp +++ b/addons/explosives/CfgVehicles.hpp @@ -6,24 +6,24 @@ class CfgVehicles { class ACE_SelfActions { class ACE_Explosives { displayName = CSTRING(Menu); - condition = QUOTE(!(_player getVariable [ARR_2(QQGVAR(PlantingExplosive),false)])); + condition = QUOTE(!(_player getVariable [ARR_2(QQGVAR(plantingExplosive),false)])); statement = ""; 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 = ""; - condition = "true"; + condition = QUOTE(true); exceptions[] = {"isNotSwimming"}; icon = QPATHTOF(UI\Place_Explosive_ca.paa); insertChildren = QUOTE(_player call FUNC(addExplosiveActions)); }; class ACE_Cellphone { displayName = CSTRING(cellphone_displayName); - condition = "('ACE_Cellphone' in (items ace_player))"; - statement = "closeDialog 0;createDialog 'Rsc_ACE_PhoneInterface';"; + condition = QUOTE([ARR_2(_player,'ACE_Cellphone')] call EFUNC(common,hasItem)); + statement = QUOTE(closeDialog 0; createDialog 'Rsc_ACE_PhoneInterface'); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; showDisabled = 0; icon = QPATHTOF(Data\UI\Cellphone_UI.paa); @@ -87,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 QQGVAR(class),_target,_player)] call FUNC(addTriggerActions)); showDisabled = 0; exceptions[] = {"isNotSwimming"}; icon = QPATHTOF(UI\Explosives_Menu_ca.paa); @@ -96,7 +96,7 @@ class CfgVehicles { selection = ""; displayName = CSTRING(Pickup); condition = "true"; - statement = QUOTE([ARR_2(_player,_target getVariable QUOTE(QGVAR(class)))] call EFUNC(common,addToInventory);deleteVehicle _target;); + statement = QUOTE([ARR_2(_player,_target getVariable QQGVAR(class))] call EFUNC(common,addToInventory); deleteVehicle _target); showDisabled = 0; exceptions[] = {"isNotSwimming"}; icon = "\A3\ui_f\data\IGUI\Cfg\Actions\Obsolete\ui_action_takemine_ca.paa"; @@ -106,60 +106,60 @@ class CfgVehicles { }; class ACE_Explosives_Place_DemoCharge: ACE_Explosives_Place { - displayName = "Demo Charge"; + displayName = "$STR_A3_cfgMagazines_DemoCharge0"; model = "\A3\Weapons_F\explosives\c4_charge_small_d"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { - position = "[-0.07,0,0.055]"; + position = "[-0.07, 0, 0.055]"; }; }; }; class ACE_Explosives_Place_APERSBoundingMine: ACE_Explosives_Place { - displayName = "APERS Bounding Mine"; + displayName = "$STR_A3_cfgMagazines_BouncingMineRangeMagazine0"; model = "\A3\Weapons_F\explosives\mine_AP_bouncing"; }; class ACE_Explosives_Place_APERSMine: ACE_Explosives_Place { - displayName = "APERS Mine"; + displayName = "$STR_A3_cfgMagazines_ClassicMineRangeMagazine0"; model = "\A3\Weapons_F\explosives\mine_ap"; }; class ACE_Explosives_Place_APERSTripwireMine: ACE_Explosives_Place { - displayName = "APERS Tripwire Mine"; + displayName = "$STR_A3_cfgMagazines_ClassicMineWireMagazine0"; model = "\A3\Weapons_F\explosives\mine_AP_tripwire"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { - position = "[1.415,0,0.12]"; + position = "[1.415, 0, 0.12]"; }; }; }; class ACE_Explosives_Place_ATMine: ACE_Explosives_Place { - displayName = "AT Mine"; + displayName = "$STR_A3_CfgMagazines_Mine0"; model = "\A3\Weapons_f\Explosives\mine_at"; }; class ACE_Explosives_Place_Claymore: ACE_Explosives_Place { - displayName = "Claymore"; + displayName = "$STR_A3_cfgMagazines_DirectionalMineRemoteMagazine0"; model = "\A3\Weapons_F\explosives\mine_AP_miniclaymore"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { - position = "[0,0,0.038]"; + position = "[0, 0, 0.038]"; }; }; }; class ACE_Explosives_Place_SatchelCharge: ACE_Explosives_Place { - displayName = "Satchel Charge"; + displayName = "$STR_A3_cfgMagazines_PipeBomb0"; model = "\A3\Weapons_F\Explosives\satchel"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { - position = "[-0.1,-0.1,0.05]"; + position = "[-0.1, -0.1, 0.05]"; }; }; }; // Orange DLC: class ACE_Explosives_Place_APERSMineDispenser: ACE_Explosives_Place { - displayName = "APERSMineDispenser"; + displayName = "$STR_A3_CfgMagazines_APERSMineDispenser_Mag0"; model = "\A3\Weapons_F_Orange\Explosives\APERSmineDispenser"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -168,7 +168,7 @@ class CfgVehicles { }; }; class ACE_Explosives_Place_TrainingMine: ACE_Explosives_Place { - displayName = "TrainingMine"; + displayName = "$STR_A3_CfgMagazines_TrainingMine_Mag0"; model = "\A3\Weapons_F_Orange\Explosives\TrainingMine_F"; class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -179,28 +179,28 @@ class CfgVehicles { class ACE_Explosives_Place_SLAM: ACE_Explosives_Place { - displayName = "SLAM"; + displayName = "$STR_A3_cfgMagazines_DirectionalMineRangeMagazine0"; model = "\A3\Weapons_F\Explosives\mine_SLAM_directional"; }; // IEDs class ACE_Explosives_Place_IEDUrbanBig: ACE_Explosives_Place { - displayName = "IED Urban Big"; + displayName = "$STR_A3_CfgVehicles_IEDUrbanBig_F"; model = "\A3\Weapons_F\Explosives\IED_urban_big"; }; class ACE_Explosives_Place_IEDLandBig: ACE_Explosives_Place { - displayName = "IED Land Big"; + displayName = "$STR_A3_CfgVehicles_IEDLandBig_F"; model = "\A3\Weapons_F\Explosives\IED_land_big"; }; class ACE_Explosives_Place_IEDUrbanSmall: ACE_Explosives_Place { - displayName = "IED Urban Small"; + displayName = "$STR_A3_CfgVehicles_IEDUrbanSmall_F"; model = "\A3\Weapons_F\Explosives\IED_urban_small"; }; class ACE_Explosives_Place_IEDLandSmall: ACE_Explosives_Place { - displayName = "IED Land Small"; + displayName = "$STR_A3_CfgVehicles_IEDLandSmall_F"; model = "\A3\Weapons_F\Explosives\IED_land_small"; }; @@ -364,7 +364,6 @@ class CfgVehicles { author = ECSTRING(common,aceteam); ammo = "ACE_SLAMDirectionalMine_Magnetic_Ammo"; displayName = CSTRING(Module_SLAMBottomAttack_DisplayName); - // TODO: Find a way to place the mine laying down instead of standing up }; class APERSTripMine: MineBase {}; @@ -374,6 +373,18 @@ class CfgVehicles { displayName = CSTRING(TripFlare_Name); }; + class Claymore_F: MineBase { + ammo = "ACE_ClaymoreDirectionalMine_Remote_Ammo"; + }; + + class APERSBoundingMine: MineBase { + ammo = "ACE_APERSBoundingMine_Range_Ammo"; + }; + + class DemoCharge_F: MineBase { + ammo = "ACE_DemoCharge_Remote_Ammo"; + }; + class IEDUrbanBig_F; class ACE_IEDUrbanBig_Range: IEDUrbanBig_F { author = ECSTRING(common,aceteam); diff --git a/addons/explosives/CfgWeapons.hpp b/addons/explosives/CfgWeapons.hpp index 30e1fb95cbb..5c81cb9aec0 100644 --- a/addons/explosives/CfgWeapons.hpp +++ b/addons/explosives/CfgWeapons.hpp @@ -12,8 +12,7 @@ class CfgWeapons { class CBA_MiscItem_ItemInfo; class ACE_ExplosiveItem: CBA_MiscItem_ItemInfo { - allowedSlots[] = {TYPE_UNIFORM,TYPE_VEST,TYPE_BACKPACK}; - //type = 201; + allowedSlots[] = {TYPE_UNIFORM, TYPE_VEST, TYPE_BACKPACK}; }; class ACE_Clacker: ACE_ItemCore { @@ -23,8 +22,8 @@ class CfgWeapons { descriptionShort = CSTRING(clacker_description); picture = QPATHTOF(Data\UI\Clacker.paa); model = QPATHTOF(data\ace_m57.p3d); - GVAR(Range) = 250; - GVAR(Detonator) = 1; + GVAR(range) = 250; + GVAR(detonator) = 1; GVAR(triggerType) = "Command"; ACE_isTool = 1; @@ -37,7 +36,7 @@ class CfgWeapons { author = ECSTRING(common,ACETeam); displayName = CSTRING(M152_Clacker_displayName); picture = QPATHTOF(Data\UI\MK26_Transmitter_ca.paa); - GVAR(Range) = 5000; + GVAR(range) = 5000; GVAR(triggerType) = "MK16_Transmitter"; }; class ACE_DefusalKit: ACE_ItemCore { @@ -47,8 +46,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; + ACE_isTool = 1; class ItemInfo: ACE_ExplosiveItem { mass = 5; @@ -62,8 +61,8 @@ class CfgWeapons { descriptionShort = CSTRING(DeadManSwitch_description); picture = QPATHTOF(Data\UI\DeadmanSwitch.paa); model = "\A3\weapons_F\ammo\mag_univ.p3d"; - GVAR(Range) = 100; - GVAR(Detonator) = 1; + GVAR(range) = 100; + GVAR(detonator) = 1; GVAR(triggerType) = "DeadManSwitch"; ACE_isTool = 1; @@ -79,8 +78,8 @@ class CfgWeapons { descriptionShort = CSTRING(cellphone_description); picture = QPATHTOF(Data\UI\Cellphone_UI.paa); model = "\A3\weapons_F\ammo\mag_univ.p3d"; - GVAR(Range) = 15000; - GVAR(Detonator) = 1; + GVAR(range) = 15000; + GVAR(detonator) = 1; GVAR(triggerType) = "Cellphone"; ACE_isTool = 1; diff --git a/addons/explosives/ExplosivesUI.hpp b/addons/explosives/ExplosivesUI.hpp index ef32c0c04b6..1b14ba5e887 100644 --- a/addons/explosives/ExplosivesUI.hpp +++ b/addons/explosives/ExplosivesUI.hpp @@ -12,10 +12,10 @@ class Rsc_ACE_CallScreen_Edit: RscEdit { text = ""; 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"; + SizeEx = "(((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 20) * 1)"; + 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)); }; 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)); }; 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"; - SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 22) * 1)"; - x = "0.288594 * safezoneW + safezoneX"; - w = "0.0825 * safezoneW"; - h = "0.044 * safezoneH"; + 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"; text = "Name"; }; class speedDial_edit: Rsc_ACE_CallScreen_Edit { idc = 1401; - y = "0.302 * safezoneH + safezoneY"; - x = "0.318 * safezoneW + safezoneX"; + y = "0.302 * safeZoneH + safeZoneY"; + x = "0.318 * safeZoneW + safeZoneX"; w = "0.1"; }; class numberEdit_Text: RscText { idc = 1406; - 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"; + 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"; 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/XEH_postInit.sqf b/addons/explosives/XEH_postInit.sqf index 40b3bb69593..4331ba3596c 100644 --- a/addons/explosives/XEH_postInit.sqf +++ b/addons/explosives/XEH_postInit.sqf @@ -22,12 +22,11 @@ _this call FUNC(setPosition); if (isServer) then { - if (missionNamespace getVariable [QGVAR(setShotParents), true]) then { - _explosive setShotParents [_unit, _unit]; - }; + private _owner = [objNull, _unit] select (missionNamespace getVariable [QGVAR(setShotParents), false]); + _explosive setShotParents [_owner, _unit]; }; }] call CBA_fnc_addEventHandler; -[QGVAR(startDefuse), FUNC(startDefuse)] call CBA_fnc_addEventHandler; +[QGVAR(startDefuse), LINKFUNC(startDefuse)] call CBA_fnc_addEventHandler; //When getting knocked out in medical, trigger deadman explosives: //Event is global, only run on server (ref: ace_medical_fnc_setUnconscious) @@ -35,14 +34,13 @@ if (isServer) then { [QGVAR(detonate), { params ["_unit", "_explosive", "_delay"]; TRACE_3("server detonate EH",_unit,_explosive,_delay); - if (missionNamespace getVariable [QGVAR(setShotParents), true]) then { - _explosive setShotParents [_unit, _unit]; - }; + private _owner = [objNull, _unit] select (missionNamespace getVariable [QGVAR(setShotParents), false]); + _explosive setShotParents [_owner, _unit]; [{ params ["_explosive"]; TRACE_1("exploding",_explosive); if (!isNull _explosive) then { - _explosive setDamage 1; + [QEGVAR(common,triggerAmmo), _explosive, _explosive] call CBA_fnc_targetEvent; }; }, _explosive, _delay] call CBA_fnc_waitAndExecute; }] call CBA_fnc_addEventHandler; @@ -53,10 +51,20 @@ if (isServer) then { TRACE_1("Knocked Out, Doing Deadman",_unit); [_unit] call FUNC(onIncapacitated); }] call CBA_fnc_addEventHandler; + + // Orient all Editor-placed SLAM (Bottom attack) mines facing upward + { + private _mine = _x; + if (typeOf _mine == "ACE_SLAMDirectionalMine_Magnetic_Ammo") then { + [_mine, MINE_PITCH_UP, 0] call CALLSTACK(BIS_fnc_setPitchBank); + }; + } forEach allMines; }; if (!hasInterface) exitWith {}; +#include "initKeybinds.inc.sqf" + GVAR(PlacedCount) = 0; GVAR(Setup) = objNull; GVAR(pfeh_running) = false; diff --git a/addons/explosives/XEH_preInit.sqf b/addons/explosives/XEH_preInit.sqf index 6141a1d3e0d..e39270f0bbc 100644 --- a/addons/explosives/XEH_preInit.sqf +++ b/addons/explosives/XEH_preInit.sqf @@ -8,7 +8,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initKeybinds.inc.sqf" #include "initSettings.inc.sqf" GVAR(activeTrigger) = ""; diff --git a/addons/explosives/config.cpp b/addons/explosives/config.cpp index b60186ab684..00909533ac9 100644 --- a/addons/explosives/config.cpp +++ b/addons/explosives/config.cpp @@ -32,6 +32,7 @@ class RscEdit; class RscPicture; class RscButton; class ctrlXSliderH; + #include "ExplosivesUI.hpp" #include "TimerDialog.hpp" #include "GUI_VirtualAmmo.hpp" @@ -53,9 +54,15 @@ class CfgActions { }; class CfgMineTriggers { - class RangeTrigger; - class ACE_MagneticTrigger: RangeTrigger { - mineMagnetic = 1; - mineTriggerRange = 1; + class IRTrigger; + class ACE_MagneticTrigger: IRTrigger { + mineWireEnd[] = {0,0.1,0.5}; + }; + + class TankTriggerMagnetic; + class ACE_TankTriggerLight: TankTriggerMagnetic { + // Reduce mass needed to trigger vanilla AT Mine to realistic levels (https://en.wikipedia.org/wiki/M15_mine#Specifications). + // Will now trigger for any vehicle heavier than the Vanilla ATV (280kg) + mineTriggerMass = 300; // Default: 7000 }; }; diff --git a/addons/explosives/dev/test_magazines.sqf b/addons/explosives/dev/test_magazines.sqf index ca9744f08da..afd091b24c4 100644 --- a/addons/explosives/dev/test_magazines.sqf +++ b/addons/explosives/dev/test_magazines.sqf @@ -5,20 +5,24 @@ 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)); + private _setupObject = getText (_cfg >> QGVAR(setupObject)); + if (_setupObject == "") then { WARNING_2("[%1](scope %2) has no setupObject",_mag,_scope); - continue + 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 { + + 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 2ac69b73ae2..d35b303fc14 100644 --- a/addons/explosives/functions/fnc_addCellphoneIED.sqf +++ b/addons/explosives/functions/fnc_addCellphoneIED.sqf @@ -29,10 +29,10 @@ private _hasRequired = true; private _detonators = [_unit] call FUNC(getDetonators); { - if !(_x in _detonators) exitWith{ + if !(_x in _detonators) exitWith { _hasRequired = false; }; -} count _requiredItems; +} forEach _requiredItems; private _code = ""; while {true} do { diff --git a/addons/explosives/functions/fnc_addClacker.sqf b/addons/explosives/functions/fnc_addClacker.sqf index 2292bfcb79c..ace01a15265 100644 --- a/addons/explosives/functions/fnc_addClacker.sqf +++ b/addons/explosives/functions/fnc_addClacker.sqf @@ -31,10 +31,10 @@ 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; +private _config = configFile >> "CfgMagazines" >> _magazineClass >> "ACE_Triggers" >> configName _config; private _clacker = _unit getVariable [QGVAR(Clackers), []]; GVAR(PlacedCount) = GVAR(PlacedCount) + 1; diff --git a/addons/explosives/functions/fnc_addDetonateActions.sqf b/addons/explosives/functions/fnc_addDetonateActions.sqf index ea4b87128a7..2e99f2bd4f0 100644 --- a/addons/explosives/functions/fnc_addDetonateActions.sqf +++ b/addons/explosives/functions/fnc_addDetonateActions.sqf @@ -19,16 +19,16 @@ params ["_unit", "_detonator"]; TRACE_2("params",_unit,_detonator); -private _range = getNumber (ConfigFile >> "CfgWeapons" >> _detonator >> QGVAR(Range)); +private _range = getNumber (configFile >> "CfgWeapons" >> _detonator >> QGVAR(Range)); private _result = [_unit] call FUNC(getPlacedExplosives); private _children = []; private _explosivesList = []; { if (!isNull(_x select 0)) then { - private _required = getArray (ConfigFile >> "ACE_Triggers" >> (_x select 4) >> "requires"); + private _required = getArray (configFile >> "ACE_Triggers" >> (_x select 4) >> "requires"); if (_detonator in _required) then { - private _item = ConfigFile >> "CfgMagazines" >> (_x select 3); + private _item = configFile >> "CfgMagazines" >> (_x select 3); _explosivesList pushBack _x; @@ -53,7 +53,7 @@ private _explosivesList = []; // 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"} && + {_detonator != "Cellphone"} && { _explosivesList isNotEqualTo [] || {_detonator == "ACE_DeadManSwitch" && {_unit getVariable [QGVAR(deadmanInvExplosive), ""] != ""}} @@ -92,19 +92,6 @@ if (_detonator != "ACE_DeadManSwitch") then { ]; }; } else { - //Add action to detonate all explosives (including the inventory explosive): - _children pushBack [ - [ - "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. private _connectedInventoryExplosive = _unit getVariable [QGVAR(deadmanInvExplosive), ""]; if ((_connectedInventoryExplosive != "") && {!(_connectedInventoryExplosive in (magazines _unit))}) then { @@ -113,14 +100,26 @@ if (_detonator != "ACE_DeadManSwitch") then { }; _connectedInventoryExplosive = _unit getVariable [QGVAR(deadmanInvExplosive), ""]; + + //Add action to detonate all explosives (including the inventory explosive): + if (_connectedInventoryExplosive != "" || {count _explosivesList > 1}) then { + _children pushBack [ + [ + "Explosive_All_Deadman", + LLSTRING(DetonateAll), + getText (configFile >> "CfgWeapons" >> _detonator >> "picture"), + {[_player] call FUNC(onIncapacitated)}, + {true} + ] call EFUNC(interact_menu,createAction), + [], + _unit + ]; + }; + if (_connectedInventoryExplosive != "") then { //Add the disconnect action private _magConfig = configFile >> "CfgMagazines" >> _connectedInventoryExplosive; - private _name = if ((getText (_magConfig >> "displayNameShort")) != "") then { - getText (_magConfig >> "displayNameShort") - } else { - getText(_magConfig >> "displayName") - }; + private _name = getText (_magConfig >> "displayName"); private _picture = getText (_magConfig >> "picture"); _children pushBack [ @@ -144,16 +143,12 @@ if (_detonator != "ACE_DeadManSwitch") then { 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"); if (({_x == "DeadmanSwitch"} count _supportedTriggers) == 1) then { //case insensitive search - private _name = if ((getText (_magConfig >> "displayNameShort")) != "") then { - getText (_magConfig >> "displayNameShort") - } else { - getText(_magConfig >> "displayName") - }; + private _name = getText (_magConfig >> "displayName"); private _picture = getText (_magConfig >> "picture"); _children pushBack [ @@ -162,6 +157,7 @@ if (_detonator != "ACE_DeadManSwitch") then { format [localize LSTRING(connectInventoryExplosiveToDeadman), _name], _picture, { + //IGNORE_PRIVATE_WARNING ["_player"]; params ["_player", "", "_mag"]; TRACE_2("set new",_player,_mag); _player setVariable [QGVAR(deadmanInvExplosive), _mag, true]; diff --git a/addons/explosives/functions/fnc_addExplosiveActions.sqf b/addons/explosives/functions/fnc_addExplosiveActions.sqf index 480ecd27012..6276e48afe6 100644 --- a/addons/explosives/functions/fnc_addExplosiveActions.sqf +++ b/addons/explosives/functions/fnc_addExplosiveActions.sqf @@ -27,11 +27,8 @@ { private _config = _cfgMagazines >> _x; if (getNumber (_config >> QGVAR(Placeable)) == 1) then { - private _name = getText (_config >> "displayNameShort"); + private _name = getText (_config >> "displayName"); private _picture = getText (_config >> "picture"); - if (_name isEqualTo "") then { - _name = getText (_config >> "displayName"); - }; private _action = [_x, format ["%1 (%2)", _name, _totalCount - count (_magazines - [_x])], _picture, {[{_this call FUNC(setupExplosive)}, _this] call CBA_fnc_execNextFrame}, {true}, {}, _x] call EFUNC(interact_menu,createAction); _actions pushBack [_action, [], _player]; diff --git a/addons/explosives/functions/fnc_addTransmitterActions.sqf b/addons/explosives/functions/fnc_addTransmitterActions.sqf index 043c9db661f..d225aeda056 100644 --- a/addons/explosives/functions/fnc_addTransmitterActions.sqf +++ b/addons/explosives/functions/fnc_addTransmitterActions.sqf @@ -21,7 +21,7 @@ TRACE_1("params",_unit); private _detonators = [_unit] call FUNC(getDetonators); private _children = []; { - private _config = ConfigFile >> "CfgWeapons" >> _x; + private _config = configFile >> "CfgWeapons" >> _x; _children pushBack [ [ diff --git a/addons/explosives/functions/fnc_addTriggerActions.sqf b/addons/explosives/functions/fnc_addTriggerActions.sqf index d3632d5bb77..8be63fbc4f9 100644 --- a/addons/explosives/functions/fnc_addTriggerActions.sqf +++ b/addons/explosives/functions/fnc_addTriggerActions.sqf @@ -22,7 +22,7 @@ TRACE_2("params",_magazine,_explosive); private _isAttached = !isNull (attachedTo _explosive); private _detonators = [ACE_player] call FUNC(getDetonators); private _triggerTypes = [_magazine] call FUNC(triggerType); -private _magTriggers = ConfigFile >> "CfgMagazines" >> _magazine >> "ACE_Triggers"; +private _magTriggers = configFile >> "CfgMagazines" >> _magazine >> "ACE_Triggers"; private _children = []; { private _required = getArray (_x >> "requires"); @@ -31,7 +31,7 @@ private _children = []; if !(_x in _detonators) exitWith { _hasRequiredItems = false; }; - } count _required; + } forEach _required; if (_hasRequiredItems && {(!_isAttached) || {(getNumber (_x >> "isAttachable")) == 1}}) then { _children pushBack [ diff --git a/addons/explosives/functions/fnc_canDefuse.sqf b/addons/explosives/functions/fnc_canDefuse.sqf index 0edb98cff57..54bf8477bc8 100644 --- a/addons/explosives/functions/fnc_canDefuse.sqf +++ b/addons/explosives/functions/fnc_canDefuse.sqf @@ -24,7 +24,7 @@ if (isNull _explosive) exitWith { deleteVehicle _target; false }; -if (vehicle _unit != _unit || {(_unit call EFUNC(common,uniqueItems)) findAny GVAR(defusalKits) == -1}) exitWith {false}; +if (!isNull objectParent _unit || {(_unit call EFUNC(common,uniqueItems)) findAny GVAR(defusalKits) == -1}) exitWith {false}; if (GVAR(RequireSpecialist) && {!([_unit] call EFUNC(Common,isEOD))}) exitWith {false}; diff --git a/addons/explosives/functions/fnc_defuseExplosive.sqf b/addons/explosives/functions/fnc_defuseExplosive.sqf index 049fff88469..1c8b687c8f3 100644 --- a/addons/explosives/functions/fnc_defuseExplosive.sqf +++ b/addons/explosives/functions/fnc_defuseExplosive.sqf @@ -19,7 +19,7 @@ params ["_unit", "_explosive"]; TRACE_2("params",_unit,_explosive); -if (GVAR(ExplodeOnDefuse) && {(random 1.0) < (getNumber (ConfigFile >> "CfgAmmo" >> typeOf _explosive >> QGVAR(explodeOnDefuseChance)))}) exitWith { +if (GVAR(ExplodeOnDefuse) && {(random 1.0) < (getNumber (configFile >> "CfgAmmo" >> typeOf _explosive >> QGVAR(explodeOnDefuseChance)))}) exitWith { TRACE_1("exploding on defuse",_explosive); [_unit, -1, [_explosive, 1], "#ExplodeOnDefuse"] call FUNC(detonateExplosive); [QGVAR(explodeOnDefuse), [_explosive, _unit]] call CBA_fnc_globalEvent; diff --git a/addons/explosives/functions/fnc_detonateExplosive.sqf b/addons/explosives/functions/fnc_detonateExplosive.sqf index 5e276745b59..e9ad9856fba 100644 --- a/addons/explosives/functions/fnc_detonateExplosive.sqf +++ b/addons/explosives/functions/fnc_detonateExplosive.sqf @@ -31,25 +31,9 @@ private _result = true; 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; - private _exp = getText (ConfigFile >> "CfgAmmo" >> typeOf (_previousExp) >> QGVAR(Explosive)); - if (_exp != "") then { - _exp = createVehicle [_exp, [0,0,15001], [], 0, "NONE"]; - _exp setDir (getDir _previousExp); - _item set [0, _exp]; - private _pos = getPosASL _previousExp; - deleteVehicle _previousExp; - _exp setPosASL _pos; - }; -}; - if (isNull (_item select 0)) then { WARNING_1("Explosive is null [%1]",_this); }; -if ((getNumber (configFile >> "CfgAmmo" >> (typeOf (_item select 0)) >> "triggerWhenDestroyed")) != 1) then { - WARNING_1("Explosive is not triggerWhenDestroyed [%1]",typeOf (_item select 0)); -}; [QGVAR(detonate), [_unit, _item select 0, _item select 1]] call CBA_fnc_serverEvent; diff --git a/addons/explosives/functions/fnc_dialPhone.sqf b/addons/explosives/functions/fnc_dialPhone.sqf index 860f7ddfdeb..f0609e2b0d2 100644 --- a/addons/explosives/functions/fnc_dialPhone.sqf +++ b/addons/explosives/functions/fnc_dialPhone.sqf @@ -30,7 +30,7 @@ for "_i" from 1 to _ran do { }; if (_unit == ace_player) then { ctrlSetText [1400,"Calling"]; - [FUNC(dialingPhone), 0.25, [_unit,4,_arr,_code]] call CALLSTACK(CBA_fnc_addPerFrameHandler); + [LINKFUNC(dialingPhone), 0.25, [_unit,4,_arr,_code]] call CALLSTACK(CBA_fnc_addPerFrameHandler); } else { private _explosive = [_code] call FUNC(getSpeedDialExplosive); if ((count _explosive) > 0) then { diff --git a/addons/explosives/functions/fnc_getPlacedExplosives.sqf b/addons/explosives/functions/fnc_getPlacedExplosives.sqf index 867bae2275f..2e6d8840d9a 100644 --- a/addons/explosives/functions/fnc_getPlacedExplosives.sqf +++ b/addons/explosives/functions/fnc_getPlacedExplosives.sqf @@ -16,14 +16,14 @@ * * Public: Yes */ -// IGNORE_PRIVATE_WARNING(_allExplosives,_deadmanExplosives); +//IGNORE_PRIVATE_WARNING ["_allExplosives", "_deadmanExplosives"]; params ["_unit"]; TRACE_1("params",_unit); private _filter = nil; if (count _this > 1) then { - _filter = ConfigFile >> "ACE_Triggers" >> (_this select 1); + _filter = configFile >> "ACE_Triggers" >> (_this select 1); }; private _clackerList = []; private _adjustedList = false; @@ -34,7 +34,7 @@ private _list = []; _clackerList set [_forEachIndex, "X"]; _adjustedList = true; } else { - if (isNil "_filter" || {(ConfigFile >> "ACE_Triggers" >> (_x select 4)) == _filter}) then { + if (isNil "_filter" || {(configFile >> "ACE_Triggers" >> (_x select 4)) == _filter}) then { _list pushBack _x; }; }; diff --git a/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf b/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf index 8490eab4521..0f4e5d923f7 100644 --- a/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf +++ b/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf @@ -24,7 +24,6 @@ private _explosive = []; if ((_x select 1) == _code) exitWith { _explosive = _x; }; - false -} count GVAR(CellphoneIEDs); +} forEach GVAR(CellphoneIEDs); _explosive diff --git a/addons/explosives/functions/fnc_hasPlacedExplosives.sqf b/addons/explosives/functions/fnc_hasPlacedExplosives.sqf index c697afb371a..7838a29e1bc 100644 --- a/addons/explosives/functions/fnc_hasPlacedExplosives.sqf +++ b/addons/explosives/functions/fnc_hasPlacedExplosives.sqf @@ -14,6 +14,6 @@ * * Public: Yes */ -// IGNORE_PRIVATE_WARNING(_hasPlacedExplosives); +//IGNORE_PRIVATE_WARNING ["getPlacedExplosives"]; (count (_this call FUNC(getPlacedExplosives)) > 0) diff --git a/addons/explosives/functions/fnc_onIncapacitated.sqf b/addons/explosives/functions/fnc_onIncapacitated.sqf index 09d1d7b21f4..5e7b8797e1d 100644 --- a/addons/explosives/functions/fnc_onIncapacitated.sqf +++ b/addons/explosives/functions/fnc_onIncapacitated.sqf @@ -37,7 +37,7 @@ TRACE_2("placed",_deadman,_range); //Handle deadman connected to explosive in inventory private _connectedInventoryExplosive = _unit getVariable [QGVAR(deadmanInvExplosive), ""]; if (_connectedInventoryExplosive != "") then { - if (!(_connectedInventoryExplosive in (magazines _unit))) exitWith {}; + if !(_connectedInventoryExplosive in (magazines _unit)) exitWith {}; //Remove mag and reset variable _unit removeMagazine _connectedInventoryExplosive; diff --git a/addons/explosives/functions/fnc_onInventoryChanged.sqf b/addons/explosives/functions/fnc_onInventoryChanged.sqf index 7cf01c2a142..d5f1077dc2d 100644 --- a/addons/explosives/functions/fnc_onInventoryChanged.sqf +++ b/addons/explosives/functions/fnc_onInventoryChanged.sqf @@ -23,7 +23,7 @@ TRACE_3("params",_receiver,_giver,_item); if ((_receiver != ace_player) && {_giver != ace_player}) exitWith {}; -private _config = ConfigFile >> "CfgWeapons" >> _item; +private _config = configFile >> "CfgWeapons" >> _item; if (isClass _config && {getNumber(_config >> QGVAR(Detonator)) == 1}) then { private _clackerItems = _giver getVariable [QGVAR(Clackers), []]; _receiver setVariable [QGVAR(Clackers), (_receiver getVariable [QGVAR(Clackers), []]) + _clackerItems, true]; diff --git a/addons/explosives/functions/fnc_openTimerUI.sqf b/addons/explosives/functions/fnc_openTimerUI.sqf index 0a490a096dd..391c71b3b24 100644 --- a/addons/explosives/functions/fnc_openTimerUI.sqf +++ b/addons/explosives/functions/fnc_openTimerUI.sqf @@ -64,14 +64,14 @@ _display displayAddEventHandler ["MouseZChanged", { [{ params ["_display", "_pfhID"]; - // Make sure explosive still exists and is near player - if ((!isNull _display) && {!alive ACE_player} || {!alive GVAR(explosive)} || {(ACE_player distance GVAR(explosive)) > 5}) exitWith { - INFO_2("explosive became invalid",ACE_player,GVAR(explosive)); - closeDialog 0; + if (isNull _display || {!alive ACE_player}) exitWith { _pfhID call CBA_fnc_removePerFrameHandler; }; - if (isNull _display) exitWith { + // Make sure explosive still exists and is near player + if (!alive GVAR(explosive) || {(ACE_player distance GVAR(explosive)) > 5}) exitWith { + INFO_2("%1's explosive %2 became invalid",ACE_player,GVAR(explosive)); + closeDialog 0; _pfhID call CBA_fnc_removePerFrameHandler; }; diff --git a/addons/explosives/functions/fnc_placeExplosive.sqf b/addons/explosives/functions/fnc_placeExplosive.sqf index ec19a6f6fd9..bb6fcea6ab3 100644 --- a/addons/explosives/functions/fnc_placeExplosive.sqf +++ b/addons/explosives/functions/fnc_placeExplosive.sqf @@ -37,15 +37,15 @@ if (isNil "_triggerConfig") exitWith { objNull }; -private _magazineTrigger = ConfigFile >> "CfgMagazines" >> _magazineClass >> "ACE_Triggers" >> _triggerConfig; -_triggerConfig = ConfigFile >> "ACE_Triggers" >> _triggerConfig; +private _magazineTrigger = configFile >> "CfgMagazines" >> _magazineClass >> "ACE_Triggers" >> _triggerConfig; +_triggerConfig = configFile >> "ACE_Triggers" >> _triggerConfig; if (isNil "_triggerConfig") exitWith { ERROR_1("Config not found in PlaceExplosive: %1",_this); objNull }; -private _ammo = getText(ConfigFile >> "CfgMagazines" >> _magazineClass >> "ammo"); +private _ammo = getText(configFile >> "CfgMagazines" >> _magazineClass >> "ammo"); if (isText(_magazineTrigger >> "ammo")) then { _ammo = getText (_magazineTrigger >> "ammo"); }; diff --git a/addons/explosives/functions/fnc_selectTrigger.sqf b/addons/explosives/functions/fnc_selectTrigger.sqf index 7c7d5e58d46..0a864a77c48 100644 --- a/addons/explosives/functions/fnc_selectTrigger.sqf +++ b/addons/explosives/functions/fnc_selectTrigger.sqf @@ -20,7 +20,7 @@ params ["_explosive", "_magazine", "_trigger"]; TRACE_3("params",_explosive,_magazine,_trigger); -private _config = ConfigFile >> "ACE_Triggers" >> _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); diff --git a/addons/explosives/functions/fnc_setupExplosive.sqf b/addons/explosives/functions/fnc_setupExplosive.sqf index 918bbb0c33c..9214b999146 100644 --- a/addons/explosives/functions/fnc_setupExplosive.sqf +++ b/addons/explosives/functions/fnc_setupExplosive.sqf @@ -29,8 +29,8 @@ if (!isClass (configFile >> "CfgVehicles" >> _setupObjectClass)) exitWith {ERROR private _p3dModel = getText (configFile >> "CfgVehicles" >> _setupObjectClass >> "model"); if (_p3dModel == "") exitWith {ERROR("No Model");}; //"" - will crash game! -[_unit, "forceWalk", "ACE_Explosives", true] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", "ACE_Explosives", true] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); //Show mouse buttons: [localize LSTRING(PlaceAction), localize LSTRING(CancelAction), localize LSTRING(ScrollAction)] call EFUNC(interaction,showMouseHint); @@ -78,7 +78,7 @@ GVAR(TweakedAngle) = 0; { private _testPos = _testBase vectorAdd [0.1 * (_x select 0) * (cos _cameraAngle), 0.1 * (_x select 0) * (sin _cameraAngle), 0.1 * (_x select 1)]; #ifdef DEBUG_MODE_FULL - drawLine3d [(eyePos _unit) call EFUNC(common,ASLToPosition), (_testPos) call EFUNC(common,ASLToPosition), [1,0,0,1]]; + drawLine3D [(eyePos _unit) call EFUNC(common,ASLToPosition), (_testPos) call EFUNC(common,ASLToPosition), [1,0,0,1]]; #endif if ((lineIntersectsSurfaces [eyePos _unit, _testPos, _unit]) isNotEqualTo []) exitWith {_return = false;}; } forEach [[0,0], [-1,-1], [1,-1], [-1,1], [1,1]]; @@ -149,8 +149,8 @@ GVAR(TweakedAngle) = 0; [_pfID] call CBA_fnc_removePerFrameHandler; GVAR(pfeh_running) = false; - [_unit, "forceWalk", "ACE_Explosives", false] call EFUNC(common,statusEffect_set); - [_unit, "blockThrow", "ACE_Explosives", false] call EFUNC(common,statusEffect_set); + [_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); + [_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); [] call EFUNC(interaction,hideMouseHint); [_unit, "DefaultAction", (_unit getVariable [QGVAR(placeActionEH), -1])] call EFUNC(common,removeActionEventHandler); [_unit, "zoomtemp", (_unit getVariable [QGVAR(cancelActionEH), -1])] call EFUNC(common,removeActionEventHandler); @@ -167,7 +167,7 @@ GVAR(TweakedAngle) = 0; if (isNull _attachVehicle) then { _placeAngle = _cameraAngle - GVAR(TweakedAngle) + 180; - _expSetupVehicle setPosAsl _virtualPosASL; + _expSetupVehicle setPosASL _virtualPosASL; _expSetupVehicle setDir _placeAngle; _placeAngle = _placeAngle + 180; //CfgAmmos seem to be 180 for some reason } else { diff --git a/addons/explosives/functions/fnc_startDefuse.sqf b/addons/explosives/functions/fnc_startDefuse.sqf index e023592547c..ef3efac885f 100644 --- a/addons/explosives/functions/fnc_startDefuse.sqf +++ b/addons/explosives/functions/fnc_startDefuse.sqf @@ -25,8 +25,8 @@ private _fnc_DefuseTime = { params ["_specialist", "_target"]; TRACE_2("defuseTime",_specialist,_target); private _defuseTime = 5; - if (isNumber(ConfigFile >> "CfgAmmo" >> typeOf (_target) >> QGVAR(DefuseTime))) then { - _defuseTime = getNumber(ConfigFile >> "CfgAmmo" >> typeOf (_target) >> QGVAR(DefuseTime)); + if (isNumber(configFile >> "CfgAmmo" >> typeOf (_target) >> QGVAR(DefuseTime))) then { + _defuseTime = getNumber(configFile >> "CfgAmmo" >> typeOf (_target) >> QGVAR(DefuseTime)); }; if (!_specialist && {GVAR(PunishNonSpecialists)}) then { _defuseTime = _defuseTime * 1.5; @@ -34,7 +34,7 @@ private _fnc_DefuseTime = { _defuseTime }; private _actionToPlay = "MedicOther"; -if (STANCE _unit == "Prone") then { +if (stance _unit == "Prone") then { _actionToPlay = "PutDown"; }; diff --git a/addons/explosives/functions/fnc_triggerType.sqf b/addons/explosives/functions/fnc_triggerType.sqf index 0fba459491b..aa890c049f2 100644 --- a/addons/explosives/functions/fnc_triggerType.sqf +++ b/addons/explosives/functions/fnc_triggerType.sqf @@ -19,10 +19,10 @@ params ["_magazineClassname"]; TRACE_1("params",_magazineClassname); private _result = []; -private _config = getArray (ConfigFile >> "CfgMagazines" >> _magazineClassname >> "ACE_Triggers" >> "SupportedTriggers"); +private _config = getArray (configFile >> "CfgMagazines" >> _magazineClassname >> "ACE_Triggers" >> "SupportedTriggers"); private _count = count _config; for "_index" from 0 to (_count - 1) do { - _result set [_index, ConfigFile >> "ACE_Triggers" >> (_config select _index)]; + _result set [_index, configFile >> "ACE_Triggers" >> (_config select _index)]; }; _result diff --git a/addons/explosives/initSettings.inc.sqf b/addons/explosives/initSettings.inc.sqf index bdbd488550d..baa38f0d8f9 100644 --- a/addons/explosives/initSettings.inc.sqf +++ b/addons/explosives/initSettings.inc.sqf @@ -6,7 +6,7 @@ private _categoryStr = format ["ACE %1", LLSTRING(Menu)]; [LLSTRING(RequireSpecialist_DisplayName),LLSTRING(RequireSpecialist_Description)], _categoryStr, false, - true + 1 ] call CBA_fnc_addSetting; [ @@ -15,7 +15,7 @@ private _categoryStr = format ["ACE %1", LLSTRING(Menu)]; [LLSTRING(PunishNonSpecialists_DisplayName),LLSTRING(PunishNonSpecialists_Description)], _categoryStr, true, - true + 1 ] call CBA_fnc_addSetting; [ @@ -24,7 +24,7 @@ private _categoryStr = format ["ACE %1", LLSTRING(Menu)]; [LLSTRING(ExplodeOnDefuse_DisplayName),LLSTRING(ExplodeOnDefuse_Description)], _categoryStr, true, - true + 1 ] call CBA_fnc_addSetting; // Variable names to preserve https://github.com/acemod/ACE3/pull/6882 @@ -34,7 +34,7 @@ private _categoryStr = format ["ACE %1", LLSTRING(Menu)]; [LLSTRING(TimerMin_DisplayName), LLSTRING(TimerMin_Description)], [_categoryStr, LLSTRING(ExplosiveTimer)], [0, 5999, TIMER_VALUE_MIN], - true + 1 ] call CBA_fnc_addSetting; [ @@ -43,7 +43,7 @@ private _categoryStr = format ["ACE %1", LLSTRING(Menu)]; [LLSTRING(TimerMax_DisplayName), LLSTRING(TimerMax_Description)], [_categoryStr, LLSTRING(ExplosiveTimer)], [0, 5999, TIMER_VALUE_MAX], - true + 1 ] call CBA_fnc_addSetting; [ @@ -51,6 +51,5 @@ private _categoryStr = format ["ACE %1", LLSTRING(Menu)]; "TIME", [LLSTRING(TimerDefault_DisplayName), LLSTRING(TimerDefault_Description)], [_categoryStr, LLSTRING(ExplosiveTimer)], - [0, 5999, TIMER_VALUE_DEFAULT], - false + [0, 5999, TIMER_VALUE_DEFAULT] ] call CBA_fnc_addSetting; diff --git a/addons/explosives/script_component.hpp b/addons/explosives/script_component.hpp index 77ca89d32e5..de27ff45c03 100644 --- a/addons/explosives/script_component.hpp +++ b/addons/explosives/script_component.hpp @@ -34,3 +34,5 @@ #define PLACE_WAITING -1 #define PLACE_CANCEL 0 #define PLACE_APPROVE 1 + +#define MINE_PITCH_UP 90 diff --git a/addons/explosives/stringtable.xml b/addons/explosives/stringtable.xml index 96b62929526..d8397320b88 100644 --- a/addons/explosives/stringtable.xml +++ b/addons/explosives/stringtable.xml @@ -74,6 +74,9 @@ Detona Tutti sul Detonatore Attivo Подрыв всех на активном детонаторе 選択した点火装置を全て起爆 + 활성화된 격발기의 모든 것을 폭파 + Détoner tout sur le détonateur actif + Detonar Todos al Activar el detonador Set Active Clacker @@ -81,6 +84,9 @@ Imposta Detonatore Attivo Установить активный детонатор この点火装置を選択 + 격발기 활성 설정 + Définir le détonateur actif + Establecer el Detonador Activo Cycle Active Clacker @@ -88,6 +94,9 @@ Cambia Detonatore Attivo Цикл активного детонатора 点火装置を切り替え + 격발기 활성 전환 + Modifier le détonateur actif + Ciclar el Detonador Activo Active Clacker @@ -95,6 +104,9 @@ Detonatore Attivo Активный детонатор 選択中の点火装置 + 격발기 활성 + Détonateur actif + Activar Detonador Explosive code: %1 @@ -209,7 +221,7 @@ Ativar Thor III Активировать Thor III Thor III を使う - Thor III 켜기 + 토르 III 켜기 开启索尔三型 開啟索爾三型 Thor III ü aç @@ -226,7 +238,7 @@ Desativar Thor III Деактивировать Thor III Thor III を止める - Thor III 끄기 + 토르 III 끄기 关闭索尔三型 關閉索爾三型 Thor III ü kapat @@ -835,7 +847,7 @@ Требуется ли специалист по минному делу для обезвреживания взрывчатки? По умолчанию: Нет 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 @@ -868,7 +880,7 @@ Увеличивать время завершения действий для не-специалистов? По умолчанию: Нет Aumenta il tempo richiesto per completare azioni per non-specialisti? Predefinito: Si 専門兵以外がアクション完了するのに必要な時間を増加しますか? デフォルト: 有効 - 비전문가가 폭발물을 해제 시 더욱 많은 시간을 소요합니까? 기본설정: 예 + 비전문가가 폭발물을 해체 시 더욱 많은 시간을 소요합니까? 기본설정: 예 增加非专业人员相关操作的时间? 预设:是 增加非專業人員相關操作的時間? 預設: 是 @@ -884,7 +896,7 @@ Взрыв при разминировании? Detona se disarmati? 解除中に爆発するか? - 해제 시 폭발합니까? + 해체 시 폭발합니까? 拆除时引爆? 拆除時引爆? @@ -900,7 +912,7 @@ Разрешить определенным взрывным устройствам взрываться при разминировании? По умолчанию: Да Permettere ad alcuni esplosivi di esplodere quando si tenta il disinnesco? Predefinito: Si 特定の爆発物を解除中に爆発可能にしますか? デフォルト: 有効 - 특정 폭발물이 해제 시 폭발하게 합니까? 기본설정: 예 + 특정 폭발물이 해체 시 폭발하게 합니까? 기본설정: 예 启用后,某些爆炸物会在拆除时引爆? 预设:是 啟用後, 某些炸彈會在拆除時引爆? 預設: 是 @@ -1162,7 +1174,7 @@ 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. @@ -1175,7 +1187,7 @@ 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. @@ -1188,7 +1200,7 @@ 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. diff --git a/addons/fastroping/XEH_postInit.sqf b/addons/fastroping/XEH_postInit.sqf index 27d3ca4008b..0cfeee67bd9 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 @@ -42,13 +40,21 @@ if (isServer) then { }, true, ["ACE_friesBase"], true] call CBA_fnc_addClassEventHandler; }; +// Handles the Vanilla respawn module +[missionNamespace, "respawn", { + params ["_vehicle"]; + + if !(_vehicle getVariable [QGVAR(addFRIESOnRespawn), false]) exitWith {}; + + _vehicle call FUNC(equipFRIES); +}] call BIS_fnc_addScriptedEventHandler; #ifdef DRAW_FASTROPE_INFO addMissionEventHandler ["Draw3D", { - if (!(cursorObject isKindOf "Helicopter")) exitWith {}; + if !(cursorObject isKindOf "Helicopter") exitWith {}; private _config = configOf cursorObject; private _enabled = getNumber (_config >> QGVAR(enabled)); - drawIcon3D ["", [.5,.5,1,1], (ASLtoAGL getPosASL cursorObject), 0.5, 0.5, 0, format ["%1 = %2", typeOf cursorObject, _enabled], 0.5, 0.025, "TahomaB"]; + 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 { { private _hookAttachment = cursorObject getVariable [QGVAR(FRIES), cursorObject]; diff --git a/addons/fastroping/functions/fnc_cutRopes.sqf b/addons/fastroping/functions/fnc_cutRopes.sqf index cbd01b56615..40d24160492 100644 --- a/addons/fastroping/functions/fnc_cutRopes.sqf +++ b/addons/fastroping/functions/fnc_cutRopes.sqf @@ -34,8 +34,8 @@ private _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; //Only delete the hook first so the rope falls down. //Note: ropeDetach was used here before, but the command seems a bit broken. deleteVehicle _hook; - [{{deleteVehicle _x} count _this}, [_ropeTop, _ropeBottom, _dummy], 60] call CBA_fnc_waitAndExecute; -} count _deployedRopes; + [{{deleteVehicle _x} forEach _this}, [_ropeTop, _ropeBottom, _dummy], 60] call CBA_fnc_waitAndExecute; +} forEach _deployedRopes; _vehicle setVariable [QGVAR(deployedRopes), [], true]; diff --git a/addons/fastroping/functions/fnc_deployRopes.sqf b/addons/fastroping/functions/fnc_deployRopes.sqf index 71cfbbbc21f..c4e999db17c 100644 --- a/addons/fastroping/functions/fnc_deployRopes.sqf +++ b/addons/fastroping/functions/fnc_deployRopes.sqf @@ -26,7 +26,7 @@ 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 >> QEGVAR(logistics_rope,length)); +private _ropeLength = getNumber (configFile >> "CfgWeapons" >> _ropeClass >> QEGVAR(logistics_rope,length)); if (_ropeLength <= 0) then { _ropeLength = DEFAULT_ROPE_LENGTH; @@ -67,9 +67,7 @@ if (GVAR(requireRopeItems) && {_ropeClass != ""}) then { //deployedRopes format: attachment point, top part of the rope, bottom part of the rope, attachTo helper object, occupied, broken _deployedRopes pushBack [_ropeOrigin, _ropeTop, _ropeBottom, _dummy, _hook, false, false]; - - false -} count _ropeOrigins; +} forEach _ropeOrigins; _vehicle setVariable [QGVAR(deployedRopes), _deployedRopes, true]; _vehicle setVariable [QGVAR(deploymentStage), 3, true]; diff --git a/addons/fastroping/functions/fnc_equipFRIES.sqf b/addons/fastroping/functions/fnc_equipFRIES.sqf index 615840cb75d..869473cdd14 100644 --- a/addons/fastroping/functions/fnc_equipFRIES.sqf +++ b/addons/fastroping/functions/fnc_equipFRIES.sqf @@ -19,7 +19,7 @@ params ["_vehicle"]; if (!alive _vehicle) exitWith { WARNING_1("bad vehicle %1",_this); }; - if (alive (_vehicle getVariable [QGVAR(FRIES),objNull])) exitWith { WARNING_1("already equiped %1",_this); }; + if (alive (_vehicle getVariable [QGVAR(FRIES), objNull])) exitWith { WARNING_1("already equipped %1",_this); }; private _config = configOf _vehicle; if !(isNumber (_config >> QGVAR(enabled))) then { @@ -29,6 +29,12 @@ private _fries = (getText (_config >> QGVAR(friesType))) createVehicle [0, 0, 0]; _fries attachTo [_vehicle, getArray (_config >> QGVAR(friesAttachmentPoint))]; _vehicle setVariable [QGVAR(FRIES), _fries, true]; + + // The Vanilla respawn module copies all variables from old object to new one + // Use that to move variable from wreck to new vehicle + _vehicle setVariable [QGVAR(addFRIESOnRespawn), true, true]; }; }; }, _this] call CBA_fnc_execNextFrame; + +nil diff --git a/addons/fastroping/functions/fnc_fastRope.sqf b/addons/fastroping/functions/fnc_fastRope.sqf index 80be8705539..430c8d86ca8 100644 --- a/addons/fastroping/functions/fnc_fastRope.sqf +++ b/addons/fastroping/functions/fnc_fastRope.sqf @@ -36,4 +36,4 @@ _vehicle setVariable [QGVAR(deployedRopes), _deployedRopes, true]; //Start server PFH asap [QGVAR(startFastRope), [_unit, _vehicle, _usableRope, _usableRopeIndex, false]] call CBA_fnc_serverEvent; moveOut _unit; -[FUNC(fastRopeLocalPFH), 0, [_unit, _vehicle, _usableRope, _usableRopeIndex, diag_tickTime]] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(fastRopeLocalPFH), 0, [_unit, _vehicle, _usableRope, _usableRopeIndex, diag_tickTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf b/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf index 92d23715b09..b1fec908a59 100644 --- a/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf +++ b/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf @@ -20,7 +20,7 @@ _arguments params ["_unit", "", "_rope", "", "_timeToPlayRopeSound"]; _rope params ["", "", "", "_dummy", "_hook"]; //Wait until the unit is actually outside of the helicopter -if (vehicle _unit != _unit) exitWith {}; +if (!isNull objectParent _unit) exitWith {}; // dummy lost hook if (isNull _hook) exitWith { diff --git a/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf b/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf index c3b7fe1ea46..716c0ab43e8 100644 --- a/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf +++ b/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf @@ -20,7 +20,7 @@ _arguments params ["_unit", "_vehicle", "_rope", "_ropeIndex", "_hasBeenAttached _rope params ["_attachmentPoint", "_ropeTop", "_ropeBottom", "_dummy", "_hook"]; //Wait until the unit is actually outside of the helicopter -if (vehicle _unit != _unit) exitWith {}; +if (!isNull objectParent _unit) exitWith {}; //Prevent teleport if hook has been deleted due to rope cut if (isNull _hook) exitWith { diff --git a/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf b/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf index 970194ab631..892997bf803 100644 --- a/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf +++ b/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf @@ -22,5 +22,4 @@ private _synchedUnits = synchronizedObjects _module; _x = vehicle _x; }; [_x] call FUNC(equipFRIES); - false -} count _synchedUnits; +} forEach _synchedUnits; diff --git a/addons/fastroping/initSettings.inc.sqf b/addons/fastroping/initSettings.inc.sqf index 844de927a23..cde4a32b47e 100644 --- a/addons/fastroping/initSettings.inc.sqf +++ b/addons/fastroping/initSettings.inc.sqf @@ -5,9 +5,7 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(setting_c [LSTRING(setting_requireRopeItems_displayName)], _category, false, // default value - true, // isGlobal - {[QGVAR(requireRopeItems), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // needRestart + true // isGlobal ] call CBA_fnc_addSetting; [ diff --git a/addons/fastroping/stringtable.xml b/addons/fastroping/stringtable.xml index b68da23d28f..b8245c77829 100644 --- a/addons/fastroping/stringtable.xml +++ b/addons/fastroping/stringtable.xml @@ -134,10 +134,10 @@ 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 + Equipa o helicóptero selecionado com um Sistema de Inserção/Extração Rápida por Corda Снаряжает выбранный вертолет оборудованием для спуска десанта по канатам 選択されたヘリコプターで Fast Rope Insertion Extraction System を使えるようにします。 - 선택된 헬리콥터에 패스트로프 투입 및 탈출 시스템을 장착합니다. + 선택된 헬리콥터에 패스트로프 투입 및 탈출 시스템(FRIES)을 장착합니다. 使指定的直升机启用快速绳降及撤离系统 使指定的直升機啟用快速繩降及撤離系統 @@ -298,6 +298,7 @@ Schnelles-Abseilen Fast Rope 패스트로프 + Descida rápida pela corda Require rope item to deploy @@ -321,10 +322,11 @@ 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. @@ -332,10 +334,11 @@ 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/CfgOptics.hpp b/addons/fcs/CfgOptics.hpp index f8770d7327d..551a965a60d 100644 --- a/addons/fcs/CfgOptics.hpp +++ b/addons/fcs/CfgOptics.hpp @@ -26,7 +26,7 @@ class RscInGameUI { }; }; class Rsc_ACE_Helo_UI_Turret: RscUnitInfo { // RscOptics_Heli_Attack_01_gunner - onLoad = "[""onLoad"",_this,""RscUnitInfo"",'IGUI'] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable ['ACE_dlgRangefinder', _this select 0]; ((_this select 0) displayCtrl 151) ctrlSetTextColor [0, 0, 0, 0];"; + onLoad = "[""onLoad"",_this,""RscUnitInfo"",'IGUI'] call (uiNamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable ['ACE_dlgRangefinder', _this select 0]; ((_this select 0) displayCtrl 151) ctrlSetTextColor [0, 0, 0, 0];"; class CA_IGUI_elements_group: RscControlsGroup { class controls { MACRO_RANGEFINDER diff --git a/addons/fcs/config.cpp b/addons/fcs/config.cpp index 88e803d0ca4..433f17ac8be 100644 --- a/addons/fcs/config.cpp +++ b/addons/fcs/config.cpp @@ -27,13 +27,6 @@ class CfgPatches { #include "CfgOptics.hpp" -class ACE_Extensions { - class ace_fcs { - windows = 1; - client = 1; - }; -}; - class ACE_Tests { fcs = QPATHTOF(dev\test_debugConfigs.sqf); }; diff --git a/addons/fcs/dev/test_debugConfigs.sqf b/addons/fcs/dev/test_debugConfigs.sqf index c3739123639..dacf8624f37 100644 --- a/addons/fcs/dev/test_debugConfigs.sqf +++ b/addons/fcs/dev/test_debugConfigs.sqf @@ -71,13 +71,13 @@ private _problemUIs = []; _problemUIs pushBackUnique format ["%1: ACE_FCS, but missing ACE_CA_DIST", _turretInfo]; }; if (_aceFCS && {(198 in _idcList)}) then { - _problemUIs pushBackUnique format ["%1: ACE_FCS, but NEW Lazr CA_DIST", _turretInfo, _vehicleType]; + _problemUIs pushBackUnique format ["%1-%2: ACE_FCS, but NEW Lazr CA_DIST", _turretInfo, _vehicleType]; }; if ((!_aceFCS) && {(1713151 in _idcList)}) then { - _problemUIs pushBackUnique format ["%1: Not ACE but has ACE_CA_DIST", _turretInfo, _vehicleType]; + _problemUIs pushBackUnique format ["%1-%2: Not ACE but has ACE_CA_DIST", _turretInfo, _vehicleType]; }; if (_vanillaFCS && {!(198 in _idcList)}) then { - _problemUIs pushBackUnique format ["%1: vanillaFCS but missing NEW Lazr CA_DIST [just a warning]", _turretInfo, _vehicleType]; + _problemUIs pushBackUnique format ["%1-%2: vanillaFCS but missing NEW Lazr CA_DIST [just a warning]", _turretInfo, _vehicleType]; }; }; }; diff --git a/addons/fcs/functions/fnc_calculateSolution.sqf b/addons/fcs/functions/fnc_calculateSolution.sqf index 5800068e4ba..de9462848d7 100644 --- a/addons/fcs/functions/fnc_calculateSolution.sqf +++ b/addons/fcs/functions/fnc_calculateSolution.sqf @@ -44,14 +44,13 @@ private _turretConfig = [configOf _vehicle, _turret] call EFUNC(common,getTurret if (_x != "this") then { _weaponMagazines append getArray (configFile >> "CfgWeapons" >> _weapon >> _x >> "magazines"); }; - false - } count _muzzles; + } forEach _muzzles; // Fix the `in` operator being case sensitive and BI fucking up the spelling of their own classnames - private _weaponMagazinesCheck = _weaponMagazines apply {toLower _x}; + private _weaponMagazinesCheck = _weaponMagazines apply {toLowerANSI _x}; // Another BIS fix: ShotBullet simulation uses weapon initSpeed, others ignore it - if (toLower _magazine in _weaponMagazinesCheck && {_bulletSimulation == "shotBullet"}) exitWith { + if (toLowerANSI _magazine in _weaponMagazinesCheck && {_bulletSimulation == "shotBullet"}) exitWith { private _initSpeedCoef = getNumber(configFile >> "CfgWeapons" >> _weapon >> "initSpeed"); if (_initSpeedCoef < 0) then { @@ -62,18 +61,16 @@ private _turretConfig = [configOf _vehicle, _turret] call EFUNC(common,getTurret _initSpeed = _initSpeedCoef; }; }; - false - } count (_vehicle weaponsTurret _turret); + } forEach (_vehicle weaponsTurret _turret); - private _offset = "ace_fcs" callExtension format ["%1,%2,%3,%4", _initSpeed, _airFriction, _angleTarget, _distance]; + private _offset = ("ace" callExtension ["fcs", [_initSpeed, _airFriction, _angleTarget, _distance]]) # 0; _offset = parseNumber _offset; _FCSInitSpeed pushBack _initSpeed; _FCSMagazines pushBack _magazine; _FCSElevation pushBack _offset; }; - false -} count (_vehicle magazinesTurret _turret); +} forEach (_vehicle magazinesTurret _turret); [_vehicle, format ["%1_%2", QGVAR(Distance), _turret], _distance] call EFUNC(common,setVariablePublic); [_vehicle, format ["%1_%2", QGVAR(InitSpeed), _turret], _FCSInitSpeed] call EFUNC(common,setVariablePublic); diff --git a/addons/fcs/functions/fnc_firedEH.sqf b/addons/fcs/functions/fnc_firedEH.sqf index 52edd6417f4..d4e79e84617 100644 --- a/addons/fcs/functions/fnc_firedEH.sqf +++ b/addons/fcs/functions/fnc_firedEH.sqf @@ -41,7 +41,7 @@ if (_zeroDistance > 0) then { private _weaponCombo = [_weapon, _magazine, _ammo, _zeroDistance]; 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]; + private _antiOffset = ("ace" callExtension ["fcs", [_initSpeed, _airFriction, 0, _zeroDistance]]) # 0; _antiOffset = parseNumber _antiOffset; _gunner setVariable [QGVAR(lastWeaponCombo), _weaponCombo]; @@ -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 9a856d46c97..03e8b4fdc8e 100644 --- a/addons/fcs/functions/fnc_getAngle.sqf +++ b/addons/fcs/functions/fnc_getAngle.sqf @@ -21,7 +21,7 @@ * Public: No */ -#define PRECISION 0.1 +#define VAR_PRECISION 0.1 params ["_distance", "_angleTarget", "_maxElev", "_initSpeed", "_airFriction", "_timeToLive", "_simulationStep"]; @@ -69,9 +69,9 @@ private _it2 = 0; _data set [7, _maxElev]; private _f1 = _data call _fnc_traceBullet; -if (abs _f1 <= PRECISION) exitWith {0}; +if (abs _f1 <= VAR_PRECISION) exitWith {0}; -while {abs _f1 > PRECISION} do { +while {abs _f1 > VAR_PRECISION} do { _data set [7, _angle2]; private _f2 = _data call _fnc_traceBullet; diff --git a/addons/field_rations/XEH_postInit.sqf b/addons/field_rations/XEH_postInit.sqf index 1ee235ca4f3..dac701845f4 100644 --- a/addons/field_rations/XEH_postInit.sqf +++ b/addons/field_rations/XEH_postInit.sqf @@ -38,6 +38,7 @@ if !(hasInterface) exitWith {}; [false, false, false, false, true] ] call EFUNC(interact_menu,createAction); + //IGNORE_PRIVATE_WARNING ["_player", "_target"]; private _subActions = [ [ QGVAR(checkWater), @@ -96,10 +97,10 @@ if !(hasInterface) exitWith {}; ] call CBA_fnc_addItemContextMenuOption; // Add water source helpers when interaction menu is opened - ["ace_interactMenuOpened", {call FUNC(addWaterSourceInteractions)}] call CBA_fnc_addEventHandler; + ["ace_interactMenuOpened", LINKFUNC(addWaterSourceInteractions)] call CBA_fnc_addEventHandler; // Add status modifiers - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [0, { if (_this getVariable [QEGVAR(medical,isBleeding), false]) exitWith { 0.5 @@ -134,7 +135,7 @@ if !(hasInterface) exitWith {}; ["CAManBase", "respawn", LINKFUNC(handleRespawn)] call CBA_fnc_addClassEventHandler; // Start update loop - [FUNC(update), CBA_missionTime + MP_SYNC_INTERVAL, 1] call CBA_fnc_waitAndExecute; + [LINKFUNC(update), CBA_missionTime + MP_SYNC_INTERVAL, 1] call CBA_fnc_waitAndExecute; #ifdef DEBUG_MODE_FULL ["ACE_player thirst", {ACE_player getVariable [QXGVAR(thirst), 0]}, [true, 0, 100]] call EFUNC(common,watchVariable); diff --git a/addons/field_rations/XEH_preStart.sqf b/addons/field_rations/XEH_preStart.sqf index 88109cf9eee..ebb22b6ee85 100644 --- a/addons/field_rations/XEH_preStart.sqf +++ b/addons/field_rations/XEH_preStart.sqf @@ -15,7 +15,7 @@ private _waterSourceOffsets = [ // Fill water source arrays from CfgVehicles { private _split = (getText (_x >> "model")) splitString "\"; - private _string = toLower (_split param [((count _split) - 1), ""]); + private _string = toLowerANSI (_split param [((count _split) - 1), ""]); // Append extension if necessary if ((_string select [count _string - 4]) != ".p3d") then { diff --git a/addons/field_rations/functions/fnc_getActionOffset.sqf b/addons/field_rations/functions/fnc_getActionOffset.sqf index dd7658dfda1..763654c6559 100644 --- a/addons/field_rations/functions/fnc_getActionOffset.sqf +++ b/addons/field_rations/functions/fnc_getActionOffset.sqf @@ -18,11 +18,11 @@ params ["_object"]; private _configOf = configOf _object; -if !(isNull _configOf) then { +if (isNull _configOf) then { + // Check for offset corresponding to p3d list + GVAR(waterSourceOffsets) param [GVAR(waterSourceP3ds) find (getModelInfo _object select 0), [0, 0, 0], [[]]]; +} else { // 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 index 9fe422109c0..73e75e29a47 100644 --- a/addons/field_rations/functions/fnc_getConsumableChildren.sqf +++ b/addons/field_rations/functions/fnc_getConsumableChildren.sqf @@ -18,6 +18,7 @@ params ["_player"]; private _fnc_getActions = { + //IGNORE_PRIVATE_WARNING ["_player"]; TRACE_1("Creating consumable item actions",_player); private _actions = []; diff --git a/addons/field_rations/functions/fnc_getRemainingWater.sqf b/addons/field_rations/functions/fnc_getRemainingWater.sqf index 253fd62285d..1011136e0ce 100644 --- a/addons/field_rations/functions/fnc_getRemainingWater.sqf +++ b/addons/field_rations/functions/fnc_getRemainingWater.sqf @@ -23,7 +23,10 @@ private _water = _source getVariable QGVAR(currentWaterSupply); if (isNil "_water") then { private _configOf = configOf _source; - if !(isNull _configOf) then { + if (isNull _configOf) then { + // Check the p3d name against list + _water = if ((getModelInfo _source select 0) in GVAR(waterSourceP3ds)) then {REFILL_WATER_INFINITE} else {REFILL_WATER_DISABLED}; + } else { // Check for waterSupply entry since we have valid typeOf _water = getNumber (_configOf >> QXGVAR(waterSupply)); if (_water == 0) then {_water = REFILL_WATER_DISABLED}; @@ -35,9 +38,6 @@ if (isNil "_water") then { _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}; }; }; diff --git a/addons/field_rations/functions/fnc_handleEffects.sqf b/addons/field_rations/functions/fnc_handleEffects.sqf index 1981cc5f996..ad60a743ad0 100644 --- a/addons/field_rations/functions/fnc_handleEffects.sqf +++ b/addons/field_rations/functions/fnc_handleEffects.sqf @@ -21,24 +21,21 @@ params ["_player", "_thirst", "_hunger"]; // Kill unit with max thirst or hunger if ((_thirst > 99.9 || {_hunger > 99.9}) && {random 1 < 0.5}) exitWith { - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { - [_player, "Hunger/Thirst empty"] call EFUNC(medical_status,setDead); - } else { - _player setDamage 1; - }; + [_player, "Hunger/Thirst empty"] call EFUNC(common,setDead); }; // Exit if unit is not awake, below are animation based consequences if !(_player call EFUNC(common,isAwake)) exitWith {}; // Set unit unconscious (chance based on how high thirst/hunger are) -if ((_thirst > 85 || {_hunger > 85}) && {random 1 < linearConversion [85, 100, _thirst max _hunger, 0.05, 0.1, true]}) exitWith { - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { - [_player, true, 5, true] call EFUNC(medical,setUnconscious); - }; +if ( + GETEGVAR(medical,enabled,false) && + {(_thirst > 85 || {_hunger > 85}) && {random 1 < linearConversion [85, 100, _thirst max _hunger, 0.05, 0.1, true]}} +) exitWith { + [_player, true, 5, true] call EFUNC(medical,setUnconscious); }; // Make unit fall if moving fast -if ((_thirst > 93 || {_hunger > 93}) && {speed _player > 1} && {vehicle _player == _player}) exitWith { +if ((_thirst > 93 || {_hunger > 93}) && {speed _player > 1} && {isNull objectParent _player}) exitWith { [_player, "down"] call EFUNC(common,doGesture); }; diff --git a/addons/field_rations/functions/fnc_update.sqf b/addons/field_rations/functions/fnc_update.sqf index 82b87bcfb6f..f66573824b8 100644 --- a/addons/field_rations/functions/fnc_update.sqf +++ b/addons/field_rations/functions/fnc_update.sqf @@ -25,7 +25,7 @@ private _player = ACE_player; // Exit if player is not alive or a virtual unit if (!alive _player || {_player isKindOf "VirtualMan_F"}) exitWith { - [FUNC(update), _nextMpSync, 1] call CBA_fnc_waitAndExecute; + [LINKFUNC(update), _nextMpSync, 1] call CBA_fnc_waitAndExecute; QGVAR(hud) cutFadeOut 0.5; }; @@ -73,4 +73,4 @@ if (!EGVAR(common,OldIsCamera) && {_thirst > XGVAR(hudShowLevel) || {_hunger > X QGVAR(hud) cutFadeOut 0.5; }; -[FUNC(update), _nextMpSync, 1] call CBA_fnc_waitAndExecute; +[LINKFUNC(update), _nextMpSync, 1] call CBA_fnc_waitAndExecute; diff --git a/addons/field_rations/initSettings.inc.sqf b/addons/field_rations/initSettings.inc.sqf index 86bf04aed2f..16e2d4eb2d6 100644 --- a/addons/field_rations/initSettings.inc.sqf +++ b/addons/field_rations/initSettings.inc.sqf @@ -4,9 +4,9 @@ [ELSTRING(common,Enabled), LSTRING(Enabled_Description)], LSTRING(DisplayName), false, - true, - {}, - true // Needs restart + 1, + {[QXGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ diff --git a/addons/field_rations/stringtable.xml b/addons/field_rations/stringtable.xml index 78e1ebfe87b..50fece7cfb1 100644 --- a/addons/field_rations/stringtable.xml +++ b/addons/field_rations/stringtable.xml @@ -31,6 +31,7 @@ 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. @@ -78,6 +79,7 @@ 먹기/마시기 Comer/Beber Comer/Beber + Manger/Boire Enable/Disable Field Rations @@ -177,6 +179,7 @@ 갈증 해소 Sed saciada Sede saciada + Soif étanchée Coefficient for the amount of thirst quenched from drinking. @@ -191,6 +194,7 @@ 마심으로써 갈증이 얼마나 해소되는지를 정합니다 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 @@ -205,6 +209,7 @@ 배부름 Hambre saciada Fome saciada + Faim rassasiée Coefficient for the amount of hunger satiated from eating. @@ -219,6 +224,7 @@ 밥을 먹어서 배고픔이 얼마나 해결되는지를 정합니다 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 @@ -232,6 +238,7 @@ 물 근처 행동 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. @@ -245,6 +252,7 @@ 물가에서 어떤 행동을 취할지 정합니다 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 @@ -258,6 +266,7 @@ 다시 채우기만 가능 Sólo rellenar Apenas reabastecer + Remplissage uniquement Terrain Object Actions @@ -271,6 +280,7 @@ 지형 물체 상호작용 Acciones sobre objetos del terreno Ações para objetos do terreno + Actions sur les objets du terrain Enables water source actions for terrain objects. @@ -284,6 +294,7 @@ 지형 물체에서 물을 얻는 게 가능해집니다. 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 @@ -291,13 +302,14 @@ 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. @@ -305,13 +317,14 @@ Determina se fame e sete influenzano la Fatica Avanzata ACE. 是否讓飲食影響到ACE的進階疲勞。 是否让饮食影响到 ACE 的进阶疲劳。 - 喉の渇きと空腹度が ACE アドバンスド疲労へ与える影響を定義します。 + 喉の渇きと空腹度が ACE 高度な疲労へ与える影響を定義します。 Определяет, будет ли жажда и голод влиять на продвинутую усталость ACE. Kontroluje czy pragnienie i głód mają wpływ na zaawansowane zmęczenie ACE. Acıkınca veya susayınca kişinin yorulup yorulmayacağını belirler. 배고픔과 목마름이 고급 피로도에 영향을 끼칠지를 정합니다 Controla si la sed y el hambre afectan a la Fatiga Avanzada de ACE Controla se a sede e a fome afetam a Fadiga Avançada do ACE. + Contrôle si la soif et la faim doivent affecter la fatigue avancée ACE. HUD Type @@ -326,6 +339,7 @@ HUD 종류 Tipo de HUD Tipo de HUD + Type de HUD Selects which HUD style will be used. @@ -340,6 +354,7 @@ 사용될 HUD 스타일을 고르십시오. Selecciona qué estilo de HUD será utilizado. Seleciona qual estilo de HUD será usado. + Sélectionne le style HUD à utiliser. Colored Icons @@ -354,6 +369,7 @@ 색깔 아이콘 Iconos coloreados Ícones coloridos + Icônes de couleur Draining Icons @@ -368,6 +384,7 @@ 빠지는 아이콘 Iconos de drenado Ícones de drenagem + Icônes incolores HUD Show Level @@ -382,6 +399,7 @@ 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. @@ -396,6 +414,7 @@ 정한 퍼센트 이하로 내려가면 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 @@ -427,6 +446,7 @@ 색깔 아이콘 - 투명도 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. @@ -435,12 +455,13 @@ 控制顏色化圖示的透明度。設定為動態使其界面透明度與飲食需求一樣,越透明越需要。 控制彩色图标 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 @@ -471,6 +492,7 @@ 식수 보급량 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) @@ -484,6 +506,7 @@ 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 @@ -498,6 +521,7 @@ 수원지 Suministro de agua Fonte de água + Source d'eau Check Remaining Water @@ -512,6 +536,7 @@ 남은 물 확인 Comprobar agua restante Verificar água restante + Vérifier l'eau restante Checking remaining water... @@ -526,6 +551,7 @@ 남은 물 확인 중... Comprobando agua restante... Verificando água restante... + Vérification de l'eau restante... There are %1 litres left. @@ -540,6 +566,7 @@ %1 리터의 물이 남아있습니다. Quedan %1 litros. Ainda há %1 litros. + Il reste %1 litres. There is no water left. @@ -554,6 +581,7 @@ 물이 한 방울도 없습니다. No queda agua. Não há mais água. + Il n'y a plus d'eau. Drink From Source @@ -567,6 +595,7 @@ 수원에서 물 마시기 Beber desde el suministro Beber da fonte + Boire à la source Refill @@ -632,6 +661,7 @@ %1 먹는 중... Comiendo %1... Comendo %1... + Manger %1... Drinking %1... @@ -646,6 +676,7 @@ %1 마시는 중... Bebiendo %1... Bebendo %1... + Boire %1... Drinking from %1... @@ -660,6 +691,7 @@ %1 으로 부터 마시는 중... Bebiendo desde %1... Bebendo de %1... + Boire à %1... Drinking from source... @@ -673,6 +705,7 @@ 수원에서 마시는 중... Bebiendo desde el suministro... Bebendo da fonte... + Boire à la source... Water Bottle @@ -837,7 +870,7 @@ 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 Наполовину заполненая водой фляга @@ -891,6 +924,7 @@ 상쾌한 레몬라임향의 탄산음료 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 @@ -905,6 +939,7 @@ 오렌지 향의 톡쏘는 탄산음료 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 @@ -919,6 +954,7 @@ 레드굴은 날개를 달아줘요 Red Gull te da alas Red Gull te dá asas + Red Gull vous donne des ailes MRE Lamb Curry @@ -967,6 +1003,7 @@ MRE 비프스튜 MRE Estofado de ternera MRE ensopado de carne + MRE Ragoût de bœuf An MRE containing Beef Stew. Heat for best effect @@ -981,6 +1018,7 @@ 비프스튜가 들어있는 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 @@ -1229,6 +1267,7 @@ Семечки подсолнуха Pipas de girasol Sementes de girassol + Graines de tournesol Roasted And Salted @@ -1241,6 +1280,7 @@ Поджаренные и солёные Tostadas y saladas Torradas e salgadas + Grillé et salé diff --git a/addons/fieldmanual/stringtable.xml b/addons/fieldmanual/stringtable.xml index 647a5bad437..9cf2290de2d 100644 --- a/addons/fieldmanual/stringtable.xml +++ b/addons/fieldmanual/stringtable.xml @@ -27,6 +27,8 @@ 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. @@ -37,6 +39,8 @@ %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 @@ -47,6 +51,8 @@ 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. @@ -57,6 +63,8 @@ %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 @@ -67,6 +75,8 @@ Cure Mediche 治療 Медицинское лечение + Traitement médical + Tratamiento Médico Decrease Heart Rate @@ -77,6 +87,8 @@ 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. @@ -87,6 +99,8 @@ %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 @@ -97,6 +111,8 @@ Bende 包帯 Бинты + Pansements + Vendas Close Wounds @@ -107,6 +123,8 @@ 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. @@ -116,6 +134,7 @@ %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 @@ -125,6 +144,8 @@ IV-Flüssigkeiten Fluidi EV IV 輸液 + IV Fluides + Fluidos IV Restore Blood Volume @@ -135,6 +156,8 @@ 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. @@ -144,6 +167,9 @@ %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. + %3IV fluides%4 restaurer le volume sanguin perdu. Sang, Plasma, and Saline fonctionnent de la même manière.<br/><br/>%3Utilisation:%4<br/>%2Utiliser [%3%13%4] ou [%3%14%4] et sélectionner un appendice.<br/>%2Restaurer le volume sanguin en sélectionnant le volume désiré %3IV Fluide%4 type. Increase Heart Rate | Wake Up Faster @@ -154,6 +180,8 @@ 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. @@ -163,6 +191,7 @@ %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 @@ -173,6 +202,8 @@ 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. @@ -182,6 +213,7 @@ 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 @@ -192,6 +224,8 @@ 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. @@ -201,6 +235,7 @@ 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 @@ -210,6 +245,9 @@ 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. @@ -218,6 +256,8 @@ 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 @@ -227,6 +267,9 @@ 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. @@ -235,6 +278,8 @@ 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 @@ -259,6 +304,8 @@ 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. @@ -266,7 +313,8 @@ %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を使って治療項目を選択できます。 + %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 @@ -275,6 +323,8 @@ 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. @@ -283,6 +333,7 @@ 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 @@ -291,6 +342,8 @@ 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. @@ -299,6 +352,7 @@ 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 @@ -307,6 +361,8 @@ 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. @@ -315,6 +371,7 @@ 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 @@ -323,6 +380,8 @@ 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. @@ -330,7 +389,8 @@ %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電話を掛けることで起爆します。 + %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 @@ -339,6 +399,8 @@ 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. @@ -347,6 +409,7 @@ 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 @@ -355,13 +418,16 @@ 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を選択します。 + %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 @@ -370,6 +436,8 @@ 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 @@ -377,6 +445,7 @@ %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 @@ -385,6 +454,8 @@ 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. @@ -392,6 +463,7 @@ %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. @@ -399,6 +471,7 @@ %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 @@ -407,6 +480,8 @@ Disinnesca Esplosivi 爆発物の解除 Обезвреживание взрывчатки + Désamorcer les explosifs + Desactivar Explosivos Protect Your Hearing @@ -415,6 +490,8 @@ 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. @@ -422,6 +499,7 @@ %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 @@ -430,6 +508,8 @@ 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. @@ -437,6 +517,7 @@ 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 @@ -445,6 +526,8 @@ 손전등 フラッシュライト Фонари + Lampes de poche + Linternas Illuminate Your Map @@ -453,6 +536,8 @@ 지도를 밝혀줍니다 地図に光あれ Осветите свою карту + É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. @@ -460,6 +545,7 @@ %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 @@ -468,6 +554,8 @@ 하늘에서 관측합니다 空から戦場を見てみよう Наблюдайте с Небес + 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. @@ -475,6 +563,7 @@ 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 @@ -483,6 +572,8 @@ 은신하여 팀을 찾아냅니다 自分の部隊を追う Следите за своей командой незаметно + 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. @@ -490,6 +581,7 @@ 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 @@ -498,6 +590,8 @@ 휴대용 기상 관측 장비입니다 携帯気象予報所 Карманная метеостанция + 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. @@ -505,6 +599,7 @@ 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 @@ -513,6 +608,8 @@ 위치를 삼각측량합니다 三角測量で位置を特定 Передавайте свое местоположение + 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]. @@ -520,21 +617,26 @@ 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 + 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 を参照してください。 + %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 @@ -543,6 +645,8 @@ 사거리표 射表 Таблицы диапазонов + Tables de tir + Tablas de Distancia Get A Firing Solution @@ -551,6 +655,8 @@ 사격 솔루션을 제공합니다 撃ち方の解を得る Получите расчёт + 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. @@ -558,6 +664,7 @@ %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 @@ -566,6 +673,8 @@ 로프 ロープ Канаты + Corde + Cuerdas Tow With Ease @@ -574,6 +683,8 @@ 쉽게 견인을 할 수 있습니다 楽々けん引 Буксируйте с легкостью + 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 @@ -581,6 +692,7 @@ %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 @@ -589,6 +701,8 @@ 당신의 요새를 확장합니다 要塞を拡張する Расширить свои укрепления + É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. @@ -596,6 +710,7 @@ %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 @@ -604,6 +719,8 @@ 총기의 온도를 낮춥니다 銃の熱を冷ます Понизьте температуру оружия + 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. @@ -611,6 +728,7 @@ %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 @@ -619,6 +737,8 @@ 스프레이 페인트 ペイントスプレー Аэрозольная краска + Bombe de peinture + Pintura En Spray Tag Your Territory @@ -627,6 +747,8 @@ 당신의 영역을 지정합니다 自分のテリトリーをマーキング Пометьте свою территорию + 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 @@ -634,6 +756,7 @@ %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 @@ -642,6 +765,8 @@ 어느 곳에나 지지대를 배치할 수 있습니다 どこでも支持器 Опора может быть установлена в любом месте + 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. @@ -649,6 +774,7 @@ 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 @@ -657,6 +783,9 @@ 하늘에서 계속 내려다봅니다 空の目を維持する Не Отрывай Глаз От Неба + 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. @@ -664,6 +793,7 @@ %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 @@ -672,6 +802,8 @@ 진입로를 만듭니다 堂々入場する Создание собственного входа + 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. @@ -679,6 +811,7 @@ 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 @@ -703,6 +836,15 @@ ACE3 ACE 3 ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 Build Fortifications @@ -711,13 +853,16 @@ 요새를 건설합니다 要塞を構築する Стройте укрепления + 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利用可能な構造物を選択し、画面上の指示に従って配置します。 + %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 @@ -726,6 +871,8 @@ 침입용 도구입니다 破壊して乗り込む Взлом и проникновение + 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. @@ -733,6 +880,7 @@ 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 @@ -741,6 +889,8 @@ 차량 열쇠 車両キー Взлом и проникновение + Clés de véhicule + Llaves de Vehículos Lock/Unlock Vehicles @@ -749,6 +899,8 @@ 차량을 잠그거나 해제합니다 車両のロック/ロック解除 Взлом и проникновение + 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. @@ -756,6 +908,7 @@ Le %3Chiavi di Veicoli%4 vengono usate per bloccare/sbloccare i propri veicoli. Chiavi di veicoli possono esistere per un'intera fazione, oppure per un veicolo particolare.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Chiave di Veicolo%4.<br/>%2Avvicinati al veicolo a cui appartiene la chiave.<br/>Usa [%3%13%4] e seleziona %3Blocca/Sblocca Veicolo%4.<br/><br/><t underline='1'>%3Note:%4</t> Grimaldelli e chiavi sono solo disponibili mediante scripting o moduli ACE Chiavi Veicoli. %3차량 열쇠%4는 차량을 잠그거나 잠금해제하는 데 사용됩니다. 차량 열쇠는 모든 세력에게 존재할 수도 있고, 특정 차량 자체에 대해 열쇠를 생성할 수도 있습니다.<br/><br/>%3사용 방법:%4<br/>%2%3차량 열쇠%4를 장착하십시오.<br/>%2해당 열쇠에 속한 차량에 접근하십시오.<br/>[%3%13%4]를 사용하고 %3차량 잠금/잠금해제%4를 선택하십시오.<br/><br/><t underline='1'>%3참고:%4</t> 해정도구와 열쇠는 스크립팅 또는 ACE 차량 열쇠 모듈에서만 사용할 수 있습니다. %3Vehicle Key%4は、車両のロック/ロック解除に使用されます。車両キーは陣営全体に存在することも、特定の車両だけに対してキーを作成することもできます。<br/><br/>%3使用方法:%4<br/>%2%3Vehicle Key%4を装備します。<br/>%2鍵の対応している車両に近づきます。<br/>[%3%13%4] を使って%3鍵を解錠/施錠%4します。<br/><br/><t underline='1'>%3備考:%4</t> ロックピックとキーは、スクリプトまたは ACE Vehicle Key モジュールを介してのみ使用できます。 + Las %3Llaves de Vehículos%4 son usadas para bloquear/desbloquear tus vehículos. Las Llaves de Vehículos existen para un bando entero o para un vehículo concreto.<br/><br/>%3Uso:%4<br/>%2Equipa una %3Llave de Vehículo%4.<br/>%2Acércate a un vehículo cuya llave corresponda.<br/>Usar [%3%13%4] y selecciona %3Bloquear/Desbloquear Vehículo%4.<br/><br/><t underline='1'>%3Nota:%4</t> Ganzúas y Llaves sólo están disponibles mediante scripting o módulos de Llaves de Vehículos ACE diff --git a/addons/finger/XEH_postInit.sqf b/addons/finger/XEH_postInit.sqf index 641c94ff926..6a44a5ae799 100644 --- a/addons/finger/XEH_postInit.sqf +++ b/addons/finger/XEH_postInit.sqf @@ -11,7 +11,7 @@ if (!hasInterface) exitWith {}; 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/functions/fnc_keyPress.sqf b/addons/finger/functions/fnc_keyPress.sqf index 59405b57a53..16dca938b34 100644 --- a/addons/finger/functions/fnc_keyPress.sqf +++ b/addons/finger/functions/fnc_keyPress.sqf @@ -29,8 +29,8 @@ if (diag_tickTime < (GVAR(lastFPTime) + FP_ACTION_TIMEOUT)) exitWith {true}; GVAR(lastFPTime) = diag_tickTime; // Find where is the finger pointing -private _originASL = AGLtoASL positionCameraToWorld [0, 0, 0]; -private _fingerPosASL = AGLtoASL positionCameraToWorld [0, 0, FP_DISTANCE]; +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 isNotEqualTo []) then { _fingerPosASL = _intersections select 0 select 0; @@ -42,7 +42,7 @@ private _sendFingerToPlayers = []; private _nearbyMen = (ACE_player nearObjects ["CAManBase", (GVAR(maxRange) + 2)]); { _nearbyMen append (crew _x); -} count (ACE_player nearObjects ["StaticWeapon", (GVAR(maxRange) + 2)]); +} forEach (ACE_player nearObjects ["StaticWeapon", (GVAR(maxRange) + 2)]); { if ((((eyePos _x) vectorDistance _playerEyePosASL) < GVAR(maxRange)) && {alive _x} && @@ -53,8 +53,7 @@ private _nearbyMen = (ACE_player nearObjects ["CAManBase", (GVAR(maxRange) + 2)] _sendFingerToPlayers pushBack _x; }; - true -} count _nearbyMen; +} forEach _nearbyMen; TRACE_1("sending finger to",_sendFingerToPlayers); diff --git a/addons/finger/functions/fnc_perFrameEH.sqf b/addons/finger/functions/fnc_perFrameEH.sqf index 4af4f6b643e..36acea8a447 100644 --- a/addons/finger/functions/fnc_perFrameEH.sqf +++ b/addons/finger/functions/fnc_perFrameEH.sqf @@ -39,7 +39,7 @@ private _iconBaseSize = GVAR(sizeCoef) * BASE_SIZE * 0.10713 * (call EFUNC(commo _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"]; + drawIcon3D [QPATHTOF(UI\fp_icon2.paa), _drawColor, ASLToAGL _pos, _iconSize, _iconSize, 0, _name, 1, 0.03, "RobotoCondensed"]; }; } forEach GVAR(fingersHash); diff --git a/addons/finger/stringtable.xml b/addons/finger/stringtable.xml index 9f61aa0f7cd..66c97c70daa 100644 --- a/addons/finger/stringtable.xml +++ b/addons/finger/stringtable.xml @@ -62,7 +62,7 @@ Distancia máxima de señalado Maximální dosah pro ukazování směru Raggio massimo puntamento - 指差しの最大範囲 + 指差しの最大距離 가리키기 최대 범위 指向标记最大显示距离 指向指示器最大顯示距離 @@ -79,7 +79,7 @@ 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 [Predefinito: 4 metri] - 指差しのマーカー表示が他のプレイヤーに表示される最大範囲を決定できます。 [デフォルト: 4メートル] + 指差しのマーカー表示が他のプレイヤーに表示される最大距離 [デフォルト: 4メートル] 플레이어 사이에서 가리키기 표시를 보이게 하는 최대거리를 설정합니다[기본설정: 4 미터] 设定指向标记最大显示距离。[预设:4米] 設定指向指示器最大顯示距離。[預設: 4公尺] diff --git a/addons/fire/CfgSounds.hpp b/addons/fire/CfgSounds.hpp index b83ce9b91a4..76fb0e64f74 100644 --- a/addons/fire/CfgSounds.hpp +++ b/addons/fire/CfgSounds.hpp @@ -1,10 +1,10 @@ // weird ass concatenation syntax. PBO Project complains otherwise... #define CONCAT(a,b) a####b #define CREATE_SCREAM(no)\ -class GVAR(DOUBLES(scream,no)) { \ - name = QUOTE(GVAR(CONCAT(scream,no)));\ - sound[] = {QUOTE(PATHTOF(CONCAT(sounds\scream,no).ogg)), QUOTE(db+8), 1};\ - titles[] = {}; \ +class GVAR(DOUBLES(scream,no)) {\ + name = QGVAR(CONCAT(scream,no));\ + sound[] = {QPATHTOF(CONCAT(sounds\scream,no).ogg), QUOTE(db+8), 1};\ + titles[] = {};\ } class CfgSounds { diff --git a/addons/fire/CfgVehicles.hpp b/addons/fire/CfgVehicles.hpp new file mode 100644 index 00000000000..0ed16faff7c --- /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 index 02ecd250e4e..fc246b84030 100644 --- a/addons/fire/RscTitles.hpp +++ b/addons/fire/RscTitles.hpp @@ -1,5 +1,6 @@ +class RscPicture; + class RscTitles { - class RscPicture; class GVAR(onFire1) { idd = -1; movingEnable = "true"; diff --git a/addons/fire/XEH_PREP.hpp b/addons/fire/XEH_PREP.hpp index d9eacfdee00..a352cdf2aaf 100644 --- a/addons/fire/XEH_PREP.hpp +++ b/addons/fire/XEH_PREP.hpp @@ -1,10 +1,10 @@ PREP(burn); -PREP(isBurning); -PREP(isPlant); +PREP(burnEffects); PREP(burnIndicator); PREP(burnReaction); +PREP(burnSimulation); PREP(fireManagerPFH); - +PREP(isBurning); +PREP(medical_canPatDown); PREP(medical_progress); PREP(medical_success); -PREP(medical_canPatDown); diff --git a/addons/fire/XEH_postInit.sqf b/addons/fire/XEH_postInit.sqf index 382c06293b3..1050d757538 100644 --- a/addons/fire/XEH_postInit.sqf +++ b/addons/fire/XEH_postInit.sqf @@ -1,38 +1,89 @@ #include "script_component.hpp" -[QGVAR(burn), FUNC(burn)] call CBA_fnc_addEventHandler; -[QGVAR(playScream), { - params ["_scream", "_source"]; - // only play sound if enabled in settings - if (GVAR(enableScreams)) then { - _source say3D _scream; - }; -}] call CBA_fnc_addEventHandler; +["CBA_settingsInitialized", { + TRACE_1("settingsInitialized",GVAR(enabled)); -["ace_settingsInitialized", { - TRACE_1("settingsInit",GVAR(enabled)); if (!GVAR(enabled)) exitWith {}; - if (isServer) then { - [QGVAR(addFireSource), { - params ["_source", "_radius", "_intensity", "_key", ["_condition", { true }], ["_conditionArgs", []]]; - private _fireLogic = createVehicle ["ACE_LogicDummy", [0, 0, 0], [], 0, "NONE"]; - if (_source isEqualType objNull) then { - _fireLogic attachTo [_source]; - } else { - _fireLogic setPosASL _source; - }; - - [GVAR(fireSources), _key, [_fireLogic, _radius, _intensity, _condition, _conditionArgs]] call CBA_fnc_hashSet; - }] call CBA_fnc_addEventHandler; - - [QGVAR(removeFireSource), { - params ["_key"]; - [GVAR(fireSources), _key] call CBA_fnc_hashRem; - }] call CBA_fnc_addEventHandler; - - [{ _this call FUNC(fireManagerPFH) }, FIRE_MANAGER_PFH_DELAY, []] call CBA_fnc_addPerFrameHandler; - GVAR(fireSources) = [[], nil] call CBA_fnc_hashCreate; - }; -}] call CBA_fnc_addEventHandler; + [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 {}; + + GVAR(fireSources) = createHashMap; + + [QGVAR(addFireSource), { + params [ + ["_source", objNull, [objNull, []]], + ["_radius", 0, [0]], + ["_intensity", 0, [0]], + ["_key", ""], + ["_condition", {true}, [{}]], + ["_conditionArgs", []] + ]; + + private _isObject = _source isEqualType objNull; + + // Check if the source is valid + if !(_isObject || {_source isEqualTypeParams [0, 0, 0]}) exitWith {}; + + if (_isObject && {isNull _source}) exitWith {}; + if (_radius == 0 || _intensity == 0) exitWith {}; + if (_key isEqualTo "") exitWith {}; // key can be many types + + // hashValue supports more types than hashmaps do by default, but not all (e.g. locations) + private _hashedKey = hashValue _key; + + if (isNil "_hashedKey") exitWith { + ERROR_2("Unsupported key type used: %1 - %2",_key,typeName _key); + }; + // If a position is passed, create a static object at said position + private _sourcePos = if (_isObject) then { + getPosATL _source + } else { + ASLToATL _source + }; + + private _fireLogic = createVehicle [QGVAR(logic), _sourcePos, [], 0, "CAN_COLLIDE"]; + + // If an object was passed, attach logic to the object + if (_isObject) then { + _fireLogic attachTo [_source]; + }; + + // To avoid issues, remove existing entries first before overwriting + if (_hashedKey in GVAR(fireSources)) then { + [QGVAR(removeFireSource), _key] call CBA_fnc_localEvent; + }; + + GVAR(fireSources) set [_hashedKey, [_fireLogic, _radius, _intensity, _condition, _conditionArgs]]; + }] call CBA_fnc_addEventHandler; + + [QGVAR(removeFireSource), { + params ["_key"]; + + private _hashedKey = hashValue _key; + + if (isNil "_hashedKey") exitWith { + ERROR_2("Unsupported key type used: %1 - %2",_key,typeName _key); + }; + + (GVAR(fireSources) deleteAt _hashedKey) params [["_fireLogic", objNull]]; + + detach _fireLogic; + deleteVehicle _fireLogic; + }] call CBA_fnc_addEventHandler; + + [LINKFUNC(fireManagerPFH), FIRE_MANAGER_PFH_DELAY, []] call CBA_fnc_addPerFrameHandler; +}] call CBA_fnc_addEventHandler; diff --git a/addons/fire/XEH_preInit.sqf b/addons/fire/XEH_preInit.sqf index 2fc794454d3..894773534a4 100644 --- a/addons/fire/XEH_preInit.sqf +++ b/addons/fire/XEH_preInit.sqf @@ -8,6 +8,4 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" -GVAR(burningPlants) = []; - ADDON = true; diff --git a/addons/fire/addon.toml b/addons/fire/addon.toml deleted file mode 100644 index bf39213892e..00000000000 --- a/addons/fire/addon.toml +++ /dev/null @@ -1,3 +0,0 @@ -[tools] -pboProject_noBinConfig = true -sqfvm_skipConfigChecks = true diff --git a/addons/fire/ACE_Medical_Treatment_Actions.hpp b/addons/fire/compat_medical_engine/ACE_Medical_Treatment_Actions.hpp similarity index 100% rename from addons/fire/ACE_Medical_Treatment_Actions.hpp rename to addons/fire/compat_medical_engine/ACE_Medical_Treatment_Actions.hpp diff --git a/addons/fire/compat_medical_engine/config.cpp b/addons/fire/compat_medical_engine/config.cpp new file mode 100644 index 00000000000..cc4431b18f3 --- /dev/null +++ b/addons/fire/compat_medical_engine/config.cpp @@ -0,0 +1,20 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_medical_engine"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "ACE_Medical_Treatment_Actions.hpp" diff --git a/addons/fire/compat_medical_engine/script_component.hpp b/addons/fire/compat_medical_engine/script_component.hpp new file mode 100644 index 00000000000..b2ce8adc8d7 --- /dev/null +++ b/addons/fire/compat_medical_engine/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT medical_engine +#define SUBCOMPONENT_BEAUTIFIED Medical Engine +#include "..\script_component.hpp" diff --git a/addons/fire/config.cpp b/addons/fire/config.cpp index da8cd0091c2..7a13dd079b9 100644 --- a/addons/fire/config.cpp +++ b/addons/fire/config.cpp @@ -1,20 +1,12 @@ #include "script_component.hpp" -#pragma hemtt flag pe23_ignore_has_include -#if __has_include("\z\ace\addons\nomedical\script_component.hpp") -#define PATCH_SKIP "No Medical" -#endif - -#ifdef PATCH_SKIP -ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) -#else class CfgPatches { class ADDON { name = COMPONENT_NAME; units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_common", "ace_medical_engine"}; + requiredAddons[] = {"ace_common"}; author = ECSTRING(common,ACETeam); authors[] = {"commy2", "tcvm"}; url = ECSTRING(main,URL); @@ -24,7 +16,5 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgSounds.hpp" -#include "ACE_Medical_Treatment_Actions.hpp" +#include "CfgVehicles.hpp" #include "RscTitles.hpp" - -#endif diff --git a/addons/fire/functions/fnc_burn.sqf b/addons/fire/functions/fnc_burn.sqf index a98aea9bc8c..1cf0fc67592 100644 --- a/addons/fire/functions/fnc_burn.sqf +++ b/addons/fire/functions/fnc_burn.sqf @@ -1,13 +1,12 @@ #include "..\script_component.hpp" /* - * Author: tcvm - * Makes object catch fire. Only call from events. Local effects only. - * Arbitrary values to ignite people. Assumed maximum is "10". + * Author: johnb43 + * Makes a unit catch fire. Only call from targeted events, is applied globally. * * Arguments: - * 0: Vehicle - * 1: Intensity of fire - * 2: Instigator of fire (default: objNull) + * 0: Unit + * 1: Fire intensity + * 2: Fire instigator (default: objNull) * * Return Value: * None @@ -18,322 +17,62 @@ * Public: No */ -#define INTENSITY_LOSS 0.03 -#define INTENSITY_UPDATE 3 -#define BURN_PROPOGATE_UPDATE 1 -#define BURN_PROPOGATE_DISTANCE 2 -#define BURN_PROPOGATE_COUNTER_MAX 5 - -params ["_unit", "_intensity", ["_instigator", objNull]]; +if (!EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [LINKFUNC(burn), _this]; +}; if (!GVAR(enabled)) exitWith {}; -private _isBurning = [_unit] call FUNC(isBurning); -if (_isBurning) exitWith {}; - -[{ - // looped function - (_this getVariable "params") params ["_unit", "", "_instigator"]; - private _unitPos = getPosASL _unit; - - _intensity = _unit getVariable [QGVAR(intensity), 0]; - - if (surfaceIsWater _unitPos && {(_unitPos#2) < 1}) then { - _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 * _intensity, 0.05 * _intensity, 0.05 * _intensity], // move velocity - 0, // rotation velocity - 0.06 * _intensity, // size - [0, 0, 0, 0], // color - 0, // random direction period - 0 // random direction intensity - ]; - - _smokeParticle setParticleCircle [0, [0, 0, 0]]; - _smokeParticle setParticleRandom [ - 0, // life time - [0.25, 0.25, 0], // position - [0.2, 0.2, 0], // move velocity - 0, // rotation velocity - 0.25, // size - [0, 0, 0, 0.1], // color - 0, // random direction period - 0 // random direction intensity - ]; - _smokeParticle setParticleParams [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 7, 48], // sprite sheet values - "", // animation name - "Billboard", // particle type - 1, // timer period - 8, // lifetime - [0, 0, 1.1], // position - [0, 0, 1], // move velocity - 0, // rotation velocity - 10, // weight - 7.9, // volume - 0.066, // rubbing - [1, 3, 6], // size - [ - [0.5, 0.5, 0.5, 0.15], - [0.75, 0.75, 0.75, 0.075], - [1, 1, 1, 0] - ], // colour - [0.125], // animation speed - 1, // random dir period - 0, // random dir intensity - "", // on timer script - "", // before destroy script - _unit // particle source - ]; - _smokeParticle setDropInterval 0.15; - - _fireLight setLightBrightness ((_intensity * 3) / 10); - _lightFlare setLightBrightness (_intensity / 30); - - private _distanceToUnit = (_unit distance ace_player); - _fireLight setLightAttenuation [1, 10 max (5 min (10 - _intensity)), 0, 15]; - _lightFlare setLightFlareSize (_intensity * (3 / 4)) * FLARE_SIZE_MODIFIER; - - if (!GVAR(enableFlare)) then { - _lightFlare setLightFlareSize 0; - }; - - // always keep flare visible to perceiving unit as long as it isnt the player - if (_unit isNotEqualTo ace_player) then { - private _relativeAttachPoint = [0, 0, 0.3]; - if (_distanceToUnit > 1.5) then { - _relativeAttachPoint = (vectorNormalized (_unit worldToModelVisual (getPos ace_player))) vectorMultiply linearConversion [5, 30, _distanceToUnit, 0.5, 1.5]; - _relativeAttachPoint set [2, 0.3 + ((_unit selectionPosition "pelvis") select 2)]; - }; - _lightFlare attachTo [_unit, _relativeAttachPoint]; - }; - - if (!isGamePaused) then { - // If the unit goes to spectator alive _unit == true and they will be on fire and still take damage - // Only workaround I could think of, kinda clunky - if (_isThisUnitAlive) then { - _isThisUnitAlive = (alive _unit) && { getNumber ((configOf _unit) >> "isPlayableLogic") != 1 }; - }; - - // propagate fire - if ((CBA_missionTime - _lastPropogateUpdate) >= BURN_PROPOGATE_UPDATE) then { - _lastPropogateUpdate = CBA_missionTime; - if !([ace_player] call FUNC(isBurning)) then { - if ((vehicle _unit) isEqualTo (vehicle ace_player)) then { - if (0.5 > random 1) then { - [QGVAR(burn), [ace_player, _intensity * (7 / 8), _instigator]] call CBA_fnc_globalEvent; - }; - } else { - if ((ace_player isKindOf "Man") && {_unit isNotEqualTo ace_player} && {isDamageAllowed ace_player && {ace_player getVariable [QEGVAR(medical,allowDamage), true]}}) then { - private _burnCounter = _unit getVariable [QGVAR(burnCounter), 0]; - if (_distanceToUnit < BURN_PROPOGATE_DISTANCE) then { - if (_burnCounter < BURN_PROPOGATE_COUNTER_MAX) then { - _burnCounter = _burnCounter + 1; - } else { - [QGVAR(burn), [ace_player, _intensity * (3 / 4), _instigator]] call CBA_fnc_globalEvent; - }; - } else { - _burnCounter = 0; - }; - _unit setVariable [QGVAR(burnCounter), _burnCounter]; - }; - }; - }; - }; - - // update intensity/fire reactions - if ((CBA_missionTime - _lastIntensityUpdate) >= INTENSITY_UPDATE) then { - _lastIntensityUpdate = CBA_missionTime; - _intensity = _intensity - INTENSITY_LOSS - (rain / 10); - if (local _unit) then { - if (_isThisUnitAlive) then { - if !(IS_UNCONSCIOUS(_unit)) then { - if !(isPlayer _unit) then { - private _sdr = _unit getVariable [QGVAR(stopDropRoll), false]; - if ((_unit isEqualTo vehicle _unit) && (_sdr || ({ 0.05 > random 1 }))) then { - _unit setVariable [QGVAR(stopDropRoll), true]; - if !(_sdr) then { - TRACE_1("stop,drop,roll!",_unit); - _unit setUnitPos "DOWN"; - doStop _unit; - }; - // queue up a bunch of animations - for "_i" from 0 to 2 do { - [_unit, selectRandom ["amovppnemstpsnonwnondnon_amovppnemevasnonwnondl", "amovppnemstpsnonwnondnon_amovppnemevasnonwnondr"], 0] call EFUNC(common,doAnimation); - }; - _intensity = _intensity - (1 / _intensity); - } else { - private _group = (group _unit); - private _vehicle = vehicle _unit; - - if (_vehicle != _unit) then { - TRACE_1("Ejecting",_unit); - _unit leaveVehicle _vehicle; - unassignVehicle _unit; - _unit action ["eject",_vehicle]; - }; - _unit disableAI "TARGET"; - _unit disableAI "AUTOTARGET"; - - // Run away - if (leader _group != _unit) then { - [_unit] join grpNull; - }; - _unit doMove ((getPosATL _unit) getPos [20 + random 35, floor (random 360)]); - _unit setSpeedMode "FULL"; - _unit setSuppression 1; - }; - } else { - if ((animationState _unit) in PRONE_ROLLING_ANIMS) then { - // decrease intensity of burn - _intensity = _intensity * INTENSITY_DECREASE_MULT_ROLLING; - }; - }; - - [_unit] call FUNC(burnReaction); - }; - - // Common burn areas are the hands and face https://www.ncbi.nlm.nih.gov/pubmed/16899341/ - private _woundSelection = ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] selectRandomWeighted [0.77, 0.5, 0.8, 0.8, 0.3, 0.3]; - if (GET_PAIN_PERCEIVED(_unit) < (PAIN_UNCONSCIOUS + random 0.2)) then { - // keep pain around unconciousness limit to allow for more fun interactions - [_unit, _intensity / BURN_MAX_INTENSITY, _woundSelection, "burn", _instigator] call EFUNC(medical,addDamageToUnit); - } else { - [_unit, 0.15, _woundSelection, "burn", _instigator] call EFUNC(medical,addDamageToUnit); - }; - }; - _unit setVariable [QGVAR(intensity), _intensity, true]; // globally sync intensity across all clients to make sure simulation is deterministic - }; - }; - - private _burnIndicatorPFH = _unit getVariable [QGVAR(burnUIPFH), -1]; - if (_unit isEqualTo ace_player && { _isThisUnitAlive } && { _burnIndicatorPFH < 0 }) then { - _burnIndicatorPFH = [FUNC(burnIndicator), 1, _unit] call CBA_fnc_addPerFrameHandler; - _unit setVariable [QGVAR(burnUIPFH), _burnIndicatorPFH]; - }; - }; -}, 0, [_unit, _intensity, _instigator], { - TRACE_1("burn init",GVAR(enableFlare)); - // init function - private _params = _this getVariable "params"; - _params params ["_unit", "_startingIntensity"]; - - _intensity = _startingIntensity; - private _unitPos = getPos _unit; - - _fireParticle = "#particlesource" createVehicleLocal _unitPos; - _fireParticle attachTo [_unit, [0, 0, 0]]; - _fireParticle setDropInterval 0.03; - - _smokeParticle = "#particlesource" createVehicleLocal _unitPos; - - _fireLight = "#lightpoint" createVehicleLocal _unitPos; - _fireLight setLightIntensity 0; - _fireLight setLightAmbient [0.8, 0.6, 0.2]; - _fireLight setLightColor [1, 0.5, 0.4]; - _fireLight attachTo [_unit, [0, 0, 0]]; - _fireLight setLightDayLight false; - - _lightFlare = "#lightpoint" createVehicleLocal _unitPos; - _lightFlare setLightIntensity 0; - _lightFlare setLightColor [1, 0.8, 0.8]; - _lightFlare setLightUseFlare true; - _lightFlare setLightFlareMaxDistance 100; - _lightFlare setLightFlareSize 0; - - if (_unit isNotEqualTo ace_player) then { - private _relativeAttachPoint = (vectorNormalized (_unit worldToModelVisual (getPos ace_player))) vectorMultiply 1; - _relativeAttachPoint set [2, 0.5]; - _lightFlare attachTo [_unit, _relativeAttachPoint]; - } else { - _lightFlare attachTo [_unit, [0, 0, 0.3]]; +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); }; - if (isServer) then { - _fireSound = createSoundSource ["Sound_Fire", _unitPos, [], 0]; - _fireSound attachTo [_unit, [0, 0, 0], "Head"]; - }; + TRACE_2("unit already burning, updating intensity",_unit,_intensity); - _unit setVariable [QGVAR(burning), true]; - _unit setVariable [QGVAR(intensity), _intensity]; - _unit setVariable [QGVAR(burnUIPFH), -1]; + _unit setVariable [QGVAR(intensity), _intensity, true]; +}; - if (local _unit) then { - if (_unit isEqualTo ace_player) then { - private _burnIndicatorPFH = [FUNC(burnIndicator), 1, _unit] call CBA_fnc_addPerFrameHandler; - _unit setVariable [QGVAR(burnUIPFH), _burnIndicatorPFH]; - }; +TRACE_2("setting unit ablaze",_unit,_intensity); - [_unit, false] call FUNC(burnReaction); - }; +_unit setVariable [QGVAR(intensity), _intensity, true]; - _lastIntensityUpdate = 0; - _lastPropogateUpdate = 0; - - _isThisUnitAlive = true; -}, { - (_this getVariable "params") params ["_unit"]; - - // deinit function - deleteVehicle _fireParticle; - deleteVehicle _smokeParticle; - deleteVehicle _fireLight; - deleteVehicle _lightFlare; - deleteVehicle _fireSound; - - if (local _unit) then { - if (!isPlayer _unit) then { - _unit setUnitPos "AUTO"; - _unit setVariable [QGVAR(stopDropRoll), false]; - }; - }; - _unit setVariable [QGVAR(burning), false]; - _unit setVariable [QGVAR(burnCounter), 0]; -}, { - // run condition - true -}, { - // exit condition - (_this getVariable "params") params ["_unit"]; +// Fire simulation (fire sources are handled differently) +[QGVAR(burnSimulation), [_unit, _instigator], _unit] call CBA_fnc_targetEvent; - private _unitAlive = (alive _unit) && { getNumber ((configOf _unit) >> "isPlayableLogic") != 1 }; - private _unitIsUnit = { (_unit != vehicle _unit) && { isNull vehicle _unit } }; +// Spawn effects for unit +private _burnEffectsJipID = [QGVAR(burnEffects), _unit] call CBA_fnc_globalEventJIP; +[_burnEffectsJipID, _unit] call CBA_fnc_removeGlobalEventJIP; - !_unitAlive || _unitIsUnit || { _intensity <= BURN_MIN_INTENSITY } || { !([_unit] call FUNC(isBurning)) } -}, ["_intensity", "_fireParticle", "_smokeParticle", "_fireLight", "_fireSound", "_lightFlare", "_lastIntensityUpdate", "_lastPropogateUpdate", "_isThisUnitAlive"]] call CBA_fnc_createPerFrameHandlerObject; +_unit setVariable [QGVAR(jipID), _burnEffectsJipID, true]; diff --git a/addons/fire/functions/fnc_burnEffects.sqf b/addons/fire/functions/fnc_burnEffects.sqf new file mode 100644 index 00000000000..4dadda8526c --- /dev/null +++ b/addons/fire/functions/fnc_burnEffects.sqf @@ -0,0 +1,191 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Spawns particle effects for a burning unit. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * player call ace_fire_fnc_burnEffects + * + * Public: No + */ + +params ["_unit"]; + +// Spawn particles +private _unitPos = getPos _unit; +private _fireParticle = objNull; +private _smokeParticle = objNull; +private _fireLight = objNull; +private _lightFlare = objNull; + +if (hasInterface) then { + _fireParticle = createVehicleLocal ["#particlesource", _unitPos, [], 0, "CAN_COLLIDE"]; + _fireParticle attachTo [_unit]; + _fireParticle setDropInterval 0.03; + + _smokeParticle = createVehicleLocal ["#particlesource", _unitPos, [], 0, "CAN_COLLIDE"]; + + _fireLight = createVehicleLocal ["#lightpoint", _unitPos, [], 0, "CAN_COLLIDE"]; + _fireLight setLightIntensity 0; + _fireLight setLightAmbient [0.8, 0.6, 0.2]; + _fireLight setLightColor [1, 0.5, 0.4]; + _fireLight attachTo [_unit]; + _fireLight setLightDayLight false; + + _lightFlare = createVehicleLocal ["#lightpoint", _unitPos, [], 0, "CAN_COLLIDE"]; + _lightFlare setLightIntensity 0; + _lightFlare setLightColor [1, 0.8, 0.8]; + _lightFlare setLightUseFlare true; + _lightFlare setLightFlareMaxDistance 100; + _lightFlare setLightFlareSize 0; + + if (_unit != ACE_player) then { + private _relativeAttachPoint = vectorNormalized (_unit worldToModelVisual (getPos ACE_player)); + _relativeAttachPoint set [2, 0.5]; + _lightFlare attachTo [_unit, _relativeAttachPoint]; + } else { + _lightFlare attachTo [_unit, [0, 0, 0.3]]; + }; +}; + +private _fireSound = objNull; + +if (isServer) then { + _fireSound = createSoundSource ["Sound_Fire", _unitPos, [], 0]; + _fireSound attachTo [_unit, [0, 0, 0], "Head"]; +}; + +[{ + params ["_args", "_pfhID"]; + _args params ["_unit", "_fireParticle", "_smokeParticle", "_fireLight", "_lightFlare", "_fireSound"]; + + if (isNull _unit || {!(_unit call FUNC(isBurning))}) exitWith { + _pfhID call CBA_fnc_removePerFrameHandler; + + deleteVehicle _fireParticle; + deleteVehicle _smokeParticle; + deleteVehicle _fireLight; + deleteVehicle _lightFlare; + deleteVehicle _fireSound; + }; + + // Display burn indicators + if (_unit == ACE_player && {alive _unit} && {isNil {_unit getVariable QGVAR(burnUIPFH)}}) then { // This accounts for player remote controlled a new unit + private _burnIndicatorPFH = [LINKFUNC(burnIndicator), 1, _unit] call CBA_fnc_addPerFrameHandler; + _unit setVariable [QGVAR(burnUIPFH), _burnIndicatorPFH]; + }; + + if (!hasInterface) exitWith {}; + + private _intensity = _unit getVariable [QGVAR(intensity), 0]; + + _fireParticle setDropInterval (0.01 max linearConversion [BURN_MAX_INTENSITY, BURN_MIN_INTENSITY, _intensity, 0.03, 0.1, false]); + _fireParticle setParticleParams [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 10, 32], // sprite sheet values + "", // animation name + "Billboard", // particle type + 1, // timer period + 0.7, // lifetime + "destructionEffect2", // position + [0, 0, 1], // move velocity + 0, // rotation velocity + 10, // weight + 7.9, // volume + 1, // rubbing + [0.3, 0.3], // size + [ + [1, 1, 1, -0], + [1, 1, 1, -1], + [1, 1, 1, -1], + [1, 1, 1, -1], + [1, 1, 1, -0] + ], // colour + [0.5, 1], // animation speed + 1, // random dir period + 0, // random dir intensity + "", // on timer script + "", // before destroy script + _unit, // particle source + 0, + false, + 0, + [[0.8, 0.6, 0.2, 1]] // emissive color + ]; + _fireParticle setParticleRandom [ + 0.04 * _intensity, // life time + [0.05, 0.05, 2], // position + [0.05, 0.05, 0.05] vectorMultiply _intensity, // move velocity + 0, // rotation velocity + 0.06 * _intensity, // size + [0, 0, 0, 0], // color + 0, // random direction period + 0 // random direction intensity + ]; + + _smokeParticle setDropInterval 0.15; + _smokeParticle setParticleCircle [0, [0, 0, 0]]; + _smokeParticle setParticleParams [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 7, 48], // sprite sheet values + "", // animation name + "Billboard", // particle type + 1, // timer period + 8, // lifetime + [0, 0, 1.1], // position + [0, 0, 1], // move velocity + 0, // rotation velocity + 10, // weight + 7.9, // volume + 0.066, // rubbing + [1, 3, 6], // size + [ + [0.5, 0.5, 0.5, 0.15], + [0.75, 0.75, 0.75, 0.075], + [1, 1, 1, 0] + ], // colour + [0.125], // animation speed + 1, // random dir period + 0, // random dir intensity + "", // on timer script + "", // before destroy script + _unit // particle source + ]; + _smokeParticle setParticleRandom [ + 0, // life time + [0.25, 0.25, 0], // position + [0.2, 0.2, 0], // move velocity + 0, // rotation velocity + 0.25, // size + [0, 0, 0, 0.1], // color + 0, // random direction period + 0 // random direction intensity + ]; + + _fireLight setLightBrightness ((_intensity * 3) / 10); + _fireLight setLightAttenuation [1, 10 max (5 min (10 - _intensity)), 0, 15]; + + _lightFlare setLightBrightness (_intensity / 30); + _lightFlare setLightFlareSize (_intensity * (3 / 4)) * FLARE_SIZE_MODIFIER; + + if (!GVAR(enableFlare)) then { + _lightFlare setLightFlareSize 0; + }; + + // Always keep flare visible to perceiving unit as long as it isn't the player + if (_unit != ACE_player) then { + private _distanceToUnit = _unit distance ACE_player; + private _relativeAttachPoint = [0, 0, 0.3]; + + if (_distanceToUnit > 1.5) then { + _relativeAttachPoint = (vectorNormalized (_unit worldToModelVisual (getPos ACE_player))) vectorMultiply linearConversion [5, 30, _distanceToUnit, 0.5, 1.5]; + _relativeAttachPoint set [2, 0.3 + ((_unit selectionPosition "pelvis") select 2)]; + }; + + _lightFlare attachTo [_unit, _relativeAttachPoint]; + }; +}, 0, [_unit, _fireParticle, _smokeParticle, _fireLight, _lightFlare, _fireSound]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/fire/functions/fnc_burnIndicator.sqf b/addons/fire/functions/fnc_burnIndicator.sqf index 13db8862c9f..5dbc1a8cbf0 100644 --- a/addons/fire/functions/fnc_burnIndicator.sqf +++ b/addons/fire/functions/fnc_burnIndicator.sqf @@ -11,26 +11,30 @@ * None * * Example: - * [player, 4] call ace_fire_fnc_burnIndicator + * [player, _pfhID] call ace_fire_fnc_burnIndicator * * Public: No */ -params ["_unit", "_pfhHandle"]; +params ["_unit", "_pfhID"]; -if !(IS_UNCONSCIOUS(_unit)) then { - private _iteration = _unit getVariable [QGVAR(indicatorIteration), 0]; - if (_iteration == 0) then { - QGVAR(indicatorLayer) cutRsc [QGVAR(onFire1), "PLAIN"]; - _iteration = 1; - } else { - QGVAR(indicatorLayer) cutRsc [QGVAR(onFire2), "PLAIN"]; - _iteration = 0; - }; - _unit setVariable [QGVAR(indicatorIteration), _iteration]; +if (!alive _unit || {!(_unit call FUNC(isBurning))}) exitWith { + _pfhID call CBA_fnc_removePerFrameHandler; + + _unit setVariable [QGVAR(burnUIPFH), nil]; }; -if (!([_unit] call FUNC(isBurning)) || { !alive _unit }) then { - [_pfhHandle] call CBA_fnc_removePerFrameHandler; - _unit setVariable [QGVAR(burnUIPFH), -1]; +// Don't show burn overlay if unconscious or dead +if !(_unit call EFUNC(common,isAwake)) exitWith {}; + +private _iteration = _unit getVariable [QGVAR(indicatorIteration), 0]; + +if (_iteration == 0) then { + QGVAR(indicatorLayer) cutRsc [QGVAR(onFire1), "PLAIN"]; + _iteration = 1; +} else { + QGVAR(indicatorLayer) cutRsc [QGVAR(onFire2), "PLAIN"]; + _iteration = 0; }; + +_unit setVariable [QGVAR(indicatorIteration), _iteration]; diff --git a/addons/fire/functions/fnc_burnReaction.sqf b/addons/fire/functions/fnc_burnReaction.sqf index 748fbbd60ee..5a9b75d48c0 100644 --- a/addons/fire/functions/fnc_burnReaction.sqf +++ b/addons/fire/functions/fnc_burnReaction.sqf @@ -5,7 +5,6 @@ * * Arguments: * 0: Unit - * 1: Should unit throw its current weapon * * Return Value: * None @@ -13,19 +12,15 @@ * Public: No */ -params ["_unit", ["_throwWeapon", true]]; +params ["_unit"]; if ( - _throwWeapon - && {GVAR(dropWeapon) > 0} - && {_unit in _unit && {(currentWeapon _unit) isNotEqualTo ""}} - && {!isPlayer _unit || GVAR(dropWeapon) >= 2} + GVAR(dropWeapon) > 0 && + {isNull objectParent _unit} && + {(currentWeapon _unit) != ""} && + {!isPlayer _unit || GVAR(dropWeapon) == 2} ) then { - [_unit] call EFUNC(common,throwWeapon); + _unit call EFUNC(common,throwWeapon); }; -if (_unit isKindOf "CAManBase") then { - private _soundID = floor (1 + random 15); - private _sound = format [QGVAR(scream_%1), _soundID]; - [QGVAR(playScream), [_sound, _unit]] call CBA_fnc_globalEvent; -}; +[QGVAR(playScream), [format [QGVAR(scream_%1), floor (1 + random 15)], _unit]] call CBA_fnc_globalEvent; diff --git a/addons/fire/functions/fnc_burnSimulation.sqf b/addons/fire/functions/fnc_burnSimulation.sqf new file mode 100644 index 00000000000..e061d1ce915 --- /dev/null +++ b/addons/fire/functions/fnc_burnSimulation.sqf @@ -0,0 +1,177 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Simulates fire intensity over time on burning units. + * Arbitrary values to ignite people. Assumed maximum is "10". + * + * Arguments: + * 0: Unit + * 1: Instigator + * + * Return Value: + * None + * + * Example: + * [player, player] call ace_fire_fnc_burnSimulation + * + * Public: No + */ + +params ["_unit", "_instigator"]; + +[{ + params ["_args", "_pfhID"]; + _args params ["_unit", "_instigator"]; + + if (isNull _unit) exitWith { + TRACE_1("unit is null",_unit); + + _pfhID call CBA_fnc_removePerFrameHandler; + }; + + // Locality has changed + if (!local _unit) exitWith { + TRACE_1("unit is no longer local",_unit); + + _pfhID call CBA_fnc_removePerFrameHandler; + + [QGVAR(burnSimulation), [_unit, _instigator], _unit] call CBA_fnc_targetEvent; + }; + + // If the unit is invulnerable, in water or if the fire has died out, stop burning the unit + if ( + !(_unit call FUNC(isBurning)) || + {!(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]})} || + {private _eyePos = eyePos _unit; surfaceIsWater _eyePos && {(_eyePos select 2) < 0.1}} + ) exitWith { + TRACE_3("unit is no longer burning, invulnerable or in water",_unit,_unit call FUNC(isBurning),isDamageAllowed _unit && {_unit getVariable [ARR_2(QEGVAR(medical,allowDamage),true)]}); + + // Remove global effects + (_unit getVariable [QGVAR(jipID), ""]) call CBA_fnc_removeGlobalEventJIP; + + // Update globally that the unit isn't burning anymore + _unit setVariable [QGVAR(intensity), nil, true]; + + _pfhID call CBA_fnc_removePerFrameHandler; + + if (!isNil {_unit getVariable QGVAR(stopDropRoll)} && {!isPlayer _unit}) then { + _unit setUnitPos "AUTO"; + + _unit setVariable [QGVAR(stopDropRoll), nil, true]; + }; + }; + + if (isGamePaused) exitWith {}; + + private _intensity = _unit getVariable [QGVAR(intensity), 0]; + + // Propagate fire to other units (alive or dead) if it's intense + if (_intensity >= BURN_THRESHOLD_INTENSE) then { + TRACE_2("check for other units",_unit,_intensity); + + { + private _distancePercent = 1 - ((_unit distance _x) / BURN_PROPAGATE_DISTANCE); + private _adjustedIntensity = _intensity * _distancePercent; + + // Don't burn if intensity is too low or already burning with higher intensity + if (BURN_MIN_INTENSITY > _adjustedIntensity || {(_x getVariable [QGVAR(intensity), 0]) > _adjustedIntensity}) then { + continue; + }; + + [QGVAR(burn), [_x, _adjustedIntensity, _instigator], _x] call CBA_fnc_targetEvent; + + TRACE_3("propagate fire",_x,_intensity,_adjustedIntensity); + } forEach nearestObjects [_unit, ["CAManBase"], BURN_PROPAGATE_DISTANCE]; + }; + + // Update intensity/fire reactions + if (CBA_missionTime >= _unit getVariable [QGVAR(intensityUpdate), 0]) then { + TRACE_2("update intensity",_unit,_intensity); + + _unit setVariable [QGVAR(intensityUpdate), CBA_missionTime + INTENSITY_UPDATE]; + + _intensity = _intensity - INTENSITY_LOSS - (rain / 10); + + if (_unit call EFUNC(common,isAwake)) then { + if (_unit call EFUNC(common,isPlayer)) then { + // Decrease intensity of burn if rolling around + if ((animationState _unit) in PRONE_ROLLING_ANIMS) then { + _intensity = _intensity * INTENSITY_DECREASE_MULT_ROLLING; + }; + } else { + private _sdr = _unit getVariable [QGVAR(stopDropRoll), false]; + + private _vehicle = objectParent _unit; + + if (isNull _vehicle && {_sdr || {0.05 > random 1}}) then { + _unit setVariable [QGVAR(stopDropRoll), true, true]; + + if (!_sdr) then { + TRACE_1("stop, drop, roll!",_unit); + + _unit setUnitPos "DOWN"; + doStop _unit; + }; + + // Queue up a bunch of animations + for "_i" from 0 to 2 do { + [_unit, selectRandom ["amovppnemstpsnonwnondnon_amovppnemevasnonwnondl", "amovppnemstpsnonwnondnon_amovppnemevasnonwnondr"], 0] call EFUNC(common,doAnimation); + }; + + _intensity = _intensity - (1 / _intensity); + } else { + // Make the unit leave the vehicle + if (_vehicle != _unit) then { + TRACE_1("Ejecting",_unit); + + _unit leaveVehicle _vehicle; + unassignVehicle _unit; + + _unit action ["Eject", _vehicle]; + }; + + _unit disableAI "TARGET"; + _unit disableAI "AUTOTARGET"; + + // Run away, erraticly + if (leader group _unit != _unit) then { + [_unit] join grpNull; + }; + + _unit doMove ((getPosATL _unit) getPos [20 + random 35, floor (random 360)]); + _unit setSpeedMode "FULL"; + _unit setSuppression 1; + }; + }; + + // Play screams and throw weapon (if enabled) + _unit call FUNC(burnReaction); + }; + + // Keep pain around unconsciousness limit to allow for more fun interactions + private _painPercieved = (0 max ((_unit getVariable [QEGVAR(medical,pain), 0]) - (_unit getVariable [QEGVAR(medical,painSuppress), 0])) min 1); + private _painUnconscious = missionNamespace getVariable [QEGVAR(medical,painUnconsciousThreshold), 0]; + private _damageToAdd = [0.15, _intensity / BURN_MAX_INTENSITY] select (!alive _unit || {_painPercieved < _painUnconscious + random 0.2}); + + if (GETEGVAR(medical,enabled,false)) then { + if (!isNull _instigator) then { + _unit setVariable [QEGVAR(medical,lastDamageSource), _instigator]; + _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; + }; + + // Common burn areas are the hands and face https://www.ncbi.nlm.nih.gov/pubmed/16899341/ + private _bodyPart = ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] selectRandomWeighted [0.77, 0.5, 0.8, 0.8, 0.3, 0.3]; + + // Use event directly, as ace_medical_fnc_addDamageToUnit requires unit to be alive + [QEGVAR(medical,woundReceived), [_unit, [[_damageToAdd, _bodyPart, _damageToAdd]], _instigator, "burn"]] call CBA_fnc_localEvent; + } else { + private _bodyParts = [["HitFace", "HitNeck", "HitHead"], ["HitPelvis", "HitAbdomen", "HitDiaphragm", "HitChest", "HitBody"], ["HitArms", "HitHands"], ["HitLegs"]] selectRandomWeighted [0.77, 0.5, 0.8, 0.3]; + + { + _unit setHitPointDamage [_x, (_unit getHitPointDamage _x) + _damageToAdd, true, _instigator, _instigator]; + } forEach _bodyParts; + }; + + _unit setVariable [QGVAR(intensity), _intensity, true]; // Globally sync intensity across all clients to make sure simulation is deterministic + }; +}, BURN_PROPAGATE_UPDATE, [_unit, _instigator]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/fire/functions/fnc_fireManagerPFH.sqf b/addons/fire/functions/fnc_fireManagerPFH.sqf index fa8e7fb7893..924279e3c8e 100644 --- a/addons/fire/functions/fnc_fireManagerPFH.sqf +++ b/addons/fire/functions/fnc_fireManagerPFH.sqf @@ -1,43 +1,48 @@ #include "..\script_component.hpp" /* - * Author: tcvm - * Handles various fire objects and determines if local units deserves to get burned. - * Used to handle external burning objects, not used internally because internal methods are more performant. + * Author: tcvm, johnb43 + * Handles various objects on fire and determines if units close to objects deserve to get burned. * * Arguments: - * 0: Unit on fire - * 1: PFH Handle + * None * * Return Value: * None * * Example: - * [ace_fire_fnc_fireManagerPFH, 0.25, [_unit]] call CBA_fnc_addPerFrameHandler + * ace_fire_fnc_fireManagerPFH call CBA_fnc_addPerFrameHandler * * Public: No */ -params ["_args", "_handle"]; +{ + _y params ["_fireLogic", "_radius", "_intensity", "_condition", "_conditionArgs"]; + TRACE_2("fireManagerPFH loop",_x,_y); + + // 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), { - _value params ["", "", "", "_condition", "_conditionArgs"]; - _conditionArgs call _condition; -}] call CBA_fnc_hashFilter; + GVAR(fireSources) deleteAt _x; -[GVAR(fireSources), { - _value params ["_source", "_radius", "_intensity"]; - private _attachedObject = attachedTo _source; - private _sourcePos = getPosATL _source; - if (_attachedObject isNotEqualTo objNull) then { - _sourcePos = getPosATL _attachedObject; + continue; }; - private _nearEntities = _sourcePos nearEntities ["Man", _radius]; + // Burn units (alive or dead) close to the fire { - private _burning = [_x] call FUNC(isBurning); - if !(_burning) then { - private _distancePercent = 1 - ((_sourcePos distance _x) / _radius); - [QGVAR(burn), [_x, _intensity * _distancePercent]] call CBA_fnc_globalEvent; + private _distancePercent = 1 - ((_fireLogic distance _x) / _radius); + private _adjustedIntensity = _intensity * _distancePercent; + + // Don't burn if intensity is too low or already burning with higher intensity + if (BURN_MIN_INTENSITY > _adjustedIntensity || {(_x getVariable [QGVAR(intensity), 0]) > _adjustedIntensity}) then { + continue; }; - } forEach _nearEntities; -}] call CBA_fnc_hashEachPair; + + [QGVAR(burn), [_x, _adjustedIntensity], _x] call CBA_fnc_targetEvent; + + TRACE_3("propagate fire",_x,_intensity,_adjustedIntensity); + } forEach nearestObjects [_fireLogic, ["CAManBase"], _radius]; +} forEach GVAR(fireSources); diff --git a/addons/fire/functions/fnc_isBurning.sqf b/addons/fire/functions/fnc_isBurning.sqf index 3bdbe560be0..04a57c29e6b 100644 --- a/addons/fire/functions/fnc_isBurning.sqf +++ b/addons/fire/functions/fnc_isBurning.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: commy2 - * Check if object is burning. + * Check if an object is burning. * * Arguments: - * 0: Vehicle + * 0: Object * * Return Value: * None @@ -15,9 +15,6 @@ * Public: Yes */ -params [["_unit", objNull, [objNull]]]; +params [["_object", objNull, [objNull]]]; -_unit getVariable [QGVAR(burning), false] || { - GVAR(burningPlants) = GVAR(burningPlants) select {!isNull _x}; - _unit in GVAR(burningPlants) -} +(_object getVariable [QGVAR(intensity), 0]) > BURN_MIN_INTENSITY diff --git a/addons/fire/functions/fnc_isPlant.sqf b/addons/fire/functions/fnc_isPlant.sqf deleted file mode 100644 index f132fc72be5..00000000000 --- a/addons/fire/functions/fnc_isPlant.sqf +++ /dev/null @@ -1,20 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Check if object is a map placed bush or tree. - * - * Arguments: - * 0: Object - * - * Return Value: - * Is bush or tree? - * - * Example: - * cursorObject call ace_fire_fnc_isPlant - * - * Public: No - */ - -params [["_object", objNull, [objNull]]]; - -_object in nearestTerrainObjects [_object, ["TREE", "SMALL TREE", "BUSH"], 0.1] diff --git a/addons/fire/functions/fnc_medical_canPatDown.sqf b/addons/fire/functions/fnc_medical_canPatDown.sqf index b7efc262b27..758b83b9227 100644 --- a/addons/fire/functions/fnc_medical_canPatDown.sqf +++ b/addons/fire/functions/fnc_medical_canPatDown.sqf @@ -18,4 +18,4 @@ params ["", "_patient"]; -[_patient] call FUNC(isBurning) +_patient call FUNC(isBurning) diff --git a/addons/fire/functions/fnc_medical_progress.sqf b/addons/fire/functions/fnc_medical_progress.sqf index 07d99958d66..fd64b5c27da 100644 --- a/addons/fire/functions/fnc_medical_progress.sqf +++ b/addons/fire/functions/fnc_medical_progress.sqf @@ -5,8 +5,8 @@ * * Arguments: * 0: Arguments - * 0: Medic - * 1: Patient + * - 0: Medic (not used) + * - 1: Patient * * Return Value: * Continue pat down @@ -18,6 +18,6 @@ */ params ["_args"]; -_args params ["_medic", "_patient"]; +_args params ["", "_patient"]; -[_patient] call FUNC(isBurning) +_patient call FUNC(isBurning) diff --git a/addons/fire/functions/fnc_medical_success.sqf b/addons/fire/functions/fnc_medical_success.sqf index 78e119a8fa5..ca569e1280e 100644 --- a/addons/fire/functions/fnc_medical_success.sqf +++ b/addons/fire/functions/fnc_medical_success.sqf @@ -2,10 +2,13 @@ /* * Author: tcvm * Decreases burning intensity on successful medical action. + * The medical action is looped until the user stops the interaction or the unit is no longer burning. * * Arguments: * 0: Medic * 1: Patient + * 2: Body Part + * 3: Treatment * * Return Value: * None @@ -20,17 +23,21 @@ params ["_medic", "_patient", "_bodyPart", "_classname"]; private _intensity = _patient getVariable [QGVAR(intensity), 0]; _intensity = _intensity * INTENSITY_DECREASE_MULT_PAT_DOWN; + _patient setVariable [QGVAR(intensity), _intensity, true]; -if (_intensity > BURN_MIN_INTENSITY) then { - TRACE_1("patient still burning, looping",_this); +// If the unit is still burning, loop the medical action +if !(_patient call FUNC(isBurning)) exitWith { + TRACE_1("patient no longer burning, quitting",_this); +}; - if (EGVAR(medical_gui,pendingReopen)) then { - LOG("temporarily blocking medical menu reopen"); +TRACE_1("patient still burning, looping",_this); - EGVAR(medical_gui,pendingReopen) = false; - [{EGVAR(medical_gui,pendingReopen) = true}] call CBA_fnc_execNextFrame; - }; +if (EGVAR(medical_gui,pendingReopen)) then { + TRACE_1("temporarily blocking medical menu reopen",_this); - [_medic, _patient, _bodyPart, _classname] call EFUNC(medical_treatment,treatment); + 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 index 97963f3e322..d9649c2ad9b 100644 --- a/addons/fire/initSettings.inc.sqf +++ b/addons/fire/initSettings.inc.sqf @@ -1,40 +1,40 @@ [ - QGVAR(enabled), "CHECKBOX", + QGVAR(enabled), + "CHECKBOX", [ELSTRING(common,Enabled), LSTRING(Setting_Description)], LSTRING(Category_DisplayName), - true, // default value - true, // isGlobal - {[QGVAR(fireEnabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true, + 1, + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, true // Needs mission restart ] call CBA_fnc_addSetting; [ - QGVAR(enableFlare), "CHECKBOX", + QGVAR(enableFlare), + "CHECKBOX", [LSTRING(Setting_FlareEnable), LSTRING(Setting_FlareDescription)], LSTRING(Category_DisplayName), - false, // default value - true, // isGlobal - {[QGVAR(flareEnabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + false, + 1 ] call CBA_fnc_addSetting; [ - QGVAR(dropWeapon), "LIST", + QGVAR(dropWeapon), + "LIST", [LSTRING(Setting_DropWeapon), LSTRING(Setting_DropWeapon_Description)], LSTRING(Category_DisplayName), [ - [0,1,2], - [localize "STR_A3_OPTIONS_DISABLED", ELSTRING(common,aiOnly), ELSTRING(common,playersAndAI)], + [0, 1, 2], + ["STR_A3_OPTIONS_DISABLED", ELSTRING(common,aiOnly), ELSTRING(common,playersAndAI)], 1 ], - true // isGlobal + 1 ] call CBA_fnc_addSetting; [ - QGVAR(enableScreams), "CHECKBOX", + QGVAR(enableScreams), + "CHECKBOX", [LSTRING(Setting_EnableScreams), LSTRING(Setting_EnableScreams_Description)], LSTRING(Category_DisplayName), - true, - false // isGlobal + true ] call CBA_fnc_addSetting; - diff --git a/addons/fire/script_component.hpp b/addons/fire/script_component.hpp index 86ef159aaea..f4b636286b1 100644 --- a/addons/fire/script_component.hpp +++ b/addons/fire/script_component.hpp @@ -16,7 +16,6 @@ #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 @@ -31,9 +30,14 @@ "amovppnemstpsoptwbindnon_amovppnemevasoptwbindr"\ ] - #define BURN_MAX_INTENSITY 10 #define BURN_MIN_INTENSITY 1 #define INTENSITY_DECREASE_MULT_PAT_DOWN 0.8 #define INTENSITY_DECREASE_MULT_ROLLING INTENSITY_DECREASE_MULT_PAT_DOWN + +#define INTENSITY_LOSS 0.02 +#define INTENSITY_UPDATE 2 +#define BURN_PROPAGATE_UPDATE 1 +#define BURN_PROPAGATE_DISTANCE 2 +#define BURN_THRESHOLD_INTENSE 3 diff --git a/addons/fortify/CfgWeapons.hpp b/addons/fortify/CfgWeapons.hpp index 66ff7f52d88..82396288721 100644 --- a/addons/fortify/CfgWeapons.hpp +++ b/addons/fortify/CfgWeapons.hpp @@ -10,6 +10,7 @@ class CfgWeapons { picture = QPATHTOF(UI\hammer_ca.paa); scope = 2; ACE_isTool = 1; + GVAR(fortifyTool) = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 0; }; diff --git a/addons/fortify/XEH_postInit.sqf b/addons/fortify/XEH_postInit.sqf index ed13a116c7f..91ce3b7b877 100644 --- a/addons/fortify/XEH_postInit.sqf +++ b/addons/fortify/XEH_postInit.sqf @@ -50,6 +50,7 @@ GVAR(objectRotationZ) = 0; private _text = [format ["Remove Object +$%1", _cost], "Remove Object"] select (_budget == -1); // Remove object action + //IGNORE_PRIVATE_WARNING ["_player"]; private _removeAction = [ QGVAR(removeObject), _text, diff --git a/addons/fortify/XEH_preInit.sqf b/addons/fortify/XEH_preInit.sqf index 382fc805660..50f641f9cf7 100644 --- a/addons/fortify/XEH_preInit.sqf +++ b/addons/fortify/XEH_preInit.sqf @@ -13,6 +13,8 @@ GVAR(locations) = []; // Custom deploy handlers GVAR(deployHandlers) = []; +GVAR(fortifyTools) = keys (uiNamespace getVariable QGVAR(fortifyTools)); + #include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/fortify/XEH_preStart.sqf b/addons/fortify/XEH_preStart.sqf index 022888575ed..4da9eeb40da 100644 --- a/addons/fortify/XEH_preStart.sqf +++ b/addons/fortify/XEH_preStart.sqf @@ -1,3 +1,9 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +private _fortifyTools = (QUOTE(getNumber (_x >> QQGVAR(fortifyTool)) > 0) configClasses (configFile >> "CfgWeapons") apply {configName _x}); +_fortifyTools append (QUOTE(getNumber (_x >> QQGVAR(fortifyTool)) > 0) configClasses (configFile >> "CfgVehicles") apply {configName _x}); +TRACE_1("",_fortifyTools); + +uiNamespace setVariable [QGVAR(fortifyTools), compileFinal (_fortifyTools createHashMapFromArray [])]; diff --git a/addons/fortify/config.cpp b/addons/fortify/config.cpp index ab12338982f..2808b56cba5 100644 --- a/addons/fortify/config.cpp +++ b/addons/fortify/config.cpp @@ -2,6 +2,7 @@ class CfgPatches { class ADDON { + name = COMPONENT_NAME; units[] = {QXGVAR(setupModule), QXGVAR(buildLocationModule)}; weapons[] = {"ACE_Fortify"}; requiredVersion = REQUIRED_VERSION; diff --git a/addons/fortify/functions/fnc_addActions.sqf b/addons/fortify/functions/fnc_addActions.sqf index 4802effa01d..7ac07d1693a 100644 --- a/addons/fortify/functions/fnc_addActions.sqf +++ b/addons/fortify/functions/fnc_addActions.sqf @@ -21,7 +21,7 @@ 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; +private _subActions = createHashMap; { _x params ["_classname", "_cost", ["_category", ""]]; diff --git a/addons/fortify/functions/fnc_buildLocationModule.sqf b/addons/fortify/functions/fnc_buildLocationModule.sqf index c777b80d4e4..497af641f41 100644 --- a/addons/fortify/functions/fnc_buildLocationModule.sqf +++ b/addons/fortify/functions/fnc_buildLocationModule.sqf @@ -18,7 +18,7 @@ params ["_logic"]; TRACE_1("buildLocations",_logic); -private _area = _logic getvariable ["objectArea",[0,0,0,false,0]]; // seems to be set via the canSetArea config +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; diff --git a/addons/fortify/functions/fnc_canFortify.sqf b/addons/fortify/functions/fnc_canFortify.sqf index 3a382bc98c9..ad676a91031 100644 --- a/addons/fortify/functions/fnc_canFortify.sqf +++ b/addons/fortify/functions/fnc_canFortify.sqf @@ -19,8 +19,12 @@ params ["_player", ["_cost", 0]]; (missionNamespace getVariable [QGVAR(fortifyAllowed), true]) && -{"ACE_Fortify" in (_player call EFUNC(common,uniqueItems))} && { + private _items = _player call EFUNC(common,uniqueItems); + _items append weapons _player; + _items pushBack backpack _player; + GVAR(fortifyTools) findAny _items != -1 +} && { private _budget = [side group _player] call FUNC(getBudget); ((_budget == -1) || {_budget >= _cost}) } && { diff --git a/addons/fortify/functions/fnc_deployConfirm.sqf b/addons/fortify/functions/fnc_deployConfirm.sqf index 37e0d4fb9d5..b0105a79196 100644 --- a/addons/fortify/functions/fnc_deployConfirm.sqf +++ b/addons/fortify/functions/fnc_deployConfirm.sqf @@ -38,7 +38,7 @@ private _perframeCheck = { _args params ["_unit", "_side", "_typeOf", "_posASL", "_vectorDir", "_vectorUp", "_cost"]; // Animation loop (required for longer constructions) - if (animationState _unit isNotEqualTo "AinvPknlMstpSnonWnonDnon_medic4") then { + if (_totalTime != 0 && {animationState _unit != "AinvPknlMstpSnonWnonDnon_medic4"}) then { // Perform animation [_unit, "AinvPknlMstpSnonWnonDnon_medic4"] call EFUNC(common,doAnimation); }; @@ -55,4 +55,3 @@ private _perframeCheck = { LLSTRING(progressBarTitle), _perframeCheck ] call EFUNC(common,progressBar); - diff --git a/addons/fortify/functions/fnc_deployObject.sqf b/addons/fortify/functions/fnc_deployObject.sqf index 4895b261bcd..f7e9e6dbadc 100644 --- a/addons/fortify/functions/fnc_deployObject.sqf +++ b/addons/fortify/functions/fnc_deployObject.sqf @@ -70,6 +70,7 @@ private _mouseClickID = [_player, "DefaultAction", {GVAR(isPlacing) == PLACE_WAI [_unit, _object] call FUNC(deployConfirm); } else { TRACE_1("deleting object",_object); + [QGVAR(onDeployStop), [_unit, _object, _cost]] call CBA_fnc_localEvent; deleteVehicle _object; }; }; diff --git a/addons/fortify/functions/fnc_getPlaceableSet.sqf b/addons/fortify/functions/fnc_getPlaceableSet.sqf index 9643d541906..dfe5a01a1b8 100644 --- a/addons/fortify/functions/fnc_getPlaceableSet.sqf +++ b/addons/fortify/functions/fnc_getPlaceableSet.sqf @@ -20,7 +20,7 @@ TRACE_1("getPlaceableSet",_preset); private _config = missionConfigFile >> "ACEX_Fortify_Presets" >> _preset; if (!isClass _config) then { - _config = configfile >> "ACEX_Fortify_Presets" >> _preset; + _config = configFile >> "ACEX_Fortify_Presets" >> _preset; }; if (!isClass _config) exitWith { private _msg = format ["Could not find [%1]", _preset]; @@ -37,11 +37,11 @@ _objects = _objects select { if (isClass (configFile >> "CfgVehicles" >> _classname)) then { true } else { - ERROR_2("Preset [%1] - Classname does not exist",_preset,_classname); + ERROR_2("Preset [%1] - Classname [%2] does not exist",_preset,_classname); false }; } else { - ERROR_2("Preset [%1] - Bad data in objects array %2",_preset,_x); + ERROR_2("Preset [%1] - Bad data [%2] in objects array %2",_preset,_x); false }; }; diff --git a/addons/fortify/functions/fnc_handleChatCommand.sqf b/addons/fortify/functions/fnc_handleChatCommand.sqf index 46bdc3cb0be..1422558de85 100644 --- a/addons/fortify/functions/fnc_handleChatCommand.sqf +++ b/addons/fortify/functions/fnc_handleChatCommand.sqf @@ -20,7 +20,7 @@ TRACE_1("handleChatCommand",_args); _args = _args splitString " "; if (_args isEqualTo []) exitWith {ERROR("Bad command");}; -private _command = toLower (_args select 0); +private _command = toLowerANSI (_args select 0); _args deleteAt 0; switch (_command) do { diff --git a/addons/fortify/functions/fnc_parseSide.sqf b/addons/fortify/functions/fnc_parseSide.sqf index 3e9ca5d78da..6af2fac4b49 100644 --- a/addons/fortify/functions/fnc_parseSide.sqf +++ b/addons/fortify/functions/fnc_parseSide.sqf @@ -22,7 +22,7 @@ TRACE_1("parseSide",_side); if (_side isEqualType sideUnknown) exitWith {_side}; -private _char = toLower (_side select [0, 1]); +private _char = toLowerANSI (_side select [0, 1]); private _return = switch (_char) do { case ("b"); diff --git a/addons/fortify/functions/fnc_registerObjects.sqf b/addons/fortify/functions/fnc_registerObjects.sqf index b8e7abd1719..7fea4996a44 100644 --- a/addons/fortify/functions/fnc_registerObjects.sqf +++ b/addons/fortify/functions/fnc_registerObjects.sqf @@ -28,7 +28,7 @@ TRACE_3("registerObjects",_side,_budget,_objects); if (_side isEqualTo sideUnknown) exitWith {ERROR_1("Bad Side %1",_this);}; -_objects select { +_objects = _objects select { private _isValid = _x params [["_xClassname", "", [""]], ["_xCost", 0, [0]]]; private _category = toLower (_x param [2, "", [""]]); if (_category != "") then { _x set [2, _category]; }; diff --git a/addons/fortify/functions/fnc_setupModule.sqf b/addons/fortify/functions/fnc_setupModule.sqf index f032d98ebe0..1215393a467 100644 --- a/addons/fortify/functions/fnc_setupModule.sqf +++ b/addons/fortify/functions/fnc_setupModule.sqf @@ -48,10 +48,10 @@ if IS_NUMBER(_preset) then { // Legacy support }; private _budget = _logic getVariable ["Budget", -1]; -if (!(_budget isEqualType 0)) then {_budget = -1}; +if !(_budget isEqualType 0) then {_budget = -1}; private _addToolItem = _logic getVariable ["AddToolItem", false]; -if (!(_addToolItem isEqualType false)) then {_addToolItem = false}; +if !(_addToolItem isEqualType false) then {_addToolItem = false}; private _objects = [_preset] call FUNC(getPlaceableSet); diff --git a/addons/fortify/stringtable.xml b/addons/fortify/stringtable.xml index c3fda20caf2..028cfbd9b2f 100644 --- a/addons/fortify/stringtable.xml +++ b/addons/fortify/stringtable.xml @@ -4,7 +4,7 @@ Fortify Verstärken - 要塞 + 野戦築城 요새화 Fortifica 要塞 @@ -20,7 +20,7 @@ Fortify Tool Bauwerkzeug Attrezzo di Fortificazione - 要塞ツール + 築城ツール 요새화 도구 要塞工具 设防工具 @@ -49,7 +49,7 @@ Auto add fortify item Füge das Bauwerkzeug automatisch hinzu - 自動的に要塞ツールを追加 + 自動的に築城ツールを追加 Auto-aggiungi attrezzo di fortificazione 요새화 도구 자동으로 추가 自動增加要塞物品 @@ -67,7 +67,7 @@ Inizializza il sistema di fortificazione con alcuni parametri di base.<br/>Preset vengono presi da configFile and missionConfigFile, leggi la wiki per il formato richiesto. Инициализирует систему фортификации с некоторыми базовыми параметрами.<br/>Предустановки взяты из configFile и missionConfigFile, формат смотри на wiki. Inşa etme sistemini bazı temel parametrelerle başlatır. <br/> Ön ayarlar configFile ve missionConfigFile'dan alınır, format için wiki'ye bakın. - 要塞システムを初期設定に戻します。<br/>プリセットは configfile と missionConfigFile から参照されます。詳細は wiki を参照してください。 + 野戦築城システムを初期設定に戻します。<br/>プリセットは configfile と missionConfigFile から参照されます。詳細は wiki を参照してください。 Initialisiert das Verstärken-System, mit grundlegenden Einstellungen <br/>Vorseinstellungen werden aus der configFile und der missionConfigFile gezogen, für mehr Informationen: siehe das ACE Wiki. 使用一些基本参数初始化设防系统。<br/>预设从 configFile 和 missionConfigFile 中提取,参见 wiki 的格式。 기본 파라미터와 함께 요새화 시스템을 활성화합니다<br/>configFile 과 missionConfigFile에서 프리셋을 뽑아옵니다, 포맷은 위키를 참조하십시오. @@ -103,7 +103,7 @@ Conferma Posizionamento Lerak Confirmar implantação - ここで作る + 配置を確定 설치 확인 确认部署 確認佈署 @@ -112,7 +112,7 @@ Fortify: Limit Build Area Verstärken: Beschränke Baubereich - 要塞: 構築制限エリア + 野戦築城: 構築制限エリア 要塞: 限制建造區 Fortificazione: Limita Area 设防:限制建造区 @@ -130,7 +130,7 @@ ACE Fortificazione ACE 要塞 ACE 设防 - ACE 要塞 + ACE 野戦築城 ACE Fortyfikowanie ACE Фортификация ACE Inşa Etme @@ -145,7 +145,7 @@ Mostra aggiornamenti di budget 顯示預算更新 显示预算更新 - 予算の更新を表示 + 予算更新を表示 Pokaż aktualizacje budżetu Показывать обновления бюджета Bütçe güncellenmelerini göster @@ -160,7 +160,7 @@ 決定預算變更時是否會顯示提示 决定预算变更时是否会显示提示 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. @@ -190,7 +190,7 @@ Ha l'attrezzo di fortificazione 有要塞工具 有设防工具 - 要塞ツール所持の時 + 築城ツール所持時 Posiada narzędzie do fortyfikowania Если имеется инструмент Insa Etme Aleti Olanlara Göster @@ -233,7 +233,7 @@ 건축물을 지을 때 걸리는 시간을 계수를 적용하여 계산합니다. 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は建造物のコストです。 + 構築する時間を定義するために使用される係数。\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 @@ -246,7 +246,7 @@ 최소 건축 시간 Minimale Bauzeit Tempo di costruzione minimo - 最短建造時間 + 最短構築時間 Minimalny czas budowy Мин. время возведения Tiempo mínimo de construcción @@ -259,7 +259,7 @@ 건축물을 지을 때 걸리는 최소 시간을 계수를 적용하여 계산합니다. 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は建造物のコストです。 + 構築に掛かる最短時間。\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 @@ -272,7 +272,7 @@ 건설 중 Bauwerk Costruendo - 建造 + 構築中 Budowanie Возведение Construyendo @@ -298,7 +298,7 @@ 건축물을 건설하고 나서 지도에 마커를 생성합니다 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 diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 7a124833b3c..ac3605499d8 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -4,272 +4,16 @@ class CfgAmmo { - // ~~~~ Bombs: - class ammo_Bomb_LaserGuidedBase; - class Bo_GBU12_LGB: ammo_Bomb_LaserGuidedBase { - GVAR(enabled) = 1; + #include "CfgAmmoBaseClasses.hpp" - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(metal) = 140000; - GVAR(charge) = 87000; - GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "1/2"; - }; - class Bomb_04_F: ammo_Bomb_LaserGuidedBase { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(metal) = 140000; - GVAR(charge) = 87000; - GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "1/2"; - }; - class BombCore; - class Bo_Mk82: BombCore { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(metal) = 140000; - GVAR(charge) = 87000; - GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "1/2"; - }; - - // ~~~~ Grenades: - class GrenadeBase; - class Grenade; - class GrenadeHand: Grenade { - GVAR(enabled) = 1; - - GVAR(skip) = 0; - GVAR(force) = 1; - // This is a good high-drag frag type for grenades. - GVAR(classes)[] = {QGVAR(tiny_HD)}; - /* - These values are based on the M67 Grenade, should be tweaked for - individual grenades. - */ - 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 - }; - class GrenadeHand_stone: GrenadeHand { - GVAR(skip) = 1; - }; - class SmokeShell: GrenadeHand { - GVAR(skip) = 1; - }; - class G_40mm_HE: GrenadeBase { - // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M441 - GVAR(enabled) = 1; - GVAR(force) = 1; - - GVAR(classes)[] = {QGVAR(tiny_HD)}; - GVAR(metal) = 200; - GVAR(charge) = 32; - GVAR(gurney_c) = 2700; - 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 - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(tiny_HD)}; - GVAR(metal) = 200; - GVAR(charge) = 45; - GVAR(gurney_c) = 2830; - GVAR(gurney_k) = "1/2"; - }; - - class ACE_G_40mm_HEDP: G_40mm_HEDP {}; - class ACE_G_40mm_HE: G_40mm_HE {}; - 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; - GVAR(force) = 1; - }; - - - // ~~~~ RPGs: - class MissileBase; - class R_PG32V_F; - class R_TBG32V_F: R_PG32V_F { // HE - GVAR(enabled) = 1; - GVAR(metal) = 400; - GVAR(charge) = 210; - GVAR(gurney_c) = 2800; - GVAR(gurney_k) = "3/5"; - GVAR(classes)[] = {"ACE_frag_medium_HD"}; - }; - class M_Titan_AA: MissileBase { - GVAR(skip) = 1; - }; - class M_Titan_AT: MissileBase { - GVAR(skip) = 1; - }; - class M_Titan_AP: M_Titan_AT { // "anti personnel" - GVAR(skip) = 0; - GVAR(enabled) = 1; - GVAR(metal) = 400; - GVAR(charge) = 210; - GVAR(gurney_c) = 2800; - GVAR(gurney_k) = "3/5"; - 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; - class M_AT: M_PG_AT { // DAR (Hydra 70) - // Source: http://fas.org/man/dod-101/sys/missile/hydra-70.htm - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 3850; - GVAR(charge) = 1040; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = "1/2"; - }; - class RocketBase; - class R_80mm_HE: RocketBase { - GVAR(skip) = 1; - }; - class Missile_AGM_02_F: MissileBase { - // Source: http://fas.org/man/dod-101/sys/smart/agm-65.htm - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 56250; - GVAR(charge) = 39000; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = "1/2"; - }; - class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) - GVAR(enabled) = 1; - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 3850; - GVAR(charge) = 1040; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = "1/2"; - }; - class M_Scalpel_AT: MissileBase { // 9K121 Vikhr - GVAR(enabled) = 1; - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 10000; - GVAR(charge) = 3000; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = "1/2"; - }; - class ACE_Hellfire_AGM114K: M_Scalpel_AT { - // Source: http://www.designation-systems.net/dusrm/m-114.html - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 8000; - GVAR(charge) = 2400; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = "1/2"; - }; - class M_Air_AA: MissileBase { - GVAR(skip) = 1; - }; - class Missile_AA_04_F: MissileBase { - GVAR(skip) = 1; - }; - - // curator ammo entries - class ShellBase; - class Sh_125mm_HEAT; - class Sh_155mm_AMOS: ShellBase { - // Source: http://www.globalsecurity.org/military/systems/munitions/m795.htm - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(metal) = 36000; - GVAR(charge) = 9979; - GVAR(gurney_c) = 2440; - GVAR(gurney_k) = "1/2"; - }; - class Sh_82mm_AMOS: Sh_155mm_AMOS { - // Source: http://www.arsenal-bg.com/defense_police/mortar_bombs_82mm.htm - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 3200; - GVAR(charge) = 420; - GVAR(gurney_c) = 2440; - GVAR(gurney_k) = "1/2"; - }; - class ModuleOrdnanceMortar_F_Ammo: Sh_82mm_AMOS { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 800; - GVAR(charge) = 4200; - GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "1/2"; - }; - class Sh_105mm_HEAT_MP: Sh_125mm_HEAT { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 11400; - GVAR(charge) = 7100; - GVAR(gurney_c) = 2800; - GVAR(gurney_k) = "1/2"; - }; - class Sh_120mm_HE: ShellBase { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 23000; - GVAR(charge) = 3148; - GVAR(gurney_c) = 2830; - GVAR(gurney_k) = "1/2"; - }; - class Sh_125mm_HE: Sh_120mm_HE { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 16000; - GVAR(charge) = 3200; - GVAR(gurney_c) = 2440; - GVAR(gurney_k) = "1/2"; - }; - class ModuleOrdnanceHowitzer_F_ammo: Sh_155mm_AMOS { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(metal) = 1950; - GVAR(charge) = 15800; - GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "1/2"; - }; - - - class B_65x39_Caseless; + class B_65x39_Caseless: BulletBase {}; class GVAR(base): B_65x39_Caseless { ACE_damageType = "grenade"; // compatibility with medical_damage, shrapnel should produce grenade wounds - timeToLive = 12; + timeToLive = 4; typicalSpeed = 1500; + maxSpeed = 1500; deflecting = 65; + GVAR(skip) = 1; }; class GVAR(tiny): GVAR(base) { @@ -317,7 +61,7 @@ class CfgAmmo { }; class GVAR(large_HD): GVAR(large) { - hit = 28; + hit = 28; indirectHit = 2; indirectHitRange = 0.25; airFriction = QUOTE(BASE_DRAG_HD*0.65); @@ -340,21 +84,6 @@ class CfgAmmo { caliber = 2.8; }; - class GVAR(spall_small): GVAR(small) { - timeToLive = 0.1; - }; - - class GVAR(spall_medium): GVAR(medium) { - timeToLive = 0.15; - }; - - class GVAR(spall_large): GVAR(large) { - timeToLive = 0.25; - }; - - class GVAR(spall_huge): GVAR(huge) { - timeToLive = 0.3; - }; - - #include "CfgAmmoReflections.hpp" + #include "CfgAmmoSpall.hpp" + #include "CfgAmmoFragParameters.hpp" }; diff --git a/addons/frag/CfgAmmoBaseClasses.hpp b/addons/frag/CfgAmmoBaseClasses.hpp new file mode 100644 index 00000000000..413dfe3dd93 --- /dev/null +++ b/addons/frag/CfgAmmoBaseClasses.hpp @@ -0,0 +1,47 @@ +// We need this since autocannons generally inherit from BulletBase +class BulletCore; +class BulletBase: BulletCore {}; + +class GrenadeCore; +class GrenadeBase: GrenadeCore {}; + +class LaserBombCore; +class ammo_Bomb_LaserGuidedBase: LaserBombCore {}; + +class MissileCore; +class MissileBase: MissileCore {}; + +class RocketCore; +class RocketBase: RocketCore { + GVAR(skip) = 1; +}; + +class ArtilleryRocketCore: RocketCore {}; + +class ShellCore; +class ShellBase: ShellCore {}; + +class ShotDeployCore; +class ShotDeployBase: ShotDeployCore { + GVAR(skip) = 1; +}; + +class ShotgunCore; +class ShotgunBase: ShotgunCore {}; + +class SubmunitionCore; +class SubmunitionBase: SubmunitionCore { + GVAR(skip) = 1; +}; + +class BoundingMineCore; +class BoundingMineBase: BoundingMineCore {}; + +class PipeBombCore; +class PipeBombBase: PipeBombCore {}; + +class DirectionalBombCore; +class DirectionalBombBase: DirectionalBombCore {}; + +class MineCore; +class MineBase: MineCore {}; diff --git a/addons/frag/CfgAmmoFragParameters.hpp b/addons/frag/CfgAmmoFragParameters.hpp new file mode 100644 index 00000000000..588032673d2 --- /dev/null +++ b/addons/frag/CfgAmmoFragParameters.hpp @@ -0,0 +1,803 @@ +// ~~~~ Autocannons +class B_19mm_HE: BulletBase { + GVAR(skip) = 1; +}; + +class B_20mm: BulletBase { + // Used in Weisel/AWC Nyx, which makes it a Rheinmetall Mk 20 Rh-202 + // Based on jane's ammunition handbook ~2002 (archive.org) + GVAR(skip) = 1; + GVAR(charge) = 6; + GVAR(metal) = 114; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(tiny_HD)}; +}; + +class B_20mm_AP: BulletBase { + GVAR(skip) = 1; +}; + +class ammo_Gun20mmAABase: BulletBase { // 20x139mm + GVAR(skip) = 1; + GVAR(charge) = 6; + GVAR(metal) = 114; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(tiny_HD)}; +}; + +class ammo_Gun30mmAABase: BulletBase { // 30x210mm HEI + GVAR(skip) = 0; + GVAR(charge) = 40; + GVAR(metal) = 410; + GVAR(gurney_k) = "1/2"; + GVAR(gurney_c) = 2901; + GVAR(classes)[] = {QGVAR(tiny_HD), QGVAR(tiny_HD), QGVAR(small_HD)}; + +}; + +class B_30mm_HE: B_19mm_HE { + // Used in Gorgon (Pandur II), assuming it's a L21A1 RARDEN, specifically HEI-T due to tracers + // https://ordtech-industries.com/30x170-mm-ammunition-for-cannons-oerlikon-kcb-hispano-hs831l-l21-rarden/ + GVAR(skip) = 0; + GVAR(charge) = 25; + GVAR(metal) = 320; + GVAR(gurney_c) = 2552; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(tiny_HD), QGVAR(tiny_HD), QGVAR(small_HD)}; +}; +class B_30mm_MP: B_30mm_HE { + // Used in Mora (FV510 Warrior), assuming it's a Mk44 Bushmaster II, specifically HEI-T due to tracers + // http://www.navweaps.com/Weapons/WNUS_30mm_BushmasterII.php + GVAR(metal) = 388; + GVAR(charge) = 56; + GVAR(gurney_c) = 2600; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(tiny_HD), QGVAR(tiny_HD), QGVAR(small_HD)}; +}; + +class Gatling_30mm_HE_Plane_CAS_01_F: BulletBase { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(tiny_HD), QGVAR(small_HD)}; + GVAR(metal) = 388; + GVAR(charge) = 56; + GVAR(gurney_c) = 2600; // guessed + GVAR(gurney_k) = "1/2"; +}; + +class ammo_Gun35mmAABase: BulletBase { + // Gepard uses an Oerlikon GDF and the AA vehicles mimics it like it + // https://en.wikipedia.org/wiki/Oerlikon_GDF#Ammunition + // https://www.nammo.com/product/our-products/ammunition/medium-caliber-ammunition/35-mm-series/35-mm-x-228-hei-sd-and-hei-t-sd/ + GVAR(skip) = 0; + GVAR(charge) = 98; + GVAR(metal) = 400; + GVAR(gurney_k) = "1/2"; + GVAR(gurney_c) = 2700; + GVAR(classes)[] = {QGVAR(tiny_HD), QGVAR(tiny_HD), QGVAR(small_HD)}; +}; + +class B_35mm_AA: BulletBase { + // Gepard uses an Oerlikon GDF and the AA vehicles mimics it like it + // https://en.wikipedia.org/wiki/Oerlikon_GDF#Ammunition + // https://www.nammo.com/product/our-products/ammunition/medium-caliber-ammunition/35-mm-series/35-mm-x-228-hei-sd-and-hei-t-sd/ + GVAR(skip) = 0; + GVAR(charge) = 98; + GVAR(metal) = 400; + GVAR(gurney_k) = "1/2"; + GVAR(gurney_c) = 2700; + GVAR(classes)[] = {QGVAR(tiny_HD), QGVAR(tiny_HD), QGVAR(small_HD)}; +}; + +class B_40mm_GPR: B_30mm_HE { + // Based on noted 40mm Autocannons, base ROF, and ammo names, looks to be a CTAS40, specifically GPR-PD-T + // https://www.cta-international.com/ammunition/ + // https://ndiastorage.blob.core.usgovcloudapi.net/ndia/2002/gun/leslie.pdf + GVAR(classes)[] = {QGVAR(tiny_HD), QGVAR(small_HD)}; + GVAR(metal) = 750; + GVAR(charge) = 120; + GVAR(gurney_c) = 2700; // guessed + GVAR(gurney_k) = "1/2"; +}; +class UnderwaterMine_Range_Ammo: MineBase { + GVAR(skip) = 1; +}; + +// ~~~~ Bombs: +class Bo_GBU12_LGB: ammo_Bomb_LaserGuidedBase { + GVAR(skip) = 0; + GVAR(charge) = 87000; + GVAR(metal) = 140000; + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large_HD), QGVAR(huge_HD), QGVAR(huge_HD), QGVAR(huge_HD)}; +}; +class Bomb_03_F: ammo_Bomb_LaserGuidedBase { + GVAR(skip) = 0; + GVAR(charge) = 100000; + GVAR(metal) = 150000; + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large_HD), QGVAR(huge_HD), QGVAR(huge_HD), QGVAR(huge_HD)}; +}; +class Bomb_04_F: ammo_Bomb_LaserGuidedBase { + GVAR(skip) = 0; + GVAR(charge) = 87000; + GVAR(metal) = 140000; + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large_HD), QGVAR(huge_HD), QGVAR(huge_HD), QGVAR(huge_HD)}; +}; +class BombCluster_01_Ammo_F: Bomb_04_F { + GVAR(skip) = 1; +}; +class ammo_Bomb_SmallDiameterBase: ammo_Bomb_LaserGuidedBase { + GVAR(skip) = 0; + GVAR(charge) = 160; // kg + GVAR(metal) = 113; // kg + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD), QGVAR(large), QGVAR(large_HD), QGVAR(huge_HD), QGVAR(huge_HD)}; +}; + +class BombCore; +class Bo_Mk82: BombCore { + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large_HD), QGVAR(huge_HD), QGVAR(huge_HD), QGVAR(huge_HD)}; + GVAR(metal) = 140000; + GVAR(charge) = 87000; + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = "1/2"; +}; + +class Mo_cluster_AP: ShellBase { + GVAR(skip) = 1; + GVAR(force) = 0; +}; +class Mo_cluster_Bomb_01_F: Mo_cluster_AP { // Mk 118 Rockeye + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(small_HD)}; + GVAR(metal) = 400; + GVAR(charge) = 180; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; +class Mo_cluster_Bomb_02_F: Mo_cluster_Bomb_01_F { // ShOAB-0.5 + GVAR(classes)[] = {QGVAR(small_HD)}; + GVAR(metal) = 400; + GVAR(charge) = 100; + GVAR(gurney_c) = 2700; +}; +class Mo_cluster_Bomb_03_F: Mo_cluster_Bomb_01_F { // idk, @lambda.tiger on the ace discord if you find out + GVAR(classes)[] = {QGVAR(small_HD)}; + GVAR(metal) = 400; + GVAR(charge) = 140; + GVAR(gurney_c) = 2400; +}; + +// ~~~~ Grenades: +class Grenade; +class GrenadeHand: Grenade { + GVAR(skip) = 0; + GVAR(force) = 1; + /* + These values are based on the M67 Grenade, should be tweaked for + individual grenades. + */ + GVAR(classes)[] = {QGVAR(tiny_HD)}; + 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 +}; +class mini_Grenade: GrenadeHand { + GVAR(classes)[] = {QGVAR(tiny_HD)}; + GVAR(metal) = 104; + GVAR(charge) = 36; +}; +class GrenadeHand_stone: GrenadeHand { + GVAR(skip) = 1; +}; +class SmokeShell: GrenadeHand { + GVAR(skip) = 1; +}; +class G_40mm_HE: GrenadeBase { + // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M441 + GVAR(skip) = 0; + GVAR(force) = 1; + GVAR(classes)[] = {QGVAR(small_HD), QGVAR(tiny_HD), QGVAR(small_HD)}; + GVAR(metal) = 200; + GVAR(charge) = 32; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "3/5"; // interior fragmenter/charge is a sphere +}; +class G_20mm_HE: G_40mm_HE { + GVAR(classes)[] = {QGVAR(tiny_HD)}; + GVAR(metal) = 50; + GVAR(charge) = 8; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "3/5"; // interior fragmenter/charge is a sphere +}; +class G_40mm_HEDP: G_40mm_HE { + // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M433 + GVAR(classes)[] = {QGVAR(tiny_HD), QGVAR(small_HD), QGVAR(small_HD)}; + GVAR(metal) = 200; + GVAR(charge) = 45; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "1/2"; +}; + +class ACE_G_40mm_HEDP: G_40mm_HEDP {}; +class ACE_G_40mm_HE: G_40mm_HE {}; +class ACE_G_40mm_Practice: ACE_G_40mm_HE { + GVAR(skip) = 1; + GVAR(force) = 0; + EGVAR(vehicle_damage,incendiary) = 0; +}; + +// ~~~~ Mines & UXO +class ATMine_Range_Ammo: MineBase { + GVAR(skip) = 1; +}; + +class APERSMine_Range_Ammo: MineBase { // VS-50 + GVAR(skip) = 0; + GVAR(force) = 1; + GVAR(classes)[] = {QGVAR(tiny_HD), QGVAR(tiny_HD), QGVAR(small_HD)}; + GVAR(metal) = 100; + GVAR(charge) = 50; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/3"; +}; + +class APERSBoundingMine_Range_Ammo: BoundingMineBase { + GVAR(skip) = 0; + GVAR(force) = 0; + GVAR(classes)[] = {QGVAR(tiny_HD)}; + GVAR(metal) = 80; + GVAR(charge) = 170; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "3/5"; +}; + +class TrainingMine_Ammo: APERSMine_Range_Ammo { + GVAR(skip) = 1; +}; + +class SLAMDirectionalMine_Wire_Ammo: DirectionalBombBase { + GVAR(skip) = 1; +}; + +class APERSTripMine_Wire_Ammo: DirectionalBombBase { + GVAR(skip) = 0; + GVAR(force) = 0; + GVAR(classes)[] = {QGVAR(tiny_HD)}; + GVAR(metal) = 210; + GVAR(charge) = 185; + GVAR(gurney_c) = 2843; + GVAR(gurney_k) = "3/5"; +}; + +class IEDUrbanBig_Remote_Ammo: PipeBombBase { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(large), QGVAR(large_HD), QGVAR(large_HD), QGVAR(large_HD), QGVAR(huge_HD), QGVAR(huge_HD), QGVAR(huge_HD)}; + GVAR(metal) = 36000; + GVAR(charge) = 9979; + GVAR(gurney_c) = 2440; + GVAR(gurney_k) = "3/5"; +}; +class IEDLandBig_Remote_Ammo: PipeBombBase { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(large), QGVAR(large_HD), QGVAR(large_HD), QGVAR(large_HD), QGVAR(huge_HD), QGVAR(huge_HD), QGVAR(huge_HD)}; + GVAR(metal) = 36000; + GVAR(charge) = 9979; + GVAR(gurney_c) = 2440; + GVAR(gurney_k) = "3/5"; +}; +class IEDUrbanSmall_Remote_Ammo: PipeBombBase { + GVAR(skip) = 0; + GVAR(metal) = 23000; + GVAR(charge) = 3148; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "3/5"; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium_HD), QGVAR(medium_HD)}; +}; +class IEDLandSmall_Remote_Ammo: PipeBombBase { + GVAR(skip) = 0; + GVAR(metal) = 23000; + GVAR(charge) = 3148; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "3/5"; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium_HD), QGVAR(medium_HD)}; +}; + +class APERSMineDispenser_Ammo: PipeBombBase { + GVAR(skip) = 1; +}; + +class UXO1_Ammo_Base_F: APERSMine_Range_Ammo { // Mk 118 Rockeye + GVAR(skip) = 0; + GVAR(charge) = 180; + GVAR(metal) = 400; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(small_HD)}; +}; + +class UXO2_Ammo_Base_F: UXO1_Ammo_Base_F { + GVAR(charge) = 100; + GVAR(classes)[] = {QGVAR(small_HD), QGVAR(tiny_HD)}; +}; + +class APERSMineDispenser_Mine_Ammo: APERSMine_Range_Ammo { + GVAR(skip) = 1; +}; + +class UXO_deploy_base_f: SubmunitionBase {}; + +class ClaymoreDirectionalMine_Remote_Ammo: DirectionalBombBase { + GVAR(skip) = 0; + GVAR(force) = 0; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(small)}; + GVAR(fragCount) = 700; + GVAR(metal) = 700; + GVAR(charge) = 680; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "3/5"; +}; + +class SatchelCharge_Remote_Ammo: PipeBombBase { + GVAR(skip) = 1; +}; + +class DemoCharge_Remote_Ammo: PipeBombBase { + GVAR(skip) = 1; +}; + +class Drone_explosive_ammo: MineBase { + GVAR(skip) = 1; +}; + +class BombDemine_01_Ammo_F: BombCore { + GVAR(skip) = 1; +}; + +class BombDemine_01_SubAmmo_F: ShellBase { + GVAR(skip) = 1; +}; + +// ~~~~ Rockets: +class R_PG7_F: RocketBase { + GVAR(skip) = 0; + GVAR(force) = 0; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(small_HD)}; + GVAR(metal) = 100; + GVAR(charge) = 560; + GVAR(gurney_c) = 2730; + GVAR(gurney_k) = "1/2"; +}; + +class R_PG32V_F: RocketBase { + GVAR(skip) = 1; +}; +class R_TBG32V_F: R_PG32V_F { // Thermobaric + GVAR(skip) = 0; + GVAR(metal) = 400; + GVAR(charge) = 210; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "3/5"; + GVAR(classes)[] = {QGVAR(medium_HD)}; +}; + +class M_SPG9_HEAT: RocketBase { + GVAR(skip) = 0; + GVAR(metal) = 4150; + GVAR(charge) = 340; + GVAR(gurney_c) = 2970; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(small_HD), QGVAR(medium_HD)}; +}; +class M_SPG9_HE: M_SPG9_HEAT { + GVAR(metal) = 4695; + GVAR(charge) = 655; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(small_HD), QGVAR(tiny), QGVAR(medium_HD), QGVAR(medium_HD)}; +}; + +// https://armypubs.army.mil/epubs/DR_pubs/DR_a/pdf/web/ARN18072_TC%203-22x84%20FINAL%20WEB.pdf +class R_MRAAWS_HEAT_F: RocketBase { // Table A-20. HEAT 751 + GVAR(skip) = 0; + GVAR(metal) = 2265; + GVAR(charge) = 635; + GVAR(gurney_c) = 2970; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(small_HD)}; + +}; +class R_MRAAWS_HEAT55_F: R_MRAAWS_HEAT_F { // Table A-16. HEAT 551C + GVAR(metal) = 1940; + GVAR(charge) = 460; +}; +class R_MRAAWS_HE_F: R_MRAAWS_HEAT_F { // Table A-6. HE 441D RS + GVAR(metal) = 2300; + GVAR(charge) = 590; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "3/5"; + GVAR(classes)[] = {QGVAR(small_HD)}; +}; + +class R_80mm_HE: RocketBase { // S-8D + GVAR(skip) = 0; + GVAR(charge) = 2150; + GVAR(metal) = 1650; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(small_HD), QGVAR(tiny_HD), QGVAR(tiny)}; +}; +class R_60mm_HE: R_80mm_HE { // no idea but looks like a FFAR so made it weaker + GVAR(metal) = 1040; + GVAR(charge) = 3850; +}; + +class m_70mm_saami: MissileBase { + GVAR(skip) = 0; + GVAR(charge) = 2150; + GVAR(metal) = 1650; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(small_HD), QGVAR(tiny_HD), QGVAR(tiny)}; +}; + +class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(metal) = 3850; + GVAR(charge) = 1040; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; +class Rocket_03_HE_F: Rocket_04_HE_F { // S-8DM makes the most sense + GVAR(metal) = 1800; + GVAR(charge) = 2000; + GVAR(gurney_c) = 2300; +}; +class Rocket_04_AP_F: Rocket_04_HE_F { + GVAR(skip) = 1; +}; + +class ammo_Missile_CannonLaunchedBase: MissileBase { + GVAR(skip) = 1; +}; + +class R_230mm_fly: ShellBase { + GVAR(skip) = 0; + GVAR(charge) = 100; // kg + GVAR(metal) = 150; // kg + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = "3/5"; + GVAR(classes)[] = {QGVAR(large_HD), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge_HD), QGVAR(huge_HD), QGVAR(huge)}; +}; + +class M_PG_AT: MissileBase { // DAGR M247 warhead + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(tiny_HD), QGVAR(small_HD), QGVAR(small), QGVAR(medium)}; + GVAR(charge) = 910; + GVAR(metal) = 3085; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; +class M_AT: M_PG_AT { // DAR (Hydra 70) M151 warhead + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(charge) = 1040; + GVAR(metal) = 3850; + GVAR(gurney_c) = 2700; +}; + +// ~~~~ Missiles: +class Missile_AGM_02_F: MissileBase { + // Source: http://fas.org/man/dod-101/sys/smart/agm-65.htm + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(metal) = 56250; + GVAR(charge) = 39000; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; +class Missile_AGM_01_F: Missile_AGM_02_F { // Kh-25MTP !!! fix me +}; +class M_Jian_AT: Missile_AGM_01_F { // imaginary missile? Not simiklar to any modern HJ-x or otherwise +}; + +class M_Titan_AA: MissileBase { + GVAR(skip) = 0; + GVAR(metal) = 1980; + GVAR(charge) = 1020; + GVAR(gurney_c) = 2501; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(tiny_HD), QGVAR(small_HD)}; +}; +class M_Titan_AT: MissileBase { + GVAR(skip) = 1; +}; +class M_Titan_AP: M_Titan_AT { + GVAR(skip) = 0; + GVAR(metal) = 400; + GVAR(charge) = 210; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "3/5"; + GVAR(classes)[] = {QGVAR(medium_HD)}; +}; + +class M_Scalpel_AT: MissileBase { // 9K121 Vikhr + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(metal) = 10000; + GVAR(charge) = 3000; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; +class ACE_Hellfire_AGM114K: M_Scalpel_AT { + // Source: http://www.designation-systems.net/dusrm/m-114.html + GVAR(skip) = 0; + + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(metal) = 8000; + GVAR(charge) = 2400; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; + +class ammo_Missile_CruiseBase: MissileBase {}; +class ammo_missile_cruise_01: ammo_Missile_CruiseBase { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium_HD), QGVAR(large_HD)}; + GVAR(metal) = 700000; + GVAR(charge) = 110000; + GVAR(gurney_c) = 2600; + GVAR(gurney_k) = "3/5"; +}; +class ammo_Missile_Cruise_01_Cluster: ammo_missile_cruise_01 {}; + +class ammo_Missile_AntiRadiationBase: MissileBase { + GVAR(gurney_k) = "1/2"; + GVAR(gurney_c) = 2400; +}; +class ammo_Missile_HARM: ammo_Missile_AntiRadiationBase { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium_HD), QGVAR(large_HD)}; + GVAR(charge) = 10000; + GVAR(metal) = 58000; +}; +class ammo_Missile_KH58: ammo_Missile_AntiRadiationBase { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium_HD), QGVAR(large_HD)}; + GVAR(charge) = 20000; + GVAR(metal) = 129000; +}; + +class M_Zephyr: M_Titan_AA { // model is an AMRAAM- WDU-41/B warhead + GVAR(skip) = 0; + GVAR(metal) = 12800; + GVAR(charge) = 4000; + GVAR(gurney_c) = 2900; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(medium_HD), QGVAR(small), QGVAR(small_HD)}; +}; + +class M_Air_AA: MissileBase { // Looks not real, maybe r-73 inspired? + GVAR(skip) = 0; + GVAR(charge) = 2450; + GVAR(metal) = 4950; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(medium_HD), QGVAR(small_HD), QGVAR(small_HD)}; +}; + +class Missile_AA_04_F: MissileBase { + GVAR(skip) = 0; + GVAR(charge) = 4400; + GVAR(metal) = 5000; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "1/2"; +}; +class Missile_AA_03_F: Missile_AA_04_F { + GVAR(charge) = 2450; + GVAR(metal) = 4950; + GVAR(gurney_c) = 2700; +}; + +class ammo_Missile_ShortRangeAABase: MissileBase { + GVAR(gurney_k) = "1/2"; +}; +class ammo_Missile_rim116: ammo_Missile_ShortRangeAABase { + GVAR(skip) = 0; + GVAR(charge) = 400; + GVAR(metal) = 730; + GVAR(gurney_c) = 2400; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(small_HD)}; +}; +class ammo_Missile_BIM9X: ammo_Missile_ShortRangeAABase { + GVAR(skip) = 0; + GVAR(charge) = 440; + GVAR(metal) = 500; + GVAR(gurney_c) = 2900; + GVAR(classes)[] = {QGVAR(small), QGVAR(tiny)}; +}; +class ammo_Missile_AA_R73: ammo_Missile_ShortRangeAABase { + GVAR(skip) = 0; + GVAR(charge) = 2450; + GVAR(metal) = 4950; + GVAR(gurney_c) = 2700; + GVAR(classes)[] = {QGVAR(small), QGVAR(small), QGVAR(tiny)}; +}; + +class ammo_Missile_MediumRangeAABase: MissileBase { + GVAR(gurney_c) = 2900; + GVAR(gurney_k) = "1/2"; +}; +class ammo_Missile_rim162: ammo_Missile_MediumRangeAABase { + GVAR(skip) = 0; + GVAR(charge) = 138; // dg + GVAR(metal) = 252; // dg + GVAR(gurney_c) = 2400; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium), QGVAR(large)}; +}; +class ammo_Missile_AMRAAM_C: ammo_Missile_MediumRangeAABase { + GVAR(skip) = 0; + GVAR(charge) = 70; // dg + GVAR(metal) = 128; // dg + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium)}; +}; +class ammo_Missile_AMRAAM_D: ammo_Missile_MediumRangeAABase { + GVAR(skip) = 0; + GVAR(charge) = 70; // dg + GVAR(metal) = 128; // dg + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium)}; +}; +class ammo_Missile_AA_R77: ammo_Missile_MediumRangeAABase { + GVAR(skip) = 0; + GVAR(charge) = 80; // dg + GVAR(metal) = 145; // dg + GVAR(gurney_c) = 2700; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(large), QGVAR(large)}; +}; + +class M_Vorona_HEAT: MissileBase { + // tandem shaped charges + GVAR(skip) = 1; +}; +class M_Vorona_HE: M_Vorona_HEAT { + // All signs point to this being a thermobaric round so low frag count + GVAR(skip) = 0; + GVAR(metal) = 13800; + GVAR(charge) = 4950; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(tiny)}; +}; + +class M_127mm_Firefist_AT: MissileBase { // HOT missile + GVAR(skip) = 1; +}; + +class M_NLAW_AT_F: MissileBase { + GVAR(skip) = 1; +}; + +// ~~~~ Shell +class Sh_75mm_Railgun_APFSDS: ShellBase { + GVAR(skip) = 1; +}; +class Sh_120mm_APFSDS: ShellBase { + GVAR(skip) = 1; +}; +class Sh_125mm_APFSDS: Sh_120mm_APFSDS { + GVAR(skip) = 1; +}; + +class Sh_155mm_AMOS: ShellBase { + // Source: http://www.globalsecurity.org/military/systems/munitions/m795.htm + GVAR(skip) = 0; + GVAR(charge) = 9979; + GVAR(metal) = 36000; + GVAR(gurney_c) = 2440; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; +}; + +class Sh_82mm_AMOS: Sh_155mm_AMOS { // VO-832DU + GVAR(charge) = 420; + GVAR(metal) = 2680; + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; +}; + +class Sh_120mm_HE: ShellBase { + GVAR(skip) = 0; + GVAR(charge) = 3148; + GVAR(metal) = 23000; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; +}; +class Sh_120mm_HEAT_MP: ShellBase { + GVAR(skip) = 0; + GVAR(charge) = 2500; + GVAR(metal) = 5000; + GVAR(gurney_c) = 2500; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium_HD), QGVAR(medium_HD)}; +}; + +class ammo_ShipCannon_120mm_HE: Sh_155mm_AMOS { + GVAR(charge) = 3148; + GVAR(metal) = 23000; + GVAR(gurney_c) = 2830; + GVAR(classes)[] = {QGVAR(small), QGVAR(small), QGVAR(medium_HD), QGVAR(large_HD)}; +}; + +class Sh_125mm_HE: Sh_120mm_HE { + GVAR(metal) = 19900; + GVAR(charge) = 3400; + GVAR(gurney_c) = 2901; +}; + +class Sh_125mm_HEAT: Sh_125mm_HE { + GVAR(skip) = 1; + GVAR(metal) = 16760; + GVAR(charge) = 1640; + GVAR(gurney_c) = 2901; +}; + +class Sh_105mm_HEAT_MP: Sh_125mm_HEAT { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD)}; + GVAR(metal) = 11400; + GVAR(charge) = 7100; + GVAR(gurney_c) = 2800; +}; + +class ModuleOrdnanceHowitzer_F_ammo: Sh_155mm_AMOS { + GVAR(skip) = 0; + GVAR(metal) = 1950; + GVAR(charge) = 15800; + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(large), QGVAR(large_HD), QGVAR(large_HD), QGVAR(large_HD), QGVAR(huge_HD), QGVAR(huge_HD), QGVAR(huge_HD)}; +}; +class ammo_Penetrator_Base: ShellBase { + GVAR(skip) = 1; +}; + +// ~~~~ Special +class ProbingBeam_01_F: BulletBase { + GVAR(skip) = 1; +}; + +class IRStrobeBase: GrenadeCore { + GVAR(skip) = 1; +}; +class FlareCore: GrenadeCore { // flares shouldn't have EH, but in case + GVAR(skip) = 1; +}; + +class Default; +class Laserbeam: Default { + GVAR(skip) = 1; +}; + +class FuelExplosion: Default { + GVAR(skip) = 1; +}; + +class HelicopterExploSmall: ShellBase { + GVAR(skip) = 1; +}; + +class LightningBolt: ShellBase { + GVAR(skip) = 1; +}; + +class M_Mo_82mm_AT: MissileBase { + GVAR(skip) = 1; +}; diff --git a/addons/frag/CfgAmmoSpall.hpp b/addons/frag/CfgAmmoSpall.hpp new file mode 100644 index 00000000000..c53ce4db4a8 --- /dev/null +++ b/addons/frag/CfgAmmoSpall.hpp @@ -0,0 +1,158 @@ +class GVAR(spallBase): B_65x39_Caseless { + GVAR(skip) = 1; + submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium), 3, QGVAR(large), 2, QGVAR(huge), 1}; + submunitionConeType[] = {"random", 20}; + submunitionConeAngle = 40; + submunitionDirectionType = "SubmunitionModelDirection"; + triggerTime = 0; + submunitionInitialOffset[] = {0, 0, 0}; + submunitionInitSpeed = 0; + triggerSpeedCoef[] = {0.75, 1.25}; + deleteParentWhenTriggered = 1; + submunitionParentSpeedCoef = 1; +}; + + +/* + * ground + */ +class GVAR(ground_spall_tiny): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 9, QGVAR(small), 1}; + submunitionConeType[] = {"poissondisccenter", 4}; +}; + +class GVAR(ground_spall_small): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium), 1}; + submunitionConeType[] = {"poissondisccenter", 6}; +}; + +class GVAR(ground_spall_medium): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(small), 2, QGVAR(small_HD), 1, QGVAR(medium), 3, QGVAR(medium_HD), 1, QGVAR(large), 2}; + submunitionConeType[] = {"poissondisccenter", 15}; +}; + +class GVAR(ground_spall_large): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5, QGVAR(large), 1, QGVAR(large_HD), 2}; + submunitionConeType[] = {"poissondisccenter", 15}; +}; + +class GVAR(ground_spall_huge): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium), 5, QGVAR(large), 1, QGVAR(large_HD), 2}; + submunitionConeType[] = {"poissondisccenter", 20}; +}; + + +/* + * rock + */ +class GVAR(rock_spall_tiny): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 4}; +}; + +class GVAR(rock_spall_small): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium), 1}; + submunitionConeType[] = {"poissondisccenter", 5}; +}; + +class GVAR(rock_spall_medium): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium), 1, QGVAR(medium_HD), 2, QGVAR(large_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 7}; +}; + +class GVAR(rock_spall_large): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(small), 5, QGVAR(medium), 2, QGVAR(large), 1}; + submunitionConeType[] = {"poissondisccenter", 10}; +}; + +class GVAR(rock_spall_huge): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(small), 5, QGVAR(medium), 2, QGVAR(large), 1, QGVAR(huge_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 13}; +}; + + +/* + * wood + */ +class GVAR(wood_spall_tiny): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 2, QGVAR(small), 4}; + submunitionConeType[] = {"poissondisccenter", 4}; +}; + +class GVAR(wood_spall_small): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 2, QGVAR(small), 4, QGVAR(medium), 1}; + submunitionConeType[] = {"poissondisccenter", 6}; +}; + +class GVAR(wood_spall_medium): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 2, QGVAR(small), 2, QGVAR(medium), 2, QGVAR(medium_HD), 1, QGVAR(large_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 8}; +}; + +class GVAR(wood_spall_large): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 1, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large_HD), 2, QGVAR(huge_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 10}; +}; + +class GVAR(wood_spall_huge): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 1, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large_HD), 2, QGVAR(huge_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 12}; +}; + + +/* + * concrete + */ +class GVAR(concrete_spall_tiny): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 6, QGVAR(tiny_HD), 3, QGVAR(small), 1}; + submunitionConeType[] = {"poissondisccenter", 4}; +}; + +class GVAR(concrete_spall_small): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 4, QGVAR(tiny_HD), 2, QGVAR(small), 2, QGVAR(medium), 1}; + submunitionConeType[] = {"poissondisccenter", 6}; +}; + +class GVAR(concrete_spall_medium): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 6, QGVAR(tiny_HD), 1, QGVAR(small), 4, QGVAR(medium), 5, QGVAR(large_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 9}; +}; + +class GVAR(concrete_spall_large): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 6, QGVAR(small), 4, QGVAR(medium), 3, QGVAR(large), 1, QGVAR(large_HD), 2}; + submunitionConeType[] = {"poissondisccenter", 12}; +}; + +class GVAR(concrete_spall_huge): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 8, QGVAR(small), 4, QGVAR(medium), 3, QGVAR(large), 1, QGVAR(large_HD), 1, QGVAR(huge_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 18}; +}; + + +/* + * metal + */ +class GVAR(metal_spall_tiny): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 9, QGVAR(small), 1}; + submunitionConeType[] = {"poissondisccenter", 4}; +}; + +class GVAR(metal_spall_small): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 4, QGVAR(small), 2, QGVAR(medium), 1}; + submunitionConeType[] = {"poissondisccenter", 6}; +}; + +class GVAR(metal_spall_medium): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 5, QGVAR(small), 4, QGVAR(medium), 2, QGVAR(large), 1}; + submunitionConeType[] = {"poissondisccenter", 8}; +}; + +class GVAR(metal_spall_large): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 4, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large), 1, QGVAR(huge), 1}; + submunitionConeType[] = {"poissondisccenter", 12}; +}; + +class GVAR(metal_spall_huge): GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 8, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large), 3, QGVAR(huge), 1}; + submunitionConeType[] = {"poissondisccenter", 18}; +}; diff --git a/addons/frag/README.md b/addons/frag/README.md index ca62771f00e..797e652b207 100644 --- a/addons/frag/README.md +++ b/addons/frag/README.md @@ -1,4 +1,4 @@ ace_frag ======== -Shrapnel system for explosives. +Explosive fragmentation, round spalling, and explosive reflection diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index a7fb8ff8c34..127f027f98e 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -1,25 +1,22 @@ -PREP(dev_debugAmmo); - -PREP(doSpall); -PREP(fired); -PREP(frago); -PREP(spallTrack); - -// * Other */ PREP(addBlackList); -PREP(dev_addTrack); -PREP(dev_drawTraces); -PREP(spallHP); -PREP(dev_startTracing); -PREP(dev_stopTracing); -PREP(dev_trackTrace); - -// New tracking mechanisms -PREP(masterPFH); -PREP(pfhRound); -PREP(addPfhRound); - -// Explosive Reflection -PREP(findReflections); +PREP(dev_clearTraces); +PREP(dev_debugAmmo); +PREP(dev_drawTrace); +PREP(dev_fragCalcDump); +PREP(dev_sphereDraw); +PREP(dev_trackHitBox); +PREP(dev_trackObj); PREP(doExplosions); PREP(doReflections); +PREP(doSpallHitPart); +PREP(doSpallPenetrate); +PREP(findReflections); +PREP(fired); +PREP(frago); +PREP(getFragInfo); +PREP(getMaterialInfo); +PREP(getSpallInfo); +PREP(initMaterialCache); +PREP(setClassBlacklisted); +PREP(shouldFrag); +PREP(shouldSpall); diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index ecebd793ce1..7b0e32e04c9 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -1,32 +1,54 @@ #include "script_component.hpp" -if (isServer) then { - GVAR(lastFragTime) = -1; - [QGVAR(frag_eh), {_this call FUNC(frago);}] call CBA_fnc_addEventHandler; -}; - ["CBA_settingsInitialized", { - if (!GVAR(enabled)) exitWith {}; + [{ + params ["_projectile", "_posASL"]; + + if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith {}; + + private _ammo = typeOf _projectile; + if (GVAR(reflectionsEnabled)) then { + [_posASL, _ammo] call FUNC(doReflections); + }; + if (GVAR(enabled) && _ammo call FUNC(shouldFrag)) then { + // only let a unit make a frag event once per second + private _shotParents = getShotParents _projectile; + private _instigator = _shotParents select !isNull (_shotParents#1); + if (CBA_missionTime < (_instigator getVariable [QGVAR(nextFragEvent), -1])) exitWith {}; + _instigator setVariable [QGVAR(nextFragEvent), CBA_missionTime + ACE_FRAG_FRAG_UNIT_HOLDOFF]; + + // Wait a frame to make sure it doesn't target the dead + [{ + [QGVAR(frag_eh), _this] call CBA_fnc_serverEvent + }, [_posASL, _ammo, [objNull, _instigator]]] call CBA_fnc_execNextFrame; + }; + }] call EFUNC(common,addExplosionEventHandler); - // Register fire event handler ["ace_firedPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; ["ace_firedNonPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; ["ace_firedPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; ["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; - - addMissionEventHandler ["EachFrame", {call FUNC(masterPFH)}]; -}] call CBA_fnc_addEventHandler; - -// Cache for ammo type configs -GVAR(cacheRoundsTypesToTrack) = [false] call CBA_fnc_createNamespace; - - -// Debug stuff: - -#ifdef DRAW_FRAG_INFO -[] call FUNC(dev_startTracing); +#ifdef DEBUG_MODE_DRAW + [QGVAR(dev_clearTraces), LINKFUNC(dev_clearTraces)] call CBA_fnc_addEventHandler; + + if (!hasInterface) exitWith {}; + GVAR(dev_drawPFEH) = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; + ["ace_interact_menu_newControllableObject", { + params ["_type"]; + + private _action = [ + QGVAR(debugReset), + "Reset ACE Frag traces", + "", + {[QGVAR(dev_clearTraces), []] call CBA_fnc_globalEvent;}, + {GVAR(dev_trackLines) isNotEqualTo createHashMap} + ] call EFUNC(interact_menu,createAction); + + [_type, 1, ["ACE_SelfActions"], _action, true] call EFUNC(interact_menu,addActionToClass); + }] call CBA_fnc_addEventHandler; #endif +}] call CBA_fnc_addEventHandler; -#ifdef DEBUG_MODE_FULL +#ifdef LOG_FRAG_INFO [true, true, 30] call FUNC(dev_debugAmmo); #endif diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index dc616917b88..2cb4a8e368d 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -6,20 +6,32 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -GVAR(blackList) = []; -GVAR(traceFrags) = false; +GVAR(spallMaterialCache) = uiNamespace getVariable QGVAR(spallMaterialCache); +GVAR(spallInfoCache) = createHashMap; +GVAR(shouldSpallCache) = createHashMap; +GVAR(nextSpallAllowTime) = -1; -GVAR(spallHPData) = []; -GVAR(spallIsTrackingCount) = 0; - -GVAR(traceID) = -1; -GVAR(traces) = []; -GVAR(tracesStarted) = false; - -GVAR(lastIterationIndex) = 0; -GVAR(objects) = []; -GVAR(arguments) = []; +GVAR(shouldFragCache) = createHashMap; +GVAR(fragInfoCache) = createHashMap; +GVAR(lastFragTime) = -1; #include "initSettings.inc.sqf" +GVAR(dev_trackLines) = createHashMap; +GVAR(dev_hitBoxes) = createHashMap; +GVAR(dev_eventSpheres) = []; +GVAR(dev_drawPFEH) = -1; + +#ifdef DEBUG_MODE_DRAW +#include "initSettingsDebug.inc.sqf" +#else +GVAR(debugOptions) = false; +GVAR(dbgSphere) = false; +GVAR(drawHitBox) = false; +#endif + +if (isServer) then { + [QGVAR(frag_eh), LINKFUNC(frago)] call CBA_fnc_addEventHandler; +}; + ADDON = true; diff --git a/addons/frag/XEH_preStart.sqf b/addons/frag/XEH_preStart.sqf index 022888575ed..d3e2573e07e 100644 --- a/addons/frag/XEH_preStart.sqf +++ b/addons/frag/XEH_preStart.sqf @@ -1,3 +1,4 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" +call FUNC(initMaterialCache); diff --git a/addons/frag/config.cpp b/addons/frag/config.cpp index f3b409dbd03..488b72c5070 100644 --- a/addons/frag/config.cpp +++ b/addons/frag/config.cpp @@ -8,7 +8,7 @@ class CfgPatches { requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; author = ECSTRING(common,ACETeam); - authors[] = {"Nou"}; + authors[] = {"Nou", "johnb43", "Lambda.Tiger"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; diff --git a/addons/frag/functions/fnc_addBlackList.sqf b/addons/frag/functions/fnc_addBlackList.sqf deleted file mode 100644 index d0cc127d059..00000000000 --- a/addons/frag/functions/fnc_addBlackList.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Jaynus, NouberNou - * Adds a round to the blacklist (will be ignored). - * - * Arguments: - * 0: Projectile - * - * Return Value: - * None - * - * Example: - * [bullet] call ace_frag_fnc_addBlackList - * - * Public: No - */ - -params ["_round"]; -TRACE_1("addBlackList",_round); - -GVAR(blackList) pushBack _round; diff --git a/addons/frag/functions/fnc_addBlacklist.sqf b/addons/frag/functions/fnc_addBlacklist.sqf new file mode 100644 index 00000000000..a835dc33702 --- /dev/null +++ b/addons/frag/functions/fnc_addBlacklist.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" +/* + * Author: Jaynus, NouberNou, Lambda.Tiger + * Adds a round to the blacklist (will be ignored) and removes any ace_frag event handlers added to it. + * Once blacklisted a projectile can not be "unblacklisted." + * + * Arguments: + * 0: Projectile to be blacklisted + * + * Return Value: + * Was the projectile blacklisted + * + * Example: + * [_projectile] call ace_frag_fnc_addBlackList + * + * Public: Yes + */ + +params [["_projectile", objNull, [objNull]]]; +TRACE_2("addBlackList",_projectile,typeOf projectile); + +if (isNull _projectile || {!isClass (configFile >> "CfgAmmo" >> (typeOf _projectile))}) exitWith { + TRACE_1("Invalid projectile",_this); + false +}; + +_projectile setVariable [QGVAR(blacklisted), true]; +(_projectile getVariable [QGVAR(spallEH), [-1, -1]]) params ["_hitPartEH", "_penetratedEH"]; +_projectile removeEventHandler ["HitPart", _hitPartEH]; +_projectile removeEventHandler ["Penetrated", _penetratedEH]; + +true diff --git a/addons/frag/functions/fnc_addPfhRound.sqf b/addons/frag/functions/fnc_addPfhRound.sqf deleted file mode 100644 index 358a9ee71ea..00000000000 --- a/addons/frag/functions/fnc_addPfhRound.sqf +++ /dev/null @@ -1,77 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Jaynus, NouberNou - * Starts tracking a round that will frag. - * Should only be called once per round. - * - * Arguments: - * 0: Shooter - * 1: Ammo classname - * 2: Projectile - * - * Return Value: - * None - * - * Example: - * [player, "handGrenade", bullet] call ace_frag_fnc_addPfhRound - * - * Public: No - */ - -params ["_gun", "_type", "_round"]; -TRACE_3("addPfhRound",_gun,_type,_round); - -if (!GVAR(enabled)) exitWith {TRACE_1("setting disabled",_this);}; - -if (!alive _round) exitWith {TRACE_1("round dead?",_this);}; - -if (_round in GVAR(blackList)) exitWith { - TRACE_1("round in blackList",_this); - REM(GVAR(blackList),_round); -}; - -// Exit on max track -if ((count GVAR(objects)) >= GVAR(maxTrack)) exitWith {TRACE_1("maxTrack limit",count GVAR(objects));}; - -private _doSpall = false; -if (GVAR(SpallEnabled)) then { - if (GVAR(spallIsTrackingCount) <= 0) then { - GVAR(spallHPData) = []; - }; - if (GVAR(spallIsTrackingCount) > 5) then { - TRACE_1("At Spall Limit",GVAR(spallIsTrackingCount)); - } else { - _doSpall = true; - INC(GVAR(spallIsTrackingCount)); - }; - TRACE_2("",_doSpall,GVAR(spallIsTrackingCount)); -}; - -#ifdef DRAW_FRAG_INFO -[ACE_player, _round, [0, 1, 0, 1]] call FUNC(dev_addTrack); -#endif - -// We only do the single track object check here. -// We should do an {!(_round in GVAR(objects))} -// But we leave that out here for optimization. So this cannot be a framework function -// Otherwise, it should only be added once and from the FiredEH -if (alive _round) then { - private _spallTrack = []; - private _spallTrackID = []; - - private _args = [ - _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); - GVAR(objects) pushBack _round; - GVAR(arguments) pushBack _args; - - if (_doSpall) then { - [_round, 1, _spallTrack, _spallTrackID] call FUNC(spallTrack); - }; -}; diff --git a/addons/frag/functions/fnc_dev_addTrack.sqf b/addons/frag/functions/fnc_dev_addTrack.sqf deleted file mode 100644 index 0e75a9fb994..00000000000 --- a/addons/frag/functions/fnc_dev_addTrack.sqf +++ /dev/null @@ -1,26 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_dev_addTrack - * - * Public: No - */ - -params ["_origin", "_obj", ["_color", [1, 0, 0, 1]]]; - -private _positions = []; -private _objSpd = vectorMagnitude (velocity _obj); -_positions pushBack [getPos _obj, _objSpd]; -private _data = [_origin, typeOf _origin, typeOf _obj, _objSpd, _positions, _color]; - -private _index = GVAR(traces) pushBack _data; -[DFUNC(dev_trackTrace), 0, [_obj, _index, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/frag/functions/fnc_dev_clearTraces.sqf b/addons/frag/functions/fnc_dev_clearTraces.sqf new file mode 100644 index 00000000000..6e2b820bacb --- /dev/null +++ b/addons/frag/functions/fnc_dev_clearTraces.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * Clears all dev spheres and traces. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_dev_clearTraces + * + * Public: No + */ + +{ + deleteVehicle _x; +} forEach GVAR(dev_eventSpheres); + +GVAR(dev_eventSpheres) = []; + +GVAR(dev_trackLines) = createHashMap; +GVAR(dev_hitBoxes) = createHashMap; diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index ec52b4b39f6..fe868df3428 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -1,11 +1,15 @@ -#define DEBUG_MODE_FULL #include "..\script_component.hpp" /* - * Author: ACE-Team - * + * Author: ACE-Team, Lambda.Tiger + * This function will dump every ammo config that would generate ace_frag + * fragments that could be fired from a weapon. * * Arguments: - * None + * 0: Log ammo types that wouldn't normally frag (default: false) + * 1: Only print ammo without ACE_frag entries, inherited or otherwise (default: true) + * 2: Only export ammo classes of classes referenced in CfgMagazines and their + * submunitions (default: false) + * 3: Force a CSV format on debug print. (default: false) * * Return Value: * None @@ -17,65 +21,90 @@ */ params [ - ["_debugMissing", true, [false]], - ["_debugForce", false, [false]], - ["_debugSkippedFragPower", 30, [0]] + ["_logAll", false, [false]], + ["_printOnlyIncomplete", true, [true]], + ["_onlyShotAmmoTypes", false, [false]], + ["_csvFormat", false, [false]] ]; diag_log text format ["~~~~~~~~~~~~~Start [%1]~~~~~~~~~~~~~", _this]; +if (_csvFormat) then { + diag_log text format ["ammo,gurney_c,gurney_m,gurney_k,gurney_gC,skip,Inheritance"]; +}; -private _allMagsConfigs = configProperties [configFile >> "CfgMagazines", "isClass _x", true]; -private _processedCfgAmmos = []; - -{ - private _ammo = toLower getText (_x >> "ammo"); - if (_ammo != "" && {!(_ammo in _processedCfgAmmos)}) then { - _processedCfgAmmos pushBack _ammo; - - //Ignore mines/bombs - if (_ammo isKindOf "TimeBombCore") exitWith {}; - - _ammoConfig = configFile >> "CfgAmmo" >> _ammo; - - //Read configs and test if it would actually cause a frag, using same logic as FUNC(pfhRound) - private _skip = getNumber (_ammoConfig >> QGVAR(skip)); - private _explosive = getNumber (_ammoConfig >> "explosive"); - private _indirectRange = getNumber (_ammoConfig >> "indirectHitRange"); - private _force = getNumber (_ammoConfig >> QGVAR(force)); - private _fragPower = getNumber (_ammoConfig >> "indirecthit") * (sqrt ((getNumber (_ammoConfig >> "indirectHitRange")))); +// Gather all configs, either those that could be created from firing or all classes +private _allAmmoConfigs = createHashMap; +if (_onlyShotAmmoTypes) then { + private _configSearchFunction = { + params [ + ["_ammo", "", [""]] + ]; + if (_ammo isEqualTo "" || {_ammo in _allAmmoConfigs}) exitWith {}; + _allAmmoConfigs set [_ammo, 1]; + private _cfgAmmoRoot = configFile >> "CfgAmmo"; + private _submunitionConfig = _cfgAmmoRoot >> _ammo >> "submunitionAmmo"; + if (isArray _submunitionConfig) then { + private _subMunition = getArray _submunitionConfig; + for "_i" from 0 to count _subMunition - 1 do { + if (_i mod 2 == 0) then { + configName (_cfgAmmoRoot >> (_subMunition#_i)) call _configSearchFunction; + }; + }; + } else { + private _subMunition = getText _submunitionConfig; + if (_subMunition isNotEqualTo "") then { + configName (_cfgAmmoRoot >> _subMunition) call _configSearchFunction; + }; + }; + }; + private _allMagazineConfigs = configProperties [configFile >> "CfgMagazines", "isClass _x", true]; + private _cfgAmmoCfgPath = configFile >> "CfgAmmo"; + { + private _magAmmo = getText (_x >> "ammo"); + configName (_cfgAmmoCfgPath >> _magAmmo) call _configSearchFunction; + } forEach _allMagazineConfigs; + _allAmmoConfigs = keys _allAmmoConfigs; +} else { + _allAmmoConfigs = configProperties [configFile >> "CfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true] apply {configName _x}; +}; - private _shouldAdd = (_skip == 0) && {(_force == 1) || {_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}}}; +private _processedCfgAmmos = 0; +private _printCount = 0; +{ // Begin forEach to check each ammo type + private _ammo = _x; + if (_ammo isNotEqualTo "") then { + INC(_processedCfgAmmos); - if (_shouldAdd) then { - if (_debugForce && {((getNumber(_ammoConfig >> "hit")) < 5) || {_fragPower < 10}}) then { - diag_log text format ["Ammo [%1] from Mag [%2] - Weak but will still frag!", _ammo, configName _x]; - diag_log text format [" - _force=%1,_fragPower=%2", _force, _fragPower]; - }; + private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; + _ammo call FUNC(shouldFrag) params ["_shouldFrag"]; - private _warn = false; + if (_shouldFrag || _logAll) then { - _fragTypes = getArray (_ammoConfig >> QGVAR(CLASSES)); - if (_fragTypes isEqualTo []) then {_warn = true;}; - _c = getNumber(_ammoConfig >> QGVAR(CHARGE)); - if (_c == 0) then {_warn = true;}; - _m = getNumber(_ammoConfig >> QGVAR(METAL)); - if (_m == 0) then {_warn = true;}; - _k = getNumber(_ammoConfig >> QGVAR(GURNEY_K)); - if (_k == 0) then {_warn = true;}; - _gC = getNumber(_ammoConfig >> QGVAR(GURNEY_C)); - if (_gC == 0) then {_warn = true;}; + private _print = false; + private _skip = getNumber (_ammoConfig >> QGVAR(skip)); + private _fragTypes = getArray (_ammoConfig >> QGVAR(classes)); + if (_fragTypes isEqualTo []) then {_print = true;}; + private _c = getNumber (_ammoConfig >> QGVAR(charge)); + if (_c == 0) then {_print = true;}; + private _m = getNumber (_ammoConfig >> QGVAR(metal)); + if (_m == 0) then {_print = true;}; + private _k = getNumber (_ammoConfig >> QGVAR(gurney_k)); + if (_k == 0) then {_print = true;}; + private _gC = getNumber (_ammoConfig >> QGVAR(gurney_c)); + if (_gC == 0) then {_print = true;}; - if (_debugMissing && {_warn}) then { - diag_log text format ["Ammo [%1] from Mag [%2] MISSING frag configs:", _ammo, configName _x]; - diag_log text format [" - _c=%1,_m=%2,_k=%3,_gC=%4,_fragTypes=%5", _c, _m, _k, _gC, _fragTypes]; - }; - } else { - if ((_fragPower > _debugSkippedFragPower) && {isArray (_ammoConfig >> QGVAR(CLASSES))}) then { - diag_log text format ["Ammo [%1] from Mag [%2] has frag configs but will NOT frag:", _ammo, configName _x]; - diag_log text format ["- skip=%1,explosive=%2,indirectHitRange=%3,force=%4,fragPower=%5", _skip, _explosive, _indirectRange, _force, _fragPower]; + if (!_printOnlyIncomplete || {_print && _skip != 0}) then { + INC(_printCount); + if (_csvFormat) then { + diag_log text format ["%6,%1,%2,%3,%4,%5,%8,%7", _c, _m, _k, _gC, _skip, _ammo, [_ammoConfig, true] call BIS_fnc_returnParents, _shouldFrag]; + } else { + diag_log text format ["Ammo [%1] MISSING frag configs:", _ammo]; + diag_log text format ["_c=%1,_m=%2,_k=%3,_gC=%4,_skip=%5,_fragTypes=%6", _c, _m, _k, _gC, _skip, _fragTypes]; + }; }; }; }; -} forEach _allMagsConfigs; +} forEach _allAmmoConfigs; -diag_log text format ["~~~~~~~~~~~~~End [%1-%2]~~~~~~~~~~~~~", count _allMagsConfigs, count _processedCfgAmmos]; +diag_log text format ["~~~~~~~~~~~~~~End [%1-%2]~~~~~~~~~~~~~~", count _allAmmoConfigs, _processedCfgAmmos]; +diag_log text format ["~~~~~~~~~~~~~~Printed: %1~~~~~~~~~~~", _printCount]; diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf new file mode 100644 index 00000000000..8b027e1f3ca --- /dev/null +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -0,0 +1,45 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * This function draws all development traces and is intended to be called on each frame. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_dev_drawTrace + * + * Public: No + */ + +#define HITBOX_DRAW_PATH [[3, 2, 1, 5, 6, 7, 3, 0, 4, 5], [0, 1], [2, 6], [7, 4]] + +if (!GVAR(debugOptions)) exitWith {}; + +{ + _y params ["_posArray", "_color"]; + if (count _posArray > 1) then { + for "_j" from 1 to count _posArray - 1 do { + drawLine3D [_posArray#(_j - 1), _posArray#_j, _color]; + }; + }; +} forEach GVAR(dev_trackLines); + +if (GVAR(drawHitBox)) then { + { + _y params ["_object", "_boxPoints", "_color"]; + if (!alive _object) then { + GVAR(dev_hitBoxes) deleteAt _x; + continue; + }; + + { + for "_i" from 1 to count _x - 1 do { + drawLine3D [_object modelToWorld (_boxPoints#(_x#_i)), _object modelToWorld (_boxPoints#(_x#(_i - 1))), _color]; + }; + } forEach HITBOX_DRAW_PATH; + } forEach GVAR(dev_hitBoxes); +}; diff --git a/addons/frag/functions/fnc_dev_drawTraces.sqf b/addons/frag/functions/fnc_dev_drawTraces.sqf deleted file mode 100644 index 7fcca3c48fe..00000000000 --- a/addons/frag/functions/fnc_dev_drawTraces.sqf +++ /dev/null @@ -1,37 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_dev_drawTraces - * - * Public: No - */ - -{ - _x params ["", "", "", "", "_positions", "_color"]; - private _index = 0; - private _max = count _positions; - // private _lastSpd = []; - private _lastPos = []; - while {_index < _max} do { - _data1 = _positions select _index; - _data2 = _positions select ([_index + ACE_TRACE_DRAW_INC, _max - 1] select (_index + ACE_TRACE_DRAW_INC >= _max)); - - _pos1 = _data1 select 0; - _pos2 = _data2 select 0; - ADD(_index,ACE_TRACE_DRAW_INC); - - drawLine3D [_pos1, _pos2, _color]; - _lastPos = _pos2; - // _lastSpd = _data1 select 1; - }; - // drawIcon3D ["", [1,0,0,1], _lastPos, 0, 0, 0, format ["%1m/s", _lastSpd], 1, 0.05, "RobotoCondensed"]; -} forEach GVAR(traces); diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf new file mode 100644 index 00000000000..88be643c258 --- /dev/null +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -0,0 +1,56 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger, based on fnc_dev_debugAmmo by "ACE-Team" + * Dumps all ammo types to see if there's any reason to spawn fragments given hit power and distance. + * Good for grasping the values used in shouldFrag to cull non-fragmenting rounds. + * + * Arguments: + * 0: Display rounds that will never frag (default: false) + * + * Return Value: + * None + * + * Example: + * false call ace_frag_fnc_dev_fragCalcDump + * + * Public: No + */ + +params [["_logAll", false, [false]]]; + +private _allAmmoConfigs = configProperties [configFile >> "CfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true]; +private _processedCfgAmmos = createHashMap; + +private _numberPrinted = 0; + +diag_log text "//****************** fragCalcDump Beg ******************//"; +{ // Begin _allAmmoConfigs forEach + private _ammo = configName _x; + + if (_ammo isEqualTo "" || {_ammo in _processedCfgAmmos}) then { + continue; + }; + + _ammo call FUNC(shouldFrag) params ["_shouldFrag"]; + if (_shouldFrag || _logAll) then { + private _fragInfo = _ammo call FUNC(getFragInfo); + _fragInfo params ["_fragRange", "_fragMaxSpeed"]; + private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; + private _indirectHitRange = getNumber (_ammoConfig >> "indirectHitRange"); + private _indirectHit = getNumber (_ammoConfig >> "indirectHit"); + private _fragPowerSpeedRange = [0.5, 1] vectorMultiply _fragMaxSpeed; + + diag_log text format ["Ammo type: %1 | Should frag: %2", _ammo, _shouldFrag]; + diag_log text format [" Indirect hit range: %1", _indirectHitRange]; + diag_log text format [" Indirect hit: %1", _indirectHit]; + diag_log text format [" Max frag speed: %1", _fragMaxSpeed]; + diag_log text format [" Frag range: %1", _fragRange]; + diag_log text format [" Frag speed range: %1", _fragPowerSpeedRange]; + INC(_numberPrinted); + }; + + _processedCfgAmmos set [_ammo, 1]; +} forEach _allAmmoConfigs; + +diag_log text "//****************** fragCalcDump End ******************//"; +diag_log text format ["//********************** printed %1 *********************//", _numberPrinted]; diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf new file mode 100644 index 00000000000..31a1393991e --- /dev/null +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * Add a colored sphere at a specified point. + * + * Arguments: + * 0: Position (posASL) to add sphere + * 1: Color of sphere (default: "blue") + * + * Return Value: + * The created sphere object + * + * Example: + * [getPosASL player, "red"] call ace_frag_fnc_dev_sphereDraw + * + * Public: No + */ + +params ["_posASL", ["_color", "blue"]]; + +if (!isServer) exitWith {}; + +if (_color select [0,1] != "(") then { + _color = switch (toLowerANSI _color) do { + case "blue": {"(0,0,0.8,0.5)"}; + case "black": {"(1,1,1,0.5)"}; + case "white": {"(0,0,0,0.5)"}; + case "red": {"(0.8,0,0,0.5)"}; + case "green": {"(0,0.8,0,0.5)"}; + case "yellow": {"(0.8,0.8,0,0.5)"}; + case "orange": {"(0.8,0.518,0,0.5)"}; + default {"(0.8,0.8,0,0.5)"}; + }; +}; +private _colorString = "#(argb,8,8,3)color" + _color; + +private _sphere = createVehicle ["Sign_Sphere10cm_F", ASLToATL _posASL, [], 0, "CAN_COLLIDE"]; +_sphere setObjectTextureGlobal [0, _colorString]; +GVAR(dev_eventSpheres) pushBack _sphere; + +_sphere // return diff --git a/addons/frag/functions/fnc_dev_startTracing.sqf b/addons/frag/functions/fnc_dev_startTracing.sqf deleted file mode 100644 index 897dde3011e..00000000000 --- a/addons/frag/functions/fnc_dev_startTracing.sqf +++ /dev/null @@ -1,23 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_dev_startTracing - * - * Public: No - */ - -if (GVAR(tracesStarted)) exitWith {}; - -INFO("Starting Trace Drawing"); - -GVAR(tracesStarted) = true; -GVAR(traceID) = [LINKFUNC(dev_drawTraces), 0, []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/frag/functions/fnc_dev_stopTracing.sqf b/addons/frag/functions/fnc_dev_stopTracing.sqf deleted file mode 100644 index 949d3cd55d6..00000000000 --- a/addons/frag/functions/fnc_dev_stopTracing.sqf +++ /dev/null @@ -1,23 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * Dev things - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * None - * - * Public: No - */ - -if (!GVAR(tracesStarted)) exitWith {}; - -INFO("Ending Trace Drawing"); - -GVAR(tracesStarted) = false; -[GVAR(traceID)] call CBA_fnc_removePerFrameHandler; diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf new file mode 100644 index 00000000000..327e45cf0d3 --- /dev/null +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -0,0 +1,75 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * Add a hit box outline to an object. + * + * Arguments: + * 0: Object that should have it's hit box drawn (default: objNull) + * 1: Add sphere at object origin (default: true) + * + * Return Value: + * None + * + * Example: + * player call ace_frag_fnc_dev_trackHitBox + * + * Public: No + */ + +params [ + ["_object", objNull], + ["_addSphere", true] +]; +TRACE_2("Adding hitbox",_object,_addSphere); + +if (isNull _object) exitWith {}; + +// Grab the right hitBox +private _boundingBox = []; +if (_object isKindOf "CAManBase") then { + if (isNull objectParent _object) then { + _boundingBox = 0 boundingBox _object; + } else { + _boundingBox = boundingBoxReal [_object, "Geometry"]; + }; +} else { + _boundingBox = boundingBoxReal [_object, "FireGeometry"]; +}; +_boundingBox params ["_lowerPoint", "_upperPoint"]; + +// adjust with stance +switch (stance _object) do { + case "STAND": {_upperPoint set [2, 1.9];}; + case "CROUCH": {_upperPoint set [2, 1.3];}; + case "PRONE": {_upperPoint set [2, 0.8];}; +}; +private _centerPoint = ASLToAGL getPosASL _object; + +if (GVAR(dbgSphere) && _addSphere && {isNull objectParent _object}) then { + private _centerSphere = [getPosASL _object, "yellow"] call FUNC(dev_sphereDraw); + _centerSphere attachTo [_object, _object worldToModel _centerPoint]; +}; + +// create an optimized outline +_upperPoint params ["_x1","_y1","_z1"]; +_lowerPoint params ["_x2","_y2","_z2"]; +private _p1 = _upperPoint; +private _p7 = _lowerPoint; +private _points = [ + _upperPoint, + [_x1, _y2, _z1], + [_x2, _y2, _z1], + [_x2, _y1, _z1], + [_x1, _y1, _z2], + [_x1, _y2, _z2], + _lowerPoint, + [_x2, _y1, _z2] +]; + +private _color = switch (side _object) do { + case east: {[0.8, 0, 0, 1]}; + case resistance: {[0, 0.8, 0, 1]}; + default {[0, 0, 0.8, 1]}; +}; + +GVAR(dev_hitBoxes) set [getObjectID _object, [_object, _points, _color]]; diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf new file mode 100644 index 00000000000..88b298fa0b8 --- /dev/null +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -0,0 +1,87 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * This function adds an object to have its course tracked (every frame). + * + * Arguments: + * 0: Object to draw track (default: objNull) + * 1: Color of trace (default: "blue") + * 2: Whether the object is a projectile or whether to add projectile EHs (default: false) + * + * Return Value: + * None + * + * Example: + * player call ace_frag_fnc_dev_trackObj + * + * Public: No + */ + +params [ + ["_object", objNull], + ["_color", "blue"], + ["_isProj", false] +]; +TRACE_3("devDraw",_object,_color,_isProj); + +// pick color and add it to the array +private _colorArray = switch (toLowerANSI _color) do { + case "purple": {[0.8, 0, 0.8, 1]}; + case "blue": {[0, 0, 0.8, 1]}; + case "green": {[0, 0.8, 0, 1]}; + case "orange": {[0.8, 0.518, 0, 1]}; + case "yellow": {[0.8, 0.8, 0, 1]}; + case "red": {[0.8, 0, 0, 1]}; + case "black": {[1, 1, 1, 1]}; + case "white": {[0, 0, 0, 1]}; + default {[0, 0.8, 0.8, 1]}; +}; +GVAR(dev_trackLines) set [getObjectID _object, [[getPosATL _object], _colorArray]]; + +// event handler to track round and cleanup when round is "dead" +[{ + if (isGamePaused || accTime == 0) exitWith {}; + params ["_object", "_handle"]; + + if (!alive _object) exitWith { + _handle call CBA_fnc_removePerFrameHandler; + }; + + private _objectArray = GVAR(dev_trackLines) get (getObjectID _object); + + if (isNil "_objectArray") exitWith { + _handle call CBA_fnc_removePerFrameHandler; + }; + + (_objectArray#0) pushBack getPosATL _object; +}, 0, _object] call CBA_fnc_addPerFrameHandler; + +// Projectile event handlers that add spheres and points for more accurate round tracking +if (!_isProj) exitWith {}; + +_object addEventHandler ["HitPart", { + params ["_projectile", "", "", "_posASL"]; + private _posArr = (GVAR(dev_trackLines) get (getObjectID _projectile))#0; + _posArr pushBack ASLToATL _posASL; + if (GVAR(dbgSphere)) then { + [_posASL, "green"] call FUNC(dev_sphereDraw); + }; +}]; + +_object addEventHandler ["Explode", { + params ["_projectile", "_posASL"]; + private _posArr = (GVAR(dev_trackLines) get (getObjectID _projectile))#0; + _posArr pushBack ASLToATL _posASL; + if (GVAR(dbgSphere)) then { + [_posASL, "red"] call FUNC(dev_sphereDraw); + }; +}]; + +_object addEventHandler ["Deflected", { + params ["_projectile", "_posASL"]; + private _posArr = (GVAR(dev_trackLines) get (getObjectID _projectile))#0; + _posArr pushBack ASLToATL _posASL; + if (GVAR(dbgSphere)) then { + [_posASL, "blue"] call FUNC(dev_sphereDraw); + }; +}]; diff --git a/addons/frag/functions/fnc_dev_trackTrace.sqf b/addons/frag/functions/fnc_dev_trackTrace.sqf deleted file mode 100644 index 6c010bdb631..00000000000 --- a/addons/frag/functions/fnc_dev_trackTrace.sqf +++ /dev/null @@ -1,27 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * Dev things - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_dev_trackTrace - * - * Public: No - */ - -params ["_args", "_pfhID"]; -_args params ["_tracerObj", "_index"]; - -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)]; -} else { - [_pfhID] call CBA_fnc_removePerFrameHandler; -}; diff --git a/addons/frag/functions/fnc_doExplosions.sqf b/addons/frag/functions/fnc_doExplosions.sqf index a5a687aa538..74e191532a5 100644 --- a/addons/frag/functions/fnc_doExplosions.sqf +++ b/addons/frag/functions/fnc_doExplosions.sqf @@ -21,7 +21,7 @@ _args params ["_explosions", "_index"]; for "_i" from _index to ((_index + 2) min (count _explosions)) do { private _exp = _explosions select _i; _exp params ["_refExp", "_bpos", "_hit", "_distance", "_indirectHitRange", "_depth"]; - _refExp createVehicle (ASLtoATL _bpos); + _refExp createVehicle (ASLToATL _bpos); // if (_hit >= 150 && _distance > _indirectHitRange) then { // [_bpos, _refExp, _depth] call FUNC(doReflections); // }; diff --git a/addons/frag/functions/fnc_doReflections.sqf b/addons/frag/functions/fnc_doReflections.sqf index 023a283e81b..70c7471181a 100644 --- a/addons/frag/functions/fnc_doReflections.sqf +++ b/addons/frag/functions/fnc_doReflections.sqf @@ -22,5 +22,5 @@ if (_depth <= 2) then { private _indirectHitRange = getNumber(configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"); private _indirectHit = getNumber(configFile >> "CfgAmmo" >> _ammo >> "indirectHit"); private _testParams = [_pos, [_indirectHitRange, _indirectHit], [], [], -4, _depth, 0]; - [DFUNC(findReflections), 0, _testParams] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(findReflections), 0, _testParams] call CBA_fnc_addPerFrameHandler; }; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf deleted file mode 100644 index 8b5a06d812d..00000000000 --- a/addons/frag/functions/fnc_doSpall.sqf +++ /dev/null @@ -1,139 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * Dev things - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_doSpall - * - * Public: No - */ - -#define WEIGHTED_SIZE [QGVAR(spall_small), 4, QGVAR(spall_medium), 3, QGVAR(spall_large), 2, QGVAR(spall_huge), 1] - -params ["_hitData", "_hitPartDataIndex"]; -private _initialData = GVAR(spallHPData) select (_hitData select 0); -_initialData params ["_hpId", "_object", "_roundType", "_round", "_curPos", "_velocity"]; - -private _hpData = (_hitData select 1) select _hitPartDataIndex; -private _objectHit = _hpData param [0, objNull]; -TRACE_1("",_objectHit); -if ((isNil "_objectHit") || {isNull _objectHit}) exitWith {WARNING_1("Problem with hitPart data - bad object [%1]",_objectHit);}; -_objectHit removeEventHandler ["hitPart", _hpId]; - -private _caliber = getNumber (configFile >> "CfgAmmo" >> _roundType >> "caliber"); -private _explosive = getNumber (configFile >> "CfgAmmo" >> _roundType >> "explosive"); -private _idh = getNumber (configFile >> "CfgAmmo" >> _roundType >> "indirectHitRange"); - -if !(_caliber >= 2.5 || {(_explosive > 0 && {_idh >= 1})}) exitWith {}; -// ACE_player sideChat format ["BBBB"]; -private _exit = false; -private _vm = 1; - -private _oldVelocity = vectorMagnitude _velocity; -private _curVelocity = vectorMagnitude (velocity _round); - -if (alive _round) then { - private _diff = _velocity vectorDiff (velocity _round); - private _polar = _diff call CBA_fnc_vect2polar; - // ACE_player sideChat format ["polar: %1", _polar]; - if (abs (_polar select 1) > 45 || {abs (_polar select 2) > 45}) then { - if (_caliber < 2.5) then { - // ACE_player sideChat format ["exit!"]; - _exit = true; - } else { - SUB(_vm,_curVelocity / _oldVelocity); - }; - }; -}; -if (_exit) exitWith {}; - -private _unitDir = vectorNormalized _velocity; -private _pos = _hpData select 3; -private _spallPos = []; -if ((isNil "_pos") || {!(_pos isEqualTypeArray [0,0,0])}) exitWith {WARNING_1("Problem with hitPart data - bad pos [%1]",_pos);}; -for "_i" from 0 to 100 do { - private _pos1 = _pos vectorAdd (_unitDir vectorMultiply (0.01 * _i)); - private _pos2 = _pos vectorAdd (_unitDir vectorMultiply (0.01 * (_i + 1))); - // _data = [nil, nil, nil, 1, [[ASLtoATL _pos1, 1], [ASLtoATL _pos2, 1]]]; - // NOU_TRACES pushBack _data; - - if (!lineIntersects [_pos1, _pos2]) exitWith { - // ACE_player sideChat format ["FOUND!"]; - _spallPos = _pos2; - }; -}; -if (_spallPos isEqualTo []) exitWith {}; -private _spallPolar = _velocity call CBA_fnc_vect2polar; - -if (_explosive > 0) then { - // ACE_player sideChat format ["EXPLOSIVE!"]; - private _warn = false; - private _c = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(CHARGE)); - if (_c == 0) then {_c = 1; _warn = true;}; - private _m = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(METAL)); - if (_m == 0) then {_m = 2; _warn = true;}; - private _k = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(GURNEY_K)); - if (_k == 0) then {_k = 1 / 2; _warn = true;}; - private _gC = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(GURNEY_C)); - if (_gC == 0) then {_gC = 2440; _warn = true;}; - - // if (_warn) then { - // WARNING_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_roundType); //TODO: turn this off when we get closer to release - // }; - - private _fragPower = (((_m / _c) + _k) ^ - (1 / 2)) * _gC; - _spallPolar set [0, _fragPower * 0.66]; -}; - -// diag_log text format ["SPALL POWER: %1", _spallPolar select 0]; -private _spread = 15 + (random 25); -private _spallCount = 5 + (random 10); -TRACE_1("",_spallCount); -for "_i" from 1 to _spallCount do { - private _elev = ((_spallPolar select 2) - _spread) + (random (_spread * 2)); - private _dir = ((_spallPolar select 1) - _spread) + (random (_spread * 2)); - if (abs _elev > 90) then { - ADD(_dir,180); - }; - _dir = _dir % 360; - private _vel = (_spallPolar select 0) * 0.33 * _vm; - _vel = (_vel - (_vel * 0.25)) + (random (_vel * 0.5)); - - private _spallFragVect = [_vel, _dir, _elev] call CBA_fnc_polar2vect; - private _fragment = (selectRandomWeighted WEIGHTED_SIZE) createVehicleLocal [0,0,10000]; - _fragment setPosASL _spallPos; - _fragment setVelocity _spallFragVect; - - #ifdef DRAW_FRAG_INFO - [ACE_player, _fragment, [1, 0.5, 0, 1]] call FUNC(dev_addTrack); - #endif -}; - -_spread = 5 + (random 5); -_spallCount = 3 + (random 5); -for "_i" from 1 to _spallCount do { - private _elev = ((_spallPolar select 2) - _spread) + (random (_spread * 2)); - private _dir = ((_spallPolar select 1) - _spread) + (random (_spread * 2)); - if (abs _elev > 90) then { - ADD(_dir,180); - }; - _dir = _dir % 360; - private _vel = (_spallPolar select 0) * 0.55 * _vm; - _vel = (_vel - (_vel * 0.25)) + (random (_vel * 0.5)); - - private _spallFragVect = [_vel, _dir, _elev] call CBA_fnc_polar2vect; - private _fragment = (selectRandomWeighted WEIGHTED_SIZE) createVehicleLocal [0, 0, 10000]; - _fragment setPosASL _spallPos; - _fragment setVelocity _spallFragVect; - - #ifdef DRAW_FRAG_INFO - [ACE_player, _fragment, [1, 0, 0, 1]] call FUNC(dev_addTrack); - #endif -}; diff --git a/addons/frag/functions/fnc_doSpallHitPart.sqf b/addons/frag/functions/fnc_doSpallHitPart.sqf new file mode 100644 index 00000000000..dc22c66a63c --- /dev/null +++ b/addons/frag/functions/fnc_doSpallHitPart.sqf @@ -0,0 +1,133 @@ +#include "..\script_component.hpp" +/* + * Author: Jaynus, NouberNou, Lambda.Tiger, + * This function creates spalling when a projectile hits a object and comes to a stop. + * + * Arguments: + * 0: The projectile that may generate spalling + * 1: The object the projectile hit + * 2: The position (ASL) of the projectile hit + * 3: The velocity of the projectile before it hit the surface + * 4: The surface normal of the surface hit + * 5: The name of the config name or path to bisurf of the surface hit + * 6: The projectiles ammo config + * 7: The projectiles shot parent + * 8: The "up" vector of the projectile when it hit the object + * + * Return Value: + * None + * + * Example: + * [BIS_HITPART_EH_ARGS] call ace_frag_fnc_doSpallHitPart; + * + * Public: No + */ +TRACE_1("doSpallHitPart",_this); +if (CBA_missionTime < GVAR(nextSpallAllowTime)) exitWith { + TRACE_2("timeExit",CBA_missionTime,GVAR(nextSpallAllowTime)); +}; +params ["_projectile", "_objectHit", "_lastPosASL", "_lastVelocity", "_surfaceNorm", "_surfaceType", "_ammo", "_vectorUp"]; + +// Find spall speed / fragment info +_ammo call FUNC(getSpallInfo) params ["_caliber", "_explosive", "_indirectHit"]; +// Add in v2.18 `getShotInfo`'s `fuseDistanceLeft <= 0` to _explosive +if ((alive _projectile && _explosive < 0.5) || + _ammo == "" || + _lastPosASL isEqualTo [0,0,0] || + {_objectHit isKindOf "CAManBase"}) exitWith { + TRACE_3("exitEarly",alive _projectile,_lastPosASL,_objectHit); +}; + +private _material = _surfaceType call FUNC(getMaterialInfo); +if (_material == "ground") exitWith { + TRACE_1("hitGround",_surfaceType); +}; + +private _speedChange = vectorMagnitude _lastVelocity; +/* + * This is all fudge factor since real spalling is too complex for calculation. + * There are two terms. The first is from round impact, taking a quasi scale + * of caliber coefficient * round caliber * srqt(change in speed). The second term is + * explosive * indirect hit, for any explosive contribution + */ +private _spallPower = (ACE_FRAG_SPALL_CALIBER_COEF * _caliber * sqrt _speedChange + _explosive * _indirectHit) * GVAR(spallIntensity); +TRACE_3("found speed",_speedChange,_caliber,_spallPower); + +if (_spallPower < ACE_FRAG_SPALL_POWER_MIN) exitWith { + TRACE_1("lowImpulse",_ammo); +}; + +private _lastVelocityNorm = vectorNormalized _lastVelocity; +private _deltaStep = _lastVelocityNorm vectorMultiply 0.05; + +if (terrainIntersectASL [_lastPosASL vectorAdd _deltaStep, _lastPosASL]) exitWith { + TRACE_2("terrainIntersect",_lastPosASL,_deltaStep); +}; + +#ifdef DEBUG_MODE_DRAW +if GVAR(dbgSphere) then { + [_lastPosASL vectorAdd _lastVelocityNorm, "orange"] call FUNC(dev_sphereDraw); + [_lastPosASL, "yellow"] call FUNC(dev_sphereDraw); +}; +#endif + +/* + * Improve performance of finding otherside of object on shallow angle + * impacts. 120 degrees due to 90 degree offset with _lastVelocityNorm into object. + */ +private _spallPosASL = _lastPosASL vectorAdd _deltaStep; +if (120 > acos (_lastVelocityNorm vectorDotProduct _surfaceNorm)) then { + _spallPosASL = _spallPosASL vectorAdd (_deltaStep vectorMultiply 5); +}; +private _lastSpallPos = _spallPosASL; +// we need to check 1.05 m in the direction of last velocity incrementing by delta step +// Our initial check is from 0m to 5 cm, so we only need to iterate from 2 to 21 to get +// to the full 1.05m +for "_stepNumber" from 2 to 21 do +{ + _spallPosASL = _lastSpallPos vectorAdd _deltaStep; + if (!lineIntersects [_lastSpallPos, _spallPosASL]) exitWith { + _spallPosASL = _lastSpallPos vectorAdd _deltaStep; + }; + _lastSpallPos = _spallPosASL; +}; + +if (_spallPosASL isEqualTo _lastSpallPos) exitWith { + TRACE_2("insideObj",_lastPosASL,_spallPosASL); +}; + +#ifdef DEBUG_MODE_DRAW +if GVAR(dbgSphere) then { + [_spallPosASL, "green"] call FUNC(dev_sphereDraw); +}; +#endif + +private _spawnSize = switch (true) do { + case (_spallPower < ACE_FRAG_SPALL_POWER_TINY_MAX): {"_spall_tiny"}; + case (_spallPower < ACE_FRAG_SPALL_POWER_SMALL_MAX): {"_spall_small"}; + case (_spallPower < ACE_FRAG_SPALL_POWER_MEDIUM_MAX): {"_spall_medium"}; + case (_spallPower < ACE_FRAG_SPALL_POWER_LARGE_MAX): {"_spall_large"}; + default {"_spall_huge"}; +}; +GVAR(nextSpallAllowTime) = CBA_missionTime + ACE_FRAG_SPALL_HOLDOFF; + +private _spallSpawner = createVehicleLocal [ + QUOTE(GLUE(ADDON,_)) + _material + _spawnSize, + ASLToAGL _spallPosASL, + [], + 0, + "CAN_COLLIDE" +]; +_spallSpawner setVectorDirAndUp [_lastVelocityNorm, _vectorUp]; +_spallSpawner setVelocityModelSpace [0, _speedChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF, 0]; + +TRACE_3("createSpallSpawner",speed _spallSpawner,_material + _spawnSize,_spallPower); +#ifdef DEBUG_MODE_DRAW +_spallSpawner addEventHandler [ + "SubmunitionCreated", + { + params ["", "_subProj"]; + [_subProj, "purple", true] call FUNC(dev_trackObj); + } +]; +#endif diff --git a/addons/frag/functions/fnc_doSpallPenetrate.sqf b/addons/frag/functions/fnc_doSpallPenetrate.sqf new file mode 100644 index 00000000000..6c8feda7a9d --- /dev/null +++ b/addons/frag/functions/fnc_doSpallPenetrate.sqf @@ -0,0 +1,98 @@ +#include "..\script_component.hpp" +/* + * Author: Jaynus, NouberNou, Lambda.Tiger, + * This function creates spalling if a projectile penetrated a surface and was slowed down enough proportional to the caliber. + * It is dissimilar in function from fnc_doSpallHitPart, but leveraging the "Penetrated" projectile EH to process faster. + * + * Arguments: + * Arguments are the same as BI's "Penetratred" EH: + * https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#Penetrated + * + * Return Value: + * None + * + * Example: + * [BIS_PENETRATED_EH_ARGS] call ace_frag_fnc_doSpallPenetrate; + * + * Public: No + */ +#define EPSILON 0.1 + +TRACE_1("doSpallPenetration",_this); +if (CBA_missionTime < GVAR(nextSpallAllowTime)) exitWith { + TRACE_1("timeExit",_this); +}; +params ["_projectile", "_hitObject", "_surfaceType", "", "_spallPosASL", "_newVelocity"]; + +private _ammo = typeOf _projectile; +if (_spallPosASL isEqualTo [0,0,0] || + {_ammo isEqualTo ""} || + {_hitObject isKindOf "CAManBase"}) exitWith { + TRACE_4("time/invalidHit",CBA_missionTime,GVAR(nextSpallAllowTime),_hitObject,_spallPosASL); +}; + +private _material = _surfaceType call FUNC(getMaterialInfo); +if (_material == "ground") exitWith { + #ifdef DEBUG_MODE_FULL + systemChat "ground spall"; + #endif +}; + +_ammo call FUNC(getSpallInfo) params ["_caliber", "_explosive", "_indirectHit"]; +private _velocityChange = velocity _projectile vectorDiff _newVelocity; +private _speedChange = vectorMagnitude _velocityChange; +/* + * This is all fudge factor since real spalling is too complex for calculation. + * The equation takes taking a quasi scale of energy using caliber and change in speed. + */ +private _spallPower = ACE_FRAG_SPALL_CALIBER_COEF * _caliber * sqrt _speedChange * GVAR(spallIntensity); +TRACE_5("found speed",_velocityChange,_speedChange,_caliber,_spallPower,_material); + +if (_spallPower < ACE_FRAG_SPALL_POWER_MIN) exitWith { + TRACE_1("lowImpulse",_ammo); +}; +private _spallDirection = vectorNormalized _velocityChange; + +#ifdef DEBUG_MODE_DRAW +if GVAR(dbgSphere) then { + [_spallPosASL, "green"] call FUNC(dev_sphereDraw); +}; +#endif + +private _spawnSize = switch (true) do { + case (_spallPower < ACE_FRAG_SPALL_POWER_TINY_MAX): {"_spall_tiny"}; + case (_spallPower < ACE_FRAG_SPALL_POWER_SMALL_MAX): {"_spall_small"}; + case (_spallPower < ACE_FRAG_SPALL_POWER_MEDIUM_MAX): {"_spall_medium"}; + case (_spallPower < ACE_FRAG_SPALL_POWER_LARGE_MAX): {"_spall_large"}; + default {"_spall_huge"}; +}; +GVAR(nextSpallAllowTime) = CBA_missionTime + ACE_FRAG_SPALL_HOLDOFF; + +// Solve for one of the vectors normal to _spallDirection on y = 0 plane +private _spallVectorUp = [0, 0, 1]; +if (_spallDirection#2 > EPSILON) then { + private _newZ = _spallDirection#0 / _spallDirection#2; + _spallVectorUp = vectorNormalized [1, 0, -_newZ]; +}; + +private _spallSpawner = createVehicleLocal [ + QUOTE(GLUE(ADDON,_)) + _material + _spawnSize, + ASLToAGL _spallPosASL, + [], + 0, + "CAN_COLLIDE" +]; +_spallSpawner setVectorDirAndUp [_spallDirection, _spallVectorUp]; +_spallSpawner setVelocityModelSpace [0, _speedChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF, 0]; +TRACE_4("dir&up",_spallDirection,vectorDir _spallSpawner,_spallVectorUp,vectorUp _spallSpawner); + +TRACE_3("createSpallSpawner",speed _spallSpawner,_material + _spawnSize,_spallPower); +#ifdef DEBUG_MODE_DRAW +_spallSpawner addEventHandler [ + "SubmunitionCreated", + { + params ["", "_subProj"]; + [_subProj, "purple", true] call FUNC(dev_trackObj); + } +]; +#endif diff --git a/addons/frag/functions/fnc_findReflections.sqf b/addons/frag/functions/fnc_findReflections.sqf index b0ae161597d..00a26022e2b 100644 --- a/addons/frag/functions/fnc_findReflections.sqf +++ b/addons/frag/functions/fnc_findReflections.sqf @@ -65,7 +65,7 @@ if (_zIndex < 5) then { while {count _nlos != count _excludes && {_c < (count _nlos)}} do { scopeName "mainSearch"; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { private _index = _buckets pushBack [_x, [_x]]; _excludes pushBack _forEachIndex; _bucketPos = _x; @@ -74,8 +74,8 @@ if (_zIndex < 5) then { }; } forEach _nlos; { - if (!(_forEachIndex in _excludes)) then { - _testPos = _x; + if !(_forEachIndex in _excludes) then { + private _testPos = _x; if (_testPos vectorDistanceSqr _bucketPos <= 30) then { _bucketList pushBack _x; _excludes pushBack _forEachIndex; @@ -120,7 +120,7 @@ if (_zIndex < 5) then { // _dirvec = _pos vectorFromTo ((player modelToWorldVisualWorld (player selectionPosition "Spine3"))); // _dirvec = _dirvec vectorMultiply 100; // _can setVelocity _dirvec; - [DFUNC(doExplosions), 0, [_explosions, 0]] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(doExplosions), 0, [_explosions, 0]] call CBA_fnc_addPerFrameHandler; [_pfhID] call CBA_fnc_removePerFrameHandler; }; END_COUNTER(fnc_findReflections); diff --git a/addons/frag/functions/fnc_fired.sqf b/addons/frag/functions/fnc_fired.sqf index 7ea4212d9a1..1cc72af2af6 100644 --- a/addons/frag/functions/fnc_fired.sqf +++ b/addons/frag/functions/fnc_fired.sqf @@ -1,14 +1,14 @@ #include "..\script_component.hpp" /* - * Author: nou, jaynus, PabstMirror - * Called from the unified fired EH for all. - * If spall is not enabled (default), then cache and only track those that will actually trigger fragmentation. + * Author: nou, jaynus, Lambda.Tiger, PabstMirror + * Add "Exploded" eventhandler to a projectile if it will produce fragments + * and a "HitPart" eventhandler if it will produce spall. * * Arguments: - * None. Parameters inherited from EFUNC(common,firedEH) + * Parameters inherited from EFUNC(common,firedEH) * * Return Value: - * None + * Nothing Useful * * Example: * [clientFiredBIS-XEH] call ace_frag_fnc_fired @@ -19,40 +19,33 @@ //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); -private _shouldAdd = GVAR(cacheRoundsTypesToTrack) getVariable _ammo; -if (isNil "_shouldAdd") then { - TRACE_1("no cache for round",_ammo); - - //Read configs and test if it would actually cause a frag, using same logic as FUNC(pfhRound) - private _skip = getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(skip)); - private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); - private _indirectRange = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"); - private _force = getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(force)); - private _fragPower = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirecthit") * (sqrt (getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"))); - - _shouldAdd = (_skip == 0) && {(_force == 1) || {_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}}}; +if (_ammo isEqualTo "" || {isNull _projectile} || + !(if (isNil "_gunner") then {local _unit} else {local _gunner}) || + {_projectile getVariable [QGVAR(blacklisted), false]}) exitWith { + TRACE_2("bad ammo or projectile, or blackList",_ammo,_projectile); +}; - if (GVAR(spallEnabled) && {!_shouldAdd}) then { - private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber"); - if !(_caliber >= 2.5 || {(_explosive > 0 && {_indirectRange >= 1})}) exitWith {}; // from check in doSpall: line 34 - TRACE_1("Won't frag, but will spall",_caliber); - _shouldAdd = true; - }; +#ifdef DEBUG_MODE_DRAW +if (GVAR(debugOptions) && {_ammo call FUNC(shouldFrag) || {_ammo call FUNC(shouldSpall)}}) then { + [_projectile, "red", true] call FUNC(dev_trackObj); +}; +#endif - TRACE_6("Setting Cache",_skip,_explosive,_indirectRange,_force,_fragPower,_shouldAdd); - GVAR(cacheRoundsTypesToTrack) setVariable [_ammo, _shouldAdd]; +if (!GVAR(spallEnabled) || {!(_ammo call FUNC(shouldSpall))}) exitWith { + TRACE_2("No spall",GVAR(spallEnabled),_ammo call FUNC(shouldSpall)); }; -if (_shouldAdd) then { - // firedMan will have nil "_gunner", so just check _unit; for firedVehicle we want to check _gunner - private _localShooter = if (isNil "_gunner") then {local _unit} else {local _gunner}; - TRACE_4("",_localShooter,_unit,_ammo,_projectile); - if (!_localShooter) exitWith {}; - if (_weapon == "Put") exitWith {}; // Ignore explosives placed without ace_explosives +private _hitPartEventHandler = _projectile addEventHandler ["HitPart", { + params ["_projectile", "_objectHit", "", "_posASL", "_velocity", "_surfNorm", "", "" ,"_surfType"]; + private _ammo = typeOf _projectile; + private _vectorUp = vectorUp _projectile; - // Skip if less than 0.5 second from last shot - if ((CBA_missionTime - (_unit getVariable [QGVAR(lastTrack), -1])) < 0.5) exitWith {}; - _unit setVariable [QGVAR(lastTrack), CBA_missionTime]; + /* + * Wait a frame to see what happens to the round + */ + [LINKFUNC(doSpallHitPart), [_projectile, _objectHit, _posASL, _velocity, _surfNorm, _surfType, _ammo, _vectorUp]] call CBA_fnc_execNextFrame; +}]; +private _penetratedEventHandler = _projectile addEventHandler ["Penetrated",LINKFUNC(doSpallPenetrate)]; +_projectile setVariable [QGVAR(hitPartEventHandler), [_hitPartEventHandler, _penetratedEventHandler]]; - [_unit, _ammo, _projectile] call FUNC(addPfhRound); -}; +TRACE_1("firedExit",_ammo); diff --git a/addons/frag/functions/fnc_frago.sqf b/addons/frag/functions/fnc_frago.sqf index 87fabc4fc55..bda1aa58f6d 100644 --- a/addons/frag/functions/fnc_frago.sqf +++ b/addons/frag/functions/fnc_frago.sqf @@ -1,15 +1,15 @@ #include "..\script_component.hpp" /* - * Author: Jaynus, NouberNou + * Author: Jaynus, NouberNou, Lambda.Tiger * Server func to create the fragmentation for a round. * * Arguments: - * 0: Last Position (ASL) - * 1: Velocity - * 2: Ammo Classname + * 0: ASL position projetile is fragmenting at + * 1: Projectile ammo classname + * 2: Projectile shot parents * * Return Value: - * None + * The number of fragments created * * Example: * [[], [], "handGrenade"] call ace_frag_fnc_frago @@ -17,139 +17,109 @@ * Public: No */ -#define FRAG_VEC_VAR 0.004 -#define MAX_FRAG_COUNT 50 +#define FRAG_VEC_VAR 0.008 BEGIN_COUNTER(frago); -params ["_lastPos", "_lastVel", "_shellType"]; -TRACE_3("frago",_lastPos,_lastVel,_shellType); +params ["_fragPosASL", "_shellType", "_shotParents"]; +TRACE_3("frago",_fragPosASL,_shellType,_shotParents); // Limit max frag count if there was a recent frag -private _maxFrags = round (MAX_FRAG_COUNT * linearConversion [0.1, 1.5, (CBA_missionTime - GVAR(lastFragTime)), 0.1, 1, true]); +private _maxFrags = round linearConversion [ + ACE_FRAG_COUNT_MIN_TIME, + ACE_FRAG_COUNT_MAX_TIME, + (CBA_missionTime - GVAR(lastFragTime)), + ACE_FRAG_COUNT_MIN, + ACE_FRAG_COUNT_MAX, + true +]; TRACE_2("",_maxFrags,CBA_missionTime - GVAR(lastFragTime)); GVAR(lastFragTime) = CBA_missionTime; -private _fragTypes = [ - QGVAR(tiny), QGVAR(tiny), QGVAR(tiny), - QGVAR(tiny_HD), QGVAR(tiny_HD), QGVAR(tiny_HD), - QGVAR(small), QGVAR(small), QGVAR(small), QGVAR(small), - QGVAR(small_HD), QGVAR(small_HD), QGVAR(small_HD), QGVAR(small_HD), - QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD) -]; - -private _warn = false; -if (isArray (configFile >> "CfgAmmo" >> _shellType >> QGVAR(CLASSES))) then { - _fragTypes = getArray (configFile >> "CfgAmmo" >> _shellType >> QGVAR(CLASSES)); -} else { - _warn = true; -}; +_shellType call FUNC(getFragInfo) params ["_fragRange", "_fragVelocity", "_fragTypes", "_metalMassModifier"]; -private _indirectHitRange = getNumber(configFile >> "CfgAmmo" >> _shellType >> "indirecthitrange"); -private _fragRange = 20 * _indirectHitRange * 4; -// _c = 185; // grams of comp-b -// _m = 210; // grams of fragmentating metal -// _k = 3/5; // spherical K factor -// _gC = 2843; // Gurney constant of comp-b in /ms - -// _c = 429; // grams of tritonal -// _m = 496; // grams of fragmentating metal -// _k = 1/2; // spherical K factor -// _gC = 2320; // Gurney constant of tritonal in /ms - -private _c = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(CHARGE)); -if (_c == 0) then {_c = 1; _warn = true;}; -private _m = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(METAL)); -if (_m == 0) then {_m = 2; _warn = true;}; -private _k = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(GURNEY_K)); -if (_k == 0) then {_k = 0.5; _warn = true;}; -private _gC = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(GURNEY_C)); -if (_gC == 0) then {_gC = 2440; _warn = true;}; - -if (_warn) then { - INFO_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_shellType); +private _fragPosAGL = ASLToAGL _fragPosASL; +TRACE_5("fragValues",_fragPosASL,_fragPosAGL,_fragRange,_fragVelocity,_metalMassModifier); +// Post 2.18 change - uncomment line 43, modify lines 45, and remove lines 44, 51-57, 64-66 +// private _targets = [ASLToAGL _fragPosAGL, _fragRange, _fragRange, 0, false, _fragRange] nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], false, true, true]; +private _objects = _fragPosAGL nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; +if (_objects isEqualTo []) exitWith { + TRACE_2("No nearby targets",_fragPosAGL,_fragRange); + 0 }; -// Gunery equation is for a non-fragmenting metal, imperical value of 80% represents fragmentation -private _fragPower = 0.8 * (((_m / _c) + _k) ^ - (1 / 2)) * _gC; - -private _atlPos = ASLtoATL _lastPos; - -private _fragPowerRandom = _fragPower * 0.5; -if ((_atlPos select 2) < 0.5) then { - _lastPos vectorAdd [0, 0, 0.5]; -}; - -private _objects = _atlPos nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; -// Add unique crews in faster way +// grab crews and add them in so that targets stay approx. sorted by distance +TRACE_1("",_objects); +private _targets = []; { - { - _objects pushBackUnique _x; - } forEach (crew _x); + private _crew = crew _x; + _crew pushBackUnique _x; + _targets append _crew; } forEach _objects; -TRACE_2("",_fragRange,count _objects); +TRACE_2("",_fragRange,count _targets); private _fragCount = 0; private _fragArcs = []; _fragArcs set [360, 0]; -private _doRandom = true; -if (_objects isNotEqualTo []) then { +if (_targets isNotEqualTo []) then { if (GVAR(reflectionsEnabled)) then { - [_lastPos, _shellType] call FUNC(doReflections); + [_fragPosASL, _shellType] call FUNC(doReflections); }; { private _target = _x; - if (alive _target) then { + if (alive _target && {getNumber ((configOf _target) >> "isPlayableLogic") == 0}) then { (boundingBox _target) params ["_boundingBoxA", "_boundingBoxB"]; private _cubic = ((abs (_boundingBoxA select 0)) + (_boundingBoxB select 0)) * ((abs (_boundingBoxA select 1)) + (_boundingBoxB select 1)) * ((abs (_boundingBoxA select 2)) + (_boundingBoxB select 2)); if (_cubic <= 1) exitWith {}; - // _doRandom = true; private _targetVel = velocity _target; private _targetPos = getPosASL _target; - private _distance = _targetPos vectorDistance _lastPos; - private _add = ((_boundingBoxB select 2) / 2) + ((((_distance - (_fragpower / 8)) max 0) / _fragPower) * 10); + private _distance = _target distance _fragPosAGL; + private _add = ((_boundingBoxB select 2) / 2) + ((((_distance - (_fragVelocity / 8)) max 0) / _fragVelocity) * 10); _targetPos = _targetPos vectorAdd [ - (_targetVel select 0) * (_distance / _fragPower), - (_targetVel select 1) * (_distance / _fragPower), - _add + (_targetVel select 0) * (_distance / _fragVelocity), + (_targetVel select 1) * (_distance / _fragVelocity), + _add ]; - private _baseVec = _lastPos vectorFromTo _targetPos; + private _baseVec = _fragPosASL vectorFromTo _targetPos; private _dir = floor (_baseVec call CBA_fnc_vectDir); private _currentCount = RETDEF(_fragArcs select _dir,0); if (_currentCount < 10) then { - private _count = ceil (random (sqrt (_m / 1000))); + private _count = ceil (random _metalMassModifier); private _vecVar = FRAG_VEC_VAR; - if (!(_target isKindOf "Man")) then { + if !(_target isKindOf "CAManBase") then { ADD(_vecVar,(sqrt _cubic) / 2000); if ((crew _target) isEqualTo [] && {_count > 0}) then { _count = 0 max (_count / 2); }; }; + private _vecVarHalf = _vecVar / 2; for "_i" from 1 to _count do { - private _vec = _baseVec vectorDiff [ - (_vecVar / 2) + (random _vecVar), - (_vecVar / 2) + (random _vecVar), - (_vecVar / 2) + (random _vecVar) + private _vectorDir = _baseVec vectorDiff [ + _vecVarHalf - (random _vecVar), + _vecVarHalf - (random _vecVar), + _vecVarHalf - (random _vecVar) ]; - private _fp = _fragPower - (random (_fragPowerRandom)); - private _vel = _vec vectorMultiply _fp; - - private _fragObj = (selectRandom _fragTypes) createVehicleLocal [0,0,10000]; - // TRACE_4("targeted",_fp,typeOf _fragObj,_lastPos vectorDistance _targetPos,typeOf _x); - _fragObj setPosASL _lastPos; - _fragObj setVectorDir _vec; - _fragObj setVelocity _vel; - #ifdef DRAW_FRAG_INFO - [ACE_player, _fragObj, [1,0,0,1]] call FUNC(dev_addTrack); + private _fragObjSpeed = _fragVelocity * (1 - random 0.5); + private _fragObjVelocity = _vectorDir vectorMultiply _fragObjSpeed; + + private _fragObj = createVehicleLocal [selectRandom _fragTypes, _fragPosAGL, [], 0, "CAN_COLLIDE"]; + _fragObj setVectorDir _vectorDir; + _fragObj setVelocity _fragObjVelocity; + _fragObj setShotParents _shotParents; + #ifdef DEBUG_MODE_DRAW + [_fragObj, "green", true] call FUNC(dev_trackObj); + if (GVAR(dbgSphere)) then { + [_targetPos, "(0.88,0.36,0.92,0.8)"] call FUNC(dev_sphereDraw); + }; #endif INC(_fragCount); INC(_currentCount); @@ -158,34 +128,31 @@ if (_objects isNotEqualTo []) then { }; }; if (_fragCount > _maxFrags) exitWith {}; - } forEach _objects; + } forEach _targets; TRACE_1("targeted",_fragCount); if (_fragCount > _maxFrags) exitWith {}; private _randomCount = ceil ((_maxFrags - _fragCount) * 0.35); TRACE_1("",_randomCount); private _sectorSize = 360 / (_randomCount max 1); - if (_doRandom) then { - for "_i" from 1 to _randomCount do { - // Distribute evenly - private _sectorOffset = 360 * (_i - 1) / (_randomCount max 1); - private _randomDir = random (_sectorSize); - _vec = [cos (_sectorOffset + _randomDir), sin (_sectorOffset + _randomDir), sin (30 - (random 45))]; - - _fp = (_fragPower - (random (_fragPowerRandom))); + for "_i" from 1 to _randomCount do { + // Distribute evenly + private _sectorOffset = 360 * (_i - 1) / (_randomCount max 1); + private _randomDir = random (_sectorSize); + private _vectorDir = [cos (_sectorOffset + _randomDir), sin (_sectorOffset + _randomDir), sin (30 - (random 45))]; - _vel = _vec vectorMultiply _fp; + private _fragObjSpeed = _fragVelocity * (1 - random 0.5); + private _fragObjVelocity = _vectorDir vectorMultiply _fragObjSpeed; - _fragObj = (selectRandom _fragTypes) createVehicleLocal [0, 0, 10000]; - _fragObj setPosASL _lastPos; - _fragObj setVectorDir _vec; - _fragObj setVelocity _vel; + private _fragObj = createVehicleLocal [selectRandom _fragTypes, _fragPosAGL, [], 0, "CAN_COLLIDE"]; + _fragObj setVectorDir _vectorDir; + _fragObj setVelocity _fragObjVelocity; + _fragObj setShotParents _shotParents; - #ifdef DRAW_FRAG_INFO - [ACE_player, _fragObj, [1,0.5,0,1]] call FUNC(dev_addTrack); - #endif - INC(_fragCount); - }; + #ifdef DEBUG_MODE_DRAW + [_fragObj, "blue", true] call FUNC(dev_trackObj); + #endif + INC(_fragCount); }; }; diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf new file mode 100644 index 00000000000..77222234235 --- /dev/null +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -0,0 +1,96 @@ +#include "..\script_component.hpp" +/* + * Author: Jaynus, NouberNou, Lambda.Tiger + * This function returns fragmentation parameters for a specific ammo type. + * + * Arguments: + * 0: Ammo classname + * + * Return Value: + * _ammoInfo + * 0: Search range for fragments in meters + * 1: Gurney equation calculated speed + * 2: Array of fragment types + * 3: Mass of fragmenting metal modified for frag count + * + * Example: + * "B_556x45_Ball" call ace_frag_fnc_getFragInfo + * + * Public: No + */ + +params ["_ammo"]; + +GVAR(fragInfoCache) getOrDefaultCall [_ammo, { + private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; + private _fragTypes = ACE_FRAG_DEFAULT_FRAG_TYPES; + private _notifyMissingEntries = false; + if (isArray (_ammoConfig >> QGVAR(classes))) then { + _fragTypes = getArray (_ammoConfig >> QGVAR(classes)); + } else { + _notifyMissingEntries = true; + }; + + /************ Gurney equation notes *****************//* + * see https://en.wikipedia.org/wiki/Gurney_equations + * + * gurney_k is the geometry constant added to _metalMass/_chargeMass + * gurney_c = sqrt(2E) + * + * _chargeMass = 185; - grams of comp-b + * _metalMass = 210; - grams of metal are accelerated by explosion + * _geometryCoefficient = 3/5; - spherical K factor + * _gurneyConstant = 2843; - Gurney constant of comp-b in /ms + * + * _chargeMass = 429; - grams of tritonal + * _metalMass = 496; - grams of metal are accelerated by explosion + * _geometryCoefficient = 1/2; - cylindrical K factor + * _gurneyConstant = 2320; - Gurney constant of tritonal in m/s + * Equation - 0.8 for empirical 80% speed + * 0.8 * (((_metalMass / _chargeMass) + _geometryCoefficient) ^ - (1 / 2)) * _gurneyConstant; + * or 0.8 * _gurneyConstant * sqrt (_chargeMass /(_metalMass + _chargeMass * _geometryCoefficient)); (slightly faster to compute) + */ + + private _chargeMass = getNumber (_ammoConfig >> QGVAR(charge)); + if (_chargeMass == 0) then { + _chargeMass = 1; + _notifyMissingEntries = true; + }; + + private _metalMass = getNumber (_ammoConfig >> QGVAR(metal)); + if (_metalMass == 0) then { + _metalMass = 2; + _notifyMissingEntries = true; + }; + + private _geometryCoefficient = getNumber (_ammoConfig >> QGVAR(gurney_k)); + if (_geometryCoefficient == 0) then { + _geometryCoefficient = 0.5; + _notifyMissingEntries = true; + }; + + private _gurneyConstant = getNumber (_ammoConfig >> QGVAR(gurney_c)); + if (_gurneyConstant == 0) then { + _gurneyConstant = 2440; + _notifyMissingEntries = true; + }; + + if (_notifyMissingEntries) then { + INFO_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_ammo); + }; + + private _indirectHitRange = getNumber (_ammoConfig >> "indirecthitrange"); + + /********************** _ammoInfo format *************************//* + * 0: _fragRange - search range for fragments + * 1: _fragVelocity - gurney equation calculated velocity + * 2: _fragTypes - array of fragment types + * 3: _metalMassModified - mass of fragmenting metal modified for frag count + */ + [ + 80 * _indirectHitRange, + ACE_FRAG_IMPERIC_VELOCITY_CONSTANT * _gurneyConstant * sqrt (_chargeMass / (_metalMass + _chargeMass * _geometryCoefficient)), + _fragTypes, + sqrt (_metalMass / 1000) + ] // return +}, true] diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf new file mode 100644 index 00000000000..199953b237b --- /dev/null +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -0,0 +1,62 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * This function returns a classification of material type based on the surface hit. + * + * Arguments: + * 0: Surface type given as either a CfgSurfaces path or .bisurf filepath, same format as "HitPart" projectile parameter + * + * Return Value: + * Material categories as expanded on in line 44 below + * + * Example: + * "a3\data_f\penetration\concrete.bisurf" call ace_frag_fnc_getMaterialInfo + * + * Public: No + */ + +#define ACE_FRAG_SOUNDENVIRON_STR_LEN 12 +#define ACE_FRAG_SOUNDHIT_STR_LEN 8 +#define ACE_FRAG_MATERIAL_SEARCH_LEN 10 + +params ["_surfType"]; + +private _material = GVAR(spallMaterialCache) get _surfType; + +TRACE_2("materialCache",_surfType,_material); +if (!isNil "_material") exitWith {_material}; +// Use 'soundEnviron' or 'soundHit' to extract approx material +private _surfaceConfig = configFile >> "CfgSurfaces" >> _surfType; +if (isClass _surfaceConfig) then { + _material = getText (_surfaceConfig >> "soundEnviron"); + if (_material == "" || {_material == "empty"}) then { + _material = getText (_surfaceConfig >> "soundhit"); + }; +} else { // Messy way when a surface isn't added to CfgSurfaces + private _surfFileText = toLowerANSI preprocessFile _surfType; + _surfFileText = _surfFileText regexReplace ["[^a-z0-9]", ""]; + private _idx = ACE_FRAG_SOUNDENVIRON_STR_LEN + (_surfFileText find "soundenviron"); + if (_surfFileText select [_idx, 5] isEqualTo "empty") then { + _idx = ACE_FRAG_SOUNDHIT_STR_LEN + (_surfFileText find "soundhit"); + }; + _material = _surfFileText select [_idx, ACE_FRAG_MATERIAL_SEARCH_LEN]; +}; +TRACE_1("materialSubString",_material); + +_material = switch (true) do { + case ("dirt" in _material); + case ("grass" in _material): { "ground" }; + case ("gravel" in _material); + case ("rock" in _material): { "rock" }; + case ("wood" in _material): { "wood" }; + case ("lino" in _material); + case ("building" in _material); + case ("concrete" in _material): { "concrete" }; + case ("metal" in _material): { "metal" }; + default { "ground" }; +}; + +GVAR(spallMaterialCache) set [_surfType, _material]; +TRACE_2("materialCacheSet",_surfType,_material); + +_material diff --git a/addons/frag/functions/fnc_getSpallInfo.sqf b/addons/frag/functions/fnc_getSpallInfo.sqf new file mode 100644 index 00000000000..7bb566064ba --- /dev/null +++ b/addons/frag/functions/fnc_getSpallInfo.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * This function returns spalling parameters for a specific ammo type. + * + * Arguments: + * 0: Ammo classname + * + * Return Value: + * _ammoInfo + * 0: Caliber config value + * 1: What part of the hit damage is from ballistic vs explosive energy (1 for all explosive) + * 2: Indirect hit damage + * + * Example: + * "B_556x45_Ball" call ace_frag_fnc_getSpallInfo + * + * Public: No + */ + +params ["_ammo"]; + +GVAR(spallInfoCache) getOrDefaultCall [_ammo, { + private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; + private _caliber = getNumber (_ammoConfig >> "caliber"); + private _explosive = getNumber (_ammoConfig >> "explosive"); + private _indirectHit = getNumber (_ammoConfig >> "indirectHitRange"); + + [_caliber, _explosive, _indirectHit] // return +}, true] diff --git a/addons/frag/functions/fnc_initMaterialCache.sqf b/addons/frag/functions/fnc_initMaterialCache.sqf new file mode 100644 index 00000000000..820133cae0a --- /dev/null +++ b/addons/frag/functions/fnc_initMaterialCache.sqf @@ -0,0 +1,96 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * For performance, we load a bunch of vanilla materials preemptively into the spall material cache. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_initMaterialCache + * + * Public: No + */ + +uiNamespace setVariable [QGVAR(spallMaterialCache), createHashMapFromArray [ + ["a3\data_f\penetration\armour.bisurf","metal"], + ["a3\data_f\penetration\armour_plate.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_100mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_12mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_16mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_1mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_20mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_23mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_250mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_30mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_3mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_40mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_5mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_60mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_7mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_80mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_heavy.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_medium.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_thin.bisurf","metal"], + ["a3\data_f\penetration\bell.bisurf","ground"], + ["a3\data_f\penetration\body.bisurf","ground"], + ["a3\data_f\penetration\building.bisurf","concrete"], + ["a3\data_f\penetration\building_dust_particle.bisurf","concrete"], + ["a3\data_f\penetration\building_dust_soft.bisurf","concrete"], + ["a3\data_f\penetration\building_plate.bisurf","concrete"], + ["a3\data_f\penetration\building_wood_particle.bisurf","wood"], + ["a3\data_f\penetration\cactus.bisurf","ground"], + ["a3\data_f\penetration\cloth.bisurf","ground"], + ["a3\data_f\penetration\cloth_plate.bisurf","ground"], + ["a3\data_f\penetration\concrete.bisurf","concrete"], + ["a3\data_f\penetration\concrete_plate.bisurf","concrete"], + ["a3\data_f\penetration\default.bisurf","ground"], + ["a3\data_f\penetration\engine.bisurf","metal"], + ["a3\data_f\penetration\foliage.bisurf","ground"], + ["a3\data_f\penetration\foliage_dead.bisurf","ground"], + ["a3\data_f\penetration\foliage_dead_plate.bisurf","ground"], + ["a3\data_f\penetration\foliage_green.bisurf","ground"], + ["a3\data_f\penetration\foliage_green_big.bisurf","ground"], + ["a3\data_f\penetration\foliage_green_big_plate.bisurf","ground"], + ["a3\data_f\penetration\foliage_green_plate.bisurf","ground"], + ["a3\data_f\penetration\foliage_palm.bisurf","ground"], + ["a3\data_f\penetration\foliage_palm_plate.bisurf","ground"], + ["a3\data_f\penetration\foliage_pine.bisurf","ground"], + ["a3\data_f\penetration\foliage_pine_plate.bisurf","ground"], + ["a3\data_f\penetration\foliage_plate.bisurf","ground"], + ["a3\data_f\penetration\fueltank.bisurf","metal"], + ["a3\data_f\penetration\glass.bisurf","ground"], + ["a3\data_f\penetration\glass_armored.bisurf","ground"], + ["a3\data_f\penetration\glass_armored_plate.bisurf","ground"], + ["a3\data_f\penetration\glass_plate.bisurf","ground"], + ["a3\data_f\penetration\granite.bisurf","ground"], + ["a3\data_f\penetration\granite_plate.bisurf","ground"], + ["a3\data_f\penetration\hard_ground.bisurf","ground"], + ["a3\data_f\penetration\hay.bisurf","ground"], + ["a3\data_f\penetration\iron_cast.bisurf","metal"], + ["a3\data_f\penetration\iron_cast_plate.bisurf","metal"], + ["a3\data_f\penetration\leather.bisurf","ground"], + ["a3\data_f\penetration\meat.bisurf","ground"], + ["a3\data_f\penetration\meatbones.bisurf","ground"], + ["a3\data_f\penetration\medium_ground.bisurf","ground"], + ["a3\data_f\penetration\metal.bisurf","metal"], + ["a3\data_f\penetration\metal_plate.bisurf","metal"], + ["a3\data_f\penetration\metal_plate_thin.bisurf","metal"], + ["a3\data_f\penetration\plastic.bisurf","ground"], + ["a3\data_f\penetration\plastic_plate.bisurf","ground"], + ["a3\data_f\penetration\plexiglass.bisurf","ground"], + ["a3\data_f\penetration\plexiglass_plate.bisurf","ground"], + ["a3\data_f\penetration\rubber.bisurf","ground"], + ["a3\data_f\penetration\soft_ground.bisurf","ground"], + ["a3\data_f\penetration\tyre.bisurf","ground"], + ["a3\data_f\penetration\tyre_armored.bisurf","ground"], + ["a3\data_f\penetration\vehicle_interior.bisurf","metal"], + ["a3\data_f\penetration\void.bisurf","ground"], + ["a3\data_f\penetration\water.bisurf","ground"], + ["a3\data_f\penetration\weapon_plate.bisurf","metal"], + ["a3\data_f\penetration\wood.bisurf","wood"], + ["a3\data_f\penetration\wood_plate.bisurf","wood"] +]]; diff --git a/addons/frag/functions/fnc_masterPFH.sqf b/addons/frag/functions/fnc_masterPFH.sqf deleted file mode 100644 index ef0fbc3eda8..00000000000 --- a/addons/frag/functions/fnc_masterPFH.sqf +++ /dev/null @@ -1,56 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: jaynus - * Master single PFH abstraction for all rounds being tracked by frag/spall. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_masterPFH - * - * Public: No - */ - -BEGIN_COUNTER(PFH); - -// Fast exit if nothing to do -if (GVAR(objects) isEqualTo []) exitWith {END_COUNTER(PFH);}; - -private _gcIndex = []; - -private _iter = 0; -private _objectCount = count GVAR(objects); -while {_objectCount > 0 && {_iter < (GVAR(maxTrackPerFrame) min _objectCount)}} do { - - if (GVAR(lastIterationIndex) >= _objectCount) then { - GVAR(lastIterationIndex) = 0; - }; - private _object = GVAR(objects) select GVAR(lastIterationIndex); - - if (!isNil "_object") then { - private _args = GVAR(arguments) select GVAR(lastIterationIndex); - - if (!(_args call FUNC(pfhRound))) then { - _gcIndex pushBack GVAR(lastIterationIndex); // Add it to the GC if it returns false - }; - }; - INC(_iter); - INC(GVAR(lastIterationIndex)); -}; - -// Clean up dead object references -private _deletionCount = 0; -{ - TRACE_1("GC Projectile",_x); - private _deleteIndex = _x - _deletionCount; - GVAR(objects) deleteAt _deleteIndex; - GVAR(arguments) deleteAt _deleteIndex; - - INC(_deletionCount); -} forEach _gcIndex; - -END_COUNTER(PFH); diff --git a/addons/frag/functions/fnc_pfhRound.sqf b/addons/frag/functions/fnc_pfhRound.sqf deleted file mode 100644 index bd5a229f0ea..00000000000 --- a/addons/frag/functions/fnc_pfhRound.sqf +++ /dev/null @@ -1,59 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_pfhRound - * - * Public: No - */ - -params ["_round", "_lastPos", "_lastVel", "_shellType", "_firedFrame", "_firedPos", "_doSpall", "_spallTrack", "_foundObjectHPIds", "_skip", "_explosive", "_indirectRange", "_force", "_fragPower"]; - -if (_round in GVAR(blackList)) exitWith { - false -}; - -if (!alive _round) exitWith { - if ((diag_frameno - _firedFrame) > 1) then { //skip if deleted within a single frame - if (_skip == 0) then { - if ((_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}) || {_force == 1}) then { - // shotbullet, shotShell don't seem to explode when touching water, so don't create frags - if ((surfaceIsWater _lastPos) && {(toLower getText (configFile >> "CfgAmmo" >> _shellType >> "simulation")) in ["shotbullet", "shotshell"]}) exitWith {}; - 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; - }; - }; - }; - if (_doSpall) then { - DEC(GVAR(spallIsTrackingCount)); - TRACE_1("doSpall",_foundObjectHPIds); - { - if (!isNil "_x") then { - _x removeEventHandler ["hitPart", _foundObjectHPIds select _forEachIndex]; - }; - } forEach _spallTrack; - }; - false -}; - -_this set [1, getPosASL _round]; -_this set [2, velocity _round]; - -if (_doSpall) then { - private _scale = ((count GVAR(objects)) / GVAR(maxTrackPerFrame)) max 0.1; - [_round, _scale, _spallTrack, _foundObjectHPIds] call FUNC(spallTrack); -}; - -true diff --git a/addons/frag/functions/fnc_setClassBlacklisted.sqf b/addons/frag/functions/fnc_setClassBlacklisted.sqf new file mode 100644 index 00000000000..03a13500258 --- /dev/null +++ b/addons/frag/functions/fnc_setClassBlacklisted.sqf @@ -0,0 +1,49 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * Blacklist an ammo class preventing it from producing fragments and/or spall. + * This function will not allow you to force a projectile to produce fragments or spall. + * Once an ammo class has been blacklisted, it can be removed from the blacklist using this function without restarting the mission. + * + * Arguments: + * 0: Class name of the ammo to be blacklisted + * 1: Should a projectile be blacklisted from producing fragments (default: true) + * 2: Should a projectile be blacklisted from producing spall (default: true) + * + * Return Value: + * Were the changes properly applied + * + * Example: + * // Stop "ACE_20mm_HE" from producing spall + * ["ACE_20mm_HE", false, true] call ace_frag_fnc_setClassBlacklisted; + * + * Public: Yes + */ +params [ + ["_ammo", "", [""]], + ["_blacklistFrag", true, [true]], + ["_blacklistSpall", true, [true]] +]; +TRACE_3("addBlackListClass",_ammo,_blacklistFrag,_blacklistSpall); + +if (_ammo isEqualTo "" || {!isClass (configFile >> "CfgAmmo" >> _ammo)}) exitWith { + INFO_1("Invalid ammo class [%1]",_ammo); + false +}; + +if (_blacklistFrag) then { + GVAR(shouldFragCache) set [_ammo, false]; +} else { + GVAR(shouldFragCache) deleteAt _ammo; + _ammo call FUNC(shouldFrag); +}; + + +if (_blacklistSpall) then { + GVAR(shouldSpallCache) set [_ammo, false]; +} else { + GVAR(shouldSpallCache) deleteAt _ammo; + _ammo call FUNC(shouldSpall); +}; + +true diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf new file mode 100644 index 00000000000..8cc62f3dac0 --- /dev/null +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -0,0 +1,46 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * This function checks whether an ammunition type should create fragments. + * + * Arguments: + * 0: Ammo classname + * + * Return Value: + * Could the ammo class generate fragments + * + * Example: + * "B_556x45_Ball" call ace_frag_fnc_shouldFrag + * + * Public: No + */ + +params ["_ammo"]; + +GVAR(shouldFragCache) getOrDefaultCall [_ammo, { + private _shouldFrag = true; + + private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; + private _skip = getNumber (_ammoConfig >> QGVAR(skip)); + if (_skip == 1) then { + _shouldFrag = false; + TRACE_1("No frag: skip",_skip); + }; + + private _force = getNumber (_ammoConfig >> QGVAR(force)); + if (_shouldFrag && _force == 0) then { + private _explosive = getNumber (_ammoConfig >> "explosive"); + if (_explosive < 0.5) exitWith { + _shouldFrag = false; + TRACE_3("No frag: _explosive",_skip,_force,_explosive); + }; + private _indirectHit = getNumber (_ammoConfig >> "indirectHit"); + private _indirectRange = getNumber (_ammoConfig >> "indirectHitRange"); + if (_indirectRange < 4.5 || {_indirectHit * sqrt(_indirectRange) < 35}) then { + _shouldFrag = false; + TRACE_5("No frag",_ammo,_skip,_explosive,_indirectRange,_indirectHit); + }; + }; + + _shouldFrag +}, true] diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf new file mode 100644 index 00000000000..430a4da8229 --- /dev/null +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * This function checks whether an ammunition type should cause spalling. + * + * Arguments: + * 0: Ammo classname + * + * Return Value: + * Whether the round type could spall when hitting an object + * + * Example: + * "B_556x45_Ball" call ace_frag_fnc_shouldSpall + * + * Public: No + */ + +params ["_ammo"]; + +GVAR(shouldSpallCache) getOrDefaultCall [_ammo, { + (_ammo call FUNC(getSpallInfo)) params ["_caliber", "_explosive", "_indirectHit"]; + + _caliber >= 2.5 || (_explosive > 0 && _indirectHit >= 1) // return +}, true] diff --git a/addons/frag/functions/fnc_spallHP.sqf b/addons/frag/functions/fnc_spallHP.sqf deleted file mode 100644 index 367bea76449..00000000000 --- a/addons/frag/functions/fnc_spallHP.sqf +++ /dev/null @@ -1,42 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * Handles the HitPart event - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_spallHP - * - * Public: No - */ - -//player sideChat format ["f: %1 c: %2", (_this select 0), (count GVAR(spallHPData))]; - -params ["_index", "_hitPartData"]; - -private _initialData = GVAR(spallHPData) param [_index, []]; -if (_initialData isEqualTo []) exitWith {}; - -private _hpRound = (_hitPartData select 0) select 2; -private _round = _initialData select 3; -private _hpDirect = (_hitPartData select 0) select 10; - -if (_hpDirect && {_round == _hpRound}) then { - { - // diag_log text format ["HPDUMP-------------------------------------"]; - // { - // _hp = _x; - // diag_log text format ["%1 --", _forEachIndex]; - // { - // diag_log text format ["%1: %2", _forEachIndex, _x]; - // } forEach _hp; - // } forEach (_this select 1); - [DFUNC(doSpall), [_this, _forEachIndex]] call CBA_fnc_execNextFrame; - // player sideChat "WEEE"; - } forEach _hitPartData; -}; diff --git a/addons/frag/functions/fnc_spallTrack.sqf b/addons/frag/functions/fnc_spallTrack.sqf deleted file mode 100644 index 43dae8afcb0..00000000000 --- a/addons/frag/functions/fnc_spallTrack.sqf +++ /dev/null @@ -1,39 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * Add HitPart EventHandler to objects in the projectile's path - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_spallTrack - * - * Public: No - */ - -params ["_round", "_multiplier", "_foundObjects", "_foundObjectHPIds"]; - -private _delta = (1 / diag_fps) * _multiplier; -private _curPos = getPosASL _round; -private _velocity = velocity _round; - -private _velocityStep = _velocity vectorMultiply _delta; -private _forwardPos = _curPos vectorAdd _velocityStep; - - -private _intersectsWith = lineIntersectsWith [_curPos, _forwardPos]; - -if (_intersectsWith isEqualTo []) exitWith {}; -{ - // diag_log text format ["Adding HP: %1", _x]; - private _index = count GVAR(spallHPData); - private _hpId = _x addEventHandler ["hitPart", compile format ["[%1, _this] call " + QFUNC(spallHP), _index]]; - _foundObjects pushBack _x; - _foundObjectHPIds pushBack _hpId; - private _data = [_hpId, _x, typeOf _round, _round, _curPos, _velocity, 0, _foundObjects, _foundObjectHPIds]; - GVAR(spallHPData) pushBack _data; -} forEach (_intersectsWith select {!(_x in _foundObjects)}); diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 421d5d45664..c4730a3dd0c 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -8,13 +8,6 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; 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)], @@ -24,17 +17,20 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(maxTrack), "SLIDER", - [LSTRING(MaxTrack), LSTRING(MaxTrack_Desc)], + QGVAR(spallEnabled), "CHECKBOX", + [LSTRING(EnableSpall), LSTRING(EnableSpall_Desc)], _category, - [0, 50, 10, -1], + false, 1 ] call CBA_fnc_addSetting; [ - QGVAR(maxTrackPerFrame), "SLIDER", - [LSTRING(MaxTrackPerFrame), LSTRING(MaxTrackPerFrame_Desc)], + QGVAR(spallIntensity), "SLIDER", + [LSTRING(SpallIntensity), LSTRING(SpallIntensity_Desc)], _category, - [0, 50, 10, -1], - 1 + [0.1, 2, 1, 1], + 1, + { + GVAR(shouldSpallCache) = createHashMap; + } ] call CBA_fnc_addSetting; diff --git a/addons/frag/initSettingsDebug.inc.sqf b/addons/frag/initSettingsDebug.inc.sqf new file mode 100644 index 00000000000..a1528a446cf --- /dev/null +++ b/addons/frag/initSettingsDebug.inc.sqf @@ -0,0 +1,25 @@ +private _category = format ["ACE %1", LLSTRING(Module_DisplayName)]; + +[ + QGVAR(debugOptions), + "CHECKBOX", + [LSTRING(EnableDebugTrace), LSTRING(EnableDebugTrace_Desc)], + [_category, LSTRING(Debug)], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(dbgSphere), + "CHECKBOX", + [LSTRING(HitSphereEnable), LSTRING(HitSphereEnable_Desc)], + [_category, LSTRING(Debug)], + false +] call CBA_fnc_addSetting; + +[ + QGVAR(drawHitBox), + "CHECKBOX", + [LSTRING(DrawHitBox), LSTRING(DrawHitBox_Desc)], + [_category, LSTRING(Debug)], + true +] call CBA_fnc_addSetting; diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 0215e9f4d74..bc69597a16b 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -2,13 +2,15 @@ #define COMPONENT_BEAUTIFIED Frag #include "\z\ace\addons\main\script_mod.hpp" -// #define DRAW_FRAG_INFO +// #define LOG_FRAG_INFO // #define DEBUG_MODE_FULL +// #define DEBUG_MODE_DRAW // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_FRAG #define DEBUG_MODE_FULL + #define DEBUG_MODE_DRAW #endif #ifdef DEBUG_SETTINGS_FRAG @@ -17,4 +19,32 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define ACE_TRACE_DRAW_INC 1 +#define GLUE(g1,g2) g1##g2 + +// Mimimum hold-off time between frag events per unit +#define ACE_FRAG_FRAG_UNIT_HOLDOFF 0.5 +#define ACE_FRAG_SPALL_UNIT_HOLDOFF 0.5 +// Scaling for the min/max # of fragments since last frag event +#define ACE_FRAG_COUNT_MIN_TIME 0.1 +#define ACE_FRAG_COUNT_MIN 5 +#define ACE_FRAG_COUNT_MAX_TIME 1.5 +#define ACE_FRAG_COUNT_MAX 50 +#define ACE_FRAG_IMPERIC_VELOCITY_CONSTANT 0.8 +#define ACE_FRAG_DEFAULT_FRAG_TYPES [\ + QGVAR(tiny), QGVAR(tiny), QGVAR(tiny),\ + QGVAR(tiny_HD), QGVAR(tiny_HD), QGVAR(tiny_HD),\ + QGVAR(small), QGVAR(small), QGVAR(small), QGVAR(small),\ + QGVAR(small_HD), QGVAR(small_HD), QGVAR(small_HD), QGVAR(small_HD),\ + QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD)\ +] + +// Spall values +#define ACE_FRAG_SPALL_HOLDOFF 0.2 +#define ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF 0.8 +// sqrt(2)/50 +#define ACE_FRAG_SPALL_CALIBER_COEF 0.02828427 +#define ACE_FRAG_SPALL_POWER_MIN 2 +#define ACE_FRAG_SPALL_POWER_TINY_MAX 5 +#define ACE_FRAG_SPALL_POWER_SMALL_MAX 8 +#define ACE_FRAG_SPALL_POWER_MEDIUM_MAX 11 +#define ACE_FRAG_SPALL_POWER_LARGE_MAX 15 diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index 7addcd4c388..71bda49dfc4 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -13,7 +13,7 @@ Симуляция осколков Simulazione Frammentazione 破片シミュレーション - 파편화 시뮬레이션 + 파열 시뮬레이션 破片模拟 模擬碎片 @@ -28,8 +28,8 @@ Repesz-szimuláció Симуляция осколков Simulazione Frammentazione - 破片シミュレーション - 파편화 시뮬레이션 + フラグメンテーション シミュレーション + 파열 시뮬레이션 破片模拟 模擬碎片 @@ -44,8 +44,8 @@ Az ACE repesz-szimuláció engedélyezése Включить симуляцию осколков ACE Abilita la Simulazione Frammentazione di ACE - ACE 破片シミュレーションを有効化 - ACE 파편화 시뮬레이션을 적용합니다. + ACE フラグメンテーション シミュレーションを有効化 + ACE 파열 시뮬레이션을 적용합니다. 启用 ACE 破片模拟 啟用ACE模擬碎片 @@ -60,8 +60,8 @@ Pattogzás-szimuláció Симуляция обломков Simulazione Spalling - 剥離シミュレーション - 탄환파편 시뮬레이션 + スポーリング シミュレーション + 파편 시뮬레이션 模拟剥落 模擬剝落 @@ -76,8 +76,8 @@ Az ACE pattogzás-szimuláció engedélyezése Включить симуляцию обломков ACE Abilita la Simulazione Spalling di ACE - ACE 剥離シミュレーションを有効化 - ACE 탄환파편 시뮬레이션을 적용합니다. + ACE スポーリング シミュレーションを有効化 + ACE 파편 시뮬레이션을 적용합니다. 启用 ACE 模拟剥落 啟用ACE模擬剝落 @@ -90,7 +90,7 @@ Simulation de la réflexion des explosions Simulação de reflexo de explosão Cимуляция отражения взрывов ACE - 爆発反射シミュレーション + 爆風反射シミュレーション 폭발 반사 시뮬레이션 模拟爆炸反射 模擬爆炸反射 @@ -105,107 +105,86 @@ 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 - Máximos proyectiles rastreados - Maks. liczba śledzonych pocisków - Maximalzahl der verfolgten Projektile - Maximální počet sledovaných projektilů - Máximo de projéteis rastreados - Nombre maximum de projectiles suivis - Maximum követett repeszek - Макс. количество отслеживаемых снарядов - Numero massimo di Proiettili Tracciati - 飛翔体最大追跡数 - 최대 발사체 추적수 - 最大破片粒子追踪数量 - 最大碎片/剝落粒子追蹤數量 - - - This setting controls the maximum amount of projectiles the fragmentation and spalling system will track at any given time. If more projectiles are fired, they will not be tracked. Lower this setting if you do not want FPS drops at high-count projectile scenarios ( >200 rounds in the air at once) - Este ajuste controla la cantidad máxima de proyectiles del sistema de fragmentación y astillamiento de los que se hará un seguimiento en cualquier momento dado. Si se disparan más proyectiles, no serán rastreados. Baja esta opción si no deseas una bajada de FPS en escenarios con muchos proyectiles (>200 proyectiles en el aire a la vez) - To ustawienie kontroluje maksymalną ilość pocisków, jakie fragmentacja i odpryski symulują w danym momencie. Jeżeli więcej pocisków będzie wystrzelonych, wtedy nie będą one śledzone. Zmniejsz tą opcję jeżeli nie chcesz odczuwać spadków FPS podczas ciężkiej wymiany ognia (więcej niż 200 pocisków w powietrzu na raz). - 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) - 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 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顆粒子) - - - Maximum Projectiles Per Frame - Máximos proyectiles por cuadro - Maximale Anzahl an Projektilen pro Frame - Maks. liczba pocisków na klatkę - Maximální počet projektilů za jeden snímek - Projéteis máximos por quadro - Nombre maximal de projectiles par image - Maximum repesz/képkocka - Макс. количество снарядов за кадр - Numero massimo di proiettili per Frame - フレームごとの飛翔体最大数 - 프레임 당 최대 발사체 수 - 每帧最大破片粒子数量 - 每一幀數(FPS)最大碎片/剝落粒子數量 - - - The number of spall track calculations to perform in any given frame. This helps spread the FPS impact of tracking spall rounds across multiple frames, limiting its impact even further. - Ilość obliczeń wykonywanych przez symulację odprysków w danej klatce. Ta opcja pomaga rozprzestrzenić obliczenia odprysków na więcej klatek, zmniejszając spadek FPS jeszcze bardziej. - Gibt die Anzahl der Explosionverfolgungsberechnungen an, die gleichzeitig ausgeführt werden. Das kann dabei helfen den FPS-Einfluss abzuschwächen, wenn Teile über mehrere Frames hinweg verfolgt werden. - 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 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, riducendolo ulteriormente. - 与えられたフレームごとに追跡する剥離飛翔体の数を決定します。FPS に影響をあたえないよう、剥離飛翔体を複数のフレームで追跡し、分散させています。 - 가능한 프레임마다 파편을 추적 및 계산합니다. 여러 프레임에 걸쳐 파편난 발사체를 추적하여 FPS에 도움을 줍니다. 이를 제한함으로써 더욱 큰 효과를 볼 수 있습니다. - 设定在每一帧数内,系统最大可追踪的破片粒子数量。此设定可有效帮助系统减低计算压力。 - 設定在每一幀數內,系統最大可追蹤的碎片/剝落粒子數量。此設定可有效幫助系統減低計算壓力 + + Debug + 디버그 + デバッグ + Отладка + Debug + Debug + + + Spalling Intensity + 파편 강도 + スポーリング強度 + Интенсивность обрушения + Intensità dello spalling + Intensidad del astillamiento + + + Modifier to increase or decrease the number and intensity of spalling events. Increasing this value may cause performance degradation. + 파편 이벤트 수와 강도를 늘리거나 줄입니다. 이 값을 늘리면 성능이 저하될 수 있습니다. + スポーリング現象が発生する数と強度を増減することが出来ます。この値を大きくすることはパフォーマンスの低下につながる可能性があります。 + Модификатор для увеличения или уменьшения количества и интенсивности событий обрушения. Увеличение этого значения может привести к ухудшению производительности. + Modificatore per il numero e intensità di spalling simulato, ovvero la frammentazione interna ad un veicolo colpito. Valori alti possono causare una degradazione della performance. + Modificador para aumentar o disminuir el número y la intensidad de los eventos de astillamiento. Aumentar este valor puede producir una degradación en el rendimiento. - (SP Only) Frag/Spall Debug Tracing - (Solo SP) Seguimiento de depuración de Fragmentación/Astillamiento - (Tylko SP) Wizualny debug odł./odpr. - (Pouze SP) Debug sledování Frag/Úlomků - (nur SP) Splitter-/Explosions-Debug-Verfolgung - (Somente SP) Depuração de fragmentação e estilhaços traçantes - (SP uniquement) Fragmentation/éclat debug - (Csak SP) Repesz/Pattogzás debug követés - (Только для одиночной игры) Отслеживаение/отладка осколков - (Solo SP) Debug Tracciamento Frag/Spall - (SP のみ) 破片/剥離のデバッグ用表示 - (싱글플레이 전용) 탄환파편/파편 디버그 추적화 - (仅单人)追踪显示破片粒子 - (僅在單人模式) 碎片/剝落除錯追蹤 + Frag/Spall Debug Tracing + Splitter-/Explosions-Debug-Verfolgung + フラグとスポールの追跡デバッグ + 파열/파편 디버그 추적 + Отладка трассировки фрагментации/осколков + Traccia Frag/Spall per Debug + Trazado Debug de Fragmentación/Astillamiento - (SP Only) Requires a mission/editor restart. Enables visual tracing of fragmentation and spalling rounds in SP game mode only. - (Solo SP) Requiere un reinicio misión/editor. Permite el seguimiento visual de la fragmentación y astillamientos de los proyectiles en modo SP. - (Tylko SP) Wymaga restartu misji/edytora. Aktywuje wizualne śledzenie odłamków oraz odprysków w trybie gry Single Player. - (nur SP) Splitter-/Explosions-Debugging - (Pouze SP) Vyžaduje restart mise/editoru. Aktivuje vizuální stopování fragmentace a úlomů pouze v režimu jednoho hráče. - (Somente SP) Requer um reinício de missão / editor. Habilita o rastreamento visual de projéteis de fragmentação e estilhaçamento apenas no modo de jogo SP. - (SP seulement) Requiert un redémarrage de mission ou de l'éditeur. Active les traceurs visuels de fragmentation et d'éclats en mode solo seulement. - (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 게임 모드에서만 파편화 및 탄환파편의 시각적 추적을 가능하게 합니다. + Enables visual tracing of fragmentation and spalling rounds. + Splitter-/Explosions-Debugging + 파열과 파편의 시각적 추적을 활성화합니다. + フラグメンテーションとスポーリングによって発生した破片飛翔体の動きを視覚的に追跡できる機能を有効化します。 + Включает визуальную трассировку фрагментации и осколочных снарядов. + Abilita il tracciamento visivo di effetti di frammentazione e spalling. + Habilitar trazado visual de los proyectiles generados por la fragmentación y el astillamiento. + + + Draw Event Spheres + 이벤트 구체 그리기 + イベントを球体として描画 + Изобразить сферы событий + Visualizza sfere eventi + Dibujar Esferas de Eventos + + + Draw color coded spheres at any event for tracked rounds. + 모든 이벤트에서 추적된 파편을 위한 색상으로 구분하는 구체를 그립니다. + 追跡中の飛翔体に発生した全てのイベントを色付けた球体として描画します。 + Изобразить цветные сферы на любом событии для отслеживаемых раундов. + Visualizza sfere colorate su ogni evento di un frammento tracciato. + Dibujar esferas codificadas por color en cualquier evento para proyectiles seguidos. + + + Draw Hitboxes + 히트박스 그리기 + ヒットボックスを描画 + Изобразить хитбоксы + Visualizza hitbox + Dibujar hitboxes + + + Draw hitboxes on objects that were targeted. + Splitter-/Explosions-Debugging + 被弾した物体のヒットボックスを描画します。 + 타겟팅된 오브젝트에 히트박스를 그립니다. + Изобразить хитбоксы на объектах, которые были нацелены. + Visualizza hitbox su potenziali bersagli della frammentazione. + Dibuja hitboxes en objetos que son seguidos. diff --git a/addons/gestures/XEH_postInit.sqf b/addons/gestures/XEH_postInit.sqf index 935b81aa612..5133f48c419 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/stringtable.xml b/addons/gestures/stringtable.xml index 33b73290c3d..0f483e17a26 100644 --- a/addons/gestures/stringtable.xml +++ b/addons/gestures/stringtable.xml @@ -12,7 +12,7 @@ ACE Gestos ACE Жесты ACE Gestos - ACE ジェスチャー + ACE ジェスチャ ACE 수신호 ACE 手势 ACE 手勢 @@ -29,7 +29,7 @@ ACE Gestos ACE Жесты ACE Gestos - ACE ジェスチャー + ACE ジェスチャ ACE 수신호 ACE 手势 ACE 手勢 @@ -46,7 +46,7 @@ Kézjelek Gestos Gesti - ジェスチャー + ジェスチャ 수신호 手势 手勢 @@ -293,7 +293,7 @@ Afficher les gestes dans le menu d'interaction Mostrar gestos no menu de interação Показать жесты в меню взаимодействия - インタラクションメニュー上でジェスチャー表示 + ジェスチャのアクションを表示 수신호를 상호작용 메뉴에서 보여줍니다 显示手势互动菜单 顯示手勢互動選單 @@ -309,7 +309,7 @@ Afficher les gestes dans le menu d'interaction personnel, ou utiliser uniquement les touches, ou désactiver complètement. Mostra gestos no menu de interação, ou utilize um dos atalhos de teclado ou desative completamente Показать жесты в меню взамиодейтсвия с собой или только использовать горячие клавиши, или полностью отключить - セルフ インタラクションメニューでジェスチャーを表示するか、キーバインドのみを使用するか、完全に無効にします + セルフ・インタラクション メニューにジェスチャのアクションを表示するか、キーバインドのみを使用するか、完全に無効にします 수신호를 상호작용 메뉴에서 보여주거나 혹은 단축키를 지정하거나 아니면 아예 사용하지 않습니다. 显示手势选项在自己的互动菜单上,或只利用键盘来使用手势,或完全禁用 顯示手勢選項在自己的互動選單上,或只利用鍵盤來使用手勢,或完全禁用 @@ -341,7 +341,7 @@ Touches + menu d'interaction Atalhos + Menu de Interação Клавиши + Меню взаимодействия - キー操作とインタラクションメニュー + キー操作とメニュー 단축키 및 상호작용 메뉴 键盘 + 互动菜单 鍵盤 + 互動選單 diff --git a/addons/gforces/functions/fnc_pfhUpdateGForces.sqf b/addons/gforces/functions/fnc_pfhUpdateGForces.sqf index 7ff3444b7dc..487ba15b2a2 100644 --- a/addons/gforces/functions/fnc_pfhUpdateGForces.sqf +++ b/addons/gforces/functions/fnc_pfhUpdateGForces.sqf @@ -71,13 +71,13 @@ private _suitCoef = if ((uniform ACE_player) != "") then { private _gBlackOut = MAXVIRTUALG / _classCoef + MAXVIRTUALG / _suitCoef - MAXVIRTUALG; // Unconsciousness -if ((_average > _gBlackOut) && {["ace_medical"] call EFUNC(common,isModLoaded) && {!(ACE_player getVariable ["ACE_isUnconscious", false])}}) then { +if (_average > _gBlackOut && {GETEGVAR(medical,enabled,false) && {ACE_player call EFUNC(common,isAwake)}}) then { [ACE_player, true, (10 + floor(random 5)), true] call EFUNC(medical,setUnconscious); }; GVAR(GForces_CC) ppEffectAdjust [1,1,0,[0,0,0,1],[0,0,0,0],[1,1,1,1],[10,10,0,0,0,0.1,0.5]]; -if !(ACE_player getVariable ["ACE_isUnconscious", false]) then { +if (ACE_player call EFUNC(common,isAwake)) then { if (_average > 0.30 * _gBlackOut) then { private _strength = ((_average - 0.30 * _gBlackOut) / (0.70 * _gBlackOut)) max 0; GVAR(GForces_CC) ppEffectAdjust [1,1,0,[0,0,0,1],[0,0,0,0],[1,1,1,1],[2 * (1 - _strength),2 * (1 - _strength),0,0,0,0.1,0.5]]; diff --git a/addons/goggles/RscTitles.hpp b/addons/goggles/RscTitles.hpp index 0716892312d..6bb5364fe12 100644 --- a/addons/goggles/RscTitles.hpp +++ b/addons/goggles/RscTitles.hpp @@ -1,6 +1,6 @@ -class RscTitles { - #include "define.hpp" +class RscPicture; +class RscTitles { class RscACE_Goggles_BaseTitle { idd = -1; onLoad = "uiNamespace setVariable ['ACE_Goggles_Display', _this select 0]"; @@ -19,6 +19,10 @@ class RscTitles { class controls { class gogglesImage: RscPicture { idc = 10650; + x = "safeZoneX"; + y = "safeZoneY"; + w = "safeZoneW"; + h = "safeZoneH"; }; }; }; @@ -33,9 +37,17 @@ class RscTitles { class controls { class dirtImage: RscPicture { idc = 10660; + x = "safeZoneX"; + y = "safeZoneY"; + w = "safeZoneW"; + h = "safeZoneH"; }; class dustImage: RscPicture { idc = 10662; + x = "safeZoneX"; + y = "safeZoneY"; + w = "safeZoneW"; + h = "safeZoneH"; }; }; }; diff --git a/addons/goggles/XEH_postInit.sqf b/addons/goggles/XEH_postInit.sqf index 7700d4cc81b..e5a6bf5d1c7 100644 --- a/addons/goggles/XEH_postInit.sqf +++ b/addons/goggles/XEH_postInit.sqf @@ -88,10 +88,10 @@ if (!hasInterface) exitWith {}; if (GVAR(effects) in [2, 3]) then { // Register fire event handler - ["ace_firedPlayer", DFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; //Add Explosion XEH - ["CAManBase", "explosion", FUNC(handleExplosion)] call CBA_fnc_addClassEventHandler; + ["CAManBase", "explosion", LINKFUNC(handleExplosion)] call CBA_fnc_addClassEventHandler; GVAR(PostProcessEyes) = ppEffectCreate ["ColorCorrections", 1992]; GVAR(PostProcessEyes) ppEffectAdjust [1, 1, 0, [0, 0, 0, 0], [0, 0, 0, 1], [1, 1, 1, 0]]; diff --git a/addons/goggles/define.hpp b/addons/goggles/define.hpp deleted file mode 100644 index 81d3fcb6896..00000000000 --- a/addons/goggles/define.hpp +++ /dev/null @@ -1,25 +0,0 @@ -// Control types -#define CT_STATIC 0 -#define ST_PICTURE 0x30 - -//////////////// -//Base Classes// -//////////////// - -class RscPicture { - idc = -1; - type = CT_STATIC; - style = ST_PICTURE; - colorBackground[] = {0,0,0,0}; - colorText[] = {1,1,1,1}; - font = "RobotoCondensed"; - sizeEx = 0; - lineSpacing = 0; - fixedWidth = 0; - shadow = 0; - text = ""; - 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 38fc57f0ce6..a246f1293fc 100644 --- a/addons/goggles/functions/fnc_applyDirtEffect.sqf +++ b/addons/goggles/functions/fnc_applyDirtEffect.sqf @@ -33,6 +33,7 @@ if ([_unit] call FUNC(isGogglesVisible)) then { private _effectBrightness = linearConversion [0,1,([] call EFUNC(common,ambientBrightness)),0.25,1]; (GETUVAR(GVAR(DisplayEffects),displayNull) displayCtrl 10660) ctrlSetTextColor [_effectBrightness, _effectBrightness, _effectBrightness, 1]; + [QGVAR(effect), [_unit, "dirt"]] call CBA_fnc_localEvent; TRACE_1("dirt",_effectBrightness); }; }; diff --git a/addons/goggles/functions/fnc_applyDustEffect.sqf b/addons/goggles/functions/fnc_applyDustEffect.sqf index 93bcbad1d6b..c00754c4eaa 100644 --- a/addons/goggles/functions/fnc_applyDustEffect.sqf +++ b/addons/goggles/functions/fnc_applyDustEffect.sqf @@ -57,7 +57,7 @@ GVAR(DustHandler) = [{ private _amount = 1 - (GETDUSTT(DAMOUNT) * 0.125); - if !(_unit getVariable ["ACE_EyesDamaged", false]) then { + if !(ACE_player getVariable ["ACE_EyesDamaged", false]) then { GVAR(PostProcessEyes) ppEffectAdjust [1, 1, 0, [0, 0, 0, 0], [_amount, _amount, _amount, _amount], [1, 1, 1, 0]]; GVAR(PostProcessEyes) ppEffectCommit 0.5; }; @@ -68,6 +68,7 @@ GVAR(DustHandler) = [{ GVAR(PostProcessEyes) ppEffectAdjust [1, 1, 0, [0, 0, 0, 0], [1, 1, 1, 1], [1, 1, 1, 0]]; GVAR(PostProcessEyes) ppEffectCommit 2; + [QGVAR(effect), [ACE_player, "dust"]] call CBA_fnc_localEvent; [{ if (GVAR(DustHandler) == -1) then { diff --git a/addons/goggles/functions/fnc_applyRainEffect.sqf b/addons/goggles/functions/fnc_applyRainEffect.sqf index 3332db536af..bf1d6fd04aa 100644 --- a/addons/goggles/functions/fnc_applyRainEffect.sqf +++ b/addons/goggles/functions/fnc_applyRainEffect.sqf @@ -22,7 +22,7 @@ if (!alive _unit) exitWith {}; private _fnc_underCover = { params ["_unit"]; - if (vehicle _unit != _unit && {!isTurnedOut _unit}) exitWith {true}; + if (!isNull objectParent _unit && {!isTurnedOut _unit}) exitWith {true}; // looking up and no roof over head private _position = eyePos _unit; @@ -52,6 +52,7 @@ if (GVAR(RainLastLevel) != rain) then { GVAR(RainDrops) setParticleClass "ACERainEffect"; GVAR(RainDrops) setDropInterval (0.07 * (1.1 - GVAR(RainLastLevel))); GVAR(RainDrops) attachTo [vehicle _unit, [0,0,0]]; + [QGVAR(effect), [_unit, "rain"]] call CBA_fnc_localEvent; }; } else { if (GVAR(RainLastLevel) > 0.05) then { diff --git a/addons/goggles/functions/fnc_applyRotorWashEffect.sqf b/addons/goggles/functions/fnc_applyRotorWashEffect.sqf index 3513eb191a3..b2369d15107 100644 --- a/addons/goggles/functions/fnc_applyRotorWashEffect.sqf +++ b/addons/goggles/functions/fnc_applyRotorWashEffect.sqf @@ -23,7 +23,7 @@ if (!alive _unit) exitWith {}; GVAR(FrameEvent) set [0, !(GVAR(FrameEvent) select 0)]; if (GVAR(FrameEvent) select 0) exitWith { - if (vehicle _unit != _unit && {!isTurnedOut _unit}) exitWith { + if (!isNull objectParent _unit && {!isTurnedOut _unit}) exitWith { (GVAR(FrameEvent) select 1) set [0, false]; }; @@ -64,18 +64,18 @@ if !(_safe) then { if !([_unit] call FUNC(isGogglesVisible)) exitWith {}; if (GETDUSTT(DAMOUNT) < 2) then { - if !(GETDUSTT(DACTIVE)) then { - SETDUST(DACTIVE,true); - - call FUNC(applyDustEffect); - } else { + if (GETDUSTT(DACTIVE)) then { if (_rotorWash select 1 > 0.5) then { call FUNC(applyDustEffect); }; + } else { + SETDUST(DACTIVE,true); + + call FUNC(applyDustEffect); }; }; - _safe = getNumber (ConfigFile >> "CfgGlasses" >> goggles _unit >> "ACE_Protection") == 1; + _safe = getNumber (configFile >> "CfgGlasses" >> goggles _unit >> "ACE_Protection") == 1; }; // quit if protected by goggles or helmet @@ -101,5 +101,6 @@ if (_rotorWash select 1 > 0) then { GVAR(PostProcessEyes) ppEffectAdjust [1, 1, 0, [0, 0, 0, 0], [_scale, _scale, _scale, _scale], [1, 1, 1, 0]]; GVAR(PostProcessEyes) ppEffectCommit 0.5; GVAR(PostProcessEyes) ppEffectEnable true; + [QGVAR(effect), [_unit, "rotorWash"]] call CBA_fnc_localEvent; }; }; diff --git a/addons/goggles/functions/fnc_canWipeGlasses.sqf b/addons/goggles/functions/fnc_canWipeGlasses.sqf index ef9d961bc13..cb24b4137a7 100644 --- a/addons/goggles/functions/fnc_canWipeGlasses.sqf +++ b/addons/goggles/functions/fnc_canWipeGlasses.sqf @@ -15,4 +15,4 @@ * Public: No */ -GVAR(effects) in [2, 3] && {!GETVAR(ACE_player,ACE_isUnconscious,false)} // return +GVAR(effects) in [2, 3] && {ACE_player call EFUNC(common,isAwake)} // return diff --git a/addons/goggles/functions/fnc_isInRotorWash.sqf b/addons/goggles/functions/fnc_isInRotorWash.sqf index 8c3b29723de..6784e9db122 100644 --- a/addons/goggles/functions/fnc_isInRotorWash.sqf +++ b/addons/goggles/functions/fnc_isInRotorWash.sqf @@ -36,7 +36,6 @@ private _rotorWash = [false, 0]; _rotorWash set [1, _distance]; }; }; - false -} count (position _unit nearEntities [["Helicopter"], _radius]); +} forEach (position _unit nearEntities [["Helicopter"], _radius]); _rotorWash diff --git a/addons/goggles/stringtable.xml b/addons/goggles/stringtable.xml index 5fc06612d05..233ac3e6caf 100644 --- a/addons/goggles/stringtable.xml +++ b/addons/goggles/stringtable.xml @@ -101,7 +101,7 @@ Effects - эффекты + Эффекты エフェクト Efekty Effekte @@ -137,7 +137,7 @@ Pokaż interakcję Wyczyść Gogle Mostra interazione automatica per la pulizia degli occhiali Ukaž Vyčistit brýle v menu Interakce (vlastní) - ゴーグル拭き取りをセルフ インタラクションに表示 + ゴーグル拭き取りのアクションを表示 在自我互動中顯示擦拭護目鏡的動作 在自我互动中显示擦拭护目镜的动作 Afficher l'interaction "Essuyer les lunettes" diff --git a/addons/grenades/CfgAmmo.hpp b/addons/grenades/CfgAmmo.hpp index 5082dd432d9..2b0849d2f71 100644 --- a/addons/grenades/CfgAmmo.hpp +++ b/addons/grenades/CfgAmmo.hpp @@ -1,4 +1,3 @@ - class CfgAmmo { class Default; class Grenade: Default { @@ -153,7 +152,7 @@ class CfgAmmo { class ACE_G_M14: SmokeShell { GVAR(incendiary) = 1; model = QPATHTOF(models\ace_anm14th3_armed.p3d); - hit = 5; + hit = 10; indirectHit = 4; indirectHitRange = 1.1; dangerRadiusHit = 50; diff --git a/addons/grenades/CfgEventHandlers.hpp b/addons/grenades/CfgEventHandlers.hpp index 6c29240403a..f6503c2479b 100644 --- a/addons/grenades/CfgEventHandlers.hpp +++ b/addons/grenades/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); diff --git a/addons/grenades/CfgMagazines.hpp b/addons/grenades/CfgMagazines.hpp index ea4641ab7fb..2ff86c443d4 100644 --- a/addons/grenades/CfgMagazines.hpp +++ b/addons/grenades/CfgMagazines.hpp @@ -1,4 +1,3 @@ - class CfgMagazines { class HandGrenade; class ACE_HandFlare_Base: HandGrenade { diff --git a/addons/grenades/CfgVehicles.hpp b/addons/grenades/CfgVehicles.hpp index f9ac60d9fe6..34cf4196e6c 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 842862f7f98..683ec7532bc 100644 --- a/addons/grenades/CfgWeapons.hpp +++ b/addons/grenades/CfgWeapons.hpp @@ -1,4 +1,3 @@ - class CfgWeapons { class GrenadeLauncher; class Throw: GrenadeLauncher { diff --git a/addons/grenades/Effects.hpp b/addons/grenades/Effects.hpp index 95c3f12ba89..b4a16c6412f 100644 --- a/addons/grenades/Effects.hpp +++ b/addons/grenades/Effects.hpp @@ -1,4 +1,3 @@ - class ACE_M84FlashbangEffect { // empty }; diff --git a/addons/grenades/XEH_PREP.hpp b/addons/grenades/XEH_PREP.hpp index 6b5fb578016..06ceebc6b4f 100644 --- a/addons/grenades/XEH_PREP.hpp +++ b/addons/grenades/XEH_PREP.hpp @@ -1,8 +1,8 @@ - +PREP(addChangeFuseItemContextMenuOptions); +PREP(damageEngineAndWheels); PREP(flare); PREP(flashbangExplosionEH); PREP(flashbangThrownFuze); PREP(incendiary); PREP(nextMode); PREP(throwGrenade); -PREP(addChangeFuseItemContextMenuOptions); diff --git a/addons/grenades/XEH_postInit.sqf b/addons/grenades/XEH_postInit.sqf index 7f67e181ccc..c13bc81b43d 100644 --- a/addons/grenades/XEH_postInit.sqf +++ b/addons/grenades/XEH_postInit.sqf @@ -1,13 +1,15 @@ // by commy2 #include "script_component.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" -["ace_flashbangExploded", {_this call FUNC(flashbangExplosionEH)}] call CBA_fnc_addEventHandler; +["ace_flashbangExploded", LINKFUNC(flashbangExplosionEH)] call CBA_fnc_addEventHandler; +[QGVAR(damageEngineAndWheels), LINKFUNC(damageEngineAndWheels)] call CBA_fnc_addEventHandler; // Register fired event handlers -["ace_firedPlayer", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; -["ace_firedPlayerNonLocal", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; -["ace_firedNonPlayer", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; +["ace_firedPlayer", LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler; +["ace_firedPlayerNonLocal", LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler; +["ace_firedNonPlayer", LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler; if (!hasInterface) exitWith {}; @@ -15,20 +17,45 @@ GVAR(flashbangPPEffectCC) = ppEffectCreate ["ColorCorrections", 4265]; GVAR(flashbangPPEffectCC) ppEffectForceInNVG true; // Add keybinds -["ACE3 Weapons", QGVAR(switchGrenadeMode), localize LSTRING(SwitchGrenadeMode), { +["ACE3 Weapons", QGVAR(switchGrenadeMode), LLSTRING(SwitchGrenadeMode), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotEscorting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {false}; + // Don't change mode or show hint if advanced throwing is active if (ACE_player getVariable [QEGVAR(advanced_throwing,inHand), false]) exitWith {false}; // Statement - [] call FUNC(nextMode); -}, {false}, [9, [false, false, false]], false] call CBA_fnc_addKeybind; //8 Key + call FUNC(nextMode) // return +}, {}, [DIK_8, [false, false, false]], false] call CBA_fnc_addKeybind; // 8 Key ["CBA_settingsInitialized", { if (GVAR(convertExplosives)) then { - [] call FUNC(addChangeFuseItemContextMenuOptions); + call FUNC(addChangeFuseItemContextMenuOptions); }; }] call CBA_fnc_addEventHandler; + +["vehicle", { + private _currentThrowable = currentThrowable ACE_player; + + // Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle) + if !( + GVAR(currentThrowMode) == 3 && + {_currentThrowable isNotEqualTo []} && + { + !isNull objectParent ACE_player || + {getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL} + } + ) exitWith {}; + + // If the player can't use throwables, don't change it + if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {}; + + // Force the user into the normal throw mode + // Next throw mode after roll would be drop, which isn't ideal if the user tries to throw unknowingly... + [format [LLSTRING(RollGrenadeDisabled), LLSTRING(NormalThrow)], 2] call EFUNC(common,displayTextStructured); + + GVAR(currentThrowMode) = 0; + GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; +}, true] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/grenades/XEH_preInit.sqf b/addons/grenades/XEH_preInit.sqf index 894773534a4..9456dc9c9fb 100644 --- a/addons/grenades/XEH_preInit.sqf +++ b/addons/grenades/XEH_preInit.sqf @@ -6,6 +6,9 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +GVAR(currentThrowMode) = 0; +GVAR(throwModePFEH) = -1; + #include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf b/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf index d778ca33497..c0b5c9dc801 100644 --- a/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf +++ b/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Cyruz - * Allows conversion of explosive charges in to throwable versions + * Allows conversion of explosive charges into throwable versions. * * Arguments: * None @@ -14,7 +14,8 @@ * * Public: No */ - TRACE_1("addChangeFuseItemContextMenuOptions",_this); + +LOG("addChangeFuseItemContextMenuOptions"); { _x params ["_mag", "_throwableMag"]; @@ -29,21 +30,25 @@ {true}, { params ["", "", "_item", "", "_magArr"]; - _item isEqualTo (_magArr select 0); + + _item == (_magArr select 0) } ], { params ["_unit", "", "", "_slot", "_magArr"]; - private _container = ""; - switch _slot do { + + private _container = switch (_slot) do { case "UNIFORM_CONTAINER": { - _container = "uniform"; + "uniform" }; case "VEST_CONTAINER": { - _container = "vest"; + "vest" }; case "BACKPACK_CONTAINER": { - _container = "backpack"; + "backpack" + }; + default { + "" }; }; @@ -54,7 +59,7 @@ false }, true, - [_mag,_throwableMag] + [_mag, _throwableMag] ] call CBA_fnc_addItemContextMenuOption; [ @@ -67,21 +72,25 @@ {true}, { params ["", "", "_item", "", "_magArr"]; - _item isEqualTo (_magArr select 1); + + _item == (_magArr select 1) } ], { params ["_unit", "", "", "_slot", "_magArr"]; - private _container = ""; - switch _slot do { + + private _container = switch (_slot) do { case "UNIFORM_CONTAINER": { - _container = "uniform"; + "uniform" }; case "VEST_CONTAINER": { - _container = "vest"; + "vest" }; case "BACKPACK_CONTAINER": { - _container = "backpack"; + "backpack" + }; + default { + "" }; }; @@ -92,7 +101,7 @@ false }, true, - [_mag,_throwableMag] + [_mag, _throwableMag] ] call CBA_fnc_addItemContextMenuOption; } forEach [ ["SatchelCharge_Remote_Mag", "ACE_SatchelCharge_Remote_Mag_Throwable"], diff --git a/addons/grenades/functions/fnc_damageEngineAndWheels.sqf b/addons/grenades/functions/fnc_damageEngineAndWheels.sqf new file mode 100644 index 00000000000..ab95ecbe6a2 --- /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 8214a5600dc..2db6335a77a 100644 --- a/addons/grenades/functions/fnc_flare.sqf +++ b/addons/grenades/functions/fnc_flare.sqf @@ -4,7 +4,7 @@ * Makes flare shine. * * Arguments: - * 0: The flare + * 0: Flare * 1: Color of flare * 2: Intensity of flare * 3: Flare lifetime @@ -34,6 +34,5 @@ _light setLightFlareMaxDistance 1000; _light setLightDayLight true; _light lightAttachObject [_projectile, [0,0,0]]; -//_light attachTo [_projectile, [0,0,0]]; [{deleteVehicle _this}, _light, _timeToLive] call CBA_fnc_waitAndExecute; diff --git a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf index 36b84f942f2..a1be243b4fa 100644 --- a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf +++ b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf @@ -4,7 +4,7 @@ * Creates the flashbang effect and knock out AI units. * * Arguments: - * 0: The flashBang position ASL + * 0: Flashbang position ASL * * Return Value: * None @@ -18,152 +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; +// 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]) - [ACE_player]; - _light setLightBrightness 20; - _light setLightAmbient [1,1,1]; - _light setLightColor [1,1,1]; - _light setLightDayLight true; - _light setLightAttenuation [0, 1, 5, 1000, 0, 20]; +{ + private _unit = _x; + private _strength = 1 - (((eyePos _unit) vectorDistance _grenadePosASL) min 20) / 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; -}; + TRACE_3("FlashBangEffect Start",_unit,((getPosASL _unit) vectorDistance _grenadePosASL),_strength); -// Affect local AI -// @todo: Affect units in static weapons, turned out, etc -private _affected = (ASLtoAGL _grenadePosASL) nearEntities ["CAManBase", 20]; -_affected = _affected - [ACE_player]; -{ - if (local _x && {alive _x}) then { - private _unit = _x; - private _strength = 1 - (((eyePos _unit) vectorDistance _grenadePosASL) min 20) / 20; + [_unit, true] call EFUNC(common,disableAI); + + // Make AI try to look away + private _dirToFlash = _unit getDir _grenadePosASL; + _unit setDir (_dirToFlash + linearConversion [0.2, 1, _strength, 40, 135] * selectRandom [-1, 1]); + + private _flashReactionDebounce = _unit getVariable [QGVAR(flashReactionDebounce), 0]; + _unit setVariable [QGVAR(flashReactionDebounce), _flashReactionDebounce max (CBA_missionTime + (7 * _strength))]; - TRACE_3("FlashBangEffect Start",_unit,((getPosASL _unit) vectorDistance _grenadePosASL),_strength); + if (_flashReactionDebounce < CBA_missionTime) then { + // Not used internally but could be useful for other mods + _unit setVariable [QGVAR(flashStrength), _strength, true]; - [_unit, true] call EFUNC(common,disableAI); + [QGVAR(flashbangedAI), [_unit, _strength, _grenadePosASL]] call CBA_fnc_localEvent; - // Make AI try to look away - private _dirToFlash = _unit getDir _grenadePosASL; - _unit setDir (_dirToFlash + linearConversion [0.2, 1, _strength, 40, 135] * selectRandom [-1, 1]); + { + _unit setSkill [_x, (_unit skill _x) / 50]; + } forEach SUBSKILLS; + + [{ + CBA_missiontime >= _this getVariable [QGVAR(flashReactionDebounce), 0] + }, { + params ["_unit"]; + + _unit setVariable [QGVAR(flashStrength), 0, true]; + + // Make sure we don't enable AI for unconscious units + if (_unit call EFUNC(common,isAwake)) then { + [_unit, false] call EFUNC(common,disableAI); + }; - private _flashReactionDebounce = _unit getVariable [QGVAR(flashReactionDebounce), 0]; - _unit setVariable [QGVAR(flashReactionDebounce), _flashReactionDebounce max (CBA_missionTime + (7 * _strength))]; - if (_flashReactionDebounce < CBA_missionTime) then { - // Not used interally but could be useful for other mods - _unit setVariable [QGVAR(flashStrength), _strength, true]; - [QGVAR(flashbangedAI), [_unit, _strength, _grenadePosASL]] call CBA_fnc_localEvent; { - _unit setSkill [_x, (_unit skill _x) / 50]; + _unit setSkill [_x, (_unit skill _x) * 50]; } forEach SUBSKILLS; - [{ - params ["_unit"]; - CBA_missiontime >= _unit getVariable [QGVAR(flashReactionDebounce), 0] - },{ - params ["_unit"]; - - _unit setVariable [QGVAR(flashStrength), 0, true]; - - // Make sure we don't enable AI for unconscious units - if !(_unit getVariable ["ace_isUnconscious", false]) then { - [_unit, false] call EFUNC(common,disableAI); - }; - { - _unit setSkill [_x, (_unit skill _x) * 50]; - } forEach SUBSKILLS; - }, [_unit]] call CBA_fnc_waitUntilAndExecute; - }; + }, _unit] call CBA_fnc_waitUntilAndExecute; }; -} count _affected; +} forEach (_affected select {local _x && {_x call EFUNC(common,isAwake)}}); -// Affect local player, independently of distance -if (hasInterface && {!isNull ACE_player} && {alive ACE_player}) then { - if ((getNumber (configOf ACE_player >> "isPlayableLogic")) == 1) exitWith { - TRACE_1("skipping playable logic",typeOf ACE_player); // VirtualMan_F (placeable logic zeus / spectator) - }; - // Do effects for player - // is there line of sight to the grenade? - private _eyePos = eyePos ACE_player; //PositionASL - _grenadePosASL set [2, (_grenadePosASL select 2) + 0.2]; // compensate for grenade glitching into ground - - 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; +if (!hasInterface) exitWith {}; - // 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); - }; +// Create flash to illuminate environment +private _light = "#lightpoint" createVehicleLocal ASLToAGL _grenadePosASL; +_light setPosASL _grenadePosASL; - // add ace_medical pain effect: - if (["ace_medical"] call EFUNC(common,isModLoaded) && {_strength > 0.1}) then { - [ACE_player, _strength / 2] call EFUNC(medical,adjustPainLevel); - }; +_light setLightBrightness 20; +_light setLightAmbient [1,1,1]; +_light setLightColor [1,1,1]; +_light setLightDayLight true; +_light setLightAttenuation [0, 1, 5, 1000, 0, 20]; - // 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); - }; +// Reduce the light after 0.1 seconds +[{ + _this setLightBrightness 5; - // Blind player - if (_strength > 0.1) then { - private _blend = [[1,1,1,0], [0.3,0.3,0.3,1]] select EGVAR(common,epilepsyFriendlyMode); + // Delete the light after 0.2 more seconds + [{deleteVehicle _this}, _this, 0.2] call CBA_fnc_waitAndExecute; +}, _light, 0.1] call CBA_fnc_waitAndExecute; - 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; +// Ignore dead and placeable logic (zeus / spectator) +if (!alive ACE_player || {(getNumber (configOf ACE_player >> "isPlayableLogic")) == 1}) exitWith {}; - //PARTIALRECOVERY - start decreasing effect over time - [{ - params ["_strength"]; +// Affect local player, independently of distance +// 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; + +// 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); + +private _losCoefficient = [1, 0.1] select (_losCount <= 1); +_strength = _strength * _losCoefficient; + +// 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); +}; - 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; +// Add ace_medical pain effect +if (GETEGVAR(medical,enabled,false) && {_strength > 0.1} && {isDamageAllowed ACE_player} && {ACE_player getVariable [QEGVAR(medical,allowDamage), true]}) then { + [ACE_player, _strength / 2] call EFUNC(medical,adjustPainLevel); +}; - //FULLRECOVERY - end effect - [{ - GVAR(flashbangPPEffectCC) ppEffectEnable false; - }, [], 17 * _strength] call CBA_fnc_waitAndExecute; - }; +// Effect on vision has a wider range, with a higher falloff +_strength = 1 - (((_eyePos vectorDistance _grenadePosASL) min 25) / 25) ^ 0.4; +_strength = _strength * _losCoefficient; - // 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); +// 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)); - [QGVAR(flashbangedPlayer), [_strength, _grenadePosASL]] call CBA_fnc_localEvent; +// From 0-45deg, full effect +if (_angleDiff > 45) then { + _strength = _strength * ((1 - (_angleDiff - 45) / (120 - 45)) max 0); }; -true + +// 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 7f1a52417cf..89020842d2a 100644 --- a/addons/grenades/functions/fnc_flashbangThrownFuze.sqf +++ b/addons/grenades/functions/fnc_flashbangThrownFuze.sqf @@ -4,7 +4,7 @@ * Waits for the flashbang grenade fuze to trigger and 'explode' * * Arguments: - * 0: projectile - Flashbang Grenade + * 0: Flashbang grenade * * Return Value: * None @@ -18,8 +18,17 @@ params ["_projectile"]; TRACE_1("params",_projectile); -if (alive _projectile) then { - playSound3D ["A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_01.wss", _projectile, false, getPosASL _projectile, 5, 1.2, 400]; +if (!alive _projectile) exitWith {}; - ["ace_flashbangExploded", [getPosASL _projectile]] call CBA_fnc_globalEvent; -}; +private _posASL = getPosASL _projectile; +private _sounds = getArray (_projectile call CBA_fnc_getObjectConfig >> QGVAR(flashbangExplodeSound)); + +(if (_sounds isEqualTo []) then { + [format ["A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_0%1.wss", floor (random 4) + 1], 5, 1.2, 400] +} else { + selectRandom _sounds +}) params ["_file", "_volume", "_pitch", "_distance"]; + +playSound3D [_file, _projectile, false, _posASL, _volume, _pitch, _distance]; + +["ace_flashbangExploded", [_posASL]] call CBA_fnc_globalEvent; diff --git a/addons/grenades/functions/fnc_incendiary.sqf b/addons/grenades/functions/fnc_incendiary.sqf index 11d89d4ca53..9d416c5e115 100644 --- a/addons/grenades/functions/fnc_incendiary.sqf +++ b/addons/grenades/functions/fnc_incendiary.sqf @@ -1,11 +1,12 @@ #include "..\script_component.hpp" /* * Author: commy2 - * Makes incendiary burn. + * Makes an incendiary grenade burn. * * Arguments: - * 0: The grenade + * 0: Incendiary grenade * 1: Incendiary lifetime + * 2: Instigator's side * * Return Value: * None @@ -30,11 +31,11 @@ #define PARTICLE_SMOKE_LIFTING 1 #define PARTICLE_SMOKE_WIND_EFFECT 1 -#define EFFECT_SIZE 1 #define ORIENTATION 5.4 #define EXPANSION 1 #define DESTRUCTION_RADIUS 1.8 +#define SEARCH_RADIUS 5 params ["_projectile", "_timeToLive", "_center"]; @@ -42,16 +43,16 @@ if (isNull _projectile) exitWith {TRACE_1("null",_projectile);}; private _position = position _projectile; -// --- AI +// Alert nearby hostile AI private _nearLocalEnemies = []; { { - if (local _x && {[_center, side _x] call BIS_fnc_sideIsEnemy}) then { // WE WANT THE OBJECTS SIDE HERE! + if (local _x && {[_center, side group _x] call BIS_fnc_sideIsEnemy}) then { // WE WANT THE OBJECT'S SIDE HERE! _nearLocalEnemies pushBackUnique _x; }; } forEach crew _x; -} forEach (_position nearObjects ALERT_NEAR_ENEMY_RANGE); +} forEach (_position nearObjects ALERT_NEAR_ENEMY_RANGE); //@todo replace with nearEntities in 2.18 { if (behaviour _x in ["SAFE", "AWARE"]) then { @@ -59,7 +60,7 @@ private _nearLocalEnemies = []; }; } forEach _nearLocalEnemies; -// --- fire +// Fire particles private _fire = "#particlesource" createVehicleLocal _position; _fire setParticleParams [ @@ -99,7 +100,7 @@ _fire setParticleRandom [PARTICLE_LIFE_TIME / 4, [0.15 * EFFECT_SIZE, 0.15 * EFF _fire setParticleFire [1.2,1.0,0.1]; _fire setDropInterval (1 / PARTICLE_DENSITY); -// --- smoke +// Smoke particles private _smoke = "#particlesource" createVehicleLocal _position; _smoke setParticleParams [ @@ -137,7 +138,7 @@ _smoke setParticleParams [ _smoke setParticleRandom [PARTICLE_SMOKE_LIFE_TIME / 2, [0.5 * EFFECT_SIZE, 0.5 * EFFECT_SIZE, 0.2 * EFFECT_SIZE], [0.3,0.3,0.5], 1, 0, [0,0,0,0.06], 0, 0]; _smoke setDropInterval (1 / PARTICLE_SMOKE_DENSITY); -// --- light +// Light private _light = "#lightpoint" createVehicleLocal (_position vectorAdd [0,0,0.5]); _light setLightBrightness 1.0; @@ -150,92 +151,72 @@ _light setLightDayLight false; _light lightAttachObject [_projectile, [0,0,0]]; -// --- sound +// Sound private _sound = objNull; if (isServer) then { _sound = createSoundSource ["Sound_Fire", _position, [], 0]; private _radius = 1.5 * getNumber (configOf _projectile >> "indirectHitRange"); private _intensity = getNumber (configOf _projectile >> "hit"); - [QEGVAR(fire,addFireSource), [_projectile, _radius, _intensity, _projectile, {CBA_missionTime < _this}, CBA_missionTime + _timeToLive]] call CBA_fnc_serverEvent; -}; - -[{ - {deleteVehicle _x} forEach _this; -}, [_fire, _smoke, _light, _sound], _timeToLive] call CBA_fnc_waitAndExecute; - -// --- damage -{ - if (local _x) then { - //systemChat format ["burn: %1", _x]; - // --- destroy nearby static weapons and ammo boxes - if (_x isKindOf "StaticWeapon" || {_x isKindOf "ACE_RepairItem_Base"}) then { - _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; - }; - }; + [QEGVAR(fire,addFireSource), [_projectile, _radius, _intensity, _projectile, { + params ["_endTime", "_projectile"]; - // --- delete nearby ground weapon holders - if (_x isKindOf "WeaponHolder" || {_x isKindOf "WeaponHolderSimulated"}) then { - deleteVehicle _x; + // If incendiary no longer exists, exit + if (isNull _projectile) exitWith { + false // return }; - // --- inflame fireplace, barrels etc. - _x inflame true; - }; -} forEach (_position nearObjects DESTRUCTION_RADIUS); - -// --- damage local vehicle -private _vehicle = _position nearestObject "Car"; - -if (!local _vehicle) exitWith {}; - -private _config = configOf _vehicle; + // Need to get the position every time, as grenade might have been moved + private _position = position _projectile; -// --- burn tyres -private _fnc_isWheelHitPoint = { - params ["_selectionName"]; + { + // Damage vehicles + [QGVAR(damageEngineAndWheels), [_x, _position], _x] call CBA_fnc_targetEvent; + } forEach (_position nearEntities ["Car", SEARCH_RADIUS]); - // 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 + 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 { - private _wheelSelection = getText (_config >> "HitPoints" >> _x >> "name"); + // Inflame fireplace, barrels etc. + _x inflame true; - if (_wheelSelection call _fnc_isWheelHitPoint) then { - private _wheelPosition = _vehicle modelToWorld (_vehicle selectionPosition _wheelSelection); + // Destroy nearby static weapons and ammo boxes + if (_x isKindOf "StaticWeapon" || {_x isKindOf "ACE_RepairItem_Base"}) then { + _x setDamage 1; - if (_position distance _wheelPosition < EFFECT_SIZE * 2) then { - _vehicle setHit [_wheelSelection, 1]; - }; + continue; }; -} 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 (_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), _x] call CBA_fnc_serverEvent; + } else { + _x setDamage 1; + }; -if (_position distance _enginePosition < EFFECT_SIZE * 2) then { - _vehicle setHit [_engineSelection, 1]; + continue; + }; - if ("ace_cookoff" call EFUNC(common,isModLoaded)) then { - private _enabled = _vehicle getVariable [QEGVAR(cookoff,enable), EGVAR(cookoff,enable)]; - if (_enabled in [2, true] || {_enabled isEqualTo 1 && {fullCrew [_vehicle, "", false] findIf {isPlayer (_x select 0)} != -1}}) then { - _vehicle call EFUNC(cookoff,engineFire); - }; + // 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}}); + +{ + // 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 1a64cf9f7ba..f33fa7a5a5d 100644 --- a/addons/grenades/functions/fnc_nextMode.sqf +++ b/addons/grenades/functions/fnc_nextMode.sqf @@ -7,25 +7,29 @@ * 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 { - _mode = _mode + 1; -}; +private _currentThrowable = currentThrowable ACE_player; -// ROLL GRENADE DOESN'T WORK RIGHT NOW -if (_mode == 3) then { - _mode = 4; +// 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; }; private _hint = localize ([ @@ -38,6 +42,37 @@ private _hint = localize ([ [_hint] call EFUNC(common,displayTextStructured); +GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; GVAR(currentThrowMode) = _mode; +// If in rolling mode, check every frame if current throwable is rollable +if (GVAR(currentThrowMode) == 3) then { + GVAR(currentThrowable) = _currentThrowable; + + GVAR(throwModePFEH) = { + private _currentThrowable = currentThrowable ACE_player; + + if (GVAR(currentThrowable) isEqualTo _currentThrowable) exitWith {}; + + GVAR(currentThrowable) = _currentThrowable; + + // Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle) + if !( + GVAR(currentThrowMode) == 3 && + {_currentThrowable isNotEqualTo []} && + { + !isNull objectParent ACE_player || + {getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL} + } + ) exitWith {}; + + // Force the user into the normal throw mode + // Next throw mode after roll would be drop, which isn't ideal if the user tries to throw unknowingly... + [format [LLSTRING(RollGrenadeDisabled), LLSTRING(NormalThrow)], 2] call EFUNC(common,displayTextStructured); + + GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; + GVAR(currentThrowMode) = 0; + } call CBA_fnc_addPerFrameHandler; +}; + true diff --git a/addons/grenades/functions/fnc_throwGrenade.sqf b/addons/grenades/functions/fnc_throwGrenade.sqf index 9a0168da3ea..a440c8fd1b7 100644 --- a/addons/grenades/functions/fnc_throwGrenade.sqf +++ b/addons/grenades/functions/fnc_throwGrenade.sqf @@ -27,40 +27,26 @@ if (isNull _projectile) then { private _config = configFile >> "CfgAmmo" >> _ammo; -// handle special grenades and sounds +// Handle special grenades and sounds if (local _unit) then { - // handle priming sound, if present - private _soundConfig = getArray (configFile >> "CfgAmmo" >> _ammo >> QGVAR(pullPinSound)); + // Handle priming sound, if present + private _soundConfig = getArray (_config >> QGVAR(pullPinSound)); + if (_soundConfig isNotEqualTo []) then { _soundConfig params ["_file", "_volume", "_pitch", "_distance"]; - playSound3D [_file, objNull, false, getPosASL _projectile, _volume, _pitch, _distance]; + playSound3D [_file, objNull, insideBuilding _unit >= 0.5, getPosASL _projectile, _volume, _pitch, _distance]; }; if (getNumber (_config >> QGVAR(flashbang)) == 1) then { - private _bangs = 1; - private _entry = _config >> QGVAR(flashbangBangs); - if (isNumber _entry || isText _entry) then { - _bangs = getNumber _entry; - }; - private _fuzeTimeBase = getNumber (_config >> "explosionTime"); - - private _interval = 0.5; - _entry = _config >> QGVAR(flashbangInterval); - if (isNumber _entry || isText _entry) then { - _interval = getNumber _entry; - }; - - private _maxDeviation = 0.1; - _entry = _config >> QGVAR(flashbangIntervalMaxDeviation); - if (isNumber _entry || isText _entry) then { - _maxDeviation = getNumber _entry; - }; + private _bangs = [_config >> QGVAR(flashbangBangs), "NUMBER", 1] call CBA_fnc_getConfigEntry; + private _interval = [_config >> QGVAR(flashbangInterval), "NUMBER", 0.5] call CBA_fnc_getConfigEntry; + private _maxDeviation = [_config >> QGVAR(flashbangIntervalMaxDeviation), "NUMBER", 0.1] call CBA_fnc_getConfigEntry; for "_i" from 0 to (_bangs - 1) do { - private _fuzeTime = _fuzeTimeBase + _i*_interval + random [- _maxDeviation, 0, _maxDeviation]; + private _fuzeTime = _fuzeTimeBase + _i * _interval + random [-_maxDeviation, 0, _maxDeviation]; - [FUNC(flashbangThrownFuze), [_projectile], _fuzeTime] call CBA_fnc_waitAndExecute; + [LINKFUNC(flashbangThrownFuze), _projectile, _fuzeTime] call CBA_fnc_waitAndExecute; }; }; }; @@ -71,47 +57,56 @@ if (getNumber (_config >> QGVAR(flare)) == 1) then { private _color = getArray (_config >> QGVAR(color)); private _intensity = _color deleteAt 3; - [FUNC(flare), [_projectile, _color, _intensity, _timeToLive], _fuzeTime] call CBA_fnc_waitAndExecute; + [LINKFUNC(flare), [_projectile, _color, _intensity, _timeToLive], _fuzeTime] call CBA_fnc_waitAndExecute; }; if (getNumber (_config >> QGVAR(incendiary)) == 1) then { private _fuzeTime = getNumber (_config >> "explosionTime"); private _timeToLive = getNumber (_config >> "timeToLive"); - [FUNC(incendiary), [_projectile, _timeToLive, side _unit], _fuzeTime] call CBA_fnc_waitAndExecute; // WE WANT THE OBJECTS SIDE HERE! + [LINKFUNC(incendiary), [_projectile, _timeToLive, side group _unit], _fuzeTime] call CBA_fnc_waitAndExecute; // Get the unit's real side (will return civilian if unconscious) }; -// handle throw modes +// Handle throw modes if (_unit != ACE_player) exitWith {}; if (_unit getVariable [QEGVAR(advanced_throwing,primed), false]) exitWith {LOG("advanced_throwing throw");}; -private _mode = missionNamespace getVariable [QGVAR(currentThrowMode), 0]; +if (GVAR(currentThrowMode) == 0) exitWith {}; -if (_mode != 0) then { - private _velocity = velocity _projectile; +private _velocity = velocity _projectile; - switch (_mode) do { - //high throw - case 1 : { - _velocity = [ - 0.5 * (_velocity select 0), - 0.5 * (_velocity select 1), - [0, 0, 0] distance (_velocity vectorMultiply 0.5) - ]; - }; - //precise throw - case 2 : { - _velocity = (_unit weaponDirection _weapon) vectorMultiply (vectorMagnitude _velocity); - }; - //roll grande - case 3 : { - //@todo - }; - //drop grenade - case 4 : { - _velocity = [0, 0, 0]; - }; +switch (GVAR(currentThrowMode)) do { + // High throw + case 1: { + _velocity = _velocity vectorMultiply 0.5; + + _velocity set [2, vectorMagnitude _velocity]; + }; + // Precise throw + case 2: { + _velocity = (_unit weaponDirection _weapon) vectorMultiply (vectorMagnitude _velocity); }; + // Roll grenade + case 3: { + private _posASL = getPosASL _projectile; + + // 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]]; - _projectile setVelocity _velocity; + // Do as if object were facing north + _projectile setVectorDirAndUp ([[_vectorDir, _vectorUp], -(direction _projectile), 0, 0] call BIS_fnc_transformVectorDirAndUp); + + _velocity = (vectorDir _unit) vectorMultiply 10; + }; + // Drop grenade + case 4: { + _velocity = [0, 0, 0]; + }; }; + +_projectile setVelocity _velocity; diff --git a/addons/grenades/initSettings.inc.sqf b/addons/grenades/initSettings.inc.sqf index b6fa36f459c..6a6ceb8c37b 100644 --- a/addons/grenades/initSettings.inc.sqf +++ b/addons/grenades/initSettings.inc.sqf @@ -1,9 +1,10 @@ [ - QGVAR(convertExplosives), "CHECKBOX", + QGVAR(convertExplosives), + "CHECKBOX", [LSTRING(convertExplosives_DisplayName), LSTRING(convertExplosives_Description)], LSTRING(Settings_DisplayName), true, - true, - {}, - true + 1, + {[QGVAR(convertExplosives), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; diff --git a/addons/grenades/script_component.hpp b/addons/grenades/script_component.hpp index 49dbe92a3f3..e49fa21ca90 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 d5c1b142a65..3e08275cbf1 100644 --- a/addons/grenades/stringtable.xml +++ b/addons/grenades/stringtable.xml @@ -103,6 +103,16 @@ 下丟投擲 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 + Grenade ne peut pas rouler, passé à %1 + No se puede rodar esta granada, cambiando a %1 + M84 Stun Grenade M84 Blendgranate @@ -149,7 +159,7 @@ Anche conosciuta come flashbang. Causa accecamento immediato, sensazioni di sposatezza, mancanza d'equilibrio e disturbi al timpano. Também conhecida como flashbang. Causa uma clarão imediato, cegueira, surdez, zumbido e distúrbio no tímpano. フラッシュバンとも知られています。即時に失明と難聴、耳鳴り、内耳障害を引き起こします。 - 플래시뱅이라고도 알려져있습니다. 사용 즉시 섬광으로 인한 시력장애, 청각장애, 이명, 내이기관방해를 유발합니다. + 플래시뱅이라고도 알려져 있습니다. 사용 즉시 섬광으로 인한 시력장애, 청각장애, 이명, 내이기관방해를 유발합니다. 也被称为闪光弹,会造成暂时性失明,耳聋,耳鸣等效果。 也被稱為閃光彈,會造成暫時性失明,耳聾,耳鳴等效果 Flashbang olarak da bilinir. Ani flaş körlüğü, sağırlık, kulak çınlaması ve iç kulak rahatsızlığına neden olur. diff --git a/addons/gunbag/functions/fnc_calculateMass.sqf b/addons/gunbag/functions/fnc_calculateMass.sqf index 6dd6a5a660d..b614d95f587 100644 --- a/addons/gunbag/functions/fnc_calculateMass.sqf +++ b/addons/gunbag/functions/fnc_calculateMass.sqf @@ -23,7 +23,7 @@ private _mass = getNumber (configFile >> "CfgWeapons" >> _weapon >> "WeaponSlots { _mass = _mass + getNumber (configFile >> "CfgWeapons" >> _x >> "ItemInfo" >> "mass"); -} foreach _items; +} forEach _items; { _mass = _mass + getNumber (configFile >> "CfgMagazines" >> _x >> "mass"); diff --git a/addons/gunbag/functions/fnc_isMachineGun.sqf b/addons/gunbag/functions/fnc_isMachineGun.sqf index f07866a4aa5..e6e4e5c96cd 100644 --- a/addons/gunbag/functions/fnc_isMachineGun.sqf +++ b/addons/gunbag/functions/fnc_isMachineGun.sqf @@ -22,7 +22,7 @@ private _config = _weapon call CBA_fnc_getItemConfig; // definition of a machine gun by BIS_fnc_itemType private _cursor = getText (_config >> "cursor"); -if (toLower _cursor in ["", "emptycursor"]) then { +if (toLowerANSI _cursor in ["", "emptycursor"]) then { _cursor = getText (_config >> "cursorAim"); }; diff --git a/addons/gunbag/functions/fnc_offGunbagCallback.sqf b/addons/gunbag/functions/fnc_offGunbagCallback.sqf index 8edd3e4582b..68b22fb1ef3 100644 --- a/addons/gunbag/functions/fnc_offGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_offGunbagCallback.sqf @@ -11,7 +11,7 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_offGunbagCallback + * [player, cursorObject] call ace_gunbag_fnc_offGunbagCallback * * Public: No */ @@ -23,39 +23,28 @@ private _gunbag = backpackContainer _target; private _state = _gunbag getVariable [QGVAR(gunbagWeapon), []]; if (_state isEqualTo []) exitWith { - [localize LSTRING(empty)] call EFUNC(common,displayTextStructured); + [LLSTRING(empty)] call EFUNC(common,displayTextStructured); }; _state params ["_weapon", "_items", "_magazines"]; -_unit addWeapon _weapon; +[_unit, _weapon, true, _magazines] call EFUNC(common,addWeapon); -// Game will auto add magazines from player's inventory, put these back in player inventory as they will be overwritten -([_unit, _weapon] call EFUNC(common,getWeaponState)) params ["", "", "_addedMags", "_addedAmmo"]; +// Add attachments { - if (((_x select 0) != "") && {(_addedMags select _forEachIndex) != ""}) then { - TRACE_2("Re-adding mag",_x,_addedMags select _forEachIndex); - _unit addMagazine [_addedMags select _forEachIndex, _addedAmmo select _forEachIndex]; - }; -} forEach _magazines; - -removeAllPrimaryWeaponItems _unit; - -{ - _unit addWeaponItem [_weapon, _x]; -} forEach (_items + _magazines); + _unit addWeaponItem [_weapon, _x, true]; +} forEach (_items select {_x != ""}); _unit selectWeapon _weapon; -_magazines = _magazines apply {_x select 0}; +private _mass = [_weapon, _items, _magazines apply {_x select 0}] call FUNC(calculateMass); -private _mass = [_weapon, _items, _magazines] call FUNC(calculateMass); - -// remove virtual load +// Remove virtual load [_target, _gunbag, -_mass] call EFUNC(movement,addLoadToUnitContainer); + _gunbag setVariable [QGVAR(gunbagWeapon), [], true]; -// play sound +// Play sound if (["ace_backpacks"] call EFUNC(common,isModLoaded)) then { [_target, _gunbag] call EFUNC(backpacks,backpackOpened); }; diff --git a/addons/gunbag/functions/fnc_swapGunbagCallback.sqf b/addons/gunbag/functions/fnc_swapGunbagCallback.sqf index a7d319506bf..cb4bca2ea4a 100644 --- a/addons/gunbag/functions/fnc_swapGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_swapGunbagCallback.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: Ir0n1E and mjc4wilton + * Author: Ir0n1E, mjc4wilton * Swap primary weapon and weapon in gunbag. * * Arguments: @@ -11,66 +11,49 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_swapGunbagCallback + * [player, cursorObject] call ace_gunbag_fnc_swapGunbagCallback * * Public: No */ params ["_unit", "_target"]; -private _currentWeapon = primaryWeapon _unit; //Get Current Weapon -private _gunbag = backpackContainer _target; - - -//---Set up current weapon for storing -private _currentWeaponState = [_unit, _currentWeapon] call EFUNC(common,getWeaponState); //Gets weapon attachments -/* - * example return value _state - * [["","","optic_Aco",""],["arifle_MX_GL_ACO_F","GL_3GL_F"],["30Rnd_65x39_caseless_mag","1Rnd_HE_Grenade_shell"],[30,1]] - */ +// Set up current weapon for storing +private _gunbag = backpackContainer _target; +private _currentItems = (getUnitLoadout _unit) select 0; -_currentWeaponState params ["_currentWeaponItems", "", "_currentWeaponMagazines", "_currentWeaponAmmo"]; //Extract Weapon Attachments to separate arrays +private _currentMagazines = _currentItems select [4, 2]; +_currentItems deleteRange [4, 2]; -private _currentWeaponMass = [_currentWeapon, _currentWeaponItems, _currentWeaponMagazines] call FUNC(calculateMass); +private _currentWeapon = _currentItems deleteAt 0; -{ - _currentWeaponMagazines set [_forEachIndex, [_x, _currentWeaponAmmo select _forEachIndex]]; -} forEach _currentWeaponMagazines; +private _currentMass = [_currentWeapon, _currentItems, _currentMagazines apply {_x select 0}] call FUNC(calculateMass); -//---Set up weapon in gunbag -private _newWeaponState = _gunbag getVariable [QGVAR(gunbagWeapon), []]; +// Set up weapon in gunbag +private _newState = _gunbag getVariable [QGVAR(gunbagWeapon), []]; -if (_newWeaponState isEqualTo []) exitWith { +if (_newState isEqualTo []) exitWith { [LLSTRING(empty)] call EFUNC(common,displayTextStructured); }; -_newWeaponState params ["_newWeapon", "_newWeaponItems", "_newWeaponMagazines"]; +_newState params ["_newWeapon", "_newItems", "_newMagazines"]; -//---Swap Weapons +// Swap Weapons _unit removeWeapon _currentWeapon; -_unit addWeapon _newWeapon; - -// Game will auto add magazines from player's inventory, put these back in player inventory as they will be overwritten -([_unit, _newWeapon] call EFUNC(common,getWeaponState)) params ["", "", "_addedMags", "_addedAmmo"]; -{ - if (((_x select 0) != "") && {(_addedMags select _forEachIndex) != ""}) then { - TRACE_2("Re-adding mag",_x,_addedMags select _forEachIndex); - _unit addMagazine [_addedMags select _forEachIndex, _addedAmmo select _forEachIndex]; - }; -} forEach _newWeaponMagazines; -removeAllPrimaryWeaponItems _unit; +[_unit, _newWeapon, true, _newMagazines] call EFUNC(common,addWeapon); +// Add attachments { - _unit addWeaponItem [_newWeapon, _x]; -} forEach (_newWeaponItems + _newWeaponMagazines); + _unit addWeaponItem [_newWeapon, _x, true]; +} forEach (_newItems select {_x != ""}); _unit selectWeapon _newWeapon; -_newWeaponMagazines = _newWeaponMagazines apply {_x select 0}; +private _newMass = [_newWeapon, _newItems, _newMagazines apply {_x select 0}] call FUNC(calculateMass); -private _newWeaponMass = [_newWeapon, _newWeaponItems, _newWeaponMagazines] call FUNC(calculateMass); +// Update virtual load +[_target, _gunbag, _currentMass - _newMass] call EFUNC(movement,addLoadToUnitContainer); -// update virtual load -[_target, _gunbag, _currentWeaponMass - _newWeaponMass] call EFUNC(movement,addLoadToUnitContainer); -_gunbag setVariable [QGVAR(gunbagWeapon), [_currentWeapon, _currentWeaponItems, _currentWeaponMagazines], true]; //Replace weapon in gunbag +// Replace weapon in gunbag +_gunbag setVariable [QGVAR(gunbagWeapon), [_currentWeapon, _currentItems, _currentMagazines], true]; diff --git a/addons/gunbag/functions/fnc_toGunbagCallback.sqf b/addons/gunbag/functions/fnc_toGunbagCallback.sqf index 4930d1d95ae..9958eed32b6 100644 --- a/addons/gunbag/functions/fnc_toGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_toGunbagCallback.sqf @@ -11,38 +11,32 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_toGunbagCallback + * [player, cursorObject] call ace_gunbag_fnc_toGunbagCallback * * Public: No */ params ["_unit", "_target"]; -private _weapon = primaryWeapon _unit; +// Set up current weapon for storing private _gunbag = backpackContainer _target; +private _items = (getUnitLoadout _unit) select 0; -private _state = [_unit, _weapon] call EFUNC(common,getWeaponState); +private _magazines = _items select [4, 2]; +_items deleteRange [4, 2]; -/* - * example return value _state - * [["","","optic_Aco",""],["arifle_MX_GL_ACO_F","GL_3GL_F"],["30Rnd_65x39_caseless_mag","1Rnd_HE_Grenade_shell"],[30,1]] - */ - -_state params ["_items", "", "_magazines", "_ammo"]; +private _weapon = _items deleteAt 0; -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/stringtable.xml b/addons/gunbag/stringtable.xml index cf7198f41e9..6389a667c84 100644 --- a/addons/gunbag/stringtable.xml +++ b/addons/gunbag/stringtable.xml @@ -19,12 +19,12 @@ Gunbag (Tan) - Waffentasche (hellbraun) - Housse d'arme (marron clair) + Waffentasche (Hellbraun) + Housse d'arme (Marron clair) Чехол (желтовато-коричневый) Pouzdro na zbraň (Žlutohnědá) ガンバッグ (タン) - Torba na broń (jasnobrązowa) + Torba na broń (Jasnobrązowa) 총가방 (황갈색) Borsa per Armi (Marroncina) 枪袋(黄褐色) diff --git a/addons/headless/XEH_PREP.hpp b/addons/headless/XEH_PREP.hpp index 11e09adf100..e1c65cc083d 100644 --- a/addons/headless/XEH_PREP.hpp +++ b/addons/headless/XEH_PREP.hpp @@ -1,3 +1,4 @@ +ACEX_PREP(blacklist); ACEX_PREP(endMissionNoPlayers); ACEX_PREP(handleConnectHC); ACEX_PREP(handleDisconnect); diff --git a/addons/headless/XEH_postInit.sqf b/addons/headless/XEH_postInit.sqf index 103d5c18342..90677042f45 100644 --- a/addons/headless/XEH_postInit.sqf +++ b/addons/headless/XEH_postInit.sqf @@ -1,15 +1,49 @@ #include "script_component.hpp" -["ace_settingsInitialized", { +if (!isMultiplayer) exitWith {}; + +["CBA_settingsInitialized", { // Register and remove HCs if not client that is not server and distribution or end mission enabled if ((!hasInterface || isServer) && {XGVAR(enabled) || XGVAR(endMission) != 0}) then { if (isServer) then { // Request rebalance on any unit spawn (only if distribution enabled) if (XGVAR(enabled)) then { - ["AllVehicles", "initPost", FUNC(handleSpawn), nil, nil, true] call CBA_fnc_addClassEventHandler; + ["CAManBase", "initPost", LINKFUNC(handleSpawn), nil, nil, true] call CBA_fnc_addClassEventHandler; }; // Add disconnect EH addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; + + [QGVAR(transferGroupsRebalance), { + params ["_groups", "_owner", "_rebalance"]; + + if (_groups isNotEqualTo [] && {_owner > 1}) then { + { + _x setGroupOwner _owner; + } forEach _groups; + }; + + // Rebalance units + if (_rebalance in [REBALANCE, FORCED_REBALANCE]) then { + (_rebalance == FORCED_REBALANCE) call FUNC(rebalance); + }; + }] call CBA_fnc_addEventHandler; + + // If CBA's loadout validation is enabled, warn users + if (XGVAR(transferLoadout) > 0 && {(missionNamespace getVariable ["CBA_network_loadoutValidation", 0]) isEqualTo 2}) then { + WARNING("CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled"); + [QEGVAR(common,displayTextStructured), ["CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled", 3]] call CBA_fnc_globalEvent; + }; + + ["CBA_SettingChanged", { + params ["_setting", "_value"]; + + if (_setting != "CBA_network_loadoutValidation") exitWith {}; + + if (XGVAR(transferLoadout) > 0 && {_value isEqualTo 2}) then { + WARNING("CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled"); + [QEGVAR(common,displayTextStructured), ["CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled", 3]] call CBA_fnc_globalEvent; + }; + }] call CBA_fnc_addEventHandler; } else { // Register HC (this part happens on HC only) [QXGVAR(headlessClientJoined), [player]] call CBA_fnc_globalEvent; // Global event for API purposes diff --git a/addons/headless/XEH_preInit.sqf b/addons/headless/XEH_preInit.sqf index bd64702f5cb..c51b62cf578 100644 --- a/addons/headless/XEH_preInit.sqf +++ b/addons/headless/XEH_preInit.sqf @@ -12,8 +12,7 @@ if (isServer) then { GVAR(headlessClients) = []; GVAR(inRebalance) = false; GVAR(endMissionCheckDelayed) = false; - GVAR(blacklistType) = [BLACKLIST_UAV]; - [QXGVAR(headlessClientJoined), FUNC(handleConnectHC)] call CBA_fnc_addEventHandler; + [QXGVAR(headlessClientJoined), LINKFUNC(handleConnectHC)] call CBA_fnc_addEventHandler; }; ADDON = true; diff --git a/addons/headless/functions/fnc_blacklist.sqf b/addons/headless/functions/fnc_blacklist.sqf new file mode 100644 index 00000000000..1c15406ba61 --- /dev/null +++ b/addons/headless/functions/fnc_blacklist.sqf @@ -0,0 +1,51 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Modifies which units are blacklisted from being transferred to HCs. + * + * Arguments: + * 0: Units + * 1: Add (true) or remove (false) from blacklist (default: true) + * 2: Owner to transfer units to (default: -1) + * 3: Rebalance (default: 0) + * + * Return Value: + * None + * + * Example: + * [cursorObject, true] call ace_headless_fnc_blacklist + * + * Public: Yes + */ + +params [["_units", objNull, [objNull, grpNull, []]], ["_blacklist", true, [false]], ["_owner", -1, [false]], ["_rebalance", NO_REBALANCE, [0]]]; + +if !(_units isEqualType []) then { + _units = [_units]; +}; + +// Make sure passed arguments are objects or groups +_units = _units select {_x isEqualType objNull || {_x isEqualType grpNull}}; +_units = _units select {!isNull _x}; + +if (_units isEqualTo []) exitWith {}; + +private _transfer = _blacklist && {_owner > 1}; +private _groups = []; + +{ + _x setVariable [QXGVAR(blacklist), _blacklist, true]; + + if (_transfer) then { + if (_x isEqualType objNull) then { + _groups pushBack group _x; + } else { + _groups pushBack _x; + }; + }; +} forEach _units; + +// Try to move AI to new owner; Also takes care of rebalancing groups +if (_transfer || {_rebalance in [REBALANCE, FORCED_REBALANCE]}) then { + [QGVAR(transferGroupsRebalance), [_groups arrayIntersect _groups, _owner, _rebalance]] call CBA_fnc_serverEvent; +}; diff --git a/addons/headless/functions/fnc_handleConnectHC.sqf b/addons/headless/functions/fnc_handleConnectHC.sqf index b19ef250121..e5acaf48fcb 100644 --- a/addons/headless/functions/fnc_handleConnectHC.sqf +++ b/addons/headless/functions/fnc_handleConnectHC.sqf @@ -19,17 +19,14 @@ params ["_headlessClient"]; // Exit if HC already registered // No need to check if distribution or end mission enabled, as if disabled this will never run -if (_headlessClient in GVAR(headlessClients)) exitWith {}; - -// Register for use -GVAR(headlessClients) pushBack _headlessClient; +if (GVAR(headlessClients) pushBackUnique _headlessClient == -1) exitWith {}; if (XGVAR(log)) then { INFO_1("Registered HC: %1",_headlessClient); }; // Exit if AI distribution is disabled -if (!XGVAR(enabled)) exitWith {true}; +if (!XGVAR(enabled)) exitWith {}; // Rebalance [true] call FUNC(rebalance); diff --git a/addons/headless/functions/fnc_handleDisconnect.sqf b/addons/headless/functions/fnc_handleDisconnect.sqf index c94cec2599f..a18f22a3bd3 100644 --- a/addons/headless/functions/fnc_handleDisconnect.sqf +++ b/addons/headless/functions/fnc_handleDisconnect.sqf @@ -17,7 +17,7 @@ */ params ["_object"]; -TRACE_1("HandleDisconnect",_this); +TRACE_1("HandleDisconnect",_object); // Exit if not HC if !(_object in GVAR(headlessClients)) exitWith { @@ -28,9 +28,7 @@ if !(_object in GVAR(headlessClients)) exitWith { if (CBA_missionTime < 150) then { TRACE_1("Mission start delay",CBA_missionTime); GVAR(endMissionCheckDelayed) = true; - [{ - call FUNC(endMissionNoPlayers); - }, [], 150 - CBA_missionTime] call CBA_fnc_waitAndExecute; + [LINKFUNC(endMissionNoPlayers), [], 150 - CBA_missionTime] call CBA_fnc_waitAndExecute; } else { // End instantly or after delay if (XGVAR(endMission) == 1) then { @@ -39,7 +37,7 @@ if !(_object in GVAR(headlessClients)) exitWith { } else { TRACE_2("Delayed 60s end",GVAR(endMission),CBA_missionTime); GVAR(endMissionCheckDelayed) = true; - [FUNC(endMissionNoPlayers), [], 60] call CBA_fnc_waitAndExecute; + [LINKFUNC(endMissionNoPlayers), [], 60] call CBA_fnc_waitAndExecute; }; }; }; diff --git a/addons/headless/functions/fnc_handleSpawn.sqf b/addons/headless/functions/fnc_handleSpawn.sqf index 50277e38456..56b74f407db 100644 --- a/addons/headless/functions/fnc_handleSpawn.sqf +++ b/addons/headless/functions/fnc_handleSpawn.sqf @@ -4,27 +4,22 @@ * Handles AI spawn and requests a rebalance if applicable. * * Arguments: - * 0: Object + * 0: Unit * * Return Value: * None * * Example: - * [object] call ace_headless_fnc_handleSpawn + * [cursorObject] call ace_headless_fnc_handleSpawn * * Public: No */ -params ["_object"]; -TRACE_1("Spawn",_object); +params ["_unit"]; +TRACE_1("Spawn",_unit); -// Exit if HC transferring disabled or object not a unit (including unit inside vehicle) or is player -if (!(_object in allUnits) || {isPlayer _object}) exitWith {}; - -// Exit and blacklist if of blacklist type -if ({_object isKindOf _x} count GVAR(blacklistType) > 0) exitWith { - _object setVariable [QXGVAR(blacklist), true]; -}; +// Exit if unit is player or UAV crew +if (isPlayer _unit || {unitIsUAV _unit}) exitWith {}; // Rebalance [false] call FUNC(rebalance); diff --git a/addons/headless/functions/fnc_rebalance.sqf b/addons/headless/functions/fnc_rebalance.sqf index 84be441ebe8..5ec32f39bd8 100644 --- a/addons/headless/functions/fnc_rebalance.sqf +++ b/addons/headless/functions/fnc_rebalance.sqf @@ -23,7 +23,7 @@ TRACE_3("Rebalance",GVAR(inRebalance),GVAR(headlessClients),_force); if (GVAR(inRebalance) || {GVAR(headlessClients) isEqualTo []}) exitWith {}; // Transfer after rebalance delay -[FUNC(transferGroups), [_force], XGVAR(Delay)] call CBA_fnc_waitAndExecute; +[LINKFUNC(transferGroups), _force, XGVAR(delay)] call CBA_fnc_waitAndExecute; // Currently in rebalance flag GVAR(inRebalance) = true; diff --git a/addons/headless/functions/fnc_transferGroups.sqf b/addons/headless/functions/fnc_transferGroups.sqf index 37580c4fff9..920470c335f 100644 --- a/addons/headless/functions/fnc_transferGroups.sqf +++ b/addons/headless/functions/fnc_transferGroups.sqf @@ -17,6 +17,9 @@ params ["_force"]; +// Filter out any invalid entries +GVAR(headlessClients) = GVAR(headlessClients) select {!isNull _x}; + GVAR(headlessClients) params [ ["_HC1", objNull, [objNull]], ["_HC2", objNull, [objNull]], @@ -36,12 +39,13 @@ private _idHC2 = -1; private _idHC3 = -1; private _currentHC = 0; -if (!local _HC1) then { +// objNull is never local +if (!local _HC1 && !isNull _HC1) then { _idHC1 = owner _HC1; _currentHC = 1; }; -if (!local _HC2) then { +if (!local _HC2 && !isNull _HC2) then { _idHC2 = owner _HC2; if (_currentHC == 0) then { @@ -49,7 +53,7 @@ if (!local _HC2) then { }; }; -if (!local _HC3) then { +if (!local _HC3 && !isNull _HC3) then { _idHC3 = owner _HC3; if (_currentHC == 0) then { @@ -57,6 +61,14 @@ if (!local _HC3) then { }; }; +if (_currentHC == 0) exitWith { + TRACE_1("No Valid HC to transfer to",_currentHC); + + if (XGVAR(log)) then { + INFO("No Valid HC to transfer to"); + }; +}; + // Prepare statistics private _numTransferredHC1 = 0; private _numTransferredHC2 = 0; @@ -64,75 +76,139 @@ private _numTransferredHC3 = 0; // Transfer AI groups { - // No transfer if empty group - private _transfer = ((units _x) isNotEqualTo []) && {!(_x getVariable [QXGVAR(blacklist), false])}; - if (_transfer) then { - // No transfer if waypoints with synchronized triggers exist for the group - private _allWaypointsWithTriggers = (waypoints _x) select {(synchronizedTriggers _x) isNotEqualTo []}; - if (_allWaypointsWithTriggers isNotEqualTo []) exitWith { + private _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; + }; + + private _transfer = true; + + { + // No transfer if already transferred + if (!_force && {(owner _x) in [_idHC1, _idHC2, _idHC3]}) exitWith { _transfer = false; }; - { - // No transfer if already transferred - if (!_force && {(owner _x) in [_idHC1, _idHC2, _idHC3]}) exitWith { - _transfer = false; - }; + // No transfer if any unit in group is blacklisted + if (_x getVariable [QXGVAR(blacklist), false]) exitWith { + _transfer = false; + }; - // No transfer if player in this group - if (isPlayer _x) exitWith { - _transfer = false; - }; + // No transfer if player or UAV in this group + if (isPlayer _x || {unitIsUAV _x}) exitWith { + _transfer = false; + }; - // No transfer if any unit in group is blacklisted - if (_x getVariable [QXGVAR(blacklist), false]) exitWith { - _transfer = false; - }; + private _vehicle = objectParent _x; - // No transfer if vehicle unit is in or crew in that vehicle is blacklisted - if (vehicle _x != _x && {(vehicle _x) getVariable [QXGVAR(blacklist), false]}) exitWith { - _transfer = false; - }; + // No transfer if the vehicle the unit is in or if the crew in that vehicle is blacklisted + if ((_vehicle getVariable [QXGVAR(blacklist), false]) || {unitIsUAV _vehicle}) exitWith { + _transfer = false; + }; - // Save gear if unit about to be transferred with current loadout (naked unit work-around) - if (XGVAR(transferLoadout) == 1) then { - _x setVariable [QGVAR(loadout), [_x] call CBA_fnc_getLoadout, true]; - }; - } forEach (units _x); + // Save gear if unit about to be transferred with current loadout (naked unit work-around) + if (XGVAR(transferLoadout) == 1) then { + _x setVariable [QGVAR(loadout), _x call CBA_fnc_getLoadout, true]; + }; + } forEach _units; + + if (!_transfer) then { + continue; }; // Round robin between HCs if load balance enabled, else pass all to one HC - if (_transfer) then { - switch (_currentHC) do { - case 1: { - private _transferred = _x setGroupOwner _idHC1; - if (_loadBalance) then { - _currentHC = [3, 2] select (!local _HC2); - }; - if (_transferred) then { - _numTransferredHC1 = _numTransferredHC1 + 1; + private _previousOwner = groupOwner _x; + + switch (_currentHC) do { + case 1: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC2 != -1) then { + _currentHC = 2; + } else { + if (_idHC3 != -1) then { + _currentHC = 3; + }; }; }; - case 2: { - private _transferred = _x setGroupOwner _idHC2; - if (_loadBalance) then { - _currentHC = [1, 3] select (!local _HC3); - }; - if (_transferred) then { - _numTransferredHC2 = _numTransferredHC2 + 1; - }; + + // Don't transfer if it's already local to HC1 + if (_previousOwner == _idHC1) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC1, _previousOwner, _idHC1], _previousOwner] call CBA_fnc_ownerEvent; // API + [QGVAR(groupTransferPre), [_x, _HC1, _previousOwner, _idHC1], _idHC1] call CBA_fnc_ownerEvent; // API + + private _transferred = _x setGroupOwner _idHC1; + + [QGVAR(groupTransferPost), [_x, _HC1, _previousOwner, _idHC1, _transferred], _previousOwner] call CBA_fnc_ownerEvent; // API + [QGVAR(groupTransferPost), [_x, _HC1, _previousOwner, _idHC1, _transferred], _idHC1] call CBA_fnc_ownerEvent; // API + + if (_transferred) then { + _numTransferredHC1 = _numTransferredHC1 + 1; }; - case 3: { - private _transferred = _x setGroupOwner _idHC3; - if (_loadBalance) then { - _currentHC = [2, 1] select (!local _HC1); + }; + 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; + }; }; - if (_transferred) then { - _numTransferredHC3 = _numTransferredHC3 + 1; + }; + + // Don't transfer if it's already local to HC2 + if (_previousOwner == _idHC2) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC2, _previousOwner, _idHC2], _previousOwner] call CBA_fnc_ownerEvent; // API + [QGVAR(groupTransferPre), [_x, _HC2, _previousOwner, _idHC2], _idHC2] call CBA_fnc_ownerEvent; // API + + private _transferred = _x setGroupOwner _idHC2; + + [QGVAR(groupTransferPost), [_x, _HC2, _previousOwner, _idHC2, _transferred], _previousOwner] call CBA_fnc_ownerEvent; // API + [QGVAR(groupTransferPost), [_x, _HC2, _previousOwner, _idHC2, _transferred], _idHC2] call CBA_fnc_ownerEvent; // API + + if (_transferred) then { + _numTransferredHC2 = _numTransferredHC2 + 1; + }; + }; + case 3: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC1 != -1) then { + _currentHC = 1; + } else { + if (_idHC2 != -1) then { + _currentHC = 2; + }; }; }; - default { - TRACE_1("No Valid HC to transfer to",_currentHC); + + // Don't transfer if it's already local to HC3 + if (_previousOwner == _idHC3) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC3, _previousOwner, _idHC3], _previousOwner] call CBA_fnc_ownerEvent; // API + [QGVAR(groupTransferPre), [_x, _HC3, _previousOwner, _idHC3], _idHC3] call CBA_fnc_ownerEvent; // API + + private _transferred = _x setGroupOwner _idHC2; + + [QGVAR(groupTransferPost), [_x, _HC3, _previousOwner, _idHC3, _transferred], _previousOwner] call CBA_fnc_ownerEvent; // API + [QGVAR(groupTransferPost), [_x, _HC3, _previousOwner, _idHC3, _transferred], _idHC3] call CBA_fnc_ownerEvent; // API + + if (_transferred) then { + _numTransferredHC3 = _numTransferredHC3 + 1; }; }; }; diff --git a/addons/headless/initSettings.inc.sqf b/addons/headless/initSettings.inc.sqf index cb5fe6e53d7..ec720fce7c0 100644 --- a/addons/headless/initSettings.inc.sqf +++ b/addons/headless/initSettings.inc.sqf @@ -4,9 +4,9 @@ [ELSTRING(common,Enabled), LSTRING(EnabledDesc)], format ["ACE %1", LLSTRING(Module)], false, - true, - {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + 1, + {[QXGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -15,9 +15,7 @@ [LSTRING(Delay), LSTRING(DelayDesc)], format ["ACE %1", LLSTRING(Module)], [0, 60, 15, -1], - true, - {[QGVAR(delay), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + 1 ] call CBA_fnc_addSetting; [ @@ -26,9 +24,9 @@ [LSTRING(EndMission), LSTRING(EndMissionDesc)], format ["ACE %1", LLSTRING(Module)], [[0, 1, 2], [ELSTRING(Common,Disabled), LSTRING(Instant), LSTRING(Delayed)], 0], - true, - {[QGVAR(delay), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + 1, + {[QXGVAR(endMission), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -37,9 +35,7 @@ [LSTRING(Log), LSTRING(LogDesc)], format ["ACE %1", LLSTRING(Module)], false, - true, - {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + 1 ] call CBA_fnc_addSetting; [ @@ -48,7 +44,7 @@ [LSTRING(TransferLoadout), LSTRING(TransferLoadoutDesc)], format ["ACE %1", LLSTRING(Module)], [[0, 1, 2], [ELSTRING(Common,Disabled), LSTRING(TransferLoadoutCurrent), LSTRING(TransferLoadoutConfig)], 0], - true, - {}, - true // needs mission restart + 1, + {[QXGVAR(transferLoadout), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; diff --git a/addons/headless/script_component.hpp b/addons/headless/script_component.hpp index c73e2260dee..272b288d5f4 100644 --- a/addons/headless/script_component.hpp +++ b/addons/headless/script_component.hpp @@ -17,4 +17,7 @@ #include "\z\ace\addons\main\script_macros.hpp" #define DELAY_DEFAULT 15 -#define BLACKLIST_UAV "UAV", "UAV_AI_base_F", "B_UAV_AI", "O_UAV_AI", "I_UAV_AI" + +#define NO_REBALANCE 0 +#define REBALANCE 1 +#define FORCED_REBALANCE 2 diff --git a/addons/headless/stringtable.xml b/addons/headless/stringtable.xml index 584c12f954b..063f72d1404 100644 --- a/addons/headless/stringtable.xml +++ b/addons/headless/stringtable.xml @@ -62,7 +62,7 @@ Minimale Verzögerung zwischen Transfers in Sekunden. (Standard: 15) Minimalny odstęp pomiędzy transferami w sekundach. (Domyślnie: 15) 전송 간 최소 지연 시간, 초당. (기본값: 15) - 移行する際の最低遅延を秒数で設定します。 (デフォルト: 15) + 移行する際の最低遅延を秒単位で設定します。 (デフォルト: 15) Délai minimum entres les transferts, en secondes. (Défaut: 15) 设定每次转换间隔多少秒。(预设:15秒) 設定每次轉換間隔多少秒。(預設:15秒) @@ -88,7 +88,7 @@ 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는 지원함) + 연결된 플레이어가 없으면 미션을 종료합니다(서버 설정의 'persistent = 0'과 같지만 헤드리스 클라이언트는 지원합니다). プレイヤーが接続していない場合はミッション終了します。(サーバ設定の'presistent =0'と同じですが、ヘッドレスクライアントをサポートします) Termine la mission lorsqu'il n'y a plus de joueur connecté (idem que 'persistent = 0' dans la config serveur mais avec la gestion du Headless Client). 当服务器里没有任何玩家还连线时自动结束任务(效果同于伺服器设定的'persistent = 0',但支援 Headless 客户端)。 @@ -145,7 +145,7 @@ 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) + 전송 통계 및 헤드리스 클라이언트 연결(해제)를 RPT파일에 기록합니다. (기본값: No) 統計とヘッドレスクライアントの接続有無を PRT へ記録します。 (デフォルト: 無効) Archive les statistiques de transfert et de (dé)connections du Headless Client dans le RPT. (Défaut: Non) 记录 Headless 客户端间的转换数量与连线/断线等记录到 RPT 报告档中。(预设:关闭) diff --git a/addons/hearing/CfgEventHandlers.hpp b/addons/hearing/CfgEventHandlers.hpp index 310be3675b6..59cd1b36296 100644 --- a/addons/hearing/CfgEventHandlers.hpp +++ b/addons/hearing/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); @@ -13,15 +12,7 @@ class Extended_PreInit_EventHandlers { class Extended_PostInit_EventHandlers { class ADDON { - clientinit = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); - }; -}; - -class Extended_Init_EventHandlers { - class CAManBase { - class GVAR(AddEarPlugs) { - serverInit = QUOTE(_this call FUNC(addEarPlugs)); - }; + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/hearing/CfgVehicles.hpp b/addons/hearing/CfgVehicles.hpp index a7625344608..636184ecd22 100644 --- a/addons/hearing/CfgVehicles.hpp +++ b/addons/hearing/CfgVehicles.hpp @@ -5,7 +5,7 @@ class CfgVehicles { class ACE_Equipment { class ACE_PutInEarplugs { displayName = CSTRING(EarPlugs_On); - condition = QUOTE(GVAR(EnableCombatDeafness) && {!([_player] call FUNC(hasEarPlugsIn)) && {'ACE_EarPlugs' in items _player}}); + condition = QUOTE(GVAR(enableCombatDeafness) && {!(_player call FUNC(hasEarPlugsIn)) && {[ARR_2(_player,'ACE_EarPlugs')] call EFUNC(common,hasItem)}}); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; statement = QUOTE([ARR_2(_player,true)] call FUNC(putInEarPlugs)); showDisabled = 0; @@ -13,7 +13,7 @@ class CfgVehicles { }; class ACE_RemoveEarplugs { displayName = CSTRING(EarPlugs_Off); - condition = QUOTE(GVAR(EnableCombatDeafness) && {[_player] call FUNC(hasEarPlugsIn)}); + condition = QUOTE(GVAR(enableCombatDeafness) && {_player call FUNC(hasEarPlugsIn)}); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; statement = QUOTE([ARR_2(_player,true)] call FUNC(removeEarPlugs)); showDisabled = 0; diff --git a/addons/hearing/CfgWeapons.hpp b/addons/hearing/CfgWeapons.hpp index 23ebe5c1d2f..8cef02edfd8 100644 --- a/addons/hearing/CfgWeapons.hpp +++ b/addons/hearing/CfgWeapons.hpp @@ -80,7 +80,7 @@ class CfgWeapons { class H_HelmetO_ocamo: H_HelmetB { HEARING_PROTECTION_PELTOR; - }; // Defender and Assasin Helmet inherit. + }; // Defender and Assassin Helmet inherit. class H_HelmetO_ViperSP_hex_f: H_HelmetB { HEARING_PROTECTION_PELTOR; diff --git a/addons/hearing/XEH_PREP.hpp b/addons/hearing/XEH_PREP.hpp index e06fa5d56c0..64161300d3e 100644 --- a/addons/hearing/XEH_PREP.hpp +++ b/addons/hearing/XEH_PREP.hpp @@ -1,8 +1,8 @@ - PREP(addEarPlugs); PREP(earRinging); -PREP(explosionNear); +PREP(explosion); 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 c387ed04d85..f9fb2043334 100644 --- a/addons/hearing/XEH_postInit.sqf +++ b/addons/hearing/XEH_postInit.sqf @@ -1,10 +1,41 @@ #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; +}; + +["CBA_settingsInitialized", { + TRACE_1("settingInit - common",GVAR(enableCombatDeafness)); + // Only install event handler if combat deafness is enabled + if (!GVAR(enableCombatDeafness)) exitWith {}; + + [{ // Convert ace_common's local explosion to a hearing global explosion event + params ["_projectile", "_pos"]; + TRACE_1("Explode",_this); + + // If projectile is local only, don't raise event globally + // TODO: netId always returns valid after 2.18 + // use _projectile getShotInfo 5 (https://community.bistudio.com/wiki/getShotInfo) + if (isMultiplayer && {(netId _projectile) == "0:0"}) then { + [QGVAR(explosion), [_projectile, _pos]] call CBA_fnc_localEvent; + } else { + [QGVAR(explosion), [_projectile, _pos]] call CBA_fnc_globalEvent; + }; + }] call EFUNC(common,addExplosionEventHandler); +}] call CBA_fnc_addEventHandler; + if (!hasInterface) exitWith {}; #include "initKeybinds.inc.sqf" -GVAR(cacheAmmoLoudness) = call CBA_fnc_createNamespace; +GVAR(cacheAmmoLoudness) = createHashMap; GVAR(deafnessDV) = 0; GVAR(deafnessPrior) = 0; @@ -16,16 +47,21 @@ GVAR(volumeAttenuation) = 1; GVAR(lastPlayerVehicle) = objNull; ["CBA_settingsInitialized", { - TRACE_1("settingInit",GVAR(EnableCombatDeafness)); + TRACE_1("settingInit - client",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(explosion), LINKFUNC(explosion)] call CBA_fnc_addEventHandler; + [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); @@ -36,6 +72,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]; @@ -43,8 +80,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", { @@ -55,27 +92,24 @@ 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); + TRACE_2("removed unit eh",_oldPlayer,_firedEH); }; // Don't add a new EH if the unit respawned if ((_player getVariable [QGVAR(firedEH), -1]) == -1) then { 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); + TRACE_2("added unit eh",_player,_firedEH); }; 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 2ab07c31e6f..e47eafa56e8 100644 --- a/addons/hearing/XEH_preInit.sqf +++ b/addons/hearing/XEH_preInit.sqf @@ -10,14 +10,20 @@ PREP_RECOMPILE_END; ["CBA_loadoutSet", { params ["_unit", "_loadout", "_extendedInfo"]; + if (_extendedInfo getOrDefault ["ace_earplugs", false]) then { _unit setVariable ["ACE_hasEarPlugsIn", true, true]; - [[true]] remoteExec [QFUNC(updateVolume), _unit]; + + // Only force update volume if unit is a player (including remote controlled) + if (_unit call EFUNC(common,isPlayer)) then { + [QGVAR(updateVolume), true, _unit] call CBA_fnc_targetEvent; + }; }; }] call CBA_fnc_addEventHandler; ["CBA_loadoutGet", { params ["_unit", "_loadout", "_extendedInfo"]; + if (_unit getVariable ["ACE_hasEarPlugsin", false]) then { _extendedInfo set ["ace_earplugs", true] }; diff --git a/addons/hearing/functions/fnc_addEarPlugs.sqf b/addons/hearing/functions/fnc_addEarPlugs.sqf index f4673524109..11999f77378 100644 --- a/addons/hearing/functions/fnc_addEarPlugs.sqf +++ b/addons/hearing/functions/fnc_addEarPlugs.sqf @@ -4,7 +4,7 @@ * Called on unit initialization. Adds earplugs if the unit is equipped with either a really loud primary weapon or a rocket launcher. * * Arguments: - * 0: A Soldier + * 0: Unit * * Return Value: * None @@ -15,49 +15,62 @@ * Public: No */ +// Only run this after the settings are initialized +if (!EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [LINKFUNC(addEarPlugs), _this]; +}; + +// Exit if hearing is disabled or if autoAdd is disabled +if (!GVAR(enableCombatDeafness) || {GVAR(autoAddEarplugsToUnits) == 0}) exitWith {}; + params ["_unit"]; TRACE_2("params",_unit,typeOf _unit); -// only run this after the settings are initialized -if !(EGVAR(common,settingsInitFinished)) exitWith { - EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(addEarPlugs), _this]; -}; - -// Exit if 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 {}; +// 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 {}; -// 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 {}; - -(primaryWeaponMagazine _unit) params [["_magazine", ""]]; -if (_magazine == "") exitWith {}; +// Otherwise add earplugs if the unit has a big rifle +private _weapon = primaryWeapon _unit; -private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); -private _ammo = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); -private _count = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); +if (_weapon == "") exitWith {}; -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 }; - [_caliber, 6.5] select (_caliber <= 0); +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)}); + + // ace_gunbag_fnc_isMachineGun + private _config = _weapon call CBA_fnc_getItemConfig; + + // 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_2("primaryWeapon",_unit,_loudness); +TRACE_3("primaryWeapon",_unit,_weapon,_maxLoudness); -if (_loudness > 0.2) then { +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 f5a2a714dbd..57888e90a2e 100644 --- a/addons/hearing/functions/fnc_earRinging.sqf +++ b/addons/hearing/functions/fnc_earRinging.sqf @@ -1,24 +1,25 @@ #include "..\script_component.hpp" /* * Author: KoffeinFlummi, commy2, Rocko, Rommel, Ruthberg - * Handle new sound souce near ace_player and apply hearing damage + * Handle new sound souce near ace_player and apply hearing damage. * * Arguments: - * 0: strength of ear ringing + * 0: Strength of ear ringing * * Return Value: * None * * Example: - * [_strength] call ace_hearing_fnc_earRinging + * 10 call ace_hearing_fnc_earRinging * * Public: No */ + params ["_strength"]; if (_strength < 0.05) exitWith {}; if (!isNull curatorCamera) exitWith {}; -if ((!GVAR(enabledForZeusUnits)) && {player != ACE_player}) exitWith {}; +if (!GVAR(enabledForZeusUnits) && {player != ACE_player}) exitWith {}; TRACE_2("adding",_strength * GVAR(damageCoefficent),GVAR(deafnessDV)); diff --git a/addons/hearing/functions/fnc_explosion.sqf b/addons/hearing/functions/fnc_explosion.sqf new file mode 100644 index 00000000000..f0a1ee6aab1 --- /dev/null +++ b/addons/hearing/functions/fnc_explosion.sqf @@ -0,0 +1,56 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Handles deafness due to explosions going off near the player. + * + * Arguments: + * 0: Projectile + * 1: Explosion position ASL + * + * Return Value: + * None + * + * Example: + * [_projectile, [0, 0, 0]] call ace_hearing_fnc_explosion + * + * Public: No + */ + +// Ignore spectators, curators and alike +if ((getNumber (configOf ACE_player >> "isPlayableLogic")) == 1) exitWith {}; + +params ["_projectile", "_pos"]; + +// Don't allow for distances under 1 +private _distance = ((eyePos ACE_player) vectorDistance _pos) max 1; + +// Fast exit if explosion far away +if (_distance > 100) exitWith { + TRACE_1("too far away",_distance); +}; + +private _ammoConfig = configOf _projectile; +private _hit = getNumber (_ammoConfig >> "hit"); +if (_hit < 0.5) exitWith { TRACE_1("ignore smoke/flare",_hit) }; +private _explosive = getNumber (_ammoConfig >> "explosive"); + +private _vehAttenuation = [GVAR(playerVehAttenuation), 1] select (isNull objectParent ACE_player || {isTurnedOut ACE_player}); + +TRACE_4("",typeOf _projectile,_distance,_explosive,_vehAttenuation); + +(if (isArray (_ammoConfig >> "soundHit1")) then { + getArray (_ammoConfig >> "soundHit1") +} else { + getArray (_ammoConfig >> "soundHit") +}) params ["", ["_volume", 1], "", ["_maxDistance", 1500]]; + +if (_distance > _maxDistance) exitWith { + TRACE_2("too far away",_distance,_maxDistance); +}; + +private _strength = _vehAttenuation * _explosive * _volume * _maxDistance / _distance^2; + +TRACE_2("strength",_volume,_strength); + +// 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_explosionNear.sqf b/addons/hearing/functions/fnc_explosionNear.sqf deleted file mode 100644 index c65cf31c764..00000000000 --- a/addons/hearing/functions/fnc_explosionNear.sqf +++ /dev/null @@ -1,27 +0,0 @@ -#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 - * - * Return Value: - * None - * - * Example: - * [clientExplosionEvent] call ace_hearing_fnc_explosionNear - * - * Public: No - */ - -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); diff --git a/addons/hearing/functions/fnc_firedNear.sqf b/addons/hearing/functions/fnc_firedNear.sqf index 0d8596f53bf..1c9a1c54968 100644 --- a/addons/hearing/functions/fnc_firedNear.sqf +++ b/addons/hearing/functions/fnc_firedNear.sqf @@ -4,97 +4,60 @@ * Handles deafness due to large-caliber weapons going off near the player. * * Arguments: - * 0: Unit - Object the event handler is assigned to - * 1: Firer: Object - Object which fires a weapon near the unit - * 2: Distance - Distance in meters between the unit and firer - * 3: weapon - Fired weapon - * 4: muzzle - Muzzle that was used (not used) - * 5: mode - Current mode of the fired weapon (not used) - * 6: ammo - Ammo used + * 0: Object the event handler is assigned to (unused) + * 1: Object which fires a weapon near the unit + * 2: Distance in meters between the unit and firer + * 3: Weapon + * 4: Muzzle + * 5: Current mode of the fired weapon + * 6: Ammo + * 7: Unit that fired the weapon * * Return Value: * None * * Example: - * [clientFiredNearEvent] call ace_hearing_fnc_firedNear - * [player, player, 10, "arifle_MX_ACO_pointer_F", "arifle_MX_ACO_pointer_F", "single", "B_65x39_Caseless"] call ace_hearing_fnc_firedNear + * [player, player, 10, "arifle_MX_ACO_pointer_F", "arifle_MX_ACO_pointer_F", "single", "B_65x39_Caseless", player] call ace_hearing_fnc_firedNear * * Public: No */ -params ["_object", "_firer", "_distance", "_weapon", "", "", "_ammo"]; +params ["", "_firer", "_distance", "_weapon", "_muzzle", "_mode", "_ammo", "_gunner"]; if (_weapon in ["Throw", "Put"]) exitWith {}; if (_distance > 50) exitWith {}; -private _vehAttenuation = [GVAR(playerVehAttenuation), 1] select ( - (ACE_player == (vehicle ACE_player)) || {isTurnedOut ACE_player} -); -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 (_suppressor != "") then { + _audibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _suppressor >> "ItemInfo" >> "AmmoCoef" >> "audibleFire"); + }; - 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 }; - [_caliber, 6.5] select (_caliber <= 0) - }; + (_firer weaponState _muzzle) select 3 +} else { + // Unit that fired is in a vehicle + (weaponState [_firer, _firer unitTurret _gunner, _weapon, _muzzle, _mode]) select 3 +}; - _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; - TRACE_6("building cache",_weapon,_ammo,_magazine,_initSpeed,_caliber,_loudness); - }; - GVAR(cacheAmmoLoudness) setVariable [(format ["%1%2",_weapon,_ammo]), _loudness]; +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 00000000000..062b96fa718 --- /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 b436aa7c410..a075d7901e0 100644 --- a/addons/hearing/functions/fnc_handleRespawn.sqf +++ b/addons/hearing/functions/fnc_handleRespawn.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Reset earplugs on respawn, and then re-add if appropriate + * Reset earplugs on respawn, and then re-add if appropriate. * * Arguments: * 0: Unit @@ -10,29 +10,29 @@ * None * * Example: - * [player] call ACE_hearing_fnc_handleRespawn; + * player call ace_hearing_fnc_handleRespawn; * * Public: No */ +// Do not add or remove earplugs if gear should be preserved +if (missionNamespace getVariable [QEGVAR(respawn,savePreDeathGear), false]) exitWith {}; + params ["_unit"]; TRACE_2("params",_unit,typeOf _unit); -if (!local _unit) exitWith {}; //XEH should only be called on local units - -//Do not add or remove earplugs if gear should be preserved -if (missionNamespace getVariable [QEGVAR(respawn,SavePreDeathGear), false]) exitWith {}; +if (!local _unit) exitWith {}; // XEH should only be called on local units private _respawn = [0] call BIS_fnc_missionRespawnType; -//if respawn is not Group or side: +// If respawn is not group or side: if (_respawn <= 3) then { - //Remove earplugs if they have them: + // Remove earplugs if they have them: if (_unit getVariable ["ACE_hasEarPlugsin", false]) then { TRACE_1("had EarPlugs in - removing",_unit); _unit setVariable ["ACE_hasEarPlugsin", false, true]; }; }; -//Re-add if they need them: -[_unit] call FUNC(addEarPlugs); +// Re-add if they need them +_unit call FUNC(addEarPlugs); diff --git a/addons/hearing/functions/fnc_hasEarPlugsIn.sqf b/addons/hearing/functions/fnc_hasEarPlugsIn.sqf index f4b84281fb6..fd6682e4de2 100644 --- a/addons/hearing/functions/fnc_hasEarPlugsIn.sqf +++ b/addons/hearing/functions/fnc_hasEarPlugsIn.sqf @@ -4,16 +4,17 @@ * Check if the unit has earplugs put in. * * Arguments: - * 0: Unit (player) + * 0: Unit * * Return Value: - * Have Earplugs in + * Has Earplugs in * * Example: - * [ace_player] call ace_hearing_fnc_hasEarPlugsIn + * player call ace_hearing_fnc_hasEarPlugsIn * * Public: No */ + params ["_unit"]; _unit getVariable ["ACE_hasEarPlugsin", false] diff --git a/addons/hearing/functions/fnc_moduleHearing.sqf b/addons/hearing/functions/fnc_moduleHearing.sqf index 924f2baa211..f7943a712e9 100644 --- a/addons/hearing/functions/fnc_moduleHearing.sqf +++ b/addons/hearing/functions/fnc_moduleHearing.sqf @@ -10,7 +10,7 @@ * None * * Example: - * [player] call ACE_hearing_fnc_moduleHearing + * player call ace_hearing_fnc_moduleHearing * * Public: No */ @@ -23,6 +23,8 @@ params ["_logic"]; if ((_logic getVariable "DisableEarRinging") != -1) then { [_logic, QGVAR(DisableEarRinging), "DisableEarRinging"] call EFUNC(common,readSettingFromModule); }; + [_logic, QGVAR(enabledForZeusUnits), "enabledForZeusUnits"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(autoAddEarplugsToUnits), "autoAddEarplugsToUnits"] call EFUNC(common,readSettingFromModule); + INFO("Hearing Module Initialized."); diff --git a/addons/hearing/functions/fnc_putInEarplugs.sqf b/addons/hearing/functions/fnc_putInEarplugs.sqf index 2af4df8e86c..aa2166a112f 100644 --- a/addons/hearing/functions/fnc_putInEarplugs.sqf +++ b/addons/hearing/functions/fnc_putInEarplugs.sqf @@ -1,38 +1,35 @@ #include "..\script_component.hpp" /* - * Author: Hope Johnson and commy2 + * Author: Hope Johnson, commy2 * Puts in earplugs. * * Arguments: - * 0: Unit (player) + * 0: Unit * 1: Display hint (default: false) * * Return Value: * None * * Example: - * [ace_player, false] call ace_hearing_fnc_putInEarplugs + * [player, false] call ace_hearing_fnc_putInEarplugs * * Public: No */ -params ["_player", ["_displayHint", false, [false]]]; +if (!GVAR(enableCombatDeafness)) exitWith {}; -if (!GVAR(EnableCombatDeafness)) exitWith {}; +params ["_unit", ["_displayHint", false]]; // Plugs in inventory, putting them in -_player removeItem "ACE_EarPlugs"; +_unit removeItem "ACE_EarPlugs"; -_player setVariable ["ACE_hasEarPlugsIn", true, true]; +_unit setVariable ["ACE_hasEarPlugsIn", true, true]; if (_displayHint) then { - [localize LSTRING(EarPlugs_Are_On)] call EFUNC(common,displayTextStructured); + [LLSTRING(EarPlugs_Are_On)] call EFUNC(common,displayTextStructured); }; -//Force an immediate fast volume update: -[[true]] call FUNC(updateVolume); +// Force an immediate volume update +true call FUNC(updateVolume); -// No Earplugs in inventory, telling user -//[localize LSTRING(NoPlugs)] call EFUNC(common,displayTextStructured); - -[] call FUNC(updateHearingProtection); +call FUNC(updateHearingProtection); diff --git a/addons/hearing/functions/fnc_removeEarplugs.sqf b/addons/hearing/functions/fnc_removeEarplugs.sqf index 20a49bb5300..743e89ef531 100644 --- a/addons/hearing/functions/fnc_removeEarplugs.sqf +++ b/addons/hearing/functions/fnc_removeEarplugs.sqf @@ -1,39 +1,40 @@ #include "..\script_component.hpp" /* - * Author: Hope Johnson and commy2 + * Author: Hope Johnson, commy2 * Takes out earplugs. * * Arguments: - * 0: Unit (player) - * 1: Display hint (default false) + * 0: Unit + * 1: Display hint (default: false) * * Return Value: * None * * Example: - * [ace_player, false] call ace_hearing_fnc_removeEarplugs + * [player, false] call ace_hearing_fnc_removeEarplugs * * Public: No */ -params ["_player", ["_displayHint", false, [false]]]; +if (!GVAR(enableCombatDeafness)) exitWith {}; -if (!GVAR(EnableCombatDeafness)) exitWith {}; +params ["_unit", ["_displayHint", false]]; -if !([_player, "ACE_EarPlugs"] call CBA_fnc_canAddItem) exitWith { // inventory full +// Inventory full +if !([_unit, "ACE_EarPlugs"] call CBA_fnc_canAddItem) exitWith { [LELSTRING(common,Inventory_Full)] call EFUNC(common,displayTextStructured); }; // Plugs already in and removing them. -_player addItem "ACE_EarPlugs"; +_unit addItem "ACE_EarPlugs"; -_player setVariable ["ACE_hasEarPlugsIn", false, true]; +_unit setVariable ["ACE_hasEarPlugsIn", false, true]; if (_displayHint) then { - [localize LSTRING(EarPlugs_Are_Off)] call EFUNC(common,displayTextStructured); + [LLSTRING(EarPlugs_Are_Off)] call EFUNC(common,displayTextStructured); }; -//Force an immediate fast volume update: -[[true]] call FUNC(updateVolume); +// Force an immediate volume update +true call FUNC(updateVolume); -[] call FUNC(updateHearingProtection); +call FUNC(updateHearingProtection); diff --git a/addons/hearing/functions/fnc_updateHearingProtection.sqf b/addons/hearing/functions/fnc_updateHearingProtection.sqf index 15973b73a92..b9d7f1f9a0b 100644 --- a/addons/hearing/functions/fnc_updateHearingProtection.sqf +++ b/addons/hearing/functions/fnc_updateHearingProtection.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Updates the hearing protection and volume attenuation for player on earbuds/helmet change + * Updates the hearing protection and volume attenuation for player on earbuds/helmet change. * * Arguments: * None @@ -10,12 +10,12 @@ * None * * Example: - * [] call ace_hearing_fnc_updateHearingProtection + * call ace_hearing_fnc_updateHearingProtection * * Public: No */ -TRACE_1("params",_this); +LOG("updateHearingProtection"); if (isNull ACE_player) exitWith { GVAR(damageCoefficent) = 0; @@ -23,22 +23,32 @@ if (isNull ACE_player) exitWith { }; // Handle Earplugs -private _hasEarPlugsIn = [ACE_player] call FUNC(hasEarPlugsIn); +private _hasEarPlugsIn = ACE_player call FUNC(hasEarPlugsIn); GVAR(damageCoefficent) = [1, 0.25] select _hasEarPlugsIn; -GVAR(volumeAttenuation) = [1, GVAR(EarplugsVolume)] select _hasEarPlugsIn; +GVAR(volumeAttenuation) = [1, GVAR(earplugsVolume)] select _hasEarPlugsIn; // Handle Headgear -if (headgear ACE_player != "") then { - private _protection = getNumber (configFile >> "CfgWeapons" >> headgear ACE_player >> QGVAR(protection)) min 1; +private _headgear = headgear ACE_player; + +if (_headgear != "") then { + private _heargearConfig = configFile >> "CfgWeapons" >> _headgear; + + private _protection = getNumber (_heargearConfig >> QGVAR(protection)) min 1; GVAR(damageCoefficent) = GVAR(damageCoefficent) * (1 - _protection); - private _attenuation = getNumber (configFile >> "CfgWeapons" >> headgear ACE_player >> QGVAR(lowerVolume)) min 1; + + private _attenuation = getNumber (_heargearConfig >> QGVAR(lowerVolume)) min 1; GVAR(volumeAttenuation) = GVAR(volumeAttenuation) * (1 - _attenuation); }; // Handle Goggles -if (goggles ACE_player != "") then { - private _protection = getNumber (configFile >> "CfgGlasses" >> goggles ACE_player >> QGVAR(protection)) min 1; +private _goggles = goggles ACE_player; + +if (_goggles != "") then { + private _gogglesConfig = configFile >> "CfgGlasses" >> _goggles; + + private _protection = getNumber (_gogglesConfig >> QGVAR(protection)) min 1; GVAR(damageCoefficent) = GVAR(damageCoefficent) * (1 - _protection); - private _attenuation = getNumber (configFile >> "CfgGlasses" >> goggles ACE_player >> QGVAR(lowerVolume)) min 1; + + private _attenuation = getNumber (_gogglesConfig >> QGVAR(lowerVolume)) min 1; GVAR(volumeAttenuation) = GVAR(volumeAttenuation) * (1 - _attenuation); }; diff --git a/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf b/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf index 207c0f07a3a..856b694a3f6 100644 --- a/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf +++ b/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf @@ -7,10 +7,10 @@ * None * * Return Value: - * Ammount that unit can hear outside + * Amount that unit can hear outside * * Example: - * [] call ace_hearing_fnc_updatePlayerVehAttenuation + * call ace_hearing_fnc_updatePlayerVehAttenuation * * Public: No */ @@ -20,12 +20,14 @@ private _vehicle = vehicle ACE_player; if (isNull _vehicle) exitWith {}; private _newAttenuation = 1; + if (ACE_player != _vehicle) then { - private _turretPath = [ACE_player] call EFUNC(common,getTurretIndex); - private _effectType = getText (configOf _vehicle >> "attenuationEffectType"); + private _vehicleConfig = configOf _vehicle; + private _turretPath = _vehicle unitTurret ACE_player; + private _effectType = getText (_vehicleConfig >> "attenuationEffectType"); if (_turretPath isNotEqualTo []) then { - private _turretConfig = [(configOf _vehicle), _turretPath] call EFUNC(common,getTurretConfigPath); + private _turretConfig = [_vehicleConfig, _turretPath] call EFUNC(common,getTurretConfigPath); if ((getNumber (_turretConfig >> "disableSoundAttenuation")) == 1) then { _effectType = ""; @@ -40,7 +42,7 @@ if (ACE_player != _vehicle) then { case (_effectType == ""): {1}; case (_effectType == "CarAttenuation"); case (_effectType == "RHS_CarAttenuation"): { // Increase protection for armored cars - private _armor = getNumber (configOf _vehicle >> "HitPoints" >> "HitBody" >> "armor"); + private _armor = getNumber (_vehicleConfig >> "HitPoints" >> "HitBody" >> "armor"); linearConversion [2, 8, _armor, 0.5, 0.3, true];}; case (_effectType == "OpenCarAttenuation"): {1}; case (_effectType == "TankAttenuation"): {0.1}; diff --git a/addons/hearing/functions/fnc_updateVolume.sqf b/addons/hearing/functions/fnc_updateVolume.sqf index 0029cdc4de2..bb1d57e3c14 100644 --- a/addons/hearing/functions/fnc_updateVolume.sqf +++ b/addons/hearing/functions/fnc_updateVolume.sqf @@ -1,55 +1,61 @@ #include "..\script_component.hpp" /* - * Author: commy2 and esteldunedain and Ruthberg + * Author: commy2, esteldunedain, Ruthberg * Updates and applies the current deafness. Called every 1 sec from a PFEH. * * Arguments: - * 0: Args - * - 0: Just update volume (skip ringing/recovery) (default: false) + * 0: Update volume only (skip ringing/recovery) (default: false) * * Return Value: * None * * Example: - * [] call ace_hearing_fnc_updateVolume + * call ace_hearing_fnc_updateVolume * * Public: No */ +if (isGamePaused) exitWith {}; + if (!alive ACE_player) exitWith { - if (missionNameSpace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; + if (missionNamespace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; + TRACE_1("dead - removing hearing effects",ACE_player); + [QUOTE(ADDON), 1, true] call EFUNC(common,setHearingCapability); }; -(_this select 0) params [["_justUpdateVolume", false]]; +params [["_updateVolumeOnly", false]]; GVAR(deafnessDV) = (GVAR(deafnessDV) min 20) max 0; GVAR(volume) = (1 - (GVAR(deafnessDV) / 20)) max 0.05; + TRACE_3("",GVAR(volume),GVAR(deafnessDV),GVAR(deafnessDV) - GVAR(deafnessPrior)); -if (!_justUpdateVolume) then { +if (!_updateVolumeOnly) then { // Ring if we got a big increase in the last second or enough accumulated damage if (GVAR(deafnessDV) - GVAR(deafnessPrior) > 1 || GVAR(deafnessDV) > 10) then { if (CBA_missionTime - GVAR(time3) < 3) exitWith {}; + if (!isGameFocused) exitWith {}; // prevent audio from stacking when tabbed out + GVAR(time3) = CBA_missionTime; - if (!isGameFocused) exitWith {}; if (GVAR(deafnessDV) > 19.75) then { - playSound (["ACE_Combat_Deafness_Heavy", "ACE_Combat_Deafness_Heavy_NoRing"] select GVAR(DisableEarRinging)); + playSound (["ACE_Combat_Deafness_Heavy", "ACE_Combat_Deafness_Heavy_NoRing"] select GVAR(disableEarRinging)); } else { - playSound (["ACE_Combat_Deafness_Medium", "ACE_Combat_Deafness_Medium_NoRing"] select GVAR(DisableEarRinging)); + playSound (["ACE_Combat_Deafness_Medium", "ACE_Combat_Deafness_Medium_NoRing"] select GVAR(disableEarRinging)); }; }; + GVAR(deafnessPrior) = GVAR(deafnessDV); // Hearing takes longer to return to normal after it hits rock bottom - GVAR(deafnessDV) = (GVAR(deafnessDV) - (0.5 * (GVAR(volume) max 0.1))) max 0; + GVAR(deafnessDV) = (GVAR(deafnessDV) - (0.5 * (GVAR(volume) max 0.1))) max 0; }; -if (missionNameSpace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; +if (missionNamespace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; private _volume = GVAR(volume); @@ -57,8 +63,8 @@ private _volume = GVAR(volume); _volume = _volume min GVAR(volumeAttenuation); // Reduce volume if player is unconscious -if (ACE_player getVariable ["ACE_isUnconscious", false]) then { - _volume = _volume min GVAR(UnconsciousnessVolume); +if (lifeState ACE_player == "INCAPACITATED") then { + _volume = _volume min GVAR(unconsciousnessVolume); }; [QUOTE(ADDON), _volume, true] call EFUNC(common,setHearingCapability); diff --git a/addons/hearing/initKeybinds.inc.sqf b/addons/hearing/initKeybinds.inc.sqf index 22cf132add6..d1299661986 100644 --- a/addons/hearing/initKeybinds.inc.sqf +++ b/addons/hearing/initKeybinds.inc.sqf @@ -2,14 +2,17 @@ // 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 { + if (GVAR(enableCombatDeafness) && {!(ACE_player call FUNC(hasEarPlugsIn))} && {[ACE_player, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith { [ACE_player, true] call FUNC(putInEarPlugs); - true + + true // return }; - if (GVAR(EnableCombatDeafness) && {[ACE_player] call FUNC(hasEarPlugsIn)}) exitWith { + + if (GVAR(enableCombatDeafness) && {ACE_player call FUNC(hasEarPlugsIn)}) exitWith { [ACE_player, true] call FUNC(removeEarPlugs); - true + + true // return }; - - false + + false // return }] call CBA_fnc_addKeybind; // UNBOUND diff --git a/addons/hearing/initSettings.inc.sqf b/addons/hearing/initSettings.inc.sqf index f22a7b4eda5..adc6c6def75 100644 --- a/addons/hearing/initSettings.inc.sqf +++ b/addons/hearing/initSettings.inc.sqf @@ -1,15 +1,19 @@ -private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; +private _category = format ["ACE %1", LLSTRING(Module_DisplayName)]; [ - QGVAR(enableCombatDeafness), "CHECKBOX", + QGVAR(enableCombatDeafness), + "CHECKBOX", [LSTRING(EnableCombatDeafness_DisplayName), LSTRING(EnableCombatDeafness_Description)], _category, true, - 1 + 1, + {[QGVAR(enableCombatDeafness), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ - QGVAR(earplugsVolume), "SLIDER", + QGVAR(earplugsVolume), + "SLIDER", [LSTRING(earplugsVolume_DisplayName), LSTRING(earplugsVolume_Description)], _category, [0, 1, 0.5, 1], @@ -17,7 +21,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(unconsciousnessVolume), "SLIDER", + QGVAR(unconsciousnessVolume), + "SLIDER", [LSTRING(unconsciousnessVolume_DisplayName), LSTRING(unconsciousnessVolume_Description)], _category, [0, 1, 0.4, 1], @@ -25,15 +30,16 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(disableEarRinging), "CHECKBOX", + QGVAR(disableEarRinging), + "CHECKBOX", [LSTRING(DisableEarRinging_DisplayName), LSTRING(DisableEarRinging_Description)], _category, - false, - 0 + false ] call CBA_fnc_addSetting; [ - QGVAR(enabledForZeusUnits), "CHECKBOX", + QGVAR(enabledForZeusUnits), + "CHECKBOX", [LSTRING(enabledForZeusUnits_DisplayName), LSTRING(enabledForZeusUnits_Description)], _category, true, @@ -41,9 +47,10 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(autoAddEarplugsToUnits), "CHECKBOX", + QGVAR(autoAddEarplugsToUnits), + "LIST", [LSTRING(autoAddEarplugsToUnits_DisplayName), LSTRING(autoAddEarplugsToUnits_Description)], _category, - true, + [[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(heavyWeaponUnits), ELSTRING(common,Enabled)], 1], 1 ] call CBA_fnc_addSetting; diff --git a/addons/hearing/stringtable.xml b/addons/hearing/stringtable.xml index 83a69086944..08419d4e42b 100644 --- a/addons/hearing/stringtable.xml +++ b/addons/hearing/stringtable.xml @@ -45,7 +45,7 @@ Füldugó berakva Protetores colocados Indossa i tappi auricolari - 耳栓を着ける + 耳栓を装着 귀마개 착용 塞入耳塞 塞入耳塞 @@ -79,7 +79,7 @@ Füldugó berakva Protetores colocados Tappi auricolari indossati - 耳栓を着けました + 耳栓を装着しました 귀마개 착용 耳塞已塞入 耳塞已塞入 @@ -144,7 +144,7 @@ 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 Убирает эффект звона в ушах, когда игрок получает повреждение слуха - プレイヤーの聴覚が損傷したときの耳鳴り効果を削除します + プレイヤーが聴覚にダメージを受けた際の耳鳴り効果音を無効化します 플레이어가 청력손실을 입을 때 생기는 이명현상을 제거합니다. 关闭耳鸣效果时,就算玩家受到相当程度的听力伤害,也不会造成耳鸣效果 關閉耳鳴效果時,就算玩家受到相當程度的聽力傷害, 也不會造成耳鳴效果 @@ -192,7 +192,7 @@ Уменьшает возможность игрока слышать звуки при повреждении органов слуха Assorda il giocatore quando riceve danni all'udito Réduit la capacité auditive du joueur lorsqu'il subit des dommages auditifs. - プレイヤーが聴覚ダメージを受けると聴力が低下します + プレイヤーが聴覚にダメージを受けると聴力が低下します 청력에 손상을 입으면 듣는 소리가 감소합니다. 当玩家听力受损时降低听力能力? 當玩家聽力受損時降低聽力能力? @@ -268,7 +268,7 @@ Aggiungi l'oggetto 'ACE_EarPlugs' a tutte le unità che hanno armi/lanciatori rumorosi. Può essere disabilitato se vengono usati loadout personalizzati. Agregar el item `ACE_EarPlugs` a todas las unidades equipadas con armas muy ruidosas. Desactivar si quieren utilizarse equipamientos personalizados. Ajoute l'objet `Ace_EarPlugs` à toutes les unités ayant des armes bruyantes. Peut être désactivé si de l'équipement personnalisé est utilisé. - 全ユニットへ`ACE_EarPlugs`アイテムを持たせます。これはロードアウトの編集で無効化できます。 + 全てのユニットに`ACE_EarPlugs`アイテムを所持させます。これはロードアウトの編集で無効化できます。 무기를 가지고 있는 모든 인원에게 'ACE_EarPlugs'를 지급합니다. 임의의 장비를 사용시 비활성화할 수 있습니다. 增加`ACE_EarPlugs`物品给拥有巨大噪音武器的单位。当你想自定装备时,此功能可被关闭。 增加`ACE_EarPlugs`物品給擁有巨大噪音武器的單位。當你想自定裝備時,此功能可被關閉。 @@ -292,7 +292,7 @@ Volume muffling Lautstärkedämpfung Atténuation du volume - 音量低下 + 音量の抑制 降低音量 進低音量 Attenuazione del volume @@ -306,7 +306,7 @@ Earplugs Volume Lautstärke Ohrenstöpsel - 耳栓時の音量 + 耳栓装着時音量 耳塞时音量 耳塞時音量 Volume con i Tappi @@ -321,7 +321,7 @@ Volume when using earplugs. Lautstärke wenn man Ohrenstöpsel benutzt - 耳栓使用時の音量を決定します。 + 耳栓を使用した時の音量。 决定带上耳塞时的音量 使用耳塞時音量 Volume audio quandi si indossano i tappi per le orecchie. @@ -336,7 +336,7 @@ Unconscious Volume Lautstärke Bewusstlosigkeit - 気絶時の音量 + 無意識状態時音量 无意识时音量 昏迷時音量 Volume quando incoscente @@ -351,7 +351,7 @@ Volume when unconscious. Lautstärke während man Bewusstlos ist - 無意識状態時の音量を決定します。 + 無意識状態になった時の音量。 决定处于无意识时的音量 昏迷時使用耳塞的音量 Volume quando incoscente. @@ -365,7 +365,25 @@ Put/take out earplugs - 耳栓を着け外す + 耳栓の着脱 + Вставить/вынуть беруши + Metti/Togli tappi + 귀마개 토글 + Mettre/enlever les bouchons + Ohrstöpsel einsetzen/herausnehmen + Poner/quitar tapones + Colocar/retirar protetores auriculares + + + 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 + 중화기를 가진 유닛만 해당 + Apenas unidades com armas pesadas diff --git a/addons/hellfire/CfgAmmo.hpp b/addons/hellfire/CfgAmmo.hpp index 5eef9ad47eb..8789be711ce 100644 --- a/addons/hellfire/CfgAmmo.hpp +++ b/addons/hellfire/CfgAmmo.hpp @@ -1,3 +1,4 @@ +class ace_missileguidance_type_Hellfire; class CfgAmmo { class M_Scalpel_AT; @@ -23,32 +24,8 @@ class CfgAmmo { EGVAR(rearm,caliber) = 178; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Hellfire { enabled = 1; - - minDeflection = 0.0005; // Minium flap deflection for guidance - maxDeflection = 0.01; // 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 = "SALH"; - seekerTypes[] = { "SALH", "LIDAR", "SARH", "Optic", "Thermal", "GPS", "SACLOS", "MCLOS" }; - - defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = { "LOAL", "LOBL" }; - - seekLastTargetPos = 1; // seek last target position [if seeker loses LOS of target, continue to last known pos] - seekerAngle = 70; // Angle in front of the missile which can be searched - seekerAccuracy = 1; // seeker accuracy multiplier - - seekerMinRange = 1; - seekerMaxRange = 8000; // Range from the missile which the seeker can visually search - - // Attack profile type selection - defaultAttackProfile = "hellfire"; - attackProfiles[] = {"hellfire", "hellfire_hi", "hellfire_lo"}; }; }; class ACE_Hellfire_AGM114N: ACE_Hellfire_AGM114K { @@ -75,8 +52,8 @@ class CfgAmmo { canVanillaLock = 1; enabled = 1; // Missile Guidance must be explicitly enabled seekLastTargetPos = 0; - defaultSeekerType = "ARH"; - seekerTypes[] = { "ARH" }; + defaultSeekerType = "MillimeterWaveRadar"; + seekerTypes[] = { "MillimeterWaveRadar" }; defaultSeekerLockMode = "LOBL"; seekerLockModes[] = { "LOBL" }; diff --git a/addons/hellfire/CfgMagazines.hpp b/addons/hellfire/CfgMagazines.hpp index 8abf2529b57..d025afadde4 100644 --- a/addons/hellfire/CfgMagazines.hpp +++ b/addons/hellfire/CfgMagazines.hpp @@ -32,7 +32,7 @@ class CfgMagazines { count = 3; mass = 250; pylonWeapon = QGVAR(launcher); - hardpoints[] = {"B_MISSILE_PYLON", "UNI_SCALPEL", "CUP_NATO_HELO_LARGE", "RHS_HP_LONGBOW_RACK"}; + hardpoints[] = {"B_MISSILE_PYLON", "UNI_SCALPEL", "CUP_NATO_HELO_LARGE"}; model = "\A3\Weapons_F\DynamicLoadout\PylonPod_3x_Missile_LG_scalpel_F.p3d"; mirrorMissilesIndexes[] = {2, 1, 3}; }; @@ -41,7 +41,7 @@ class CfgMagazines { count = 4; mass = 340; pylonWeapon = QGVAR(launcher); - hardpoints[] = {"UNI_SCALPEL", "CUP_NATO_HELO_LARGE", "RHS_HP_HELLFIRE_RACK", "RHS_HP_LONGBOW_RACK"}; + hardpoints[] = {"UNI_SCALPEL", "CUP_NATO_HELO_LARGE"}; model = "\A3\Weapons_F\DynamicLoadout\PylonPod_4x_Missile_LG_scalpel_F.p3d"; mirrorMissilesIndexes[] = {2, 1, 4, 3}; }; diff --git a/addons/hellfire/XEH_PREP.hpp b/addons/hellfire/XEH_PREP.hpp index f30cf0bffdf..011810aa044 100644 --- a/addons/hellfire/XEH_PREP.hpp +++ b/addons/hellfire/XEH_PREP.hpp @@ -2,3 +2,4 @@ LOG("prep"); PREP(attackProfile); PREP(getAttackProfileSettings); PREP(setupVehicle); +PREP(midCourseTransition); diff --git a/addons/hellfire/functions/fnc_attackProfile.sqf b/addons/hellfire/functions/fnc_attackProfile.sqf index 26bc3f1ff07..aa457d02fa5 100644 --- a/addons/hellfire/functions/fnc_attackProfile.sqf +++ b/addons/hellfire/functions/fnc_attackProfile.sqf @@ -18,80 +18,99 @@ */ params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; -_args params ["_firedEH", "_launchParams", "", "", "_stateParams"]; +_args params ["_firedEH", "_launchParams", "_flightParams", "", "_stateParams"]; _stateParams params ["", "_seekerStateParams"]; _launchParams params ["","_targetLaunchParams","_seekerType"]; -_targetLaunchParams params ["", "", "_launchPos"]; +_targetLaunchParams params ["", "", "_launchPos", "_launchDir"]; _firedEH params ["","","","","","","_projectile"]; // Get state params: if (_attackProfileStateParams isEqualTo []) then { _this call FUNC(getAttackProfileSettings); }; -_attackProfileStateParams params ["_attackStage", "_configLaunchHeightClear"]; - +_attackProfileStateParams params ["_attackStage", "_configLaunchHeightClear", "_missileStateData"]; private _projectilePos = getPosASL _projectile; -private _distanceFromLaunch2d = _launchPos distance2d _projectilePos; +private _distanceFromLaunch2d = _launchPos distance2D _projectilePos; private _heightAboveLaunch = (_projectilePos select 2) - (_launchPos select 2); // Add height depending on distance for compensate -private _returnTargetPos = nil; +private _returnTargetPos = _seekerTargetPos; +if (_returnTargetPos isEqualTo [0, 0, 0]) then { + private _initialDistanceToTarget = 8000; + _returnTargetPos = _launchPos vectorAdd (_launchDir vectorMultiply _initialDistanceToTarget); +}; + +private _closingRate = vectorMagnitude velocity _projectile; +// subtract 500 meters to account for the fact that we don't want to be at the perfect pitch exactly when we cross the target +// 500 seemed good in testing +private _timeToGo = ((_projectilePos distance2D _seekerTargetPos) - 500) / _closingRate; + +// we could do stuff like desired attack angle, but I'm not going that far today +private _los = _projectilePos vectorFromTo _seekerTargetPos; + +_flightParams params ["_pitchRate", "_yawRate"]; + +private _angleToTarget = acos ((vectorDir _projectile) vectorCos _los); +private _atMinRotationAngle = _angleToTarget >= (_pitchRate * _timeToGo); switch (_attackStage) do { case STAGE_LAUNCH: { // Gain height quickly to pass terrain mask - _returnTargetPos = _projectilePos getPos [100, getDir _projectile]; - _returnTargetPos set [2, (_projectilePos select 2) + 36.4]; // 100 and 36.4 gives a 20 deg angle + _missileStateData params ["_heightBeforeStateSwitch", "_initialDistanceToTarget"]; + + _returnTargetPos set [2, _heightBeforeStateSwitch + (_initialDistanceToTarget * sin 20)]; // 100 and 36.4 gives a 20 deg angle if (_heightAboveLaunch > _configLaunchHeightClear) then { _attackProfileStateParams set [0, STAGE_SEEK_CRUISE]; + + _attackProfileStateParams set [2, [_projectilePos select 2, _seekerTargetPos distance2D _projectilePos]]; TRACE_2("New Stage: STAGE_SEEK_CRUISE",_distanceFromLaunch2d,_heightAboveLaunch); }; + + if (_atMinRotationAngle) then { + _attackProfileStateParams set [0, STAGE_ATTACK_TERMINAL]; + + _attackProfileStateParams set [2, [_projectilePos select 2, _seekerTargetPos distance2D _projectilePos]]; + TRACE_2("New Stage: STAGE_ATTACK_TERMINAL",_distanceToTarget2d,_currentHeightOverTarget); + }; }; case STAGE_SEEK_CRUISE: { // Slowly gain altitude while searching for target + _missileStateData params ["_heightBeforeStateSwitch", "_initialDistanceToTarget"]; + // Before 4000 cruise at 5.7 degrees up, then level out - private _cruiseHeight = linearConversion [3000, 5000, _distanceFromLaunch2d, 10, 0, true]; - - _returnTargetPos = _projectilePos getPos [100, getDir _projectile]; - _returnTargetPos set [2, (_projectilePos select 2) + _cruiseHeight]; - + _returnTargetPos set [2, _heightBeforeStateSwitch + (_initialDistanceToTarget * sin 5.7)]; + if (_seekerTargetPos isNotEqualTo [0,0,0]) then { _attackProfileStateParams set [0, STAGE_ATTACK_CRUISE]; + + _attackProfileStateParams set [2, [_projectilePos select 2, _seekerTargetPos distance2D _projectilePos]]; TRACE_1("New Stage: STAGE_ATTACK_CRUISE",_distanceFromLaunch2d); }; }; case STAGE_ATTACK_CRUISE: { + _missileStateData params ["_heightBeforeStateSwitch", "_initialDistanceToTarget"]; + private _currentHeightOverTarget = (_projectilePos select 2) - (_seekerTargetPos select 2); - private _distanceToTarget2d = _seekerTargetPos distance2d _projectilePos; - private _distToGoRatio = _distanceToTarget2d / (_launchPos distance2d _seekerTargetPos); + private _distanceToTarget2d = _seekerTargetPos distance2D _projectilePos; - // 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]; - _returnTargetPos = +_seekerTargetPos; - _returnTargetPos set [2, ((_projectilePos select 2) + (_distanceToTarget2d * sin _gainSlope)) max (_seekerTargetPos select 2)]; + _returnTargetPos set [2, _heightBeforeStateSwitch + (_initialDistanceToTarget * sin 7)]; - if ((_distanceToTarget2d < 500) || {(_currentHeightOverTarget atan2 _distanceToTarget2d) > 15}) then { // Wait until we can come down at a sharp angle + // if we are at the rotation limit, rotate to target + if (_atMinRotationAngle || {(_currentHeightOverTarget atan2 _distanceToTarget2d) > 15}) then { // Wait until we can come down at a sharp angle _attackProfileStateParams set [0, STAGE_ATTACK_TERMINAL]; + + _attackProfileStateParams set [2, [_projectilePos select 2, _seekerTargetPos distance2D _projectilePos]]; TRACE_2("New Stage: STAGE_ATTACK_TERMINAL",_distanceToTarget2d,_currentHeightOverTarget); }; }; case STAGE_ATTACK_TERMINAL: { - private _distanceToTarget2d = _seekerTargetPos distance2d _projectilePos; - _returnTargetPos = _seekerTargetPos vectorAdd [0, 0, _distanceToTarget2d * 0.02]; }; }; -// 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); - }; -}; +// missile guidance defines this variable in doAttackProfile +//IGNORE_PRIVATE_WARNING ["_attackProfileName"]; +_attackProfileName = ["na", "hellfire - LAUNCH", "hellfire - SEEK CRUISE", "hellfire - ATTACK CRUISE", "hellfire - TERMINAL"] select _attackStage; -// TRACE_1("Adjusted target position",_returnTargetPos); +TRACE_1("Adjusted target position",_returnTargetPos); _returnTargetPos; diff --git a/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf b/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf index 14d89f82e31..d9e1c23b205 100644 --- a/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf +++ b/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf @@ -27,6 +27,8 @@ private _attackConfig = configFile >> QEGVAR(missileguidance,AttackProfiles) >> // Launch (clearing terrain mask for LO/HI): private _configLaunchHeightClear = getNumber (_attackConfig >> QGVAR(launchHeightClear)); +private _projectilePos = getPosASL _projectile; + // Get starting stage private _startingStage = if (_configLaunchHeightClear > 0) then { STAGE_LAUNCH; // LOAL-HI / LO @@ -40,5 +42,9 @@ private _startingStage = if (_configLaunchHeightClear > 0) then { // Set data in param array _attackProfileStateParams set [0, _startingStage]; _attackProfileStateParams set [1, _configLaunchHeightClear]; +_attackProfileStateParams set [2, [ + _projectilePos select 2, + _seekerTargetPos distance2D _projectilePos +]]; TRACE_1("new shot settings",_attackProfileStateParams); diff --git a/addons/hellfire/functions/fnc_midCourseTransition.sqf b/addons/hellfire/functions/fnc_midCourseTransition.sqf new file mode 100644 index 00000000000..034bd25d61a --- /dev/null +++ b/addons/hellfire/functions/fnc_midCourseTransition.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Condition to switch to next navigation profile + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * None + * + * Example: + * [] call ace_hellfire_fnc_midCourseTransition + * + * Public: No + */ + +params ["_args", "_timestep"]; +_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateData"]; +_firedEH params ["_shooter","","","","_ammo","","_projectile"]; +_launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; +_targetLaunchParams params ["_target", "_targetPos", "_launchPos", "_launchDir", "_launchTime"]; +_flightParams params ["_pitchRate", "_yawRate", "_isBangBangGuidance"]; +_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState","_navigationParams", "_guidanceParameters"]; +_seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; +_targetData params ["_targetDirection", "_attackProfileDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"]; + +_attackProfileStateParams params ["_state"]; +_state isEqualTo STAGE_ATTACK_TERMINAL; + diff --git a/addons/hellfire/functions/fnc_setupVehicle.sqf b/addons/hellfire/functions/fnc_setupVehicle.sqf index 49eefd82746..ce3961d77af 100644 --- a/addons/hellfire/functions/fnc_setupVehicle.sqf +++ b/addons/hellfire/functions/fnc_setupVehicle.sqf @@ -46,7 +46,7 @@ if ((getNumber (configOf _vehicle >> QGVAR(addLaserDesignator))) == 1) then { params ["_vehicle", "_turretPath"]; TRACE_3("checking for laser",_vehicle,_turretPath,_vehicle turretLocal _turretPath); if (!alive _vehicle) exitWith {}; - if (!(_vehicle turretLocal _turretPath)) then {WARNING("Turret not local");}; + if !(_vehicle turretLocal _turretPath) then {WARNING("Turret not local");}; private _hasLaser = false; { // Most addons just use "Laserdesignator_mounted", but this should cover custom ones diff --git a/addons/hitreactions/ACE_Settings.hpp b/addons/hitreactions/ACE_Settings.hpp index 90c1445eba7..78a510a1419 100644 --- a/addons/hitreactions/ACE_Settings.hpp +++ b/addons/hitreactions/ACE_Settings.hpp @@ -1,4 +1,3 @@ - class ACE_Settings { class GVAR(minDamageToTrigger) { movedToSQF = 1; diff --git a/addons/hitreactions/CfgEventHandlers.hpp b/addons/hitreactions/CfgEventHandlers.hpp index eecf08c69da..b737b7bcbfc 100644 --- a/addons/hitreactions/CfgEventHandlers.hpp +++ b/addons/hitreactions/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); @@ -11,6 +10,12 @@ class Extended_PreInit_EventHandlers { }; }; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; + class Extended_Hit_EventHandlers { class CAManBase { class ADDON { diff --git a/addons/hitreactions/XEH_PREP.hpp b/addons/hitreactions/XEH_PREP.hpp index 7701b8ef19b..eea48dcaa8b 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 00000000000..2750ae11592 --- /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 894773534a4..296279c7ebe 100644 --- a/addons/hitreactions/XEH_preInit.sqf +++ b/addons/hitreactions/XEH_preInit.sqf @@ -8,4 +8,16 @@ 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 00000000000..ad4e7c4a417 --- /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_getRandomAnimation.sqf b/addons/hitreactions/functions/fnc_getRandomAnimation.sqf index 8b26bf70efd..a52f2958dca 100644 --- a/addons/hitreactions/functions/fnc_getRandomAnimation.sqf +++ b/addons/hitreactions/functions/fnc_getRandomAnimation.sqf @@ -25,6 +25,7 @@ if (_weapon == "") exitWith { if (_weapon == primaryWeapon _unit) exitWith { if (_unit call EFUNC(common,isPlayer)) then { + //IGNORE_PRIVATE_WARNING ["_velocity"]; // from upper scope private _isRunning = _velocity > 4; [ diff --git a/addons/hitreactions/initSettings.inc.sqf b/addons/hitreactions/initSettings.inc.sqf index 2ca4ceaeacd..820f6647670 100644 --- a/addons/hitreactions/initSettings.inc.sqf +++ b/addons/hitreactions/initSettings.inc.sqf @@ -1,9 +1,30 @@ private _category = [LELSTRING(common,categoryUncategorized), QUOTE(COMPONENT_BEAUTIFIED)]; [ - QGVAR(minDamageToTrigger), "SLIDER", + 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 dccbef24f74..dd407a914b3 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 b07e9be9a03..7d335532909 100644 --- a/addons/hitreactions/stringtable.xml +++ b/addons/hitreactions/stringtable.xml @@ -6,7 +6,7 @@ Danno Minimo per far cadere 觸發倒下前最低需受到多少傷害 触发倒下前最低需受到多少伤害 - 崩れ落ちるまでの最低損傷値 + 転倒が発生するダメージの最低値 넘어질 때 발생하는 최소 피해량 Mindestschaden, um Sturz auszulösen Minimalne obrażenie, żeby aktywować spadanie @@ -17,5 +17,27 @@ 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) + Probabilité de lâcher l'arme (coup au bras) + Probabilidade do jogador de largar a arma após tiro no braço + Probabilidad del Jugador de Soltar el Arma (Impacto en Brazo) + + + 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) + Probabilité de l'IA de lâcher l'arme (coup au bras) + Probabilidade da IA de largar a arma após tiro no braço + Probabilidad de IA de Soltar el Arma (Impacto en Brazo) + diff --git a/addons/hot/CfgAmmo.hpp b/addons/hot/CfgAmmo.hpp index 1be8c6067f6..6f91d241fb9 100644 --- a/addons/hot/CfgAmmo.hpp +++ b/addons/hot/CfgAmmo.hpp @@ -1,3 +1,4 @@ +class ace_missileguidance_type_Hot; class CfgAmmo { class M_Scalpel_AT; class ammo_Penetrator_Base; @@ -55,35 +56,8 @@ class CfgAmmo { EGVAR(rearm,caliber) = 178; EGVAR(vehicle_damage,incendiary) = 1.0; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Hot { enabled = 1; - - minDeflection = 0; // Minium flap deflection for guidance - maxDeflection = 0.0030; // 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 = 30; // Angle from the shooter's view that can track the missile - seekerAccuracy = 1; // seeker accuracy multiplier - - seekerMinRange = 75; - seekerMaxRange = 4000; // Range from the missile which the seeker can visually search - - 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 - defaultAttackProfile = "WIRE"; - attackProfiles[] = {"WIRE"}; }; }; @@ -135,6 +109,7 @@ class CfgAmmo { class ace_missileguidance: ace_missileguidance { enabled = 1; seekerMaxRange = 4300; + offsetFromCrosshair[] = { 0, 0, 0.5 }; // where the missile wants to stay in relation to the center of the crosshair. }; }; }; diff --git a/addons/hot/CfgVehicles.hpp b/addons/hot/CfgVehicles.hpp index db5b8b5262e..46ac7d5136b 100644 --- a/addons/hot/CfgVehicles.hpp +++ b/addons/hot/CfgVehicles.hpp @@ -4,11 +4,22 @@ class CfgVehicles { class Turrets; }; class LT_01_base_F: Tank_F { + class AnimationSources; class Turrets: Turrets { class MainTurret; }; }; class LT_01_AT_base_F: LT_01_base_F { + class AnimationSources: AnimationSources { + class Missiles_revolving { + source = "revolving"; + weapon = QGVAR(generic_launcher); + }; + class Missiles_reloadMagazine { + source = "reloadMagazine"; + weapon = QGVAR(generic_launcher); + }; + }; class Turrets: Turrets { class MainTurret: MainTurret { weapons[] = {"SmokeLauncher","HMG_127",QGVAR(generic_launcher)}; diff --git a/addons/huntir/functions/fnc_cam.sqf b/addons/huntir/functions/fnc_cam.sqf index c306595fc7f..4a80a4819e9 100644 --- a/addons/huntir/functions/fnc_cam.sqf +++ b/addons/huntir/functions/fnc_cam.sqf @@ -31,10 +31,10 @@ GVAR(ELEVAT) = 0.01; HUNTIR_BACKGROUND_LAYER_ID cutText["","PLAIN"]; -closedialog 0; +closeDialog 0; createDialog QGVAR(cam_dialog); -uiNameSpace setVariable [QGVAR(monitor), findDisplay 18880]; -(uiNameSpace getVariable QGVAR(monitor)) displaySetEventHandler ["Keydown", QUOTE(_this call FUNC(keyPressed))]; +uiNamespace setVariable [QGVAR(monitor), findDisplay 18880]; +(uiNamespace getVariable QGVAR(monitor)) displaySetEventHandler ["Keydown", QUOTE(_this call FUNC(keyPressed))]; ctrlSetText [4, "0X"]; @@ -68,8 +68,9 @@ GVAR(no_cams) sort true; } forEach GVAR(no_cams); [{ //Close monitor if we no longer have the item: - if ((!([ACE_player, "ACE_HuntIR_monitor"] call EFUNC(common,hasItem))) && {!isNull (uiNameSpace getVariable [QGVAR(monitor), displayNull])}) then { + if ((!([ACE_player, "ACE_HuntIR_monitor"] call EFUNC(common,hasItem))) && {!isNull (uiNamespace getVariable [QGVAR(monitor), displayNull])}) then { closeDialog 0; + [QGVAR(monitorClosed), [ACE_player]] call CBA_fnc_localEvent; }; GVAR(nearHuntIRs) = ACE_player nearEntities ["ACE_HuntIR", HUNTIR_MAX_TRANSMISSION_RANGE]; @@ -77,8 +78,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; @@ -105,32 +105,33 @@ GVAR(no_cams) sort true; GVAR(NV) = 0; setAperture -1; - closedialog 0; - titletext [" ", "BLACK IN", 4]; + closeDialog 0; + titleText [" ", "BLACK IN", 4]; ACE_player switchCamera "INTERNAL"; - GVAR(cam) CameraEffect ["Terminate", "Back"]; - CamDestroy GVAR(cam); + GVAR(cam) cameraEffect ["Terminate", "Back"]; + camDestroy GVAR(cam); deleteVehicle GVAR(logic); if (player != ACE_player) then { player remoteControl ACE_player; }; + [QGVAR(monitorClosed), [ACE_player]] call CBA_fnc_localEvent; }; switch (GVAR(ZOOM)) do { case 0: { - GVAR(cam) camsetFOV 0.7; + GVAR(cam) camSetFov 0.7; GVAR(cam) camSetFocus [GVAR(pos) select 2, 1]; }; case 1: { - GVAR(cam) camsetFOV 0.35; + GVAR(cam) camSetFov 0.35; GVAR(cam) camSetFocus [(GVAR(pos) select 2)/2, 1]; }; case 2: { - GVAR(cam) camsetFOV 0.17; + GVAR(cam) camSetFov 0.17; GVAR(cam) camSetFocus [(GVAR(pos) select 2)/4, 1]; }; case 3: { - GVAR(cam) camsetFOV 0.1; + GVAR(cam) camSetFov 0.1; GVAR(cam) camSetFocus [(GVAR(pos) select 2)/8, 1]; }; }; @@ -138,7 +139,7 @@ GVAR(no_cams) sort true; GVAR(logic) setPosATL (GVAR(pos) vectorAdd [0, 0, -5]); GVAR(logic) setDir GVAR(ROTATE); GVAR(logic) setVectorUp [0.0001, 0.0001, 1]; - GVAR(cam) CameraEffect ["internal", "BACK"]; + GVAR(cam) cameraEffect ["internal", "BACK"]; private _cam_coord_y = GVAR(ELEVAT) * cos(GVAR(ROTATE)); private _cam_coord_x = GVAR(ELEVAT) * sin(GVAR(ROTATE)); GVAR(cam) camSetRelPos [_cam_coord_x, _cam_coord_y, 2]; diff --git a/addons/huntir/functions/fnc_huntir.sqf b/addons/huntir/functions/fnc_huntir.sqf index 60b7a1fc141..c54d193d9e3 100644 --- a/addons/huntir/functions/fnc_huntir.sqf +++ b/addons/huntir/functions/fnc_huntir.sqf @@ -18,20 +18,23 @@ #define __TYPE_WRITER_DELAY 0.05 -if ((ACE_player call CBA_fnc_getUnitAnim) select 0 == "stand") then { +if (missionNamespace getVariable [QGVAR(animatePlayer), true] && {(ACE_player call CBA_fnc_getUnitAnim) select 0 == "stand"}) then { ACE_player playMove "AmovPercMstpSrasWrflDnon_diary"; }; HUNTIR_BACKGROUND_LAYER_ID cutText ["", "BLACK", 0]; createDialog QGVAR(cam_dialog_off); +[QGVAR(monitorOpened), [ACE_player]] call CBA_fnc_localEvent; + [{ if (!dialog) exitWith { HUNTIR_BACKGROUND_LAYER_ID cutText ["", "PLAIN", 0]; + [QGVAR(monitorClosed), [ACE_player]] call CBA_fnc_localEvent; }; closeDialog 0; createDialog QGVAR(cam_dialog_inactive); - uiNameSpace setVariable [QGVAR(monitor), findDisplay 18881]; + uiNamespace setVariable [QGVAR(monitor), findDisplay 18881]; [{ GVAR(startTime) = CBA_missionTime; GVAR(done) = false; @@ -40,10 +43,12 @@ createDialog QGVAR(cam_dialog_off); GVAR(message) = []; GVAR(messageSearching) = toArray "Searching....."; GVAR(messageConnecting) = toArray "Connecting....."; + [QGVAR(monitorStarted), [ACE_player]] call CBA_fnc_localEvent; [{ //Close monitor if we no longer have item: - if ((!([ACE_player, "ACE_HuntIR_monitor"] call EFUNC(common,hasItem))) && {!isNull (uiNameSpace getVariable [QGVAR(monitor), displayNull])}) then { + if ((!([ACE_player, "ACE_HuntIR_monitor"] call EFUNC(common,hasItem))) && {!isNull (uiNamespace getVariable [QGVAR(monitor), displayNull])}) then { closeDialog 0; + [QGVAR(monitorClosed), [ACE_player]] call CBA_fnc_localEvent; }; private _elapsedTime = CBA_missionTime - GVAR(startTime); @@ -55,6 +60,7 @@ createDialog QGVAR(cam_dialog_off); GVAR(done) = false; GVAR(message) = []; GVAR(connectionDelay) = 5; + [QGVAR(monitorDisconnected), [ACE_player]] call CBA_fnc_localEvent; }; if ((!dialog) || GVAR(done)) exitWith { @@ -64,6 +70,7 @@ createDialog QGVAR(cam_dialog_off); [_nearestHuntIRs select 0] call FUNC(cam); } else { HUNTIR_BACKGROUND_LAYER_ID cutText ["", "PLAIN"]; + [QGVAR(monitorClosed), [ACE_player]] call CBA_fnc_localEvent; }; }; switch (GVAR(state)) do { @@ -75,9 +82,11 @@ createDialog QGVAR(cam_dialog_off); GVAR(message) = []; if (_elapsedTime > 10) then { GVAR(state) = "noGDS"; + [QGVAR(monitorNoGDS), [ACE_player]] call CBA_fnc_localEvent; }; if (_elapsedTime > 5 && {{_x getHitPointDamage "HitCamera" < 0.25} count _nearestHuntIRs > 0}) then { GVAR(state) = "connecting"; + [QGVAR(monitorConnecting), [ACE_player]] call CBA_fnc_localEvent; }; }; }; @@ -91,6 +100,7 @@ createDialog QGVAR(cam_dialog_off); if (GVAR(connectionDelay) <= 0) then { GVAR(done) = true; GVAR(state) = "connected"; + [QGVAR(monitorConnected), [ACE_player, _nearestHuntIRs select 0]] call CBA_fnc_localEvent; }; }; }; @@ -98,8 +108,9 @@ createDialog QGVAR(cam_dialog_off); ctrlSetText [1, "No GDS System detected"]; [{ GVAR(done) = true; - closedialog 0; + closeDialog 0; HUNTIR_BACKGROUND_LAYER_ID cutText ["", "PLAIN"]; + [QGVAR(monitorClosed), [ACE_player]] call CBA_fnc_localEvent; }, [], 3, 0] call CBA_fnc_waitAndExecute; }; }; diff --git a/addons/intelitems/CfgWeapons.hpp b/addons/intelitems/CfgWeapons.hpp new file mode 100644 index 00000000000..727b163de28 --- /dev/null +++ b/addons/intelitems/CfgWeapons.hpp @@ -0,0 +1,17 @@ +class CfgWeapons { + class ACE_ItemCore; + class CBA_MiscItem_ItemInfo; + + // Since base game doesn't support misc. items, this is needed to filling inventories in the editor + class GVAR(notepad_Item): ACE_ItemCore { + displayName = CSTRING(Notepad_DisplayName); + author = ECSTRING(common,ACETeam); + scope = 2; + scopeArsenal = 0; + descriptionShort = CSTRING(Notepad_Description); + picture = QPATHTOF(ui\notepad_ca.paa); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 0.1; + }; + }; +}; diff --git a/addons/intelitems/XEH_postInit.sqf b/addons/intelitems/XEH_postInit.sqf index f416b3667ed..f79ae9f6362 100644 --- a/addons/intelitems/XEH_postInit.sqf +++ b/addons/intelitems/XEH_postInit.sqf @@ -1,5 +1,8 @@ #include "script_component.hpp" +// Notepad item to magazine +[QGVAR(notepad_Item), QXGVAR(notepad)] call EFUNC(common,registerItemReplacement); + // Only handle loadout change when on map or have open controls ["loadout", { if (!visibleMap && {GVAR(controlsGroups) isEqualTo []}) exitWith {}; diff --git a/addons/intelitems/XEH_preInit.sqf b/addons/intelitems/XEH_preInit.sqf index 76f13135d91..ff09f6ea0e9 100644 --- a/addons/intelitems/XEH_preInit.sqf +++ b/addons/intelitems/XEH_preInit.sqf @@ -18,8 +18,8 @@ if (isServer) then { GVAR(intelData) = [true] call CBA_fnc_createNamespace; publicVariable QGVAR(intelData); - [QGVAR(handleMagIndex), FUNC(handleMagIndex)] call CBA_fnc_addEventHandler; - [QGVAR(setObjectData), FUNC(setObjectData)] call CBA_fnc_addEventHandler; + [QGVAR(handleMagIndex), LINKFUNC(handleMagIndex)] call CBA_fnc_addEventHandler; + [QGVAR(setObjectData), LINKFUNC(setObjectData)] call CBA_fnc_addEventHandler; }; if (hasInterface) then { diff --git a/addons/intelitems/config.cpp b/addons/intelitems/config.cpp index 3b9b37b5b63..1eafb3fe860 100644 --- a/addons/intelitems/config.cpp +++ b/addons/intelitems/config.cpp @@ -8,7 +8,7 @@ class CfgPatches { QXGVAR(document), QXGVAR(photo) }; - weapons[] = {}; + weapons[] = {QGVAR(notepad_Item)}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_interact_menu", "ace_zeus"}; author = ECSTRING(common,ACETeam); @@ -23,5 +23,6 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgEditorSubcategories.hpp" #include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" #include "CfgVehicles.hpp" #include "gui.hpp" diff --git a/addons/interact_menu/CursorMenus.hpp b/addons/interact_menu/CursorMenus.hpp index 79f1109598c..82cb9e79e66 100644 --- a/addons/interact_menu/CursorMenus.hpp +++ b/addons/interact_menu/CursorMenus.hpp @@ -28,10 +28,10 @@ class RscTitles { size = 1; colorBackground[] = {0, 0, 0, 0.65}; colorText[] = {0, 0, 0, 0}; - x = "safezoneX"; - y = "safezoneY"; - w = "safezoneW"; - h = "safezoneH"; + x = "safeZoneX"; + y = "safeZoneY"; + w = "safeZoneW"; + h = "safeZoneH"; }; }; }; diff --git a/addons/interact_menu/XEH_clientInit.sqf b/addons/interact_menu/XEH_clientInit.sqf index a76bf90e1cd..d0c6d93940e 100644 --- a/addons/interact_menu/XEH_clientInit.sqf +++ b/addons/interact_menu/XEH_clientInit.sqf @@ -3,16 +3,16 @@ if (!hasInterface) exitWith {}; // Wait until player controls (man,vehicle or uav) a thing before compiling the menu -GVAR(controllableSelfActionsAdded) = [] call CBA_fnc_createNamespace; +GVAR(controllableSelfActionsAdded) = createHashMap; DFUNC(newControllableObject) = { params ["_object"]; private _type = typeOf _object; TRACE_2("newControllableObject",_object,_type); if (_type == "") exitWith {}; - if (!(GVAR(controllableSelfActionsAdded) getVariable [_type, false])) then { + if !(_type in GVAR(controllableSelfActionsAdded)) then { [_type] call FUNC(compileMenuSelfAction); - GVAR(controllableSelfActionsAdded) setVariable [_type, true]; + GVAR(controllableSelfActionsAdded) set [_type, nil]; [{ TRACE_1("sending newControllableObject event",_this); // event for other systems to add self actions, running addActionToClass before this will cause compiling @@ -27,8 +27,7 @@ DFUNC(newControllableObject) = { GVAR(blockDefaultActions) = []; -GVAR(cachedBuildingTypes) = []; -GVAR(cachedBuildingActionPairs) = []; +GVAR(cachedBuildingTypes) = createHashMap; GVAR(ParsedTextCached) = []; @@ -47,7 +46,7 @@ GVAR(ParsedTextCached) = []; }] call CBA_fnc_addEventHandler; //Add Actions to Houses: -["ace_interactMenuOpened", {_this call FUNC(userActions_addHouseActions)}] call CBA_fnc_addEventHandler; +["ace_interactMenuOpened", LINKFUNC(userActions_addHouseActions)] call CBA_fnc_addEventHandler; ["ACE3 Common", QGVAR(InteractKey), (localize LSTRING(InteractKey)), { diff --git a/addons/interact_menu/XEH_preInit.sqf b/addons/interact_menu/XEH_preInit.sqf index b60f1bb7451..a62996df688 100644 --- a/addons/interact_menu/XEH_preInit.sqf +++ b/addons/interact_menu/XEH_preInit.sqf @@ -10,14 +10,14 @@ PREP_RECOMPILE_END; 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) = { @@ -88,8 +88,8 @@ GVAR(inheritedClassesMan) = []; if (GVAR(inheritedClassesAll) pushBackUnique _type == -1) exitWith { END_COUNTER(InitPost); }; { - _x params ["_objectType", "_typeNum", "_parentPath", "_action"]; - if (_object isKindOf _objectType) then { + _x params ["_objectType", "_typeNum", "_parentPath", "_action", "_excludedClasses"]; + if (_type isKindOf _objectType && {_excludedClasses findIf {_type isKindOf _x} == -1}) then { [_type, _typeNum, _parentPath, _action] call FUNC(addActionToClass); }; } forEach GVAR(inheritedActionsAll); @@ -102,8 +102,10 @@ GVAR(inheritedClassesMan) = []; if (GVAR(inheritedClassesMan) pushBackUnique _type == -1) exitWith { END_COUNTER(InitPost); }; { - _x params ["_typeNum", "_parentPath", "_action"]; - [_type, _typeNum, _parentPath, _action] call FUNC(addActionToClass); + _x params ["_typeNum", "_parentPath", "_action", "_excludedClasses"]; + if (_excludedClasses findIf {_type isKindOf _x} == -1) then { // skip excluded classes and children + [_type, _typeNum, _parentPath, _action] call FUNC(addActionToClass); + }; } forEach GVAR(inheritedActionsMan); END_COUNTER(InitPost); }, true, ["VirtualMan_F"]] call CBA_fnc_addClassEventHandler; diff --git a/addons/interact_menu/config.cpp b/addons/interact_menu/config.cpp index 756e8775abc..d29a9fb6879 100644 --- a/addons/interact_menu/config.cpp +++ b/addons/interact_menu/config.cpp @@ -21,10 +21,3 @@ class CfgPatches { #include "CursorMenus.hpp" #include "ACE_Settings.hpp" - -class ACE_Extensions { - 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 93d54c991c2..d2167c8079c 100644 --- a/addons/interact_menu/functions/fnc_addActionToClass.sqf +++ b/addons/interact_menu/functions/fnc_addActionToClass.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: esteldunedain - * Insert an ACE action to a class, under a certain path + * Inserts an ACE action to a class, under a certain path. * Note: This function is NOT global. * * Arguments: @@ -10,12 +10,13 @@ * 2: Parent path of the new action * 3: Action * 4: Use Inheritance (default: false) + * 5: Classes excluded from inheritance (children included) (default: []) * * Return Value: * The entry full path, which can be used to remove the entry, or add children entries . * * Example: - * [typeOf cursorTarget, 0, ["ACE_TapShoulderRight"],VulcanPinchAction] call ace_interact_menu_fnc_addActionToClass; + * [typeOf cursorTarget, 0, ["ACE_TapShoulderRight"], VulcanPinchAction] call ace_interact_menu_fnc_addActionToClass; * * Public: Yes */ @@ -25,22 +26,30 @@ if (!params [["_objectType", "", [""]], ["_typeNum", 0, [0]], ["_parentPath", [] ERROR("Bad Params"); [] }; -TRACE_4("addActionToClass",_objectType,_typeNum,_parentPath,_action); +private _useInheritance = _this param [4, false, [false]]; +private _excludedClasses = _this param [5, [], [[]]]; +TRACE_6("addActionToClass",_objectType,_typeNum,_parentPath,_action,_useInheritance,_excludedClasses); -if (param [4, false, [false]]) exitwith { +if (_useInheritance) exitWith { BEGIN_COUNTER(addAction); + private _cfgVehicles = configFile >> "CfgVehicles"; // store this so we don't resolve for every element + _excludedClasses = (_excludedClasses apply {configName (_cfgVehicles >> _x)}) - [""]; // ends up being faster than toLower'ing everything else if (_objectType == "CAManBase") then { - GVAR(inheritedActionsMan) pushBack [_typeNum, _parentPath, _action]; + GVAR(inheritedActionsMan) pushBack [_typeNum, _parentPath, _action, _excludedClasses]; { - [_x, _typeNum, _parentPath, _action] call FUNC(addActionToClass); - } forEach GVAR(inheritedClassesMan); + private _type = _x; + if (_excludedClasses findIf {_type isKindOf _x} == -1) then { // skip excluded classes and children + [_x, _typeNum, _parentPath, _action] call FUNC(addActionToClass); + }; + } forEach (GVAR(inheritedClassesMan) - _excludedClasses); } else { - GVAR(inheritedActionsAll) pushBack [_objectType, _typeNum, _parentPath, _action]; + GVAR(inheritedActionsAll) pushBack [_objectType, _typeNum, _parentPath, _action, _excludedClasses]; { - if (_x isKindOf _objectType) then { - [_x, _typeNum, _parentPath, _action] call FUNC(addActionToClass); + private _type = _x; + if (_type isKindOf _objectType && {_excludedClasses findIf {_type isKindOf _x} == -1}) then { + [_type, _typeNum, _parentPath, _action] call FUNC(addActionToClass); }; - } forEach GVAR(inheritedClassesAll); + } forEach (GVAR(inheritedClassesAll) - _excludedClasses); }; END_COUNTER(addAction); @@ -48,6 +57,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 +67,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_addMainAction.sqf b/addons/interact_menu/functions/fnc_addMainAction.sqf index 83349c21b39..beb02997b9e 100644 --- a/addons/interact_menu/functions/fnc_addMainAction.sqf +++ b/addons/interact_menu/functions/fnc_addMainAction.sqf @@ -19,14 +19,10 @@ 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 { +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 82235493e60..9a3eb315983 100644 --- a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf +++ b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf @@ -43,12 +43,21 @@ _origActionData params [ "_distance" ]; +private _result = [_target, ACE_player, _customParams] call _conditionCode; + +// Handle nil as false +if (isNil "_result") then { + ERROR_1("Action [%1] bad condition return",_actionName); + + _result = false; +}; + // Return nothing if the action itself is not active -if !([_target, ACE_player, _customParams] call _conditionCode) exitWith { +if (!_result) exitWith { [] }; -// Return nothing if the action is to far (including checking sub actions) [DISABLED FOR NOW ref #2196] +// Return nothing if the action is too far (including checking sub actions) [DISABLED FOR NOW ref #2196] // if (_distanceToBasePoint > _distance) exitWith { // [] // }; @@ -64,21 +73,19 @@ if (_insertChildrenCode isNotEqualTo {}) then { // Collect dynamic children class actions { private _action = [_x select 2, _x, _fullPath, _distanceToBasePoint] call FUNC(collectActiveActionTree); - if ((count _action) > 0) then { + if (_action isNotEqualTo []) then { _activeChildren pushBack _action; }; - nil - } count _dynamicChildren; + } forEach _dynamicChildren; }; // Collect children class actions { private _action = [_object, _x, _fullPath, _distanceToBasePoint] call FUNC(collectActiveActionTree); - if ((count _action) > 0) then { + if (_action isNotEqualTo []) then { _activeChildren pushBack _action; }; - nil -} count _origActionChildren; +} forEach _origActionChildren; // Collect children object actions { @@ -87,12 +94,11 @@ if (_insertChildrenCode isNotEqualTo {}) then { // Check if the action is children of the original action if (_pPath isEqualTo _fullPath) then { private _action = [_object, [_actionData,[]], _fullPath, _distanceToBasePoint] call FUNC(collectActiveActionTree); - if ((count _action) > 0) then { + if (_action isNotEqualTo []) then { _activeChildren pushBack _action; }; }; - nil -} count GVAR(objectActionList); +} forEach GVAR(objectActionList); // If the original action has no statement, and no children, don't display it @@ -103,14 +109,14 @@ if ((_activeChildren isEqualTo []) && {_statementCode isEqualTo {}}) exitWith { if (GVAR(consolidateSingleChild) && {count _activeChildren == 1} && {_statementCode isEqualTo {}}) then { _activeChildren select 0 params ["_childActionData", "_childChildren", "_childObject"]; - _childActionData params ["", "_displayNameChild", "_iconChild", "_statementChild", "", "", "_customParamsChild", "", "", "_paramsChild"]; + _childActionData params ["", "_displayNameChild", "_iconChild", "_statementChild", "_conditionChild", "_insertChildrenChild", "_customParamsChild", "", "", "_paramsChild"]; _origActionData = [ _actionName, format ["%1 > %2", _displayName, _displayNameChild], _iconChild, _statementChild, - _conditionCode, - _insertChildrenCode, + _conditionChild, + _insertChildrenChild, _customParamsChild, _position, _distance, diff --git a/addons/interact_menu/functions/fnc_compileMenu.sqf b/addons/interact_menu/functions/fnc_compileMenu.sqf index 5290d8f284e..8c5d3c5fa1a 100644 --- a/addons/interact_menu/functions/fnc_compileMenu.sqf +++ b/addons/interact_menu/functions/fnc_compileMenu.sqf @@ -17,22 +17,22 @@ params ["_target"]; -private _objectType = _target; -if (_target isEqualType objNull) then { - _objectType = typeOf _target; +private _objectType = if (_target isEqualType objNull) then { + typeOf _target +} else { + _target call EFUNC(common,getConfigName) }; -private _namespace = GVAR(ActNamespace); // Exit if the action menu is already compiled for this class -if (!isNil {_namespace getVariable _objectType}) exitWith {}; +if (_objectType in GVAR(ActNamespace)) exitWith {}; if (_objectType isKindOf "VirtualMan_F") exitWith { // these have config: isPlayableLogic = 1 TRACE_1("skipping playable logic",_objectType); - _namespace setVariable [_objectType, []]; + GVAR(ActNamespace) set [_objectType, []]; }; if ((_objectType isKindOf "CAManBase") && {!isNil QGVAR(cacheManActions)}) exitWith { - _namespace setVariable [_objectType, +GVAR(cacheManActions)]; // copy + GVAR(ActNamespace) set [_objectType, +GVAR(cacheManActions)]; // copy }; private _recurseFnc = { @@ -114,8 +114,7 @@ private _recurseFnc = { ]; _actions pushBack _entry; }; - nil - } count (configProperties [_actionsCfg, "isClass _x", true]); + } forEach (configProperties [_actionsCfg, "isClass _x", true]); _actions }; @@ -140,7 +139,7 @@ if (_objectType isKindOf "CAManBase") then { }; }; -_namespace setVariable [_objectType, _actions]; +GVAR(ActNamespace) set [_objectType, _actions]; /* [ diff --git a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf index 75fdb93819e..a7fe168a5d9 100644 --- a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf +++ b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf @@ -17,15 +17,14 @@ params ["_target"]; -private _objectType = _target; -if (_target isEqualType objNull) then { - _objectType = typeOf _target; +private _objectType = if (_target isEqualType objNull) then { + typeOf _target +} else { + _target call EFUNC(common,getConfigName) }; -private _namespace = GVAR(ActSelfNamespace); // Exit if the action menu is already compiled for this class -if (!isNil {_namespace getVariable _objectType}) exitWith {}; - +if (_objectType in GVAR(actSelfNamespace)) exitWith {}; private _recurseFnc = { params ["_actionsCfg"]; @@ -84,8 +83,7 @@ private _recurseFnc = { ]; _actions pushBack _entry; }; - nil - } count (configProperties [_actionsCfg, "isClass _x", true]); + } forEach (configProperties [_actionsCfg, "isClass _x", true]); _actions }; @@ -111,6 +109,7 @@ if (_objectType isKindOf "CAManBase") then { TRACE_1("Building ACE_SelfActions",_objectType); // Create a master action to base on self action +//IGNORE_PRIVATE_WARNING ["_target"]; private _actions = [ [ [ @@ -121,7 +120,7 @@ private _actions = [ // Dummy statement so it's not collapsed when there's no available actions true }, - {[ACE_player, _target, ["isNotInside","isNotDragging", "isNotCarrying", "isNotSwimming", "notOnMap", "isNotEscorting", "isNotSurrendering", "isNotSitting", "isNotOnLadder", "isNotRefueling"]] call EFUNC(common,canInteractWith)}, + {[ACE_player, _target, ["isNotInside","isNotDragging", "isNotCarrying", "isNotSwimming", "notOnMap", "isNotEscorting", "isNotSurrendering", "isNotHandcuffed", "isNotSitting", "isNotOnLadder", "isNotRefueling"]] call EFUNC(common,canInteractWith)}, {}, {}, "Spine3", @@ -132,4 +131,4 @@ private _actions = [ ] ]; -_namespace setVariable [_objectType, _actions]; +GVAR(ActSelfNamespace) set [_objectType, _actions]; diff --git a/addons/interact_menu/functions/fnc_createAction.sqf b/addons/interact_menu/functions/fnc_createAction.sqf index ae00f4fb820..f099ae9fb03 100644 --- a/addons/interact_menu/functions/fnc_createAction.sqf +++ b/addons/interact_menu/functions/fnc_createAction.sqf @@ -26,7 +26,8 @@ * Public: Yes */ -// IGNORE_PRIVATE_WARNING(_actionName,_displayName,_icon,_statement,_condition,_insertChildren,_customParams,_position,_distance,_params,_modifierFunction); +//IGNORE_PRIVATE_WARNING ["_actionName", "_displayName", "_icon", "_statement", "_condition", "_insertChildren"]; +//IGNORE_PRIVATE_WARNING ["_customParams", "_position", "_distance", "_params", "_modifierFunction"]; if (!hasInterface) exitWith { [] }; params [ diff --git a/addons/interact_menu/functions/fnc_initMenuReorder.sqf b/addons/interact_menu/functions/fnc_initMenuReorder.sqf index 48445b3fa02..d55f2f06ea6 100644 --- a/addons/interact_menu/functions/fnc_initMenuReorder.sqf +++ b/addons/interact_menu/functions/fnc_initMenuReorder.sqf @@ -17,7 +17,7 @@ params ["_class"]; -private _actionTrees = GVAR(ActSelfNamespace) getVariable _class; +private _actionTrees = GVAR(ActSelfNamespace) get _class; private _rootNode = [_actionTrees, ["ACE_SelfActions"]] call FUNC(findActionNode); private _rootActions = _rootNode select 1; private _settingCategoryPrefix = format ["ACE %1 - ", LELSTRING(Interaction,InteractionMenuSelf)]; diff --git a/addons/interact_menu/functions/fnc_keyDown.sqf b/addons/interact_menu/functions/fnc_keyDown.sqf index 5bce40d0a8e..d87f6cfa3ba 100644 --- a/addons/interact_menu/functions/fnc_keyDown.sqf +++ b/addons/interact_menu/functions/fnc_keyDown.sqf @@ -36,7 +36,7 @@ if (_isTextEditing) then { if ( _isTextEditing || {(isNull curatorCamera) && { - !([ACE_player, objNull, ["isNotInside","isNotDragging", "isNotCarrying", "isNotSwimming", "notOnMap", "isNotEscorting", "isNotSurrendering", "isNotSitting", "isNotOnLadder", "isNotRefueling"]] call EFUNC(common,canInteractWith)) + !([ACE_player, objNull, ["isNotInside","isNotDragging", "isNotCarrying", "isNotSwimming", "notOnMap", "isNotEscorting", "isNotSurrendering", "isNotHandcuffed", "isNotSitting", "isNotOnLadder", "isNotRefueling"]] call EFUNC(common,canInteractWith)) } }) exitWith {false}; @@ -84,8 +84,8 @@ if (GVAR(useCursorMenu)) then { } else { createDialog QGVAR(cursorMenu); }; - (finddisplay 91919) displayAddEventHandler ["KeyUp", {[_this,'keyup'] call CBA_events_fnc_keyHandler}]; - (finddisplay 91919) displayAddEventHandler ["KeyDown", { + (findDisplay 91919) displayAddEventHandler ["KeyUp", {[_this,'keyup'] call CBA_events_fnc_keyHandler}]; + (findDisplay 91919) displayAddEventHandler ["KeyDown", { // Handle the escape key being pressed with menu open: if ((_this select [1,4]) isEqualTo [1,false,false,false]) exitWith { // escape key with no modifiers [displayNull] call FUNC(handleEscapeMenu); @@ -102,8 +102,8 @@ if (GVAR(useCursorMenu)) then { _ctrl ctrlCommit 0; // handles Mouse moving and LMB in cursor mode when action on keyrelease is disabled - ((finddisplay 91919) displayctrl 9922) ctrlAddEventHandler ["MouseMoving", DFUNC(handleMouseMovement)]; - ((finddisplay 91919) displayctrl 9922) ctrlAddEventHandler ["MouseButtonDown", DFUNC(handleMouseButtonDown)]; + ((findDisplay 91919) displayCtrl 9922) ctrlAddEventHandler ["MouseMoving", DFUNC(handleMouseMovement)]; + ((findDisplay 91919) displayCtrl 9922) ctrlAddEventHandler ["MouseButtonDown", DFUNC(handleMouseButtonDown)]; setMousePosition [0.5, 0.5]; } else { if (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]) then { @@ -111,18 +111,12 @@ if (GVAR(useCursorMenu)) then { }; }; -GVAR(selfMenuOffset) = (AGLtoASL (positionCameraToWorld [0, 0, 2])) vectorDiff (AGLtoASL (positionCameraToWorld [0, 0, 0])); +GVAR(selfMenuOffset) = (AGLToASL (positionCameraToWorld [0, 0, 2])) vectorDiff (AGLToASL (positionCameraToWorld [0, 0, 0])); //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 { - GVAR(menuDepthPath) = [["ACE_SelfActions", (ACE_controlledUAV select 0)]]; - GVAR(expanded) = true; - GVAR(expandedTime) = diag_tickTime; - GVAR(lastPath) = +GVAR(menuDepthPath); - GVAR(startHoverTime) = -1000; - } else { + if (isNull (ACE_controlledUAV select 0)) then { if (vehicle ACE_player != ACE_player) then { GVAR(menuDepthPath) = [["ACE_SelfActions", (vehicle ACE_player)]]; GVAR(expanded) = true; @@ -130,6 +124,12 @@ if (GVAR(openedMenuType) == 0) then { GVAR(lastPath) = +GVAR(menuDepthPath); GVAR(startHoverTime) = -1000; }; + } else { + GVAR(menuDepthPath) = [["ACE_SelfActions", (ACE_controlledUAV select 0)]]; + GVAR(expanded) = true; + GVAR(expandedTime) = diag_tickTime; + GVAR(lastPath) = +GVAR(menuDepthPath); + GVAR(startHoverTime) = -1000; }; } else { GVAR(menuDepthPath) = [["ACE_ZeusActions", (getAssignedCuratorLogic player)]]; diff --git a/addons/interact_menu/functions/fnc_removeActionFromClass.sqf b/addons/interact_menu/functions/fnc_removeActionFromClass.sqf index 6772b61c547..87cc8609ccc 100644 --- a/addons/interact_menu/functions/fnc_removeActionFromClass.sqf +++ b/addons/interact_menu/functions/fnc_removeActionFromClass.sqf @@ -1,35 +1,68 @@ #include "..\script_component.hpp" /* * Author: esteldunedain - * Removes an action from a class + * Removes an action from a class. * * Arguments: * 0: TypeOf of the class * 1: Type of action, 0 for actions, 1 for self-actions * 2: Full path of the new action + * 3: Remove action from child classes (default: false) * * Return Value: * None * * Example: - * [typeOf cursorTarget, 0,["ACE_TapShoulderRight","VulcanPinch"]] call ace_interact_menu_fnc_removeActionFromClass; + * [typeOf cursorTarget, 0, ["ACE_TapShoulderRight", "VulcanPinch"]] call ace_interact_menu_fnc_removeActionFromClass; * * Public: No */ -params ["_objectType", "_typeNum", "_fullPath"]; +params ["_objectType", "_typeNum", "_fullPath", ["_useInheritance", false, [false]]]; + +_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 = []; +if (_useInheritance) exitWith { + // Only need to run for classes that have already been initialized + { + [_x, _typeNum, _fullPath] call FUNC(removeActionFromClass); + } forEach (GVAR(inheritedClassesAll) select {_x isKindOf _objectType}); + + // Find same path and actionName, and check if it's a parent class, needs to be checked for all classes + private _index = GVAR(inheritedActionsAll) findIf { + _x params ["_currentType", "", "_currentParentPath", "_currentAction"]; + + [_objectType isKindOf _currentType, _currentParentPath, _currentAction select 0] isEqualTo [true, _parentPath, _actionName] + }; + + // Add to exclude classes + if (_index != -1) then { + (GVAR(inheritedActionsAll) select _index select 4) pushBackUnique _objectType; + }; + + // Children of CAManBase need special treatment because of inheritedActionsMan array + if (_objectType isKindOf "CAManBase") then { + private _index = GVAR(inheritedActionsMan) findIf { + _x params ["", "_currentParentPath", "_currentAction"]; + + [_currentParentPath, _currentAction select 0] isEqualTo [_parentPath, _actionName] + }; + + // Different index because array doesn't include _objectType + if (_index != -1) then { + (GVAR(inheritedActionsMan) select _index select 3) pushBackUnique _objectType; + }; + }; }; +private _namespace = [GVAR(ActNamespace), GVAR(ActSelfNamespace)] select _typeNum; +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; diff --git a/addons/interact_menu/functions/fnc_render.sqf b/addons/interact_menu/functions/fnc_render.sqf index e4ee0d63575..2089f6b1060 100644 --- a/addons/interact_menu/functions/fnc_render.sqf +++ b/addons/interact_menu/functions/fnc_render.sqf @@ -38,7 +38,7 @@ if (GVAR(openedMenuType) >= 0) then { private _closestSelection = -1; { _x params ["", "_sPos"]; - private _distanceFromCursor = _cursorScreenPos distance2d _sPos; + private _distanceFromCursor = _cursorScreenPos distance2D _sPos; if ((_distanceFromCursor < 0.1118) && {_distanceFromCursor < _closestDistance}) then { _closestDistance = _distanceFromCursor; _closestSelection = _forEachIndex; diff --git a/addons/interact_menu/functions/fnc_renderActionPoints.sqf b/addons/interact_menu/functions/fnc_renderActionPoints.sqf index 058b5ed8462..1887a6d790e 100644 --- a/addons/interact_menu/functions/fnc_renderActionPoints.sqf +++ b/addons/interact_menu/functions/fnc_renderActionPoints.sqf @@ -19,8 +19,8 @@ GVAR(currentOptions) = []; private _player = ACE_player; -GVAR(cameraPosASL) = AGLtoASL (positionCameraToWorld [0, 0, 0]); -GVAR(cameraDir) = (AGLtoASL (positionCameraToWorld [0, 0, 1])) vectorDiff GVAR(cameraPosASL); +GVAR(cameraPosASL) = AGLToASL (positionCameraToWorld [0, 0, 0]); +GVAR(cameraDir) = (AGLToASL (positionCameraToWorld [0, 0, 1])) vectorDiff GVAR(cameraPosASL); private _fnc_renderNearbyActions = { // Render all nearby interaction menus @@ -61,7 +61,7 @@ private _fnc_renderNearbyActions = { } forEach GVAR(objectActionList); // Iterate through base level class actions and render them if appropiate - private _classActions = GVAR(ActNamespace) getVariable [typeOf _target, []]; + private _classActions = GVAR(ActNamespace) getOrDefault [typeOf _target, []]; { private _action = _x; // Try to render the menu @@ -95,18 +95,17 @@ 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) - ASLtoAGL ((AGLtoASL (positionCameraToWorld [0, 0, 0])) vectorAdd GVAR(selfMenuOffset)); - } else { + private _pos = if (GVAR(useCursorMenu)) then { [0.5, 0.5] + } else { + //Convert to ASL, add offset and then convert back to AGL (handles waves when over water) + ASLToAGL ((AGLToASL (positionCameraToWorld [0, 0, 0])) vectorAdd GVAR(selfMenuOffset)); }; { - _action = _x; + private _action = _x; [_target, _action, _pos] call FUNC(renderBaseMenu); } forEach _classActions; }; @@ -124,10 +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 { - // Render UAV self actions when in control of UAV AI - (ACE_controlledUAV select 0) call _fnc_renderSelfActions; - } else { + if (isNull (ACE_controlledUAV select 0)) then { if (vehicle ACE_player == ACE_player) then { if (diag_tickTime > GVAR(lastTimeSearchedActions) + 0.20) then { // Once every 0.2 secs, collect nearby objects active and visible action points and render them @@ -140,6 +136,10 @@ if (GVAR(openedMenuType) == 0) then { // Render vehicle self actions when in vehicle (vehicle ACE_player) call _fnc_renderSelfActions; }; + } else { + // Render UAV self actions when in control of UAV AI + (ACE_controlledUAV select 0) call _fnc_renderSelfActions; + }; } else { // Render zeus actions when zeus open @@ -161,7 +161,7 @@ if (count GVAR(collectedActionPoints) > 1) then { private _delta = vectorNormalized ((GVAR(collectedActionPoints) select _i select 1) vectorDiff (GVAR(collectedActionPoints) select _j select 1)); // If _i is inside a cone with 20º half angle with origin on _j - if ((_delta select 2 > 0.94) && {((GVAR(collectedActionPoints) select _i select 1) distance2d (GVAR(collectedActionPoints) select _j select 1)) < 0.1}) exitWith { + if ((_delta select 2 > 0.94) && {((GVAR(collectedActionPoints) select _i select 1) distance2D (GVAR(collectedActionPoints) select _j select 1)) < 0.1}) exitWith { GVAR(collectedActionPoints) deleteAt _i; }; }; diff --git a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf index 9e3aaa53a92..5af5afcc7ca 100644 --- a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf @@ -46,7 +46,7 @@ if ((GVAR(openedMenuType) == 0) && {isNull (ACE_controlledUAV select 0)} && {veh if ((_distanceToBasePoint > 1.2) && {!(_params select 4)}) exitWith { // If distance to action is greater than 1.2 m and check isn't disabled in params, check LOS - lineIntersects [AGLtoASL _headPos, AGLtoASL _pos, _object, ACE_player] + lineIntersects [AGLToASL _headPos, AGLToASL _pos, _object, ACE_player] }; false }) exitWith {false}; @@ -91,7 +91,7 @@ if (_activeActionTree isEqualTo []) exitWith {false}; BEGIN_COUNTER(fnc_renderMenus); if (count _pos > 2) then { - _sPos pushBack (((AGLtoASL _pos) vectorDiff GVAR(cameraPosASL)) vectorDotProduct GVAR(cameraDir)); + _sPos pushBack (((AGLToASL _pos) vectorDiff GVAR(cameraPosASL)) vectorDotProduct GVAR(cameraDir)); } else { _sPos pushBack 0; }; diff --git a/addons/interact_menu/functions/fnc_renderIcon.sqf b/addons/interact_menu/functions/fnc_renderIcon.sqf index fffa5e91a7f..a1118b77b0c 100644 --- a/addons/interact_menu/functions/fnc_renderIcon.sqf +++ b/addons/interact_menu/functions/fnc_renderIcon.sqf @@ -27,8 +27,8 @@ if(GVAR(iconCount) > (count GVAR(iconCtrls))-1) then { private _displayNum = [[46, 12] select visibleMap, 91919] select (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]); GVAR(iconCtrls) pushBack ((findDisplay _displayNum) ctrlCreate ["RscStructuredText", 54021 + GVAR(iconCount)]); if (GVAR(useCursorMenu)) then { - ((finddisplay _displayNum) displayctrl (54021 + GVAR(iconCount))) ctrlAddEventHandler ["MouseMoving", DFUNC(handleMouseMovement)]; - ((finddisplay _displayNum) displayctrl (54021 + GVAR(iconCount))) ctrlAddEventHandler ["MouseButtonDown", DFUNC(handleMouseButtonDown)]; + ((findDisplay _displayNum) displayCtrl (54021 + GVAR(iconCount))) ctrlAddEventHandler ["MouseMoving", DFUNC(handleMouseMovement)]; + ((findDisplay _displayNum) displayCtrl (54021 + GVAR(iconCount))) ctrlAddEventHandler ["MouseButtonDown", DFUNC(handleMouseButtonDown)]; }; }; private _ctrl = GVAR(iconCtrls) select GVAR(iconCount); @@ -41,16 +41,16 @@ if (_iconFile isEqualTo "") 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]; + format ["
%4", _iconFile, _iconColor, _textSettings, ("ace" callExtension ["break_line", [_text]]) select 0]; }; [_ctrl, GVAR(iconCount), _text] call FUNC(ctrlSetParsedTextCached); GVAR(iconCount) = GVAR(iconCount) + 1; 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] + [(_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] + [(_sPos select 0) - (0.0750 * safeZoneW), (_sPos select 1) - (0.0095 * safeZoneW), 0.15 * safeZoneW, 0.100 * safeZoneW] }; diff --git a/addons/interact_menu/functions/fnc_renderSelector.sqf b/addons/interact_menu/functions/fnc_renderSelector.sqf index bf719299244..27170d9fa83 100644 --- a/addons/interact_menu/functions/fnc_renderSelector.sqf +++ b/addons/interact_menu/functions/fnc_renderSelector.sqf @@ -22,8 +22,8 @@ if(GVAR(iconCount) > (count GVAR(iconCtrls))-1) then { private _displayNum = [[46, 12] select visibleMap,91919] select (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]); GVAR(iconCtrls) pushBack ((findDisplay _displayNum) ctrlCreate ["RscStructuredText", 54021+GVAR(iconCount)]); if (GVAR(useCursorMenu)) then { - ((finddisplay _displayNum) displayctrl (54021+GVAR(iconCount))) ctrlAddEventHandler ["MouseMoving", DFUNC(handleMouseMovement)]; - ((finddisplay _displayNum) displayctrl (54021+GVAR(iconCount))) ctrlAddEventHandler ["MouseButtonDown", DFUNC(handleMouseButtonDown)]; + ((findDisplay _displayNum) displayCtrl (54021+GVAR(iconCount))) ctrlAddEventHandler ["MouseMoving", DFUNC(handleMouseMovement)]; + ((findDisplay _displayNum) displayCtrl (54021+GVAR(iconCount))) ctrlAddEventHandler ["MouseButtonDown", DFUNC(handleMouseButtonDown)]; }; }; @@ -31,10 +31,10 @@ private _ctrl = GVAR(iconCtrls) select GVAR(iconCount); private _pos = if (GVAR(UseListMenu)) then { [_ctrl, GVAR(iconCount), format ["", _icon, GVAR(selectorColorHex)]] call FUNC(ctrlSetParsedTextCached); - [(_sPos select 0)-(0.014*SafeZoneW), (_sPos select 1)-(0.014*SafeZoneW), 0.05*SafeZoneW, 0.035*SafeZoneW] + [(_sPos select 0)-(0.014*safeZoneW), (_sPos select 1)-(0.014*safeZoneW), 0.05*safeZoneW, 0.035*safeZoneW] } else { [_ctrl, GVAR(iconCount), format ["", _icon, GVAR(selectorColorHex)]] call FUNC(ctrlSetParsedTextCached); - [(_sPos select 0)-(0.050*SafeZoneW), (_sPos select 1)-(0.014*SafeZoneW), 0.1*SafeZoneW, 0.035*SafeZoneW] + [(_sPos select 0)-(0.050*safeZoneW), (_sPos select 1)-(0.014*safeZoneW), 0.1*safeZoneW, 0.035*safeZoneW] }; GVAR(iconCount) = GVAR(iconCount) + 1; diff --git a/addons/interact_menu/functions/fnc_splitPath.sqf b/addons/interact_menu/functions/fnc_splitPath.sqf index 8c0856d118b..8fabaca5a56 100644 --- a/addons/interact_menu/functions/fnc_splitPath.sqf +++ b/addons/interact_menu/functions/fnc_splitPath.sqf @@ -17,11 +17,13 @@ */ private _parentPath = []; -for [{private _i = 0},{_i < (count _this) - 1},{_i = _i + 1}] do { - _parentPath pushBack (_this select _i); -}; -private _actionName = if (count _this > 0) then { - _this select ((count _this) - 1); + +_parentPath append _this; + +private _count = count _this; + +private _actionName = if (_count > 0) then { + _parentPath deleteAt (_count - 1) // TODO: replace with _parentPath deleteAt [-1] and drop _count in 2.18 } else { "" }; diff --git a/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf b/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf index c11da0c2710..8f289508401 100644 --- a/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf +++ b/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf @@ -17,8 +17,9 @@ params ["_typeOfBuilding"]; -private _searchIndex = GVAR(cachedBuildingTypes) find _typeOfBuilding; -if (_searchIndex != -1) exitWith {GVAR(cachedBuildingActionPairs) select _searchIndex}; +private _cachedMemPoints = GVAR(cachedBuildingTypes) get _typeOfBuilding; + +if (!isNil "_cachedMemPoints") exitWith {_cachedMemPoints}; private _memPoints = []; private _memPointsActions = []; @@ -148,8 +149,6 @@ private _ladders = getArray (configFile >> "CfgVehicles" >> _typeOfBuilding >> " } forEach _ladders; -GVAR(cachedBuildingTypes) pushBack _typeOfBuilding; -GVAR(cachedBuildingActionPairs) pushBack [_memPoints, _memPointsActions]; - +GVAR(cachedBuildingTypes) set [_typeOfBuilding, [_memPoints, _memPointsActions]]; [_memPoints, _memPointsActions] diff --git a/addons/interact_menu/initSettings.inc.sqf b/addons/interact_menu/initSettings.inc.sqf index 22287189c33..c175bd17c2c 100644 --- a/addons/interact_menu/initSettings.inc.sqf +++ b/addons/interact_menu/initSettings.inc.sqf @@ -46,9 +46,7 @@ private _categoryColors = [_category, format ["| %1 |", LELSTRING(common,subcate QGVAR(textSize), "LIST", LSTRING(textSize), _category, - [[0, 1, 2, 3, 4], ["str_very_small", "str_small", "str_medium", "str_large", "str_very_large"], 2], - 0, - {[QGVAR(textSize), _this] call EFUNC(common,cbaSettings_settingChanged)} + [[0, 1, 2, 3, 4], ["str_very_small", "str_small", "str_medium", "str_large", "str_very_large"], 2] ] call CBA_fnc_addSetting; [ diff --git a/addons/interact_menu/stringtable.xml b/addons/interact_menu/stringtable.xml index ce4da0c506d..cb05331633a 100644 --- a/addons/interact_menu/stringtable.xml +++ b/addons/interact_menu/stringtable.xml @@ -12,7 +12,7 @@ Mindig legyen a saját cselekvés kurzorja látható Mostra sempre il cursore per le autointerazioni Sempre mostrar cursor para interação pessoal - セルフ インタラクションへ常にカーソルを表示 + カーソルを常に表示 자기상호작용 시 항상 커서를 보이기 自我互动时永远显示光标 自我互動時永遠顯示游標 @@ -29,7 +29,7 @@ Immer den Mauszeiger für Fremd-Interaktionen anzeigen Mindig legyen a cselekvés kurzorja látható Sempre mostrar cursor para interação - インタラクションへ常にカーソルを表示 + カーソルを常に表示 상호작용 시 항상 커서를 보이기 互动时永远显示光标 互動時永遠顯示游標 @@ -46,7 +46,7 @@ Interaktionsmenü in Listen anzeigen Cselekvő menük listaként való megjelenítése Mostrar menu de interação como listas - インタラクションメニューを一覧表示 + メニューをリストで表示 상호작용메뉴를 리스트화 해서 보이기 以列表方式显示互动表单 以列表方式顯示互動表單 @@ -80,7 +80,7 @@ Saját cselekvő gomb Tasto autointerazioni Tecla de Interação Pessoal - セルフ インタラクション キー + セルフ・インタラクション キー 자기상호작용 키 自我互动键 自我互動鍵 @@ -131,7 +131,7 @@ Ações do Zeus Действия Зевса Interazioni Zeus - Zeusでのアクション + Zeusのアクション 제우스 동작 宙斯操作 宙斯操作 @@ -148,7 +148,7 @@ Interacción - Texto al max. Cselekvés - Szöveg max. Interação - Max. de Texto - インタラクション - 文字の色 + インタラクション - 文字の表示色の最大値 상호작용 - 문자색깔 互动—文字颜色最大值 互動 - 文字最大化 @@ -165,7 +165,7 @@ Interacción - Texto al min. Cselekvés - Szöveg min. Interação - Min. de Texto - インタラクション - 文字の背景色 + インタラクション - 文字の表示色の最低値 상호작용 - 문자배경색 互动—文字颜色最小值 互動 - 文字最小化 @@ -182,7 +182,7 @@ Interacción - Sombras al max. Cselekvés - Árnyék max. Interação - Max. de Sombra - インタラクション - 文字への影の色 + インタラクション - 文字の影色の最大値 상호작용 - 문자그림자색 互动—阴影最大值 互動 - 陰影最大化 @@ -199,7 +199,7 @@ Interacción - Sombras al min. Cselekvés - Árnyék min. Interação - Min. de Sombra - インタラクション - 文字への影の最低色 + インタラクション - 文字の影色の最低値 상호작용 - 문자그림자배경색 互动—阴影最小值 互動 - 陰影最小化 @@ -216,7 +216,7 @@ Udržuj kurzor na středu Manter o cursor centralizado Mantieni il cursore centrato - 常にカーソルを中央にする + カーソルを常に中心にする 커서를 항상 가운데에 둡니다 保持光标在中心点 保持游標在中心點 @@ -233,7 +233,7 @@ Mantiene el cursor centrado y despliega los menús alrededor. Útil si el tamaño de la pantalla es limitado. Manter o cursor centralizado e mover o menu de opções. Útil caso o tamanho da tela seja limitado. Mantieni il cursore centrato e sposta il menù intorno. Utile se lo schermo è piccolo. - 常にカーソルを中央へ表示させ、オプション メニューが移動します。画面の大きさが制限されている時に使いやすくなります。 + カーソルを常に中心に表示し、オプション メニューを移動させます。画面の大きさが制限されている時に便利です。 커서를 항상 가운데에 두고 메뉴를 움직입니다. 화면의 크기가 제한되있을 때 유용합니다. 保持光标在中心点并平移周遭的选项菜单。这对在屏幕尺寸有限的玩家很有用! 保持游標在中心點並平移周遭的選項選單。這對在螢幕尺寸有限的玩家很有用! @@ -250,7 +250,7 @@ Execute a ação quando soltar a tecla de menu Cselekvés végrehajtása a menügomb elengedésekor Esegui l'azione quando rilasci il tasto menu - メニュー キーを離した時にアクションを実行 + キーを離した時にアクションを実行 메뉴 키를 놓을 때 행동하기 当放开菜单键后就执行动作 當放開選單鍵後就執行動作 @@ -267,7 +267,7 @@ Tamanho do texto de interação Cselekvő szöveg mérete Dimensione del testo d'interazione - インタラクション文字の大きさ + 文字の大きさ 상호작용 - 문자크기 互动菜单文字大小 互動選單文字大小 @@ -284,7 +284,7 @@ Sombra do texto de interação Cselekvő szöveg árnyéka Ombra del testo d'interazione - インタラクション文字へ影 + 文字の影表示 상호작용 - 문자그림자 互动菜单文字阴影 互動選單文字陰影 @@ -301,7 +301,7 @@ Permite controlar a sombra do texto. Contorno ignora sombras com cores customizadas. Hozzáférést biztosít a szöveg árnyékának kezeléséhez. A körvonal nem veszi figyelembe az egyedi árnyékszíneket. Permette di controllare l'ombra del testo. L'impostazione "Contorno" ignora il colore dell'ombra. - 文字への影を設定します。縁取りは設定された影の色を無視します。 + 文字に影を表示します。縁取りは設定された影の色を無視します。 문자의 그림자를 조절하는 것을 가능케 합니다. 외곽선은 임의의 그림자색을 무시합니다. 允许控制文字阴影。轮廓部分则会忽略自定义的阴影颜色。 允許控制文字陰影。輪廓部分則會忽略自定義的陰影顏色 @@ -335,7 +335,7 @@ Cselekvő menü háttere Фон меню взаимодействия Sfondo Menù Interazioni - インタラクションメニューの背景 + メニューの背景 상호작용 메뉴 배경 互动菜单背景 互動選單背景 @@ -352,7 +352,7 @@ A háttér elmosása a cselekvő menü használata alatt. Размыть фон, пока открыто меню взаимодействия. Sfoca lo sfondo mentre il Menù Interazioni è aperto. - インタラクションメニューを開いたとき、背景をぼかします。 + インタラクション メニューを開いたときに背景をぼかします。 상호작용 메뉴가 열릴 시 배경을 흐릿하게 처리합니다. 当互动菜单开启时,模糊背景画面。 當互動選單開啟時,模糊背景畫面 @@ -386,7 +386,7 @@ Fekete Черный Nero - 背景を黒くする + 背景を暗くする 까맣게 黑色 黑色 @@ -436,7 +436,7 @@ Menú de interacción Menù Interazioni Menu d'interaction - インタラクションメニュー + インタラクション メニュー 상호작용 메뉴 互动菜单 互動選單 @@ -452,7 +452,7 @@ Velocità di Animazione delle Interazioni Velocidad de animación del menú de interacción Vitesse de l'animation d'interaction - インタラクションのアニメーション速度 + アニメーション速度 상호작용 움직임 속도 互动菜单动画速度 互動選單動畫速度 @@ -468,7 +468,7 @@ Rende le animazioni del Menù più veloci e diminuisce il tempo richiesto per mostrare sotto-azioni Hace la animación del menú más rápida, reduciendo el tiempo necesario para abrir sub-acciones. Rend les animations du menu plus rapide, et réduit le temps nécessaire à l'affichage des sous menus d'action. - メニューのアニメーションを高速化し、サブアクションを表示するためのホバーに必要な時間を短縮します。 + メニューのアニメーションを高速化し、サブアクションを表示するために必要なホバーにかかる時間を短縮します。 使菜单的动画速度更快,并减少子选项显现出来的时间 使選單的動畫速度更快,並減少子選項顯現出來的時間 상호작용을 표시하기 위해 메뉴 애니메이션을 빠르게 만들고 마우스를 가져오는 데 필요한 시간을 줄입니다. @@ -493,7 +493,7 @@ Consolidate single child actions Объединять ед. дочерные действия - 子アクションを統合 + 1個のみの子アクションを統合 Consolidar acciones hijo únicas Combiner les sous-actions uniques Untergeordnete Aktionen zusammenfassen @@ -506,7 +506,7 @@ Combines parent action with only one child action together. Объединять родительское действие с единственным дочерним действием в одно. - 親アクションと子アクションの一つを統合して表示します。 + アクションが1個のみの子アクションを親アクションと結合し表示を整理します。 Combina acciones padre con una única accion hijo de forma conjunta Lorsqu'un menu ne contient qu'une seule sous-action, elle est combinée avec son menu parent. Combina interazioni con una sola sotto-azione in una singola interazione. diff --git a/addons/interaction/CfgVehicles.hpp b/addons/interaction/CfgVehicles.hpp index 6ae0d4a9821..614cd3e0e06 100644 --- a/addons/interaction/CfgVehicles.hpp +++ b/addons/interaction/CfgVehicles.hpp @@ -78,7 +78,7 @@ class CfgVehicles { class ACE_AssignTeamRed { displayName = CSTRING(AssignTeamRed); - condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam)); + condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam) && {assignedTeam _target != 'RED'}); statement = QUOTE([ARR_3(_target,'RED',true)] call DFUNC(joinTeam)); exceptions[] = {"isNotSwimming"}; showDisabled = 1; @@ -86,7 +86,7 @@ class CfgVehicles { }; class ACE_AssignTeamGreen { displayName = CSTRING(AssignTeamGreen); - condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam)); + condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam) && {assignedTeam _target != 'GREEN'}); statement = QUOTE([ARR_3(_target,'GREEN',true)] call DFUNC(joinTeam)); exceptions[] = {"isNotSwimming"}; showDisabled = 1; @@ -94,7 +94,7 @@ class CfgVehicles { }; class ACE_AssignTeamBlue { displayName = CSTRING(AssignTeamBlue); - condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam)); + condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam) && {assignedTeam _target != 'BLUE'}); statement = QUOTE([ARR_3(_target,'BLUE',true)] call DFUNC(joinTeam)); exceptions[] = {"isNotSwimming"}; showDisabled = 1; @@ -102,14 +102,14 @@ class CfgVehicles { }; class ACE_AssignTeamYellow { displayName = CSTRING(AssignTeamYellow); - condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam)); + condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam) && {assignedTeam _target != 'YELLOW'}); statement = QUOTE([ARR_3(_target,'YELLOW',true)] call DFUNC(joinTeam)); exceptions[] = {"isNotSwimming"}; showDisabled = 1; modifierFunction = QUOTE([ARR_3('YELLOW','PATHTOF(UI\team\team_white_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); }; - class ACE_UnassignTeam { - displayName = CSTRING(LeaveTeam); + class ACE_AssignTeamMain { + displayName = "$STR_assign_main"; condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam) && {assignedTeam _target != 'MAIN'}); statement = QUOTE([ARR_3(_target,'MAIN',true)] call DFUNC(joinTeam)); exceptions[] = {"isNotSwimming"}; @@ -164,7 +164,7 @@ class CfgVehicles { }; class GVAR(Gear) { displayName = "$STR_ACTION_GEAR"; - condition = QUOTE(!(lifeState _target in [ARR_2('HEALTHY','INJURED')]) && {isNull objectParent _target}); + condition = QUOTE(!(_target call EFUNC(common,isAwake)) && {isNull objectParent _target}); statement = QUOTE(_player action [ARR_2(QUOTE(QUOTE(Gear)),_target)]); icon = "\A3\ui_f\data\igui\cfg\actions\gear_ca.paa"; }; @@ -253,9 +253,16 @@ class CfgVehicles { modifierFunction = QUOTE([ARR_3(assignedTeam _target,'PATHTOF(UI\team\team_management_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); showDisabled = 1; + class ACE_remoteTeamManagement { + displayName = CSTRING(Squad); + icon = QPATHTOF(UI\team\team_management_ca.paa); + condition = QUOTE(GVAR(remoteTeamManagement) && {_player == leader _player}); + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; + insertChildren = QUOTE(call FUNC(addSquadChildren)); + }; class ACE_JoinTeamRed { displayName = CSTRING(JoinTeamRed); - condition = QUOTE(true); + condition = QUOTE(assignedTeam _player != 'RED'); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; statement = QUOTE([ARR_3(_player,'RED',true)] call DFUNC(joinTeam)); showDisabled = 1; @@ -263,7 +270,7 @@ class CfgVehicles { }; class ACE_JoinTeamGreen { displayName = CSTRING(JoinTeamGreen); - condition = QUOTE(true); + condition = QUOTE(assignedTeam _player != 'GREEN'); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; statement = QUOTE([ARR_3(_player,'GREEN',true)] call DFUNC(joinTeam)); showDisabled = 1; @@ -271,7 +278,7 @@ class CfgVehicles { }; class ACE_JoinTeamBlue { displayName = CSTRING(JoinTeamBlue); - condition = QUOTE(true); + condition = QUOTE(assignedTeam _player != 'BLUE'); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; statement = QUOTE([ARR_3(_player,'BLUE',true)] call DFUNC(joinTeam)); showDisabled = 1; @@ -279,14 +286,14 @@ class CfgVehicles { }; class ACE_JoinTeamYellow { displayName = CSTRING(JoinTeamYellow); - condition = QUOTE(true); + condition = QUOTE(assignedTeam _player != 'YELLOW'); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; statement = QUOTE([ARR_3(_player,'YELLOW',true)] call DFUNC(joinTeam)); showDisabled = 1; modifierFunction = QUOTE([ARR_3('YELLOW','PATHTOF(UI\team\team_white_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); }; - class ACE_LeaveTeam { - displayName = CSTRING(LeaveTeam); + class ACE_JoinTeamMain { + displayName = CSTRING(JoinTeamMain); condition = QUOTE(assignedTeam _player != 'MAIN'); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; statement = QUOTE([ARR_3(_player,'MAIN',true)] call DFUNC(joinTeam)); @@ -372,6 +379,39 @@ class CfgVehicles { }; class Car_F: Car {}; + class Offroad_01_base_F: Car_F { + class GVAR(anims) { + class HideBackpacks { + positions[] = {{-1.15, -1.15, -0.2}, {1.05, -1.15, -0.2}, {1.05, -2.5, -0.2}}; + items[] = {"B_TacticalPack_blk", "B_TacticalPack_blk", "B_Carryall_khk", "B_Carryall_khk"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; + class Offroad_01_military_base_F: Offroad_01_base_F {}; + class Offroad_01_armed_base_F: Offroad_01_military_base_F { + class GVAR(anims): GVAR(anims) { + class HideBackpacks: HideBackpacks { + positions[] = {{-1.15, -1.03, -0.8}, {1.05, -1.03, -0.8}, {1.05, -2.38, -0.8}}; + }; + }; + }; + class Offroad_01_AT_base_F: Offroad_01_military_base_F { + class GVAR(anims): GVAR(anims) { + class HideBackpacks: HideBackpacks { + positions[] = {{-1.15, -1.25, -0.2}, {1.05, -1.25, -0.2}, {1.05, -2.6, -0.2}}; + }; + }; + }; + class Offroad_01_military_covered_base_F: Offroad_01_military_base_F { + class GVAR(anims): GVAR(anims) { + class HideBackpacks: HideBackpacks { + positions[] = {{-1.15, -1, -0.27}, {1.05, -1, -0.27}, {1.05, -2.35, -0.27}}; + }; + }; + }; + class Quadbike_01_base_F: Car_F { class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -405,6 +445,45 @@ class CfgVehicles { }; }; + class Wheeled_APC_F; + class APC_Wheeled_01_base_F: Wheeled_APC_F { + class GVAR(anims) { + class showBags { + phase = 0; + selections[] = {"vhc_bags"}; + items[] = {"B_Carryall_cbr", "B_Carryall_cbr"}; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; + distance = 3; + }; + }; + }; + class APC_Wheeled_02_base_F: Wheeled_APC_F { + class GVAR(anims); + }; + class APC_Wheeled_02_base_v2_F: APC_Wheeled_02_base_F { + class GVAR(anims): GVAR(anims) { + class showBags { + phase = 0; + positions[] = {"_target selectionPosition ['vhc_bags', 'FireGeometry', 'AveragePoint']"}; + items[] = {"B_Carryall_cbr"}; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; + }; + }; + }; + class APC_Wheeled_03_base_F: Wheeled_APC_F { + class GVAR(anims) { + class showBags { + phase = 0; + positions[] = {"_target selectionPosition ['vhc_bags', 'FireGeometry', 'AveragePoint']"}; + items[] = {"B_Carryall_cbr", "B_Carryall_cbr"}; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; + }; + }; + }; + class Tank: LandVehicle { class ACE_Actions { class ACE_MainActions { @@ -432,6 +511,82 @@ class CfgVehicles { }; }; }; + class Tank_F; + class LT_01_base_F: Tank_F { + class GVAR(anims) { + class showBags { + phase = 0; + positions[] = {"_target selectionPosition ['vhc_bags', 'FireGeometry', 'AveragePoint']"}; + items[] = {"B_Carryall_cbr"}; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; + }; + class showBags2: showBags { + positions[] = {"_target selectionPosition ['vhc_bags2', 'FireGeometry', 'AveragePoint']"}; + }; + }; + }; + + class APC_Tracked_01_base_F: Tank_F { + class GVAR(anims) { + class showBags { + phase = 0; + selections[] = {"vhc_bags"}; + positions[] = {"private _pos = _target selectionPosition 'vhc_bags'; _pos set [0, -(_pos select 0)]; _pos"}; // Mirror position to other side of vehicle + items[] = {"B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr"}; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; + }; + }; + }; + 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 { + class GVAR(anims): GVAR(anims) { + class showBags: showBags { + items[] = {"B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr"}; + }; + }; + }; + + class APC_Tracked_02_base_F: Tank_F { + class GVAR(anims) { + class showBags { + phase = 0; + selections[] = {"vhc_bags"}; + items[] = {"B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr"}; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; + }; + }; + }; + + class APC_Tracked_03_base_F: Tank_F { + class GVAR(anims) { + class showBags { + phase = 0; + selections[] = {"vhc_bags"}; + items[] = {"B_Carryall_cbr", "B_Carryall_cbr"}; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; + }; + }; + }; + + class MBT_01_base_F: Tank_F { + class GVAR(anims); + }; + class B_MBT_01_base_F: MBT_01_base_F {}; + class B_MBT_01_cannon_F: B_MBT_01_base_F { + class GVAR(anims): GVAR(anims) { + class showBags { + phase = 0; + selections[] = {"vhc_bags"}; + items[] = {"B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr"}; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; + }; + }; + }; class Motorcycle: LandVehicle { class ACE_Actions { diff --git a/addons/interaction/RscTitles.hpp b/addons/interaction/RscTitles.hpp index ec7856c62cb..d2f2f0ef92c 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; diff --git a/addons/interaction/XEH_PREP.hpp b/addons/interaction/XEH_PREP.hpp index 554f9037047..63053fd5122 100644 --- a/addons/interaction/XEH_PREP.hpp +++ b/addons/interaction/XEH_PREP.hpp @@ -13,6 +13,7 @@ PREP(showMouseHint); PREP(hideMouseHint); // interaction with units +PREP(addSquadChildren); PREP(canInteractWithCivilian); PREP(canInteractWithVehicleCrew); PREP(getDown); @@ -54,4 +55,5 @@ PREP(push); // misc PREP(canFlip); +PREP(initAnimActions); PREP(replaceTerrainObject); diff --git a/addons/interaction/XEH_postInit.sqf b/addons/interaction/XEH_postInit.sqf index a5f71705888..d341c27fd38 100644 --- a/addons/interaction/XEH_postInit.sqf +++ b/addons/interaction/XEH_postInit.sqf @@ -78,7 +78,7 @@ ACE_Modifier = 0; }] call CBA_fnc_addEventHandler; if (isServer) then { - [QGVAR(replaceTerrainObject), FUNC(replaceTerrainObject)] call CBA_fnc_addEventHandler; + [QGVAR(replaceTerrainObject), LINKFUNC(replaceTerrainObject)] call CBA_fnc_addEventHandler; }; if (!hasInterface) exitWith {}; @@ -149,11 +149,20 @@ GVAR(isOpeningDoor) = false; ["isNotOnLadder", {getNumber (configFile >> "CfgMovesMaleSdr" >> "States" >> animationState (_this select 0) >> "ACE_isLadder") != 1}] call EFUNC(common,addCanInteractWithCondition); ["CBA_settingsInitialized", { + TRACE_2("settingsInitialized",GVAR(disableNegativeRating),GVAR(enableAnimActions)); + if (GVAR(disableNegativeRating)) then { player addEventHandler ["HandleRating", { (_this select 1) max 0 }]; }; + + if (!GVAR(enableAnimActions)) exitWith {}; + + // Don't add inherited anim actions (but actions are added to child classes) + { + [_x, "InitPost", LINKFUNC(initAnimActions), true, [], true] call CBA_fnc_addClassEventHandler; + } forEach (keys (uiNamespace getVariable QGVAR(animActionsClasses))); }] call CBA_fnc_addEventHandler; { @@ -162,17 +171,17 @@ GVAR(isOpeningDoor) = false; }] call CBA_fnc_addPlayerEventHandler; } forEach ["loadout", "weapon"]; - // add "Take _weapon_" action to dropped weapons +//IGNORE_PRIVATE_WARNING ["_target", "_player"]; private _action = [ // action display name will be overwritten in modifier function QGVAR(takeWeapon), "take", "\A3\ui_f\data\igui\cfg\actions\take_ca.paa", {_player action ["TakeWeapon", _target, weaponCargo _target select 0]}, - {count weaponCargo _target == 1}, + {(count weaponCargo _target == 1) && {[_player, objNull, []] call EFUNC(common,canInteractWith)}}, // Not checking if container is claimed nil, nil, nil, nil, nil, { params ["_target", "", "", "_actionData"]; - _actionData set [1, format [localize "STR_ACTION_TAKE_BAG", getText (configfile >> "CfgWeapons" >> weaponCargo _target select 0 >> "displayName")]]; + _actionData set [1, format [localize "STR_ACTION_TAKE_BAG", getText (configFile >> "CfgWeapons" >> weaponCargo _target select 0 >> "displayName")]]; } ] call EFUNC(interact_menu,createAction); diff --git a/addons/interaction/XEH_preInit.sqf b/addons/interaction/XEH_preInit.sqf index c5873bcfc98..ec73b62b1b9 100644 --- a/addons/interaction/XEH_preInit.sqf +++ b/addons/interaction/XEH_preInit.sqf @@ -16,6 +16,7 @@ DFUNC(repair_Statement) = { // moved from config because of build problems }; if (hasInterface) then { + GVAR(initializedAnimClasses) = []; GVAR(replaceTerrainModels) = createHashMapFromArray call (uiNamespace getVariable QGVAR(cacheReplaceTerrainModels)); }; diff --git a/addons/interaction/XEH_preStart.sqf b/addons/interaction/XEH_preStart.sqf index 799e9e5986e..39da54b3b58 100644 --- a/addons/interaction/XEH_preStart.sqf +++ b/addons/interaction/XEH_preStart.sqf @@ -11,7 +11,7 @@ private _replaceTerrainClasses = QUOTE( private _cacheReplaceTerrainModels = createHashMap; { - private _model = toLower getText (_x >> "model"); + private _model = toLowerANSI getText (_x >> "model"); if (_model select [0, 1] == "\") then { _model = _model select [1]; }; @@ -23,3 +23,13 @@ private _cacheReplaceTerrainModels = createHashMap; } forEach _replaceTerrainClasses; uiNamespace setVariable [QGVAR(cacheReplaceTerrainModels), compileFinal str _cacheReplaceTerrainModels]; + + +// Cache classes with anim actions +private _animActionsClasses = (QUOTE(isClass (_x >> QQGVAR(anims)) && {!isClass (inheritsFrom _x >> QQGVAR(anims))}) configClasses (configFile >> "CfgVehicles")); +_animActionsClasses = _animActionsClasses apply { configName _x }; +_animActionsClasses = _animActionsClasses select { + private _class = _x; + (_animActionsClasses findIf {(_class != _x) && {_class isKindOf _x}}) == -1 // filter classes that already have a parent in the list +}; +uiNamespace setVariable [QGVAR(animActionsClasses), compileFinal (_animActionsClasses createHashMapFromArray [])]; diff --git a/addons/interaction/dev/initReplaceTerrainCursorObject.sqf b/addons/interaction/dev/initReplaceTerrainCursorObject.sqf index ee5ddcad490..6dadf678b7c 100644 --- a/addons/interaction/dev/initReplaceTerrainCursorObject.sqf +++ b/addons/interaction/dev/initReplaceTerrainCursorObject.sqf @@ -17,7 +17,7 @@ DFUNC(replaceTerrainModelsAdd) = { if (_class isEqualTo "") then { private _configClasses = QUOTE(getNumber (_x >> 'scope') == 2 && {!(configName _x isKindOf 'AllVehicles')}) configClasses (configFile >> "CfgVehicles"); { - private _xmodel = toLower getText (_x >> "model"); + private _xmodel = toLowerANSI getText (_x >> "model"); if (_xmodel select [0, 1] == "\") then { _xmodel = _xmodel select [1]; }; @@ -47,12 +47,12 @@ DFUNC(replaceTerrainModelsAdd) = { ) 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]; + private _object = cursorObject; + + if (isNull _object) exitWith {}; + + [_object, true, nil, nil, nil, true] call EFUNC(dragging,setCarryable); + [_object, true, nil, nil, nil, true] call EFUNC(dragging,setDraggable); }, [], 1] call CBA_fnc_waitAndExecute; }; true diff --git a/addons/interaction/functions/fnc_addPassengerActions.sqf b/addons/interaction/functions/fnc_addPassengerActions.sqf index 112919ee803..9b8981bfd0d 100644 --- a/addons/interaction/functions/fnc_addPassengerActions.sqf +++ b/addons/interaction/functions/fnc_addPassengerActions.sqf @@ -20,11 +20,7 @@ params ["", "", "_parameters"]; _parameters params ["_unit"]; -private _namespace = EGVAR(interact_menu,ActNamespace); -private _actionTrees = _namespace getVariable typeOf _unit; -if (isNil "_actionTrees") then { - _actionTrees = []; -}; +private _actionTrees = EGVAR(interact_menu,ActNamespace) getOrDefault [typeOf _unit, []]; private _actions = []; @@ -33,7 +29,6 @@ private _actions = []; _x params ["_actionData", "_children"]; _actions pushBack [_actionData, _children, _unit]; - false -} count (_actionTrees select 0 select 1); +} forEach (_actionTrees select 0 select 1); _actions diff --git a/addons/interaction/functions/fnc_addPassengersActions.sqf b/addons/interaction/functions/fnc_addPassengersActions.sqf index 50b0d98a21c..4a88485a3f1 100644 --- a/addons/interaction/functions/fnc_addPassengersActions.sqf +++ b/addons/interaction/functions/fnc_addPassengersActions.sqf @@ -41,6 +41,7 @@ private _icon = ""; _icon = QPATHTOEF(captives,UI\handcuff_ca.paa); }; + //IGNORE_PRIVATE_WARNING ["_target"]; _actions pushBack [ [ str _unit, diff --git a/addons/interaction/functions/fnc_addSquadChildren.sqf b/addons/interaction/functions/fnc_addSquadChildren.sqf new file mode 100644 index 00000000000..a34c2e884c3 --- /dev/null +++ b/addons/interaction/functions/fnc_addSquadChildren.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Gets the squad child actions + * + * Arguments: + * 1: Player + * + * Return Value: + * Children actions + * + * Example: + * [player, player] call ace_interaction_fnc_addSquadChildren + * + * Public: No + */ + +params ["", "_player"]; + +private _fnc_color = { + (switch (toUpper _this) 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]]}; + }) call BIS_fnc_colorRGBtoHTML +}; + +private _units = (units group _player) - [_player]; + +//IGNORE_PRIVATE_WARNING ["_target"]; +private _subActions = []; +_subActions pushBack (["drop", localize "str_a3_endgame_notifications_title_drop", "\a3\ui_f\data\igui\cfg\actions\ico_off_ca.paa", + {[_target] joinSilent grpNull}, {true}] call EFUNC(interact_menu,createAction)); + +{ + private _icon = [QPATHTOF(UI\team\team_white_ca.paa), _x call _fnc_color]; + private _name = localize format ["str_assign_%1", _x]; + _subActions pushBack ([_x, _name, _icon, + {[_target, _this#2] call FUNC(joinTeam)}, {assignedTeam _target != _this#2}, {}, _x] call EFUNC(interact_menu,createAction)); +} forEach ["RED", "GREEN", "BLUE", "YELLOW", "MAIN"]; + +private _actions = _units apply { + private _unit = _x; + private _icon = [QPATHTOF(UI\team\team_white_ca.paa), (assignedTeam _unit) call _fnc_color]; + private _actionUnit = [hashValue _x, [_x, true] call EFUNC(common,getName), _icon, {}, {true}] call EFUNC(interact_menu,createAction); + + [_actionUnit, _subActions apply { [_x, [], _unit] }, _unit] +}; + +_actions diff --git a/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf b/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf index a314a8b601a..e8b7e47d754 100644 --- a/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf +++ b/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf @@ -11,13 +11,16 @@ * Unit can interact with vehicle crew * * Example: - * [cursorObject, player] call ace_interaction_fnc_canInteractWithVehicleCrew + * [player, cursorObject] call ace_interaction_fnc_canInteractWithVehicleCrew * * Public: No */ params ["_player", "_vehicle"]; +if (GVAR(interactWithEnemyCrew) == 2) exitWith { true }; +if ((GVAR(interactWithEnemyCrew) == 1) && {_vehicle isKindOf "StaticWeapon"}) exitWith { true }; + private _crew = crew _vehicle; // If vehicle is empty, quit diff --git a/addons/interaction/functions/fnc_canJoinGroup.sqf b/addons/interaction/functions/fnc_canJoinGroup.sqf index facc3376eee..ec2feb82401 100644 --- a/addons/interaction/functions/fnc_canJoinGroup.sqf +++ b/addons/interaction/functions/fnc_canJoinGroup.sqf @@ -18,7 +18,6 @@ params ["_unit", "_target"]; -alive _target -&& {!(_target getVariable ["ACE_isUnconscious", false])} +_target call EFUNC(common,isAwake) && {side group _unit == side group _target} && {group _unit != group _target} // return diff --git a/addons/interaction/functions/fnc_canJoinTeam.sqf b/addons/interaction/functions/fnc_canJoinTeam.sqf index 09d0281dca3..e0e3684ce95 100644 --- a/addons/interaction/functions/fnc_canJoinTeam.sqf +++ b/addons/interaction/functions/fnc_canJoinTeam.sqf @@ -18,7 +18,6 @@ params ["_unit", "_target"]; -alive _target -&& {!(_target getVariable ["ACE_isUnconscious", false])} +_target call EFUNC(common,isAwake) && {!([_target] call EFUNC(common,isPlayer))} && {_target in units group _unit} diff --git a/addons/interaction/functions/fnc_canPassMagazine.sqf b/addons/interaction/functions/fnc_canPassMagazine.sqf index 9d0bed083d1..97478bffa7c 100644 --- a/addons/interaction/functions/fnc_canPassMagazine.sqf +++ b/addons/interaction/functions/fnc_canPassMagazine.sqf @@ -19,7 +19,7 @@ params ["_player", "_target", "_weapon"]; if (!GVAR(enableMagazinePassing)) exitWith {false}; -if (_weapon isEqualTo "") exitWith {false}; +if (_weapon isEqualTo "" || {!(_target call EFUNC(common,isAwake))}) exitWith {false}; if (((vehicle _target) != _target) && {(vehicle _target) != (vehicle _player)}) exitWith {false}; private _compatibleMags = [_weapon] call CBA_fnc_compatibleMagazines; diff --git a/addons/interaction/functions/fnc_canPullOutBody.sqf b/addons/interaction/functions/fnc_canPullOutBody.sqf index 167d09ecdb7..2676bfc203c 100644 --- a/addons/interaction/functions/fnc_canPullOutBody.sqf +++ b/addons/interaction/functions/fnc_canPullOutBody.sqf @@ -19,7 +19,7 @@ params ["_body", "_unit"]; // Defer to ACE Medical's unload patient if present -if (["ace_medical"] call EFUNC(common,isModLoaded)) exitWith {false}; +if (GETEGVAR(medical,enabled,false)) exitWith {false}; private _vehicle = objectParent _body; diff --git a/addons/interaction/functions/fnc_canPush.sqf b/addons/interaction/functions/fnc_canPush.sqf index 28197d12cd3..ff339d5952f 100644 --- a/addons/interaction/functions/fnc_canPush.sqf +++ b/addons/interaction/functions/fnc_canPush.sqf @@ -10,7 +10,7 @@ * Can Push * * Example: - * [target] call ace_interaction_fnc_canPush + * cursorObject call ace_interaction_fnc_canPush * * Public: No */ @@ -19,4 +19,5 @@ params ["_target"]; alive _target && {getMass _target <= 2600 || getNumber (configOf _target >> QGVAR(canPush)) == 1} && -{vectorMagnitude velocity _target < 3} +{vectorMagnitude velocity _target < 3} && +{isNull isVehicleCargo _target} // Check if vehicle is loaded as ViV cargo diff --git a/addons/interaction/functions/fnc_canTapShoulder.sqf b/addons/interaction/functions/fnc_canTapShoulder.sqf index 049c178152b..51f271fb4c9 100644 --- a/addons/interaction/functions/fnc_canTapShoulder.sqf +++ b/addons/interaction/functions/fnc_canTapShoulder.sqf @@ -19,6 +19,5 @@ params ["_unit", "_target"]; _target isKindOf "CAManBase" && -{alive _target} && -{_unit distance _target < 4} && -{!(_target getVariable ["ACE_isUnconscious", false])} // return +{_target call EFUNC(common,isAwake)} && +{_unit distance _target < 4} // return diff --git a/addons/interaction/functions/fnc_doRemoteControl.sqf b/addons/interaction/functions/fnc_doRemoteControl.sqf index a2ec19b1801..d728190b3e3 100644 --- a/addons/interaction/functions/fnc_doRemoteControl.sqf +++ b/addons/interaction/functions/fnc_doRemoteControl.sqf @@ -13,6 +13,7 @@ * * Public: No */ +//IGNORE_PRIVATE_WARNING ["_target"]; private _units = curatorSelected select 0; private _index = _units findIf { diff --git a/addons/interaction/functions/fnc_getDoor.sqf b/addons/interaction/functions/fnc_getDoor.sqf index 02daf57a83e..5f251d2589e 100644 --- a/addons/interaction/functions/fnc_getDoor.sqf +++ b/addons/interaction/functions/fnc_getDoor.sqf @@ -33,7 +33,7 @@ if (typeOf _house == "") exitWith {[objNull, ""]}; _intersections = [_house, "GEOM"] intersect [_position0, _position1]; -private _door = toLower (_intersections select 0 select 0); +private _door = toLowerANSI (_intersections select 0 select 0); if (isNil "_door") exitWith {[_house, ""]}; diff --git a/addons/interaction/functions/fnc_getDoorAnimations.sqf b/addons/interaction/functions/fnc_getDoorAnimations.sqf index 2d5c81dc2d7..b91c5eac6c4 100644 --- a/addons/interaction/functions/fnc_getDoorAnimations.sqf +++ b/addons/interaction/functions/fnc_getDoorAnimations.sqf @@ -26,8 +26,8 @@ private _lockedVariable = []; private _numberStrings = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]; { - private _animName = toLower _x; - private _index = _animName find toLower _door; + private _animName = toLowerANSI _x; + private _index = _animName find toLowerANSI _door; if (_index != -1 && {!(_animName select [_index + count _door, 1] in _numberStrings)}) then { if (((_animName find "disabled") != -1) || ((_animName find "locked") != -1)) then { diff --git a/addons/interaction/functions/fnc_getDown.sqf b/addons/interaction/functions/fnc_getDown.sqf index b8f6d7c50d7..531cd23c54a 100644 --- a/addons/interaction/functions/fnc_getDown.sqf +++ b/addons/interaction/functions/fnc_getDown.sqf @@ -22,11 +22,10 @@ params ["_unit", "_target"]; [_unit, "GestureGo"] call EFUNC(common,doGesture); -private _chance = [0.5, 0.8] select (count weapons _unit > 0); +private _chance = [0.5, 0.8] select (weapons _unit isNotEqualTo []); { - if (count weapons _x == 0 && {random 1 < _chance}) then { + if (weapons _x isEqualTo [] && {random 1 < _chance}) then { [QGVAR(getDown), [_x], [_x]] call CBA_fnc_targetEvent; }; - false -} count (_target nearEntities ["Civilian", SEND_RADIUS]); +} forEach (_target nearEntities ["Civilian", SEND_RADIUS]); diff --git a/addons/interaction/functions/fnc_getGlassDoor.sqf b/addons/interaction/functions/fnc_getGlassDoor.sqf index ffa6bfec44e..2aea74f82d4 100644 --- a/addons/interaction/functions/fnc_getGlassDoor.sqf +++ b/addons/interaction/functions/fnc_getGlassDoor.sqf @@ -26,7 +26,7 @@ private _glassDoor = _door splitString "_"; private _glassPos = (_house selectionPosition [(_glassDoor select 0) + "_" + (_glassDoor select 1) + "_effects", "Memory"]); // Calculate all animation names so we know what is there { - private _animName = toLower _x; + private _animName = toLowerANSI _x; if (((_animName find "door") != -1) && ((_animName find "locked") == -1) && ((_animName find "disabled") == -1) && ((_animName find "handle") == -1)) then { private _splitStr = _animName splitString "_"; _doorParts pushBack ((_splitStr select 0) + "_" + (_splitStr select 1) + "_trigger"); @@ -64,4 +64,3 @@ private _lowestDistance = 0; if ((isNil "_door") || ((_door find "glass") != -1)) exitWith {}; _door - diff --git a/addons/interaction/functions/fnc_getVehiclePos.sqf b/addons/interaction/functions/fnc_getVehiclePos.sqf index ce2ce9377b7..d90bc228d2d 100644 --- a/addons/interaction/functions/fnc_getVehiclePos.sqf +++ b/addons/interaction/functions/fnc_getVehiclePos.sqf @@ -14,7 +14,7 @@ * * Public: No */ -// IGNORE_PRIVATE_WARNING(_target); +//IGNORE_PRIVATE_WARNING ["_target"]; private _bb = boundingBoxReal _target; (_bb select 0) params ["_bbX", "_bbY", "_bbZ"]; diff --git a/addons/interaction/functions/fnc_getWeaponAttachmentsActions.sqf b/addons/interaction/functions/fnc_getWeaponAttachmentsActions.sqf index c771589904f..e91a027068c 100644 --- a/addons/interaction/functions/fnc_getWeaponAttachmentsActions.sqf +++ b/addons/interaction/functions/fnc_getWeaponAttachmentsActions.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: mharis001, Dystopian + * Author: mharis001, Dystopian, PabstMirror, johnb43 * Returns children actions for weapon attachment switching. * * Arguments: @@ -21,48 +21,115 @@ params ["_unit"]; params ["_unit"]; private _currentWeapon = currentWeapon _unit; - if (_currentWeapon isEqualTo "") exitWith {[]}; - private _weaponItems = _unit weaponAccessories _currentWeapon; + + if (_currentWeapon == "") exitWith {[]}; + private _cfgWeapons = configFile >> "CfgWeapons"; - private _actions = []; + private _weaponItems = _unit weaponAccessories _currentWeapon; - // "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}; + // Get current weapon attachments, as well as compatible attachments in inventory + private _allAttachments = (+_weaponItems) - [""]; + _allAttachments append ((_unit call EFUNC(common,uniqueItems)) arrayIntersect (compatibleItems _currentWeapon)); + (_allAttachments arrayIntersect _allAttachments) apply { private _config = _cfgWeapons >> _x; - private _name = format [LLSTRING(weaponAttachmentsDetach), getText (_config >> "displayName")]; + private _name = 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 + [ + [ + _x, + _name, + _picture, + {}, + {true}, + { + params ["", "_unit", "_args"]; + _args params ["_attachment", "_name", "_picture", "_weaponItems", "_currentWeapon"]; + + private _cfgWeapons = configFile >> "CfgWeapons"; + private _attachmentNotOnGun = !(_attachment in _weaponItems); + private _actions = []; + + // "attach" action + if (_attachmentNotOnGun && {[_unit, _attachment] call EFUNC(common,hasItem)}) then { + private _type = getNumber (_cfgWeapons >> _attachment >> "itemInfo" >> "type"); + private _currentAttachment = _weaponItems select ([TYPE_MUZZLE, TYPE_FLASHLIGHT, TYPE_OPTICS, TYPE_BIPOD] find _type); + + _actions pushBack [ + [ + QGVAR(attach_) + _attachment, + LLSTRING(weaponAttachmentsAttach), + _picture, + LINKFUNC(switchWeaponAttachment), + {true}, + {}, + [_currentWeapon, _attachment, _currentAttachment] + ] call EFUNC(interact_menu,createAction), + [], + _unit + ]; + }; + + // Don't show interaction with attachments that aren't on the current weapon + if (_attachmentNotOnGun) exitWith {_actions}; + + // "detach" action + _actions pushBack [ + [ + QGVAR(detach_) + _attachment, + LLSTRING(weaponAttachmentsDetach), + _picture, + LINKFUNC(switchWeaponAttachment), + {true}, + {}, + [_currentWeapon, "", _attachment] + ] call EFUNC(interact_menu,createAction), + [], + _unit + ]; + + private _CBA_PIPItems = configFile >> "CBA_PIPItems"; + + // "switch" action + { + // Ignore 2D scopes when using a PIP scope (e.g. CUP uses this) + if (getText (_CBA_PIPItems >> _x) == _attachment) then { + continue; + }; + + private _config = _cfgWeapons >> _x; + private _modeName = getText (_config >> "MRT_SwitchItemHintText"); + + if (_modeName == "") then { + _modeName = getText (_config >> "displayName"); + }; + + _actions pushBack [ + [ + QGVAR(switch_) + _x, + format ["%1: %2", localize "str_sensortype_switch", _modeName], + getText (_config >> "picture"), + { + params ["", "_unit", "_actionParams"]; + _actionParams params ["_weapon", "_newAttachment", "_oldAttachment"]; + [_unit, _weapon, _oldAttachment, _newAttachment] call EFUNC(common,switchAttachmentMode); + }, + {true}, + {}, + [_currentWeapon, _x, _attachment] + ] call EFUNC(interact_menu,createAction), + [], + _unit + ]; + } forEach ((_attachment call CBA_fnc_switchableAttachments) - [_attachment]); // Don't allow switching to current mode + + _actions + }, + [_x, _name, _picture, _weaponItems, _currentWeapon] + ] call EFUNC(interact_menu,createAction), + [], + _unit + ] + } // return }, _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 85cb3dc0076..429a012ec4d 100644 --- a/addons/interaction/functions/fnc_getWeaponPos.sqf +++ b/addons/interaction/functions/fnc_getWeaponPos.sqf @@ -14,7 +14,7 @@ * * Public: No */ -// IGNORE_PRIVATE_WARNING(_target); +//IGNORE_PRIVATE_WARNING ["_target"]; private _weaponDir = _target weaponDirection currentWeapon _target; private _refSystem = _weaponDir call EFUNC(common,createOrthonormalReference); diff --git a/addons/interaction/functions/fnc_initAnimActions.sqf b/addons/interaction/functions/fnc_initAnimActions.sqf new file mode 100644 index 00000000000..e47f80008b8 --- /dev/null +++ b/addons/interaction/functions/fnc_initAnimActions.sqf @@ -0,0 +1,202 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Initializes object interactions based on animations. + * + * Arguments: + * 0: Target + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_interaction_fnc_initAnimActions + * + * Public: No + */ + +params ["_object"]; + +private _class = typeOf _object; + +if (_class in GVAR(initializedAnimClasses)) exitWith {}; + +GVAR(initializedAnimClasses) pushBack _class; + +private _statement = { + params ["_target", "_player", "_params"]; + _params params ["_anim", "_phase", "_duration", "_text"]; + TRACE_5("statement",_target,_player,_anim,_phase,_duration); + + [ + _duration, + [_target, _player, _anim, _phase], + { + (_this select 0) params ["_target", "_player", "_anim", "_phase"]; + + private _items = _target getVariable [ + format [QGVAR(animsItems_%1), _anim], + getArray (configOf _target >> QGVAR(anims) >> _anim >> "items") + ]; + + // If 1 object was spawned in, consider it a success + private _success = false; + + if (_items isNotEqualTo []) then { + if (_items isEqualType "") then { + _items = [_items]; + }; + + private _weaponHolder = objNull; + + { + private _type = (_x call EFUNC(common,getItemType)) select 0; + + if (_type == "") then { + private _emptyPosAGL = []; + + // This covers testing vehicle stability and finding a safe position + for "_i" from 1 to 3 do { + _emptyPosAGL = [_target, _x, _player] call EFUNC(common,findUnloadPosition); + + if (_emptyPosAGL isNotEqualTo []) exitWith {}; + }; + + // If still no valid position, try the next item + if (_emptyPosAGL isEqualTo []) then { + [LELSTRING(common,NoRoomToUnload)] call EFUNC(common,displayTextStructured); + + continue; + }; + + private _object = createVehicle [_x, _emptyPosAGL, [], 0, "CAN_COLLIDE"]; + + if (!isNull _object) then { + // Prevent items from taking damage when unloaded + [_object, "blockDamage", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + [EFUNC(common,statusEffect_set), [_object, "blockDamage", QUOTE(ADDON), false], 2] call CBA_fnc_waitAndExecute; + + _success = true; + } else { + WARNING_1("Failed to create object of type '%1'",_x); + }; + + continue; + }; + + // Functions/code below are guaranteed to spawn in objects + _success = true; + + // getItemType considers backpacks as weapons, so handle them first + if (getNumber (configFile >> "CfgVehicles" >> _x >> "isBackpack") == 1) then { + if (backpack _player == "") then { + _player addBackpackGlobal _x; + } else { + if (isNull _weaponHolder) then { + _weaponHolder = nearestObject [_player, "WeaponHolder"]; + + if (isNull _weaponHolder || {_player distance _weaponHolder > 2}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", [0, 0, 0], [], 0, "NONE"]; + _weaponHolder setPosASL getPosASL _player; + }; + }; + + _weaponHolder addBackpackCargoGlobal [_x, 1]; + }; + + continue; + }; + + switch (_type) do { + case "weapon": { + [_player, _x, true] call CBA_fnc_addWeapon; + }; + case "item": { + [_player, _x, true] call CBA_fnc_addItem; + }; + case "magazine": { + [_player, _x, -1, true] call CBA_fnc_addMagazine; + }; + }; + } forEach _items; + } else { + [LELSTRING(common,disabled)] call EFUNC(common,displayTextStructured); + }; + + if (!_success) exitWith {}; + + _target animate [_anim, _phase, true]; + }, + {}, + _text, + { + (_this select 0) params ["_target", "", "_anim", "_phase"]; + + _target animationPhase _anim != _phase + }, + ["isNotSwimming"] + ] call EFUNC(common,progressBar); +}; + +private _condition = { + params ["_target", "_player", "_params"]; + _params params ["_anim", "_phase"]; + + _target animationPhase _anim != _phase + && {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} +}; + +private _config = configOf _object; + +{ + private _animConfig = _x; + private _anim = configName _animConfig; + + private _animationSourcesConfig = _config >> "AnimationSources" >> _anim; + + if !( + isClass _animationSourcesConfig // anim exist + && {0 != [_animationSourcesConfig >> "scope", "NUMBER", 1] call CBA_fnc_getConfigEntry} // anim not hidden + && {isNumber (_animationSourcesConfig >> "initPhase")} // anim correct (some CUP anims are inherited and cleared) + && {0 != [_animConfig >> "enabled", "NUMBER", 1] call CBA_fnc_getConfigEntry} // anim enabled + ) then {continue}; + + private _positions = []; + { + if (_x isEqualType "") then { + _positions pushBack compile _x; + } else { + _positions pushBack _x; + }; + } forEach getArray (_animConfig >> "positions"); + + _positions append getArray (_animConfig >> "selections"); + + if (_positions isEqualTo []) then { + ERROR_2("No action position for _class %1 anim %2",_class,_anim); + continue; + }; + + private _phase = [_animConfig >> "phase", "NUMBER", 1] call CBA_fnc_getConfigEntry; + private _name = [_animConfig >> "name", "TEXT", localize "str_a3_cfgactions_unmountitem0"] call CBA_fnc_getConfigEntry; + private _icon = [_animConfig >> "icon", "TEXT", "\A3\ui_f\data\igui\cfg\actions\take_ca.paa"] call CBA_fnc_getConfigEntry; + private _duration = [_animConfig >> "duration", "NUMBER", 10] call CBA_fnc_getConfigEntry; + private _text = getText (_animConfig >> "text"); + private _distance = [_animConfig >> "distance", "NUMBER", 2] call CBA_fnc_getConfigEntry; + + { + private _action = [ + format [QGVAR(anim_%1_%2), _anim, _forEachIndex], + _name, + _icon, + _statement, + _condition, + {}, + [_anim, _phase, _duration, _text], + _x, + _distance + ] call EFUNC(interact_menu,createAction); + [_class, 0, [], _action] call EFUNC(interact_menu,addActionToClass); + TRACE_3("add anim",_class,_anim,_x); + } forEach _positions; +} forEach configProperties [_config >> QGVAR(anims), "isClass _x"]; diff --git a/addons/interaction/functions/fnc_joinTeam.sqf b/addons/interaction/functions/fnc_joinTeam.sqf index 977e9022229..0d1928eb2fc 100644 --- a/addons/interaction/functions/fnc_joinTeam.sqf +++ b/addons/interaction/functions/fnc_joinTeam.sqf @@ -22,16 +22,8 @@ params ["_unit", "_team", ["_displayHint", false, [false]]]; _unit assignTeam _team; // display message -if (_unit == ACE_player) then { - private _message = ""; - - if (_team == "MAIN") then { - _message = localize LSTRING(LeftTeam); - } else { - _team = localize format [LSTRING(Team%1), _team]; - _message = format [localize LSTRING(JoinedTeam), _team]; - }; - if (_displayHint) then { - [_message] call EFUNC(common,displayTextStructured); - }; +if (_displayHint && {_unit == ACE_player}) then { + private _team = localize format ["str_team_%1", _team]; + private _message = format [LLSTRING(JoinedTeam), _team]; + [_message] call EFUNC(common,displayTextStructured); }; diff --git a/addons/interaction/functions/fnc_modifyJoinGroupAction.sqf b/addons/interaction/functions/fnc_modifyJoinGroupAction.sqf index eef77dfd37d..9eeda7ee3c4 100644 --- a/addons/interaction/functions/fnc_modifyJoinGroupAction.sqf +++ b/addons/interaction/functions/fnc_modifyJoinGroupAction.sqf @@ -20,7 +20,7 @@ params ["_target", "_player", "", "_actionData"]; -private _actionText = format ["%1: %2", localize LSTRING(JoinGroup), groupID group _target]; +private _actionText = format ["%1: %2", localize LSTRING(JoinGroup), groupId group _target]; TRACE_3("",_target,group _target,_actionText); _actionData set [1, _actionText]; diff --git a/addons/interaction/functions/fnc_openDoor.sqf b/addons/interaction/functions/fnc_openDoor.sqf index 540712ef418..f83cc88b1ec 100644 --- a/addons/interaction/functions/fnc_openDoor.sqf +++ b/addons/interaction/functions/fnc_openDoor.sqf @@ -35,12 +35,12 @@ if (_animations isEqualTo []) exitWith {}; private _lockedVariable = format ["bis_disabled_%1", _door]; private _lockedVariableAlt = _lockedVariable; // GM Buildings may have door names like door_01 but locking expects door_1 -if ((count _door == 7) && {(_door select [0, 6]) == "door_0"}) then { +if ((count _door == 7) && {(_door select [0, 6]) == "door_0"}) then { _lockedVariableAlt = format ["bis_disabled_door_%1", _door select [6, 1]]; // stip off the leading zero then check both vars }; // Check if the door can be locked aka have locked variable, otherwhise cant lock it -if ((_house animationPhase (_animations select 0) <= 0) && +if ((_house animationPhase (_animations select 0) <= 0) && {(_house getVariable [_lockedVariable, 0] == 1) || {_house getVariable [_lockedVariableAlt, 0] == 1}}) exitWith { private _lockedAnimation = format ["%1_locked_source", _door]; TRACE_3("locked",_house,_lockedAnimation,isClass (configOf _house >> "AnimationSources" >> _lockedAnimation)); @@ -63,8 +63,11 @@ 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; @@ -73,8 +76,11 @@ GVAR(usedScrollWheel) = false; if !(GVAR(usedScrollWheel)) then { 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 @@ -83,9 +89,9 @@ GVAR(usedScrollWheel) = false; }; // this allows for holding the door in it's current state. - if (CBA_missionTime > _time && {diag_frameno > _frame}) then { + if (CBA_missionTime > _time && {diag_frameNo > _frame}) then { GVAR(usedScrollWheel) = true; }; // do incremental door opening - {_house animate [_x, GVAR(doorTargetPhase)]; false} count _animations; -}, 0.1, [_house, _animations, getPosASL ACE_player, CBA_missionTime + 0.2, diag_frameno + 2]] call CBA_fnc_addPerFrameHandler; + {_house animate [_x, GVAR(doorTargetPhase)]} forEach _animations; +}, 0.1, [_house, _animations, getPosASL ACE_player, CBA_missionTime + 0.2, diag_frameNo + 2, _door]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/interaction/functions/fnc_passMagazine.sqf b/addons/interaction/functions/fnc_passMagazine.sqf index 09513b47629..757700ce8ba 100644 --- a/addons/interaction/functions/fnc_passMagazine.sqf +++ b/addons/interaction/functions/fnc_passMagazine.sqf @@ -7,6 +7,7 @@ * 0: Unit that passes the magazine * 1: Unit to pass the magazine to * 2: Weapon classname + * 3: Play passing animation (default: true) * * Return Value: * None @@ -16,7 +17,7 @@ * * Public: No */ -params ["_player", "_target", "_weapon"]; +params ["_player", "_target", "_weapon", ["_animate", true, [true]]]; private _compatibleMags = [_weapon] call CBA_fnc_compatibleMagazines; private _filteredMags = magazinesAmmoFull _player select { @@ -33,20 +34,14 @@ private _magToPassIndex = 0; _magToPass = _x; _magToPassIndex = _forEachIndex; }; -} foreach _filteredMags; +} 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_renameGroup.sqf b/addons/interaction/functions/fnc_renameGroup.sqf index 4ffff5771a1..8ad606a1eb1 100644 --- a/addons/interaction/functions/fnc_renameGroup.sqf +++ b/addons/interaction/functions/fnc_renameGroup.sqf @@ -20,12 +20,12 @@ params [ ["_group", grpNull, [grpNull]], ["_newName", "", [""]] ]; -if (_newName isEqualTo (groupID _group)) exitWith {true}; +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)} + && {_lowerName isEqualTo toLower (groupId _x)} && {_group != _x} } != -1; diff --git a/addons/interaction/functions/fnc_renameGroupUI.sqf b/addons/interaction/functions/fnc_renameGroupUI.sqf index 5d891b0cf8e..9e0973327da 100644 --- a/addons/interaction/functions/fnc_renameGroupUI.sqf +++ b/addons/interaction/functions/fnc_renameGroupUI.sqf @@ -21,7 +21,7 @@ private _display = findDisplay 46 createDisplay QGVAR(groupNameDisplay); private _textCtrl = _display displayCtrl 451; - _textCtrl ctrlSetText (groupID group _unit); + _textCtrl ctrlSetText (groupId group _unit); _display setVariable [QGVAR(renamedGroup), group _unit]; _display displayAddEventHandler ["Unload", { params ["_display", "_exitCode"]; diff --git a/addons/interaction/functions/fnc_sendAway.sqf b/addons/interaction/functions/fnc_sendAway.sqf index cef314756f4..b986ea2661b 100644 --- a/addons/interaction/functions/fnc_sendAway.sqf +++ b/addons/interaction/functions/fnc_sendAway.sqf @@ -22,14 +22,13 @@ params ["_unit"]; [_unit, "GestureGo"] call EFUNC(common,doGesture); -private _chance = [0.5, 0.8] select (count weapons _unit > 0); +private _chance = [0.5, 0.8] select (weapons _unit isNotEqualTo []); { - if (count weapons _x == 0 && {random 1 < _chance}) then { + if (weapons _x isEqualTo [] && {random 1 < _chance}) then { private _position = getPosASL _unit vectorAdd (eyeDirection _unit vectorMultiply SEND_DISTANCE); _position set [2, 0]; [QGVAR(sendAway), [_x, _position], [_x]] call CBA_fnc_targetEvent; }; - false -} count (_unit nearEntities ["Civilian", SEND_RADIUS]); +} forEach (_unit nearEntities ["Civilian", SEND_RADIUS]); diff --git a/addons/interaction/functions/fnc_showMouseHint.sqf b/addons/interaction/functions/fnc_showMouseHint.sqf index 73567fa5226..9adc15f4931 100644 --- a/addons/interaction/functions/fnc_showMouseHint.sqf +++ b/addons/interaction/functions/fnc_showMouseHint.sqf @@ -71,7 +71,7 @@ if (_textMMB == "") then { // Only create extra key if both name and text are valid if (_keyName != "" && {_keyText != ""}) then { // Localize Ctrl, Shift, or Alt keys - switch (toLower _keyName) do { + switch (toLowerANSI _keyName) do { case "ctrl"; case "control": {_keyName = format ["<%1>", toUpper localize "STR_dik_control"]}; case "shift": {_keyName = format ["<%1>", toUpper localize "STR_dik_shift"]}; diff --git a/addons/interaction/functions/fnc_switchWeaponAttachment.sqf b/addons/interaction/functions/fnc_switchWeaponAttachment.sqf index aaefb3315ed..6fede349624 100644 --- a/addons/interaction/functions/fnc_switchWeaponAttachment.sqf +++ b/addons/interaction/functions/fnc_switchWeaponAttachment.sqf @@ -4,9 +4,12 @@ * Switches weapon attachment. * * Arguments: - * 0: Target - * 1: Player (not used) + * 0: Target (not used) + * 1: Player * 2: Action params + * - 0: Weapon + * - 1: New Attachment + * - 2: Old Attachment * * Return Value: * None @@ -17,11 +20,13 @@ * Public: No */ -params ["_unit", "", "_actionParams"]; +params ["", "_unit", "_actionParams"]; _actionParams params ["_weapon", "_newAttachment", "_oldAttachment"]; TRACE_3("Switching attachment",_weapon,_newAttachment,_oldAttachment); -[_unit, "Gear"] call EFUNC(common,doGesture); +private _currWeaponType = [_unit, _weapon] call EFUNC(common,getWeaponIndex); + +if (_currWeaponType == -1) exitWith {}; private _addNew = _newAttachment isNotEqualTo ""; private _removeOld = _oldAttachment isNotEqualTo ""; @@ -38,22 +43,33 @@ if (_removeOld && {!([_unit, _oldAttachment] call CBA_fnc_canAddItem)}) exitWith }; }; +[_unit, "Gear"] call EFUNC(common,doGesture); + 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;}; + params ["_unit", "_currWeaponType", "_oldAttachment"]; + + switch (_currWeaponType) do { + case 0: {_unit removePrimaryWeaponItem _oldAttachment}; + case 1: {_unit removeSecondaryWeaponItem _oldAttachment}; + case 2: {_unit removeHandgunItem _oldAttachment}; + default {}; }; + _unit addItem _oldAttachment; - }, [_unit, _weapon, _oldAttachment], 0.3] call CBA_fnc_waitAndExecute; + }, [_unit, _currWeaponType, _oldAttachment], 0.3] call CBA_fnc_waitAndExecute; }; if (!_addNew) exitWith {}; [{ params ["_unit", "_weapon", "_newAttachment"]; + _unit addWeaponItem [_weapon, _newAttachment]; + + if (_unit != ACE_player) exitWith {}; + [[getText (configFile >> "CfgWeapons" >> _newAttachment >> "picture"), 4], true] call CBA_fnc_notify; + + playSound "click"; }, [_unit, _weapon, _newAttachment], 1] call CBA_fnc_waitAndExecute; diff --git a/addons/interaction/groupRename_GUI.hpp b/addons/interaction/groupRename_GUI.hpp index 20684b0e463..977b9b3efda 100644 --- a/addons/interaction/groupRename_GUI.hpp +++ b/addons/interaction/groupRename_GUI.hpp @@ -1,4 +1,4 @@ -#define FONT_H (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1) +#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) diff --git a/addons/interaction/initSettings.inc.sqf b/addons/interaction/initSettings.inc.sqf index b502ed36b00..f634b44313f 100644 --- a/addons/interaction/initSettings.inc.sqf +++ b/addons/interaction/initSettings.inc.sqf @@ -6,6 +6,14 @@ true ] call CBA_fnc_addSetting; +[ + QGVAR(remoteTeamManagement), "CHECKBOX", + [LSTRING(remoteTeamManagement_DisplayName), LSTRING(remoteTeamManagement_Description)], + format ["ACE %1", LLSTRING(DisplayName)], + true, + true +] call CBA_fnc_addSetting; + [ QGVAR(enableMagazinePassing), "CHECKBOX", LSTRING(PassMagazineSetting), @@ -20,7 +28,7 @@ false, true, {[QGVAR(disableNegativeRating), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -38,6 +46,16 @@ true ] call CBA_fnc_addSetting; +[ + QGVAR(enableAnimActions), "CHECKBOX", + LSTRING(SettingAnimActionsName), + format ["ACE %1", LLSTRING(DisplayName)], + true, + true, + {[QGVAR(enableAnimActions), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + [ QGVAR(interactWithTerrainObjects), "CHECKBOX", ["str_a3_modules_moduleomquest_defend_f_attributes_useterrainobject0", LSTRING(interactWithTerrainObjects_Description)], @@ -45,3 +63,11 @@ false, true ] call CBA_fnc_addSetting; + +[ + QGVAR(interactWithEnemyCrew), "LIST", + [LSTRING(interactWithEnemyCrew_DisplayName), LSTRING(interactWithEnemyCrew_Description)], + format ["ACE %1", LLSTRING(DisplayName)], + [[0, 1, 2], [ELSTRING(common,Never), LSTRING(interactWithEnemyCrew_allowCSW), ELSTRING(common,Always)], 0], + true +] call CBA_fnc_addSetting; diff --git a/addons/interaction/stringtable.xml b/addons/interaction/stringtable.xml index 41861dcb31f..35633463593 100644 --- a/addons/interaction/stringtable.xml +++ b/addons/interaction/stringtable.xml @@ -164,7 +164,7 @@ Cselekvő menü Menu de Interação Menù Interazioni - インタラクションメニュー + インタラクション メニュー 상호작용 메뉴 互动菜单 互動選單 @@ -181,7 +181,7 @@ Cselekvő menü (saját) Menu de Interação (Individual) Menù Interazioni (su se stesso) - インタラクションメニュー (セルフ) + インタラクション メニュー (セルフ) 상호작용 메뉴(자신) 互动菜单(自我) 互動選單 (自我) @@ -283,7 +283,7 @@ Csatlakozás a csoporthoz Unir-se ao grupo Unisciti alla squadra - グループに入る + グループに参加 그룹 참여 加入小队 加入小隊 @@ -373,7 +373,7 @@ TÁNC! DANCE! DANZA! - おどれ! + 踊ろう! 춤추기! 跳舞 跳舞 @@ -458,7 +458,7 @@ Вас похлопали по ПРАВОМУ плечу Você foi tocado no ombro Ti è stato dato un colpetto sulla spalla destra - 右肩を叩かれました + 右肩を叩かれた 누군가 오른쪽 어깨를 쳤다 你的右肩膀被轻拍了一下 你的右肩膀被輕拍了一下 @@ -475,7 +475,7 @@ Вас похлопали по ЛЕВОМУ плечу Você foi tocado no ombro. Ti è stato dato un colpetto sulla spalla sinistra - 左肩を叩かれました + 左肩を叩かれた 누군가 왼쪽 어깨를 쳤다 你的左肩膀被轻拍了一下 你的左肩膀被輕拍了一下 @@ -582,6 +582,40 @@ 小隊管理 Takım Yönetimi + + Remote Squad Management + Gestion à distance de l'escouade + Дистанционное управление отрядом + 遠隔分隊管理 + 분대 원격 관리 + Gestione squadra da remoto + Gestión Remota de Escuadra + + + Allow dropping and changing team colors of any unit in player's squad + Permettre d'abandonner et de changer les couleurs de n'importe quelle unité de l'escouade du joueur + Позволяет сбрасывать и менять командные цвета любого подразделения в отряде игрока + プレイヤー分隊内の任意のユニットにチームからの脱退と色の変更を許可します + 플레이어 분대의 모든 유닛을 삭제하고 팀 색상 변경하는 것을 허용합니다. + Permetti di cambiare il colore o rimuovere una qualsiasi unità della propria squadra + Permite abandonar y cambiar el color del equipo de cualquier unidad en la escuadra del jugador + + + Squad + Družstvo + Trupp + Отряд + Drużyna + Squadra + Escuadrón + Escouade + 分隊 + 分隊 + 분대 + Esquadrão + 小队 + Manga + Red Rot @@ -729,7 +763,7 @@ Присоединиться к Красной группе Rejoindre rouge Unirsi al team rosso - レッドに入る + レッドに参加 빨강에 참여 加入红组 加入紅組 @@ -746,7 +780,7 @@ Присоединиться к Зеленой группе Rejoindre vert Unirsi al team verde - グリーンに入る + グリーンに参加 초록에 참여 加入绿组 加入綠組 @@ -763,7 +797,7 @@ Присоединиться к Синей группе Rejoindre bleu Unirsi al team blu - ブルーに入る + ブルーに参加 파랑에 참여 加入蓝组 加入藍組 @@ -780,12 +814,25 @@ Присоединиться к Жёлтой группе Rejoindre jaune Unirsi al team giallo - イエローに入る + イエローに参加 노랑에 참여 加入黄组 加入黃組 Sarıya Katıl + + Join White + Weiss beitreten + Unirse a Blanco + Dołącz do Biała + Entrar em Branco + Připojit k Bílý Tým + Присоединиться к Белая + Rejoindre Blanc + Unirsi al team Bianco + 백팀 참여 + ホワイトに参加 + You joined Team %1 Du bist Gruppe %1 beigetreten @@ -797,7 +844,7 @@ Você uniu-se à Equipe %1 Sei entrato nel team %1 Csatlakoztál a %1 csapathoz - チーム %1 に入りました + チーム %1 に参加しました 당신은 %1팀에 참여했습니다 你已加入%1组 你已加入%1組 @@ -848,7 +895,7 @@ Perdão Perdona Megbocsátás - 許す + 赦免する 허용 原谅 原諒 @@ -1060,7 +1107,7 @@ Disable negative rating Negative Bewertung deaktivieren - 否定評価を無効化 + ネガティブな評価を無効化 Impedisci Valutazione Negativa 關閉負面評價 关闭负面评价 @@ -1075,7 +1122,7 @@ Should players receive negative rating? When enabled players are only receiving positive ratings which prevents friendly AI fire when destroying friendly equipment or killing team members. Sollen Spieler negative Bewertungen erhalten dürfen? Wenn diese Option aktiviert ist, erhalten Spieler nur positive Bewertungen, was Freundbeschuss durch KI verhindert, wenn befreundete Ausrüstung zerstört oder befreundete Einheiten von Spielern des selben Teams getötet werden. - 否定評価を受けますか?有効化した場合プレイヤーは肯定評価のみを受け、友軍の装備を壊したり殺害をしてもAIからの攻撃を防ぎます。 + プレイヤーはネガティブな評価を受けるべきですか? これを有効化すると、プレイヤーはポジティブな評価のみ受けるようになり、仮に味方の兵器を破壊したり、友軍兵士を殺害したとしても、友軍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、毁坏友军装备或杀害小队伙伴都不会收到负面评价。 @@ -1208,7 +1255,7 @@ Mostra l'interazione "passa caricatore" Mostrar "Pasar cargador" en el menú de interacción Montrer l'interaction "Passer un chargeur" - "弾倉を渡す"をインタラクションに表示 + 弾倉を渡すをインタラクションに表示 '탄창 건네기'를 상호작용에서 보여줌 显示"给予弹匣"互动动作 顯示"給予彈匣"互動動作 @@ -1237,7 +1284,7 @@ Выбить лобовое стекло Wyłam szybę Szélvédő széttörése - フロントガラスを破る + 風防を破る Sfonda il parabrezza Quebrar pára-brisa 踹開擋風玻璃 @@ -1247,30 +1294,30 @@ 전면유리 부수기 - Attach %1 - Установить %1 - %1 を取り付け - Acoplar %1 - Fixer %1 - Przyczep %1 - Befestige %1 - Attacca %1 - 附加 %1 - %1 붙이기 - Fixar %1 + Attach + Установить + を取り付け + Acoplar + Fixer + Przyczep + Befestige + Attacca + 附加 + 붙이기 + Fixar - Detach %1 - Снять %1 - %1 を外す - Desacoplar %1 - Retirer %1 - Odczep %1 - Löse %1 - Stacca %1 - 拆卸 %1 - %1 떼내기 - Desfixar %1 + Detach + Снять + を外す + Desacoplar + Retirer + Odczep + Löse + Stacca + 拆卸 + 떼내기 + Desfixar Enables attach/detach weapon attachment actions for current weapon. @@ -1324,5 +1371,41 @@ Advertencia: puede provocar que algunos objetos choquen con otros. Aviso: pode causar que alguns objetos colidam com outros. + + Interaction with animations + Взаимодействие с анимациями + Interaction avec les animations + 車両アニメーションベースのインタラクション + 애니메이션 있는 상호작용 + Interazione con animazioni + Interacción con animaciones + + + Interact With Enemy Crew + 敵乗員がいる状態でのインタラクト + Interagir avec l'équipage ennemi + Взаимодействие с вражеским экипажем + 적 승무원과의 상호작용 + Interazioni con equipaggio nemico + Interactuar Con Tripulación Enemiga + + + Limit some interactions on vehicles crewed by enemy factions. + 敵性力の乗員が乗っている車両へのインタラクションを一部制限します。 + Limiter certaines interactions sur les véhicules dont l'équipage appartient à des factions ennemies. + Ограничьте некоторые взаимодействия на транспортных средствах, управляемых вражеской стороной. + 적 진영이 탑승한 차량과의 일부 상호작용을 제한합니다. + Limita alcune interazioni su veicoli con nemici a bordo. + Limita algunas interacciones en vehículos tripulador por facciones enemigas. + + + Allow for Static Weapons + 固定火器での許可 + Autoriser les armes statiques + Разрешить использование статического оружия + 고정화기 허용 + Permetti con armi statiche + Permitir para Armas Estáticas + diff --git a/addons/inventory/RscDisplayInventory.hpp b/addons/inventory/RscDisplayInventory.hpp index 91e68f5fb1c..06752dcfec5 100644 --- a/addons/inventory/RscDisplayInventory.hpp +++ b/addons/inventory/RscDisplayInventory.hpp @@ -17,13 +17,13 @@ class RscStructuredText; class RscActiveText; class RscCombo; -#define X_BIS(num) (num * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)) -#define Y_BIS(num) (num * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)) -#define W_BIS(num) (num * (((safezoneW / safezoneH) min 1.2) / 40)) -#define H_BIS(num) (num * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)) +#define X_BIS(num) (num * (((safeZoneW / safeZoneH) min 1.2) / 40) + (safeZoneX + (safeZoneW - ((safeZoneW / safeZoneH) min 1.2))/2)) +#define Y_BIS(num) (num * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25) + (safeZoneY + (safeZoneH - (((safeZoneW / safeZoneH) min 1.2) / 1.2))/2)) +#define W_BIS(num) (num * (((safeZoneW / safeZoneH) min 1.2) / 40)) +#define H_BIS(num) (num * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)) -#define X_MAKEITBIGGA(num) (num * (safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2)) -#define Y_MAKEITBIGGA(num) (num * (safeZoneH / 30) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2)) +#define X_MAKEITBIGGA(num) (num * (safeZoneH / 40) + (safeZoneX + (safeZoneW - safeZoneH)/2)) +#define Y_MAKEITBIGGA(num) (num * (safeZoneH / 30) + (safeZoneY + (safeZoneH - (safeZoneH / 1.2))/2)) #define W_MAKEITBIGGA(num) (num * (safeZoneH / 40)) #define H_MAKEITBIGGA(num) (num * (safeZoneH / 30)) diff --git a/addons/inventory/XEH_preStart.sqf b/addons/inventory/XEH_preStart.sqf index cc01ae5ef39..a9a634ab5a5 100644 --- a/addons/inventory/XEH_preStart.sqf +++ b/addons/inventory/XEH_preStart.sqf @@ -29,7 +29,7 @@ uiNamespace setVariable [QGVAR(backpackKeyCache), compileFinal createHashMapFrom }; // Listboxes store pictures as lowercase - [format ["%1:%2", _displayName, toLower _picture], _x] + [format ["%1:%2", _displayName, toLowerANSI _picture], _x] })]; // Generate list of grenades diff --git a/addons/inventory/functions/fnc_forceItemListUpdate.sqf b/addons/inventory/functions/fnc_forceItemListUpdate.sqf index fb8f09b5c84..ede73b01519 100644 --- a/addons/inventory/functions/fnc_forceItemListUpdate.sqf +++ b/addons/inventory/functions/fnc_forceItemListUpdate.sqf @@ -29,9 +29,9 @@ private _itemKeyCache = uiNamespace getVariable QGVAR(itemKeyCache); private _backpackKeyCache = uiNamespace getVariable QGVAR(backpackKeyCache); private _config = configNull; -for "_i" from (lbSize _itemList) to 0 step -1 do { +for "_i" from (lbSize _itemList) - 1 to 0 step -1 do { // All items have their classnames in lbData, except backpacks - _className = _itemList lbData _i; + private _className = _itemList lbData _i; _config = if (_className != "") then { _itemKeyCache get _className diff --git a/addons/irlight/XEH_PREP.hpp b/addons/irlight/XEH_PREP.hpp index db1a29d22e1..83c619aab87 100644 --- a/addons/irlight/XEH_PREP.hpp +++ b/addons/irlight/XEH_PREP.hpp @@ -1,3 +1 @@ -PREP(getGlowOffset); PREP(initItemContextMenu); -PREP(onLightToggled); diff --git a/addons/irlight/XEH_postInit.sqf b/addons/irlight/XEH_postInit.sqf index 47763b8414f..77b98936c19 100644 --- a/addons/irlight/XEH_postInit.sqf +++ b/addons/irlight/XEH_postInit.sqf @@ -1,30 +1,27 @@ #include "script_component.hpp" -[] call FUNC(initItemContextMenu); - -addUserActionEventHandler ["headlights", "Deactivate", FUNC(onLightToggled)]; +call FUNC(initItemContextMenu); ["ACE3 Equipment", QGVAR(hold), LLSTRING(MomentarySwitch), { - ACE_player action ["GunLightOn", ACE_player]; - ACE_player action ["IRLaserOn", ACE_player]; - [] call FUNC(onLightToggled); + if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {}; + + // Save current weapon state to reapply later + private _weaponState = (weaponState ACE_player) select [0, 3]; + + action ["GunLightOn", ACE_player]; + action ["IRLaserOn", ACE_player]; + + ACE_player selectWeapon _weaponState; + true }, { - ACE_player action ["GunLightOff", ACE_player]; - ACE_player action ["IRLaserOff", ACE_player]; - [] call FUNC(onLightToggled); - true -}] call CBA_fnc_addKeybind; + if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {}; + + // Save current weapon state to reapply later + private _weaponState = (weaponState ACE_player) select [0, 3]; -["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; + action ["GunLightOff", ACE_player]; + action ["IRLaserOff", ACE_player]; + + ACE_player selectWeapon _weaponState; +}] call CBA_fnc_addKeybind; diff --git a/addons/irlight/functions/fnc_getGlowOffset.sqf b/addons/irlight/functions/fnc_getGlowOffset.sqf deleted file mode 100644 index 613e551111c..00000000000 --- a/addons/irlight/functions/fnc_getGlowOffset.sqf +++ /dev/null @@ -1,41 +0,0 @@ -#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 index fa75eba77be..75a9508b180 100644 --- a/addons/irlight/functions/fnc_initItemContextMenu.sqf +++ b/addons/irlight/functions/fnc_initItemContextMenu.sqf @@ -10,7 +10,7 @@ * None * * Example: - * [] call ace_irlight_fnc_initItemContextMenu + * call ace_irlight_fnc_initItemContextMenu * * Public: No */ @@ -19,30 +19,34 @@ _x params ["_variant", "_displayName"]; [ - "ACE_DBAL_A3_Red", "POINTER", _displayName, [], "", { + "ACE_DBAL_A3_Red", + "POINTER", + _displayName, + [], + "", + { params ["", "", "_item", "", "_variant"]; private _baseClass = getText (configFile >> "CfgWeapons" >> _item >> "baseWeapon"); _item != _baseClass + _variant }, { - params ["", "", "_item", "", "_variant"]; + params ["_unit", "", "_item", "_slot", "_variant"]; - private _baseClass = getText (configFile >> "CfgWeapons" >> _item >> "baseWeapon"); + private _weapon = switch (_slot) do { + case "RIFLE_POINTER": {primaryWeapon _unit}; + case "LAUNCHER_POINTER": {secondaryWeapon _unit}; + case "PISTOL_POINTER": {handgunWeapon _unit}; + default {""}; + }; - ACE_player removePrimaryWeaponItem _item; - ACE_player addPrimaryWeaponItem (_baseClass + _variant); - playSound "click"; + if (_weapon == "") exitWith {}; - if (_turnedOn) then { - // Force update of flashlight - ACE_player action ["GunLightOff", ACE_player]; + private _baseClass = getText (configFile >> "CfgWeapons" >> _item >> "baseWeapon"); - { - ACE_player action ["GunLightOn", ACE_player]; - ACE_player action ["IRLaserOn", ACE_player]; - } call CBA_fnc_execNextFrame; - }; - }, false, _variant + [_unit, _weapon, _item, _baseClass + _variant] call EFUNC(common,switchAttachmentMode); + }, + false, + _variant ] call CBA_fnc_addItemContextMenuOption; } forEach [ ["", LSTRING(Mode_IRDual)], diff --git a/addons/irlight/functions/fnc_onLightToggled.sqf b/addons/irlight/functions/fnc_onLightToggled.sqf deleted file mode 100644 index b3592f28f60..00000000000 --- a/addons/irlight/functions/fnc_onLightToggled.sqf +++ /dev/null @@ -1,36 +0,0 @@ -#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/stringtable.xml b/addons/irlight/stringtable.xml index ab70abdebd8..506e9deb9da 100644 --- a/addons/irlight/stringtable.xml +++ b/addons/irlight/stringtable.xml @@ -11,17 +11,19 @@ DBAL-A3 (vermelho) DBAL-A3 (赤) DBAL-A3 (красный) + DBAL-A3 (rojo) DBAL-A3 (green) - DBAL-A3 (grün) + DBAL-A3 (Grün) DBAL-A3 (Verde) - DBAL-A3 (zielony) + DBAL-A3 (Zielony) DBAL-A3 (녹색) - DBAL-A3 (vert) - DBAL-A3 (verde) + 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 @@ -33,6 +35,7 @@ <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 @@ -44,6 +47,7 @@ Laser de Pontaria de Duplo Feixe 複合ビーム照準レーザー Двухлучевой прицельный лазер + Láser de Apuntado de Doble Haz Visible Laser @@ -55,6 +59,7 @@ Laser Visível 可視光レーザー Видимый лазер + Láser Visible IR Laser @@ -66,6 +71,7 @@ Laser IR IRレーザー ИК-лазер + Láser IR IR Illuminator @@ -77,6 +83,7 @@ Iluminador IR IRイルミネーター ИК-осветитель + Iluminador IR IR Laser and Illuminator @@ -88,6 +95,7 @@ Laser e Iluminador IR IRレーザーとイルミネーター ИК-лазер и осветитель + Láser e Iluminador IR Wide Beam @@ -99,6 +107,7 @@ Feixe Largo 広角ビーム Широкий луч + Haz Ancho Medium Beam @@ -110,6 +119,7 @@ Feixe Médio 標準ビーム Средний луч + Haz Medio Narrow Beam @@ -121,6 +131,7 @@ Feixe Estreito 狭角ビーム Узкий луч + Haz Estrecho <t color='#9cf953'>Use: </t>Turn Light ON/OFF<br>Double click to switch mode @@ -132,6 +143,7 @@ <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 @@ -143,6 +155,7 @@ Iluminador LED IR de Uso Especial 特殊用途のIR LEDイルミネーター ИК-светодиодный осветитель специального назначения + Iluminador LED IR de Propósito Especial Illuminator / Laser Momentary Switch @@ -154,6 +167,7 @@ Interruptor Momentâneo Iluminador/Laser イルミネーター/レーザーモーメンタリースイッチ Мгновенный переключатель осветителя/лазера + Conmutador Momentáneo Iluminador / Láser diff --git a/addons/javelin/functions/fnc_getTarget.sqf b/addons/javelin/functions/fnc_getTarget.sqf index 6fd4686eb8d..926e400a18b 100644 --- a/addons/javelin/functions/fnc_getTarget.sqf +++ b/addons/javelin/functions/fnc_getTarget.sqf @@ -20,8 +20,8 @@ params ["_lastTarget", "_maxRange"]; scopeName "main"; -private _viewASL = AGLtoASL positionCameraToWorld [0,0,0]; -private _viewDir = _viewASL vectorFromTo (AGLtoASL positionCameraToWorld [0,0,1]); +private _viewASL = AGLToASL positionCameraToWorld [0,0,0]; +private _viewDir = _viewASL vectorFromTo (AGLToASL positionCameraToWorld [0,0,1]); // Attempt to lock onto current target if it is still valid if (!isNull _lastTarget) then { @@ -65,7 +65,7 @@ if ((cursorTarget isKindOf "AllVehicles") && {(cursorObject distance ace_player) // Attempt to scan using multiple rayscasts - This is expensive (n^2) and care should be given to balance accuracy vs speed for "_xOffset" from -14 to 14 step 2 do { for "_yOffset" from -12 to 12 step 4 do { - private _testPosASL = AGLtoASL (positionCameraToWorld [_xOffset, _yOffset, _maxRange]); + 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 isNotEqualTo []) then { diff --git a/addons/javelin/functions/fnc_mapHelperDraw.sqf b/addons/javelin/functions/fnc_mapHelperDraw.sqf index 4f7ac84b4a6..e8b917a933e 100644 --- a/addons/javelin/functions/fnc_mapHelperDraw.sqf +++ b/addons/javelin/functions/fnc_mapHelperDraw.sqf @@ -25,7 +25,7 @@ if (isNil QGVAR(arguments)) then { _currentShooter setVariable ["ace_missileguidance_target", nil, false]; GVAR(arguments) = [ - diag_frameno, // Last run frame + diag_frameNo, // Last run frame objNull, // currentTargetObject 0, // Lock Start Time 0, // Next Sound timer @@ -37,7 +37,7 @@ if (isNil QGVAR(arguments)) then { [{ if (isNull (uiNamespace getVariable ["ACE_RscOptics_javelin", displayNull])) exitWith {true}; GVAR(arguments) params ["_lastRunFrame"]; - (diag_frameno < _lastRunFrame) || {diag_frameno > (_lastRunFrame + 1)} + (diag_frameNo < _lastRunFrame) || {diag_frameNo > (_lastRunFrame + 1)} }, { TRACE_1("old/null display - ending optic draw",_this); private _fireDisabledEH = GVAR(arguments) param [4, -1]; diff --git a/addons/javelin/functions/fnc_onOpticDraw.sqf b/addons/javelin/functions/fnc_onOpticDraw.sqf index aacc4f5fa1f..9dfb7d2e484 100644 --- a/addons/javelin/functions/fnc_onOpticDraw.sqf +++ b/addons/javelin/functions/fnc_onOpticDraw.sqf @@ -53,7 +53,7 @@ if ((_ammoCount == 0) || // No ammo loaded __JavelinIGUISeek ctrlSetTextColor __ColorGray; _fireDisabledEH = [_fireDisabledEH] call FUNC(enableFire); - _this set [0, diag_frameno]; + _this set [0, diag_frameNo]; _this set [4, _fireDisabledEH]; // Fix weapon being in top-attack when loading AP magazine (https://feedback.bistudio.com/T171012) @@ -194,7 +194,7 @@ if (isNull _newTarget) then { }; // Save arguments for next run -_this set [0, diag_frameno]; +_this set [0, diag_frameNo]; _this set [1, _currentTarget]; _this set [2, _lockStartTime]; _this set [3, _soundNextPlayTime]; diff --git a/addons/javelin/functions/fnc_showFireMode.sqf b/addons/javelin/functions/fnc_showFireMode.sqf index 85ed9837185..a3315188f1f 100644 --- a/addons/javelin/functions/fnc_showFireMode.sqf +++ b/addons/javelin/functions/fnc_showFireMode.sqf @@ -14,11 +14,12 @@ * * Public: No */ +//IGNORE_PRIVATE_WARNING ["_currentShooter"]; // from upper scope (if (((vehicle ACE_player) == ACE_player) || {ACE_player call CBA_fnc_canUseWeapon}) then { weaponState ACE_player } else { - _turretPath = if (ACE_player == (driver _currentShooter)) then {[-1]} else {ACE_player call CBA_fnc_turretPath}; + private _turretPath = if (ACE_player == (driver _currentShooter)) then {[-1]} else {ACE_player call CBA_fnc_turretPath}; weaponState [vehicle ACE_player, _turretPath] }) params ["_weapon", "", "_mode"]; diff --git a/addons/javelin/script_component.hpp b/addons/javelin/script_component.hpp index 3e9ad4ebfc1..b5cf7bea3ce 100644 --- a/addons/javelin/script_component.hpp +++ b/addons/javelin/script_component.hpp @@ -18,7 +18,7 @@ // Javelin IGUI defines -#define __JavelinIGUI (uinamespace getVariable "ACE_RscOptics_javelin") +#define __JavelinIGUI (uiNamespace getVariable "ACE_RscOptics_javelin") // Custom controls #define __JavelinIGUITargeting (__JavelinIGUI displayCtrl 6999) diff --git a/addons/kestrel4500/RscTitles.hpp b/addons/kestrel4500/RscTitles.hpp index faae6a8f32b..ffb44de9132 100644 --- a/addons/kestrel4500/RscTitles.hpp +++ b/addons/kestrel4500/RscTitles.hpp @@ -64,7 +64,7 @@ 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"; @@ -74,7 +74,7 @@ class Kestrel4500_Display { }; 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"; @@ -83,7 +83,7 @@ class Kestrel4500_Display { }; 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,13 +115,13 @@ 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"; @@ -129,13 +129,13 @@ class Kestrel4500_Display { }; 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; @@ -236,7 +236,7 @@ class RscTitles { font="TahomaB"; 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"; @@ -246,7 +246,7 @@ class RscTitles { }; 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"; diff --git a/addons/kestrel4500/config.cpp b/addons/kestrel4500/config.cpp index 5ea15f07ffe..fc339ccf6b0 100644 --- a/addons/kestrel4500/config.cpp +++ b/addons/kestrel4500/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {"ACE_Item_Kestrel4500"}; weapons[] = {"ACE_Kestrel4500"}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ACE_common", "ACE_weather"}; + requiredAddons[] = {"ace_common", "ace_weather"}; author = ECSTRING(common,ACETeam); authors[] = {ECSTRING(common,ACETeam), "Ruthberg"}; url = ECSTRING(main,URL); diff --git a/addons/kestrel4500/functions/fnc_generateOutputData.sqf b/addons/kestrel4500/functions/fnc_generateOutputData.sqf index 59bb3056dd1..1aeac9a182a 100644 --- a/addons/kestrel4500/functions/fnc_generateOutputData.sqf +++ b/addons/kestrel4500/functions/fnc_generateOutputData.sqf @@ -89,7 +89,7 @@ if (GVAR(referenceHeadingMenu) == 0) then { private _monthString = localize (["str_january","str_february","str_march","str_april","str_may","str_june","str_july","str_august","str_september","str_october","str_november","str_december"] select (_month - 1)); _textTop = _dayString; _textCenter = format["%1 %2 %3", _day, _monthString, _year]; - _textBottomBig = [daytime, "HH:MM:SS"] call bis_fnc_timeToString; + _textBottomBig = [dayTime, "HH:MM:SS"] call bis_fnc_timeToString; }; case 1: { // Direction if (!GVAR(MinAvgMax)) then { @@ -105,7 +105,7 @@ if (GVAR(referenceHeadingMenu) == 0) then { }; case 2: { // Wind SPD if (!GVAR(MinAvgMax)) then { - _textCenterBig = Str(round(_windSpeed * 10) / 10); + _textCenterBig = str(round(_windSpeed * 10) / 10); } else { _textCenterLine1Left = "Max"; _textCenterLine2Left = "Avg"; @@ -116,13 +116,13 @@ if (GVAR(referenceHeadingMenu) == 0) then { _textInfoLine2 = "- average"; }; case 1: { - _textCenterLine1Right = Str(round((GVAR(Max) select 2) * 10) / 10); - _textCenterLine2Right = Str(round((GVAR(Total) select 2) / (GVAR(Entries) select 2) * 10) / 10); + _textCenterLine1Right = str(round((GVAR(Max) select 2) * 10) / 10); + _textCenterLine2Right = str(round((GVAR(Total) select 2) / (GVAR(Entries) select 2) * 10) / 10); _textInfoLine2 = "- stop"; }; case 2: { - _textCenterLine1Right = Str(round((GVAR(Max) select 2) * 10) / 10); - _textCenterLine2Right = Str(round((GVAR(Total) select 2) / (GVAR(Entries) select 2) * 10) / 10); + _textCenterLine1Right = str(round((GVAR(Max) select 2) * 10) / 10); + _textCenterLine2Right = str(round((GVAR(Total) select 2) / (GVAR(Entries) select 2) * 10) / 10); _textInfoLine2 = "- clear"; }; }; @@ -131,10 +131,10 @@ if (GVAR(referenceHeadingMenu) == 0) then { case 3: { // CROSSWIND if (!GVAR(MinAvgMax)) then { if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { - _textCenterBig = Str(round(abs(sin(GVAR(RefHeading) - _playerDir) * _windSpeed) * 10) / 10); + _textCenterBig = str(round(abs(sin(GVAR(RefHeading) - _playerDir) * _windSpeed) * 10) / 10); _textInfoLine1 = format["%1 m/s @ %2", round(_windSpeed * 10) / 10, round(_playerDir)]; } else { - _textCenterBig = Str(round(abs(sin(GVAR(RefHeading) - _windDir) * _windSpeed) * 10) / 10); + _textCenterBig = str(round(abs(sin(GVAR(RefHeading) - _windDir) * _windSpeed) * 10) / 10); _textInfoLine1 = format["%1 m/s @ %2", round(_windSpeed * 10) / 10, round(180 + _windDir)]; }; _textInfoLine2 = "- set heading"; @@ -148,13 +148,13 @@ if (GVAR(referenceHeadingMenu) == 0) then { _textInfoLine2 = "- average"; }; case 1: { - _textCenterLine1Right = Str(round((GVAR(Max) select 3) * 10) / 10); - _textCenterLine2Right = Str(round((GVAR(Total) select 3) / (GVAR(Entries) select 3) * 10) / 10); + _textCenterLine1Right = str(round((GVAR(Max) select 3) * 10) / 10); + _textCenterLine2Right = str(round((GVAR(Total) select 3) / (GVAR(Entries) select 3) * 10) / 10); _textInfoLine2 = "- stop"; }; case 2: { - _textCenterLine1Right = Str(round((GVAR(Max) select 3) * 10) / 10); - _textCenterLine2Right = Str(round((GVAR(Total) select 3) / (GVAR(Entries) select 3) * 10) / 10); + _textCenterLine1Right = str(round((GVAR(Max) select 3) * 10) / 10); + _textCenterLine2Right = str(round((GVAR(Total) select 3) / (GVAR(Entries) select 3) * 10) / 10); _textInfoLine2 = "- clear"; }; }; @@ -163,10 +163,10 @@ if (GVAR(referenceHeadingMenu) == 0) then { case 4: { // HEADWIND if (!GVAR(MinAvgMax)) then { if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { - _textCenterBig = Str(round(cos(GVAR(RefHeading) - _playerDir) * _windSpeed * 10) / 10); + _textCenterBig = str(round(cos(GVAR(RefHeading) - _playerDir) * _windSpeed * 10) / 10); _textInfoLine1 = format["%1 m/s @ %2", round(_windSpeed * 10) / 10, round(_playerDir)]; } else { - _textCenterBig = Str(round(-cos(GVAR(RefHeading) - _windDir) * _windSpeed * 10) / 10); + _textCenterBig = str(round(-cos(GVAR(RefHeading) - _windDir) * _windSpeed * 10) / 10); _textInfoLine1 = format["%1 m/s @ %2", round(_windSpeed * 10) / 10, round(180 + _windDir)]; }; _textInfoLine2 = "- set heading"; @@ -180,13 +180,13 @@ if (GVAR(referenceHeadingMenu) == 0) then { _textInfoLine2 = "- average"; }; case 1: { - _textCenterLine1Right = Str(round((GVAR(Max) select 4) * 10) / 10); - _textCenterLine2Right = Str(round((GVAR(Total) select 4) / (GVAR(Entries) select 4) * 10) / 10); + _textCenterLine1Right = str(round((GVAR(Max) select 4) * 10) / 10); + _textCenterLine2Right = str(round((GVAR(Total) select 4) / (GVAR(Entries) select 4) * 10) / 10); _textInfoLine2 = "- stop"; }; case 2: { - _textCenterLine1Right = Str(round((GVAR(Max) select 4) * 10) / 10); - _textCenterLine2Right = Str(round((GVAR(Total) select 4) / (GVAR(Entries) select 4) * 10) / 10); + _textCenterLine1Right = str(round((GVAR(Max) select 4) * 10) / 10); + _textCenterLine2Right = str(round((GVAR(Total) select 4) / (GVAR(Entries) select 4) * 10) / 10); _textInfoLine2 = "- clear"; }; }; @@ -194,124 +194,124 @@ if (GVAR(referenceHeadingMenu) == 0) then { }; case 5: { // TEMP if (!GVAR(MinAvgMax)) then { - _textCenterBig = Str(round(_temperature * 10) / 10); + _textCenterBig = str(round(_temperature * 10) / 10); } else { _textCenterLine1Left = "Min"; _textCenterLine2Left = "Avg"; _textCenterLine3Left = "Max"; - _textCenterLine1Right = Str(round((GVAR(Min) select 5) * 10) / 10); - _textCenterLine2Right = Str(round((GVAR(Total) select 5) / (GVAR(Entries) select 5) * 10) / 10); - _textCenterLine3Right = Str(round((GVAR(Max) select 5) * 10) / 10); + _textCenterLine1Right = str(round((GVAR(Min) select 5) * 10) / 10); + _textCenterLine2Right = str(round((GVAR(Total) select 5) / (GVAR(Entries) select 5) * 10) / 10); + _textCenterLine3Right = str(round((GVAR(Max) select 5) * 10) / 10); }; }; case 6: { // CHILL if (!GVAR(MinAvgMax)) then { - _textCenterBig = Str(round(_chill * 10) / 10); + _textCenterBig = str(round(_chill * 10) / 10); } else { _textCenterLine1Left = "Min"; _textCenterLine2Left = "Avg"; _textCenterLine3Left = "Max"; - _textCenterLine1Right = Str(round((GVAR(Min) select 6) * 10) / 10); - _textCenterLine2Right = Str(round((GVAR(Total) select 6) / (GVAR(Entries) select 6) * 10) / 10); - _textCenterLine3Right = Str(round((GVAR(Max) select 6) * 10) / 10); + _textCenterLine1Right = str(round((GVAR(Min) select 6) * 10) / 10); + _textCenterLine2Right = str(round((GVAR(Total) select 6) / (GVAR(Entries) select 6) * 10) / 10); + _textCenterLine3Right = str(round((GVAR(Max) select 6) * 10) / 10); }; }; case 7: { // HUMIDITY if (!GVAR(MinAvgMax)) then { - _textCenterBig = Str(round(_humidity * 100 * 10) / 10); + _textCenterBig = str(round(_humidity * 100 * 10) / 10); } else { _textCenterLine1Left = "Min"; _textCenterLine2Left = "Avg"; _textCenterLine3Left = "Max"; - _textCenterLine1Right = Str(round((GVAR(Min) select 7) * 100 * 10) / 10); - _textCenterLine2Right = Str(round((GVAR(Total) select 7) / (GVAR(Entries) select 7) * 100 * 10) / 10); - _textCenterLine3Right = Str(round((GVAR(Max) select 7) * 100 * 10) / 10); + _textCenterLine1Right = str(round((GVAR(Min) select 7) * 100 * 10) / 10); + _textCenterLine2Right = str(round((GVAR(Total) select 7) / (GVAR(Entries) select 7) * 100 * 10) / 10); + _textCenterLine3Right = str(round((GVAR(Max) select 7) * 100 * 10) / 10); }; }; case 8: { // HEAT INDEX if (!GVAR(MinAvgMax)) then { - _textCenterBig = Str(round(_heatIndex * 10) / 10); + _textCenterBig = str(round(_heatIndex * 10) / 10); } else { _textCenterLine1Left = "Min"; _textCenterLine2Left = "Avg"; _textCenterLine3Left = "Max"; - _textCenterLine1Right = Str(round((GVAR(Min) select 8) * 10) / 10); - _textCenterLine2Right = Str(round((GVAR(Total) select 8) / (GVAR(Entries) select 8) * 10) / 10); - _textCenterLine3Right = Str(round((GVAR(Max) select 8) * 10) / 10); + _textCenterLine1Right = str(round((GVAR(Min) select 8) * 10) / 10); + _textCenterLine2Right = str(round((GVAR(Total) select 8) / (GVAR(Entries) select 8) * 10) / 10); + _textCenterLine3Right = str(round((GVAR(Max) select 8) * 10) / 10); }; }; case 9: { // DEW POINT if (!GVAR(MinAvgMax)) then { - _textCenterBig = Str(round(_dewPoint * 10) / 10); + _textCenterBig = str(round(_dewPoint * 10) / 10); } else { _textCenterLine1Left = "Min"; _textCenterLine2Left = "Avg"; _textCenterLine3Left = "Max"; - _textCenterLine1Right = Str(round((GVAR(Min) select 9) * 10) / 10); - _textCenterLine2Right = Str(round((GVAR(Total) select 9) / (GVAR(Entries) select 9) * 10) / 10); - _textCenterLine3Right = Str(round((GVAR(Max) select 9) * 10) / 10); + _textCenterLine1Right = str(round((GVAR(Min) select 9) * 10) / 10); + _textCenterLine2Right = str(round((GVAR(Total) select 9) / (GVAR(Entries) select 9) * 10) / 10); + _textCenterLine3Right = str(round((GVAR(Max) select 9) * 10) / 10); }; }; case 10: { // WET BULB if (!GVAR(MinAvgMax)) then { - _textCenterBig = Str(round(_wetBulb * 10) / 10); + _textCenterBig = str(round(_wetBulb * 10) / 10); } else { _textCenterLine1Left = "Min"; _textCenterLine2Left = "Avg"; _textCenterLine3Left = "Max"; - _textCenterLine1Right = Str(round((GVAR(Min) select 10) * 10) / 10); - _textCenterLine2Right = Str(round((GVAR(Total) select 10) / (GVAR(Entries) select 10) * 10) / 10); - _textCenterLine3Right = Str(round((GVAR(Max) select 10) * 10) / 10); + _textCenterLine1Right = str(round((GVAR(Min) select 10) * 10) / 10); + _textCenterLine2Right = str(round((GVAR(Total) select 10) / (GVAR(Entries) select 10) * 10) / 10); + _textCenterLine3Right = str(round((GVAR(Max) select 10) * 10) / 10); }; }; case 11: { // BARO if (!GVAR(MinAvgMax)) then { - _textCenterBig = Str(round(_barometricPressure * 10) / 10); + _textCenterBig = str(round(_barometricPressure * 10) / 10); } else { _textCenterLine1Left = "Min"; _textCenterLine2Left = "Avg"; _textCenterLine3Left = "Max"; - _textCenterLine1Right = Str(round((GVAR(Min) select 11) * 10) / 10); - _textCenterLine2Right = Str(round((GVAR(Total) select 11) / (GVAR(Entries) select 11) * 10) / 10); - _textCenterLine3Right = Str(round((GVAR(Max) select 11) * 10) / 10); + _textCenterLine1Right = str(round((GVAR(Min) select 11) * 10) / 10); + _textCenterLine2Right = str(round((GVAR(Total) select 11) / (GVAR(Entries) select 11) * 10) / 10); + _textCenterLine3Right = str(round((GVAR(Max) select 11) * 10) / 10); }; }; case 12: { // ALTITUDE if (!GVAR(MinAvgMax)) then { - _textCenterBig = Str(round(EGVAR(common,mapAltitude) + _playerAltitude)); + _textCenterBig = str(round(EGVAR(common,mapAltitude) + _playerAltitude)); } else { _textCenterLine1Left = "Min"; _textCenterLine2Left = "Avg"; _textCenterLine3Left = "Max"; - _textCenterLine1Right = Str(round(GVAR(Min) select 12)); - _textCenterLine2Right = Str(round((GVAR(Total) select 12) / (GVAR(Entries) select 12))); - _textCenterLine3Right = Str(round(GVAR(Max) select 12)); + _textCenterLine1Right = str(round(GVAR(Min) select 12)); + _textCenterLine2Right = str(round((GVAR(Total) select 12) / (GVAR(Entries) select 12))); + _textCenterLine3Right = str(round(GVAR(Max) select 12)); }; }; case 13: { // DENSITY ALTITUDE if (!GVAR(MinAvgMax)) then { - _textCenterBig = Str(round(_densityAltitude)); + _textCenterBig = str(round(_densityAltitude)); } else { _textCenterLine1Left = "Min"; _textCenterLine2Left = "Avg"; _textCenterLine3Left = "Max"; - _textCenterLine1Right = Str(round(GVAR(Min) select 13)); - _textCenterLine2Right = Str(round((GVAR(Total) select 13) / (GVAR(Entries) select 13))); - _textCenterLine3Right = Str(round(GVAR(Max) select 13)); + _textCenterLine1Right = str(round(GVAR(Min) select 13)); + _textCenterLine2Right = str(round((GVAR(Total) select 13) / (GVAR(Entries) select 13))); + _textCenterLine3Right = str(round(GVAR(Max) select 13)); }; }; case 14: { // User Screen 1 - _textCenterLine1Left = Str(round(_playerDir)); - _textCenterLine2Left = Str(round(EGVAR(common,mapAltitude) + _playerAltitude)); - _textCenterLine3Left = Str(round(abs(_windSpeed) * 10) / 10); + _textCenterLine1Left = str(round(_playerDir)); + _textCenterLine2Left = str(round(EGVAR(common,mapAltitude) + _playerAltitude)); + _textCenterLine3Left = str(round(abs(_windSpeed) * 10) / 10); _textCenterLine1Right = GVAR(Directions) select GVAR(Direction); _textCenterLine2Right = "m"; _textCenterLine3Right = "m/s"; }; case 15: { // User Screen 2 - _textCenterLine1Left = Str(round(_temperature * 10) / 10); - _textCenterLine2Left = Str(round(_humidity * 100 * 10) / 10); - _textCenterLine3Left = Str(round((_playerAltitude call EFUNC(weather,calculateBarometricPressure)) * 10) / 10); + _textCenterLine1Left = str(round(_temperature * 10) / 10); + _textCenterLine2Left = str(round(_humidity * 100 * 10) / 10); + _textCenterLine3Left = str(round((_playerAltitude call EFUNC(weather,calculateBarometricPressure)) * 10) / 10); _textCenterLine1Right = "C"; _textCenterLine2Right = "%"; _textCenterLine3Right = "hPA"; @@ -322,7 +322,7 @@ if (GVAR(referenceHeadingMenu) == 0) then { switch (GVAR(referenceHeadingMenu)) do { case 1: { _textCenterLine1 = "MAGNETIC HEADING"; - _textCenterLine2 = Str(round(GVAR(RefHeading))); + _textCenterLine2 = str(round(GVAR(RefHeading))); _textCenterLine3 = "Auto Set "; _textCenterLine4 = "Manual Set "; _textCenterLine5 = "================"; @@ -330,7 +330,7 @@ if (GVAR(referenceHeadingMenu) == 0) then { }; case 2: { _textCenterLine1 = "MAGNETIC HEADING"; - _textCenterLine2 = Str(round(_playerDir)); + _textCenterLine2 = str(round(_playerDir)); _textCenterLine3 = "Point Down the"; _textCenterLine4 = "Runway or Range"; _textCenterLine5 = "================"; @@ -338,7 +338,7 @@ if (GVAR(referenceHeadingMenu) == 0) then { }; case 3: { _textCenterLine1 = "MAGNETIC HEADING"; - _textCenterLine2 = Str(round(GVAR(TmpHeading))); + _textCenterLine2 = str(round(GVAR(TmpHeading))); _textCenterLine3 = "Press < and >"; _textCenterLine4 = "to Adjust"; _textCenterLine5 = "================"; diff --git a/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf b/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf index 9ecbca180cc..756a5418a49 100644 --- a/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf +++ b/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf @@ -15,7 +15,7 @@ * Public: No */ -private _playerDir = getDir ACE_player; +private _playerDir = (ACE_player call CBA_fnc_headDir) select 0; private _windSpeed = vectorMagnitude wind; private _windDir = (wind select 0) atan2 (wind select 1); if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { diff --git a/addons/killtracker/XEH_postInit.sqf b/addons/killtracker/XEH_postInit.sqf index c5adc266924..bf944c930e0 100644 --- a/addons/killtracker/XEH_postInit.sqf +++ b/addons/killtracker/XEH_postInit.sqf @@ -16,10 +16,11 @@ * Public: No */ -if ((getText (missionconfigfile >> "CfgDebriefingSections" >> QUOTE(XADDON) >> "variable")) != QXGVAR(outputText)) exitWith { +if ((getText (missionConfigFile >> "CfgDebriefingSections" >> QUOTE(XADDON) >> "variable")) != QXGVAR(outputText)) exitWith { TRACE_1("no mission debriefing config",_this); }; -if (!(["ace_medical"] call EFUNC(common,isModLoaded))) exitWith { + +if !(GETEGVAR(medical,enabled,false)) exitWith { WARNING("No ACE-Medical"); XGVAR(outputText) = "No ACE-Medical"; }; @@ -64,7 +65,7 @@ GVAR(killCount) = 0; private _killInfo = []; if (!isNull _killer) then { - if (!(_killer isKindof "CAManBase")) then { // If killer is a vehicle log the vehicle type + if !(_killer isKindOf "CAManBase") then { // If killer is a vehicle log the vehicle type _killInfo pushBack format [LLSTRING(Vehicle), getText ((configOf _killer) >> "displayName")]; }; if (isNull _instigator) then { @@ -73,11 +74,11 @@ GVAR(killCount) = 0; }; }; private _unitIsPlayer = hasInterface && {_unit in [player, ace_player]}; // isPlayer check will fail at this point - private _killerIsPlayer = (!isNull _instigator) && {_unit != _instigator} && {[_instigator] call EFUNC(common,isPlayer)}; - TRACE_2("",_unitIsPlayer,_killerIsPlayer); + private _instigatorIsPlayer = (!isNull _instigator) && {_unit != _instigator} && {[_instigator] call EFUNC(common,isPlayer)}; + TRACE_2("",_unitIsPlayer,_instigatorIsPlayer); // Don't do anything if neither are players - if (!(_unitIsPlayer || _killerIsPlayer)) exitWith {}; + if !(_unitIsPlayer || _instigatorIsPlayer) exitWith {}; // Log firendly fire private _fnc_getSideFromConfig = { @@ -89,7 +90,7 @@ GVAR(killCount) = 0; default {civilian}; }; }; - if ((!isNull _instigator) && {_unit != _instigator} && {_instigator isKindOf "CAManBase"}) then { + if (!isNull _instigator && {_unit != _instigator} && {_instigator isKindOf "CAManBase"}) then { // Because of unconscious group switching/captives it's probably best to just use unit's config side private _unitSide = [_unit] call _fnc_getSideFromConfig; private _killerSide = [_instigator] call _fnc_getSideFromConfig; @@ -110,23 +111,23 @@ GVAR(killCount) = 0; // If unit was player then send event to self if (_unitIsPlayer) then { - private _killerName = "Self?"; - if ((!isNull _killer) && {_unit != _killer}) then { - if (_killerIsPlayer) then { - _killerName = [_killer, true, false] call EFUNC(common,getName); + private _instigatorName = "Self?"; + if ((!isNull _instigator) && {_unit != _instigator}) then { + if (_instigatorIsPlayer) then { + _instigatorName = [_instigator, true, false] call EFUNC(common,getName); } else { - _killerName = _killer getVariable [QGVAR(aiName), ""]; // allow setting a custom AI name (e.g. VIP Target) - if (_killerName == "") then { - _killerName = format ["*AI* - %1", getText ((configOf _killer) >> "displayName")]; + _instigatorName = _instigator getVariable [QGVAR(aiName), ""]; // allow setting a custom AI name (e.g. VIP Target) + if (_instigatorName == "") then { + _instigatorName = format ["*AI* - %1", getText ((configOf _instigator) >> "displayName")]; }; }; }; - TRACE_3("send death event",_unit,_killerName,_killInfo); - [QGVAR(death), [_killerName, _killInfo]] call CBA_fnc_localEvent; + TRACE_3("send death event",_unit,_instigatorName,_killInfo); + [QGVAR(death), [_instigatorName, _killInfo]] call CBA_fnc_localEvent; }; - // If killer was player then send event to killer - if (_killerIsPlayer) then { + // If shooter was player then send event to them (and optionally the whole crew) + if (_instigatorIsPlayer && {_unitIsPlayer || GVAR(trackAI)}) then { private _unitName = ""; if (_unitIsPlayer) then { _unitName = [_unit, true, false] call EFUNC(common,getName); // should be same as profileName @@ -136,9 +137,18 @@ GVAR(killCount) = 0; _unitName = format ["*AI* - %1", getText ((configOf _unit) >> "displayName")]; }; }; - if (_unitIsPlayer || GVAR(trackAI)) then { - TRACE_3("send kill event",_killer,_unitName,_killInfo); - [QGVAR(kill), [_unitName, _killInfo], _killer] call CBA_fnc_targetEvent; + TRACE_3("send kill event",_instigator,_unitName,_killInfo); + [QGVAR(kill), [_unitName, _killInfo], _instigator] call CBA_fnc_targetEvent; + + if (GVAR(showCrewKills) && {!(_killer isKindOf "CAManBase")}) then { + private _crew = [driver _killer, gunner _killer, commander _killer] - [_instigator]; + _crew = _crew select {[_x] call EFUNC(common,isPlayer)}; + _crew = _crew arrayIntersect _crew; + TRACE_1("showCrewKills",_crew); + _killInfo = format [" - [%1, %2", localize "str_a3_rscdisplaygarage_tab_crew", _killInfo select [4]]; + { + [QGVAR(kill), [_unitName, _killInfo], _x] call CBA_fnc_targetEvent; + } forEach _crew; }; }; }] call CBA_fnc_addEventHandler; diff --git a/addons/killtracker/initSettings.inc.sqf b/addons/killtracker/initSettings.inc.sqf index ebe1e55ccb2..9e4775bd7f7 100644 --- a/addons/killtracker/initSettings.inc.sqf +++ b/addons/killtracker/initSettings.inc.sqf @@ -6,3 +6,12 @@ true, 1 ] call CBA_fnc_addSetting; + +[ + QGVAR(showCrewKills), + "CHECKBOX", + [LSTRING(showCrewKills_DisplayName), LSTRING(showCrewKills_Description)], + LSTRING(Category), + false, + 1 +] call CBA_fnc_addSetting; diff --git a/addons/killtracker/stringtable.xml b/addons/killtracker/stringtable.xml index 47866c9adb0..fe3fae44863 100644 --- a/addons/killtracker/stringtable.xml +++ b/addons/killtracker/stringtable.xml @@ -3,14 +3,19 @@ ACE Kill Tracker + ACE Tracciatore di Uccisioni ACE Kill Tracker ACE Отслеживание убийств - ACE キルトラッカー + ACE キル追跡 + ACE 킬트래커 + ACE Suivi des morts + ACE Abschüsse + ACE Contador de Muertes ACE Killed Events ACE キルイベント - ACE Abgeschossene Ereignisse + ACE Abschusszähler ACE Eventi di Morte ACE Licznik Zabójstw ACE 击杀事件 @@ -25,7 +30,7 @@ Всего убийств: Liczba zabójstw: Toplam Öldürme: - 総キル: + 合計キル数: Gesammte Abschüsse: Uccisioni Totali: 总击杀数: @@ -39,7 +44,7 @@ Убил: %1 %2 Zabójstwo: %1 %2 Öldürülen: %1 %2 - キル: %1 %2 + 殺害: %1 %2 Abschuss: %1 %2 Uccisione: %1 %2 击杀:%1 %2 @@ -53,7 +58,7 @@ Убийца: %1 %2 Zabójca: %1 %2 Öldüren: %1 %2 - キラー: %1 %2 + 殺害者: %1 %2 Täter: %1 %2 Uccisore: %1 %2 击杀者:%1 %2 @@ -94,15 +99,45 @@ Track AI units killed by player + Traccia IA uccise da giocatori Sledovat AI zabité hráči Отслеживание юнитов ИИ, убитых игроком - プレイヤーに殺害されたAIユニットを追跡 + プレイヤーがキルした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をミッション終了デブリーフィング画面に表示させるかどうかを定義します。 + 사후강평 중 살해된 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 + 車両でのキルを乗員全員に表示する + 다른 승무원에게 차량 처치 표시 + Montrer les véhicules tués aux membres de l'équipage + Mostrar bajas provocadas por el vehículo a otros miembros de la tripulación + + + 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 + 車両でのキルを操縦手、砲手、車長で共有して表示する + 차량 처치를 운전수, 사수, 지휘관에게 보여줍니다 + Montrer les véhicules tués au pilote, à l'artilleur et au commandant. + Muestra las bajas de un vehículo al conductor, artillero y comandante diff --git a/addons/laser/RscTitles.hpp b/addons/laser/RscTitles.hpp index 7421246181b..c63b601ab77 100644 --- a/addons/laser/RscTitles.hpp +++ b/addons/laser/RscTitles.hpp @@ -9,10 +9,10 @@ class RscTitles { 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)"; + 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 AttackMode: RscText { @@ -21,29 +21,29 @@ class RscTitles { colorBackground[] = {0, 0, 0, 0}; x = "0"; y = "0"; - w = "(2.6) * (((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)"; + w = "(2.6) * (((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 LaserCode: RscText { idc = IDC_LASERCODE; colorText[] = {1, 1, 1, 1}; colorBackground[] = {0, 0, 0, 0}; - x = "(3.6) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + x = "(3.6) * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; y = "0"; - w = "(2.5) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - h = "(1) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - sizeEx = "0.8 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + w = "(2.5) * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; + h = "(1) * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; + sizeEx = "0.8 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; }; class LaserIcon: RscPictureKeepAspect { idc = IDC_LASERICON; colorText[] = {1, 0, 0, 1}; colorBackground[] = {0, 0, 0, 0}; text = "\a3\Ui_F_Curator\Data\CfgCurator\laser_ca.paa"; - x = "(6.1) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + x = "(6.1) * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; y = "0"; - w = "(1) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - h = "(1) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + w = "(1) * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; + h = "(1) * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)"; }; }; }; diff --git a/addons/laser/XEH_postInit.sqf b/addons/laser/XEH_postInit.sqf index 768752bee2e..eb4cb247ed7 100644 --- a/addons/laser/XEH_postInit.sqf +++ b/addons/laser/XEH_postInit.sqf @@ -21,10 +21,10 @@ if (hasInterface) then { ["ACE_controlledUAV", { params ["_UAV", "_seatAI", "_turret", "_position"]; TRACE_4("ACE_controlledUAV EH",_UAV,_seatAI,_turret,_position); - if (!isNull _seatAI) then { - [_seatAI] call FUNC(showVehicleHud); - } else { + if (isNull _seatAI) then { [ace_player] call FUNC(showVehicleHud); + } else { + [_seatAI] call FUNC(showVehicleHud); }; }] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/laser/functions/fnc_addLaserTarget.sqf b/addons/laser/functions/fnc_addLaserTarget.sqf index 08ea6f65b0b..f0414fd3ad2 100644 --- a/addons/laser/functions/fnc_addLaserTarget.sqf +++ b/addons/laser/functions/fnc_addLaserTarget.sqf @@ -20,9 +20,9 @@ params ["_targetObject", "_vehicle"]; TRACE_2("params",_targetObject,_vehicle); // Get the designator variables, or use defaults -private _waveLength = _vehicle getVariable [QEGVAR(laser,waveLength), ACE_DEFAULT_LASER_WAVELENGTH]; -private _laserCode = _vehicle getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; -private _beamSpread = _vehicle getVariable [QEGVAR(laser,beamSpread), ACE_DEFAULT_LASER_BEAMSPREAD]; +private _waveLength = _vehicle getVariable [QGVAR(waveLength), ACE_DEFAULT_LASER_WAVELENGTH]; +private _laserCode = _vehicle getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]; +private _beamSpread = _vehicle getVariable [QGVAR(beamSpread), ACE_DEFAULT_LASER_BEAMSPREAD]; TRACE_3("codes",_waveLength,_laserCode,_beamSpread); // Laser method is the method ACE_Laser will use to determine from where to where it should project the designator cone @@ -55,5 +55,5 @@ TRACE_1("",GVAR(trackedLaserTargets)); if (GVAR(pfehID) == -1) then { TRACE_1("starting pfeh",count GVAR(trackedLaserTargets)); - GVAR(pfehID) = [DFUNC(laserTargetPFH), 0, []] call CBA_fnc_addPerFrameHandler; + GVAR(pfehID) = [LINKFUNC(laserTargetPFH), 0, []] call CBA_fnc_addPerFrameHandler; }; diff --git a/addons/laser/functions/fnc_dev_drawVisibleLaserTargets.sqf b/addons/laser/functions/fnc_dev_drawVisibleLaserTargets.sqf index 4c57a613252..294a0262385 100644 --- a/addons/laser/functions/fnc_dev_drawVisibleLaserTargets.sqf +++ b/addons/laser/functions/fnc_dev_drawVisibleLaserTargets.sqf @@ -35,8 +35,8 @@ private _testSeekerDir = vectorDirVisual _seekerVehicle; 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"]; + 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 [ACE_DEFAULT_LASER_CODE, 1688]; // Scan at codes 1111 and 1688 @@ -51,29 +51,29 @@ private _testSeekerDir = vectorDirVisual _seekerVehicle; if (_laserMethod isEqualTo QFUNC(findLaserSource)) then { // Normal vanilla laserTarget func private _targetObject = _obj getVariable [QGVAR(targetObject), objNull]; 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"]; + 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"]; (_y call FUNC(findLaserSource)) params ["_laserPosASL", "_laserDir"]; private _resultsRay = [_laserPosASL, _laserDir, _obj] call FUNC(shootRay); private _rayPos = _resultsRay select 0; if (isNil "_rayPos") then { - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,0,1], (ASLtoAGL _targetPosASL), 2, 2, 0, "Nil Ray", 0.5, 0.025, "TahomaB"]; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,0,1], (ASLToAGL _targetPosASL), 2, 2, 0, "Nil Ray", 0.5, 0.025, "TahomaB"]; } else { private _diff = _rayPos vectorDistance (getPosASL _targetObject); // Diff from ray position compared to actual - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,0,1], (ASLtoAGL _rayPos), 2, 2, 0, format ["Diff %1",_diff], 0.5, 0.025, "TahomaB"]; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,0,1], (ASLToAGL _rayPos), 2, 2, 0, format ["Diff %1",_diff], 0.5, 0.025, "TahomaB"]; }; }; // Draw array weapon lasers [YELLOW] if ((_laserMethod isEqualType []) && {(count _laserMethod) == 2}) then { _laserMethod params ["_modelPosition", "_weaponName"]; 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"]; + 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); private _rayPos = _resultsRay select 0; if (!isNil "_rayPos") then { - 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"]; + 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"]; }; }; } forEach GVAR(laserEmitters); diff --git a/addons/laser/functions/fnc_handleLaserTargetCreation.sqf b/addons/laser/functions/fnc_handleLaserTargetCreation.sqf index bd42a3e5a53..4d5a7164b75 100644 --- a/addons/laser/functions/fnc_handleLaserTargetCreation.sqf +++ b/addons/laser/functions/fnc_handleLaserTargetCreation.sqf @@ -22,13 +22,13 @@ TRACE_1("params",_this); // Only handle locally created lasers if(!(local _targetObject)) exitWith {TRACE_1("not local",_targetObject);}; - private _owners = allUnits select {(lasertarget _x) == _targetObject}; + private _owners = allUnits select {(laserTarget _x) == _targetObject}; if (count _owners == 1) exitWith { TRACE_2("Laser target owner [allUnits]",_targetObject,_owners select 0); [_targetObject, _owners select 0] call FUNC(addLaserTarget); }; - _owners = vehicles select {(lasertarget _x) == _targetObject}; + _owners = vehicles select {(laserTarget _x) == _targetObject}; if (count _owners == 1) exitWith { TRACE_2("Laser target owner [vehicles]",_targetObject,_owners select 0); [_targetObject, _owners select 0] call FUNC(addLaserTarget); @@ -58,7 +58,7 @@ TRACE_1("params",_this); }; }; if (!_foundSource) then { - WARNING_1("Laser target doesn't have owner",_targetObject); + WARNING_1("Laser target %1 doesn't have owner",_targetObject); }; }, _this] call CBA_fnc_execNextFrame; diff --git a/addons/laser/functions/fnc_laserTargetPFH.sqf b/addons/laser/functions/fnc_laserTargetPFH.sqf index 0b19b4d1c34..af2098a6f8d 100644 --- a/addons/laser/functions/fnc_laserTargetPFH.sqf +++ b/addons/laser/functions/fnc_laserTargetPFH.sqf @@ -29,7 +29,7 @@ GVAR(trackedLaserTargets) = GVAR(trackedLaserTargets) select { TRACE_1("Laser off:",_laserUuid); false } else { - private _newCode = _owner getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; + private _newCode = _owner getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]; if (_laserCode != _newCode) then { TRACE_2("code change",_newCode,_laserCode); [QGVAR(updateCode), [_laserUuid, _newCode]] call CBA_fnc_globalEvent; diff --git a/addons/laser/functions/fnc_seekerFindLaserSpot.sqf b/addons/laser/functions/fnc_seekerFindLaserSpot.sqf index d1e4626d53c..cf805f7496f 100644 --- a/addons/laser/functions/fnc_seekerFindLaserSpot.sqf +++ b/addons/laser/functions/fnc_seekerFindLaserSpot.sqf @@ -72,7 +72,7 @@ private _finalOwner = objNull; TRACE_1("",_laser); //Handle Weird Data Return - skips over this laser in the for loop - if ((_laser isEqualTo []) || {_laser isEqualTo [-1, -1]}) exitWith {WARNING_1("Bad Laser Return",_laser);}; + if ((_laser isEqualTo []) || {_laser isEqualTo [-1, -1]}) exitWith {WARNING_1("Bad Laser Return %1",_laser);}; _laser params [["_laserPos", [], [[]], 3], ["_laserDir", [], [[]], 3]]; if (GVAR(dispersionCount) > 0) then { @@ -103,7 +103,7 @@ private _finalOwner = objNull; TRACE_2("",count _spots,_spots); -if ((count _spots) > 0) then { +if (_spots isNotEqualTo []) then { private _bucketList = nil; private _bucketPos = nil; private _c = 0; @@ -115,7 +115,7 @@ if ((count _spots) > 0) then { while { count(_spots) != count(_excludes) && _c < (count _spots) } do { scopeName "mainSearch"; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { private _index = _buckets pushBack [_x, [_x]]; _excludes pushBack _forEachIndex; _bucketPos = _x select 0; @@ -124,7 +124,7 @@ if ((count _spots) > 0) then { }; } forEach _spots; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { private _testPos = (_x select 0); if ((_testPos vectorDistanceSqr _bucketPos) <= 100) then { _bucketList pushBack _x; @@ -192,10 +192,10 @@ END_COUNTER(seekerFindLaserSpot); #ifdef DRAW_LASER_INFO if (isNil "_finalPos") then { - drawIcon3D ["\A3\ui_f\data\map\vehicleicons\iconMan_ca.paa", [0.9,1,0,1], (ASLtoAGL _posASL), 1, 1, 0, format ["Seeker: %1", _seekerCode], 0.5, 0.025, "TahomaB"]; + drawIcon3D ["\A3\ui_f\data\map\vehicleicons\iconMan_ca.paa", [0.9,1,0,1], (ASLToAGL _posASL), 1, 1, 0, format ["Seeker: %1", _seekerCode], 0.5, 0.025, "TahomaB"]; } else { - drawIcon3D ["\A3\ui_f\data\map\vehicleicons\iconManAT_ca.paa", [0.5,1,0,1], (ASLtoAGL _posASL), 1, 1, 0, format ["Seeker: %1", _seekerCode], 0.5, 0.025, "TahomaB"]; - drawLine3D [ASLtoAGL _posASL, ASLtoAGL _finalPos, [0.5,1,0,1]]; + drawIcon3D ["\A3\ui_f\data\map\vehicleicons\iconManAT_ca.paa", [0.5,1,0,1], (ASLToAGL _posASL), 1, 1, 0, format ["Seeker: %1", _seekerCode], 0.5, 0.025, "TahomaB"]; + drawLine3D [ASLToAGL _posASL, ASLToAGL _finalPos, [0.5,1,0,1]]; }; #endif diff --git a/addons/laser/functions/fnc_shootRay.sqf b/addons/laser/functions/fnc_shootRay.sqf index 862e972dd1b..9b8341909c3 100644 --- a/addons/laser/functions/fnc_shootRay.sqf +++ b/addons/laser/functions/fnc_shootRay.sqf @@ -48,8 +48,8 @@ TRACE_3("",_resultPos,_distance,_intersects); #ifdef DRAW_LASER_INFO 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]]; + 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]]; }; #endif diff --git a/addons/laser/functions/fnc_showVehicleHud.sqf b/addons/laser/functions/fnc_showVehicleHud.sqf index 778df61a6ca..856030bf8cb 100644 --- a/addons/laser/functions/fnc_showVehicleHud.sqf +++ b/addons/laser/functions/fnc_showVehicleHud.sqf @@ -68,7 +68,7 @@ GVAR(pfID) = [{ if (_adjustDown) then { private _ctrl = (uiNamespace getVariable [QGVAR(display), displayNull]) displayCtrl IDC_MODECONTROLGROUP; private _pos = ctrlPosition _ctrl; - _pos set [1, (_pos select 1) + ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)]; + _pos set [1, (_pos select 1) + ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25)]; _ctrl ctrlSetPosition _pos; _ctrl ctrlCommit 0; }; @@ -91,7 +91,7 @@ GVAR(pfID) = [{ // Do Laser Scan: private _ammo = getText (configFile >> "CfgMagazines" >> _vehicle currentMagazineTurret _turretPath >> "ammo"); private _laserSource = _vehicle modelToWorldWorld (_vehicle selectionPosition _seekerSource); - private _laserCode = _vehicle getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; + private _laserCode = _vehicle getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]; private _seekerAngle = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_missileguidance" >> "seekerAngle"); private _seekerMaxRange = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_missileguidance" >> "seekerMaxRange"); private _laserResult = [_laserSource, vectorDir _vehicle, _seekerAngle, _seekerMaxRange, [ACE_DEFAULT_LASER_WAVELENGTH,ACE_DEFAULT_LASER_WAVELENGTH], _laserCode, _vehicle] call EFUNC(laser,seekerFindLaserSpot); diff --git a/addons/laser/functions/fnc_toggleLST.sqf b/addons/laser/functions/fnc_toggleLST.sqf index 59969d014eb..eae4ad68ef7 100644 --- a/addons/laser/functions/fnc_toggleLST.sqf +++ b/addons/laser/functions/fnc_toggleLST.sqf @@ -39,7 +39,7 @@ if (_enabled) exitWith {}; [_pfhID] call CBA_fnc_removePerFrameHandler; }; - private _laserCode = _vehicle getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; + private _laserCode = _vehicle getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]; private _angle = 25; private _pos = _vehicle modelToWorldVisualWorld [0,0,0]; diff --git a/addons/laser/stringtable.xml b/addons/laser/stringtable.xml index f0977c84f79..c6bf7cfc25e 100644 --- a/addons/laser/stringtable.xml +++ b/addons/laser/stringtable.xml @@ -129,6 +129,7 @@ Traqueur laser : activé Rastreador a Laser: Ligado Лазерный точечный трекер: Включен + Rastreador del Puntero Láser: On Laser Spot Tracker: Off @@ -140,6 +141,7 @@ Traqueur laser : désactivé Rastreador a Laser: Desligado Лазерный точечный трекер: выключен + Rastreador del Puntero Láser: Off Draw Laser on Map diff --git a/addons/laserpointer/stringtable.xml b/addons/laserpointer/stringtable.xml index 8eead72ecaf..b8d0a657d87 100644 --- a/addons/laserpointer/stringtable.xml +++ b/addons/laserpointer/stringtable.xml @@ -37,15 +37,15 @@ 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) レーザー ポインター (緑) 레이저 지시기 (초록) 激光指示器(绿色) diff --git a/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf b/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf index 3e7ce4f15ce..925178d642d 100644 --- a/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf +++ b/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf @@ -18,4 +18,4 @@ params ["_caller", "_target"]; -("ACE_UAVBattery" in (_caller call EFUNC(common,uniqueItems))) && {(fuel _target) < 1} && {(speed _target) < 1} && {!(isEngineOn _target)} && {(_target distance _caller) <= 4} +(alive _target) && {"ACE_UAVBattery" in (_caller call EFUNC(common,uniqueItems))} && {(fuel _target) < 1} && {(speed _target) < 1} && {!(isEngineOn _target)} && {(_target distance _caller) <= 4} diff --git a/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf b/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf index 8c73052c453..a471e82cbf7 100644 --- a/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf +++ b/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf @@ -17,7 +17,7 @@ */ params ["_caller", "_target"]; -if (!(_this call FUNC(canRefuelUAV))) exitWith {}; +if !(_this call FUNC(canRefuelUAV)) exitWith {}; private _onFinish = { (_this select 0) params ["_caller", "_target"]; diff --git a/addons/logistics_wirecutter/XEH_postInit.sqf b/addons/logistics_wirecutter/XEH_postInit.sqf index 29dc5063962..fc0a38bf261 100644 --- a/addons/logistics_wirecutter/XEH_postInit.sqf +++ b/addons/logistics_wirecutter/XEH_postInit.sqf @@ -1,11 +1,11 @@ #include "script_component.hpp" if (hasInterface) then { - ["ace_interactMenuOpened", {_this call FUNC(interactEH)}] call CBA_fnc_addEventHandler; + ["ace_interactMenuOpened", LINKFUNC(interactEH)] call CBA_fnc_addEventHandler; }; if (isServer) then { - [QGVAR(destroyFence), {_this call FUNC(destroyFence)}] call CBA_fnc_addEventHandler; + [QGVAR(destroyFence), LINKFUNC(destroyFence)] call CBA_fnc_addEventHandler; }; GVAR(possibleWirecutters) = call (uiNamespace getVariable [QGVAR(possibleWirecutters), {[]}]); diff --git a/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf b/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf index 2176793aed5..8b44f7be5a6 100644 --- a/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf +++ b/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf @@ -63,7 +63,7 @@ if !(_unit call EFUNC(common,isSwimming)) then { !isNull _fence && {damage _fence < 1} - && {HAS_WIRECUTTER(_player)} + && {HAS_WIRECUTTER(_unit)} }, ["isNotSwimming"] ] call EFUNC(common,progressBar); diff --git a/addons/logistics_wirecutter/functions/fnc_destroyFence.sqf b/addons/logistics_wirecutter/functions/fnc_destroyFence.sqf index 3698f4a22f9..9a8bde077b7 100644 --- a/addons/logistics_wirecutter/functions/fnc_destroyFence.sqf +++ b/addons/logistics_wirecutter/functions/fnc_destroyFence.sqf @@ -17,7 +17,7 @@ params ["_fence"]; -private _fenceModel = toLower ((getModelInfo _fence)#0); +private _fenceModel = toLowerANSI ((getModelInfo _fence)#0); // If fence cannot be replaced with destroyed model, just knock it over if !(_fenceModel in GVAR(replacements)) exitWith { diff --git a/addons/magazinerepack/functions/fnc_canRepackMagazine.sqf b/addons/magazinerepack/functions/fnc_canRepackMagazine.sqf index d6d8f3b827c..2c32ec57276 100644 --- a/addons/magazinerepack/functions/fnc_canRepackMagazine.sqf +++ b/addons/magazinerepack/functions/fnc_canRepackMagazine.sqf @@ -18,6 +18,9 @@ params ["_unit", "_magazine"]; +// Exit if repack is disabled for this magazine. +if (getNumber (configFile >> "CfgMagazines" >> _magazine >> "ace_disableRepacking") == 1) exitWith {false}; + private _maxAmmoCount = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); { diff --git a/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf b/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf index b4cf8b16ef6..09d6974fefe 100644 --- a/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf +++ b/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror, commy2, esteldunedain, Ruthberg - * Gets magazine children for interaciton menu. + * Gets magazine children for interaction menu. * * Arguments: * 0: Target @@ -18,16 +18,20 @@ params ["_target", "_player"]; +private _cfgMagazines = configFile >> "CfgMagazines"; + // get all mags and ammo count private _unitMagazines = []; private _unitMagCounts = []; { _x params ["_xClassname", "_xCount", "_xLoaded", "_xType"]; - private _xFullMagazineCount = getNumber (configFile >> "CfgMagazines" >> _xClassname >> "count"); + private _configMagazine = _cfgMagazines >> _xClassname; + private _xFullMagazineCount = getNumber (_configMagazine >> "count"); + private _isRepackDisabled = getNumber (_configMagazine >> "ace_disableRepacking") == 1; //for every partial magazine, that is either in inventory or can be moved there - if ((_xCount < _xFullMagazineCount) && {_xCount > 0} && {(!_xLoaded) || {GVAR(repackLoadedMagazines) && {[_player, _xClassname] call CBA_fnc_canAddItem}}}) then { + if ((!_isRepackDisabled) && {_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 9383089d284..c2785c5fadb 100644 --- a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf +++ b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf @@ -25,7 +25,7 @@ _args params ["_magazineClassname", "_lastAmmoCount"]; private _fullMagazineCount = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "count"); // Don't show anything if player can't interact -if (!([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,canInteractWith))) exitWith {}; +if !([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {}; // Count mags private _fullMags = 0; diff --git a/addons/main/script_mod.hpp b/addons/main/script_mod.hpp index 12faeb07c07..7ca3793586c 100644 --- a/addons/main/script_mod.hpp +++ b/addons/main/script_mod.hpp @@ -10,7 +10,7 @@ #define VERSION_AR MAJOR,MINOR,PATCHLVL,BUILD // MINIMAL required version for the Mod. Components can specify others.. -#define REQUIRED_VERSION 2.14 +#define REQUIRED_VERSION 2.16 #define REQUIRED_CBA_VERSION {3,16,0} #ifndef COMPONENT_BEAUTIFIED diff --git a/addons/main/script_version.hpp b/addons/main/script_version.hpp index c94b9e61937..2ccada406ec 100644 --- a/addons/main/script_version.hpp +++ b/addons/main/script_version.hpp @@ -1,4 +1,4 @@ #define MAJOR 3 -#define MINOR 16 -#define PATCHLVL 3 -#define BUILD 79 +#define MINOR 18 +#define PATCHLVL 0 +#define BUILD 90 diff --git a/addons/main/stringtable.xml b/addons/main/stringtable.xml index 902c0d97c22..b676359f74f 100644 --- a/addons/main/stringtable.xml +++ b/addons/main/stringtable.xml @@ -6,7 +6,7 @@ ACE Logistik ACE Logistyka Logísticas ACE - ACE: логистика + ACE: Логистика ACE Logistika ACE Logística ACE Logistica diff --git a/addons/map/XEH_postInitClient.sqf b/addons/map/XEH_postInitClient.sqf index 49b8239e0a8..083cd02b59f 100644 --- a/addons/map/XEH_postInitClient.sqf +++ b/addons/map/XEH_postInitClient.sqf @@ -8,7 +8,7 @@ LOG(MSG_INIT); // Calculate the maximum zoom allowed for this map call FUNC(determineZoom); -GVAR(flashlights) = [] call CBA_fnc_createNamespace; +GVAR(flashlights) = createHashMap; ["CBA_settingsInitialized", { if (isMultiplayer && {GVAR(DefaultChannel) != -1}) then { @@ -73,8 +73,7 @@ GVAR(hasWatch) = true; GVAR(hasWatch) = false; { if (_x isKindOf ["ItemWatch", configFile >> "CfgWeapons"]) exitWith {GVAR(hasWatch) = true;}; - false - } count (assignedItems _unit); + } forEach (assignedItems _unit); }, true] call CBA_fnc_addPlayerEventHandler; @@ -93,7 +92,7 @@ GVAR(vehicleLightColor) = [1,1,1,0]; // Handle vehicles with toggleable interior lights: private _vehicleLightCondition = getText (_cfg >> QGVAR(vehicleLightCondition)); if (_vehicleLightCondition == "") then { - private _userAction = toLower getText (_cfg >> "UserActions" >> "ToggleLight" >> "statement"); + private _userAction = toLowerANSI getText (_cfg >> "UserActions" >> "ToggleLight" >> "statement"); if ( false // isClass (_cfg >> "compartmentsLights") || {_userAction find "cabinlights_hide" > 0} @@ -110,6 +109,7 @@ GVAR(vehicleLightColor) = [1,1,1,0]; compile _vehicleLightCondition }; } else { + //IGNORE_PRIVATE_WARNING ["_vehicle", "_unit"]; switch (true) do { case (_vehicle isKindOf "Tank"); case (_vehicle isKindOf "Wheeled_APC_F"): { {true} }; diff --git a/addons/map/config.cpp b/addons/map/config.cpp index 943a63c228e..a4d086d6029 100644 --- a/addons/map/config.cpp +++ b/addons/map/config.cpp @@ -119,16 +119,16 @@ class RscDisplayDiary { onButtonClick = ""; }; class CA_PlayerName: RscText { - x = "2 * ( ((safezoneW / safezoneH) min 1.2) / 40)"; + x = "2 * ( ((safeZoneW / safeZoneH) min 1.2) / 40)"; }; class ProfilePicture: RscPicture { - x = "13.5 * ( ((safezoneW / safezoneH) min 1.2) / 40)"; + x = "13.5 * ( ((safeZoneW / safeZoneH) min 1.2) / 40)"; }; class ProfileBackground: RscText { - x = "13.3 * ( ((safezoneW / safezoneH) min 1.2) / 40)"; + x = "13.3 * ( ((safeZoneW / safeZoneH) min 1.2) / 40)"; }; class Separator1: RscPicture { - x = "14.5 * ( ((safezoneW / safezoneH) min 1.2) / 40)"; + x = "14.5 * ( ((safeZoneW / safeZoneH) min 1.2) / 40)"; }; }; }; diff --git a/addons/map/functions/fnc_blueForceTrackingModule.sqf b/addons/map/functions/fnc_blueForceTrackingModule.sqf index af95ce3d6d0..8a2dcbf2452 100644 --- a/addons/map/functions/fnc_blueForceTrackingModule.sqf +++ b/addons/map/functions/fnc_blueForceTrackingModule.sqf @@ -22,4 +22,4 @@ params ["_logic"]; [_logic, QGVAR(BFT_HideAiGroups), "HideAiGroups"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(BFT_ShowPlayerNames), "ShowPlayerNames"] call EFUNC(common,readSettingFromModule); -INFO_3("Blue Force Tracking Module Initialized:",GVAR(BFT_Enabled),GVAR(BFT_Interval),GVAR(BFT_HideAiGroups)); +INFO_3("Blue Force Tracking Module Initialized:%1-%2-%3",GVAR(BFT_Enabled),GVAR(BFT_Interval),GVAR(BFT_HideAiGroups)); diff --git a/addons/map/functions/fnc_compileFlashlightMenu.sqf b/addons/map/functions/fnc_compileFlashlightMenu.sqf index 4dc24a23f64..b0778981a7e 100644 --- a/addons/map/functions/fnc_compileFlashlightMenu.sqf +++ b/addons/map/functions/fnc_compileFlashlightMenu.sqf @@ -30,6 +30,7 @@ _unitLight params ["_flashlight", ""]; private _displayName = getText (_cfg >> "displayName"); private _icon = getText (_cfg >> "picture"); + //IGNORE_PRIVATE_WARNING ["_player"]; private _statement = if (_flashlight == _x) then { _displayName = format [localize LSTRING(turnLightOff), _displayName]; {[_player, ""] call FUNC(switchFlashlight)} diff --git a/addons/map/functions/fnc_isFlashlight.sqf b/addons/map/functions/fnc_isFlashlight.sqf index e563d741145..ae26b41569d 100644 --- a/addons/map/functions/fnc_isFlashlight.sqf +++ b/addons/map/functions/fnc_isFlashlight.sqf @@ -17,14 +17,12 @@ params [["_class", "", [""]]]; -private _isFlashlight = GVAR(flashlights) getVariable _class; - -if (isNil "_isFlashlight") then { +GVAR(flashlights) getOrDefaultCall [_class, { private _items = ([_class] + (_class call CBA_fnc_switchableAttachments)); private _cfgWeapons = configFile >> "CfgWeapons"; // if this item or any of the switchable items is a flashlight - _isFlashlight = _items findIf { + _items findIf { private _weaponConfig = _cfgWeapons >> _x; [ @@ -34,10 +32,5 @@ if (isNil "_isFlashlight") then { isText (_x >> "ACE_Flashlight_Colour") || {!(getArray (_x >> "ambient") in [[], [0,0,0]]) && {getNumber (_x >> "irLight") == 0}} } != -1 // return - } != -1; - - // cache value - GVAR(flashlights) setVariable [_class, _isFlashlight]; -}; - -_isFlashlight // return + } != -1 // return +}, true] // return diff --git a/addons/map/initSettings.inc.sqf b/addons/map/initSettings.inc.sqf index fa248bf736f..20665b5a71f 100644 --- a/addons/map/initSettings.inc.sqf +++ b/addons/map/initSettings.inc.sqf @@ -67,14 +67,11 @@ false, true, { - [QGVAR(BFT_Enabled), _this] call EFUNC(common,cbaSettings_settingChanged); - if (GVAR(BFT_Enabled) && {isNil QGVAR(BFT_markers)}) then { GVAR(BFT_markers) = []; - [FUNC(blueForceTrackingUpdate), GVAR(BFT_Interval), []] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(blueForceTrackingUpdate), GVAR(BFT_Interval), []] call CBA_fnc_addPerFrameHandler; }; - }, - false + } ] call CBA_fnc_addSetting; [ @@ -94,9 +91,7 @@ [localize LSTRING(BFT_ShowPlayerNames_DisplayName), localize LSTRING(BFT_ShowPlayerNames_Description)], [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], false, - true, - {[QGVAR(BFT_ShowPlayerNames), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + true ] call CBA_fnc_addSetting; [ @@ -105,7 +100,5 @@ [localize LSTRING(BFT_HideAiGroups_DisplayName), localize LSTRING(BFT_HideAiGroups_Description)], [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], false, - true, - {[QGVAR(BFT_HideAiGroups), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + true ] call CBA_fnc_addSetting; diff --git a/addons/map/stringtable.xml b/addons/map/stringtable.xml index ed5d427424e..13ee042d1f0 100644 --- a/addons/map/stringtable.xml +++ b/addons/map/stringtable.xml @@ -268,7 +268,7 @@ Milyen gyakran frissüljenek a jelölők (másodpercben) Как часто должны обновляться маркеры (в секундах) Quanto spesso vengono aggiornati i marker (in secondi) - マーカが再描画される間隔を設定できます (秒) + マーカが再描画される間隔 (秒単位) 몇 초마다 마커를 새로 갱신합니까? 设定每多少时间重新标示出单位位置(秒) 設定每多少時間重新標示出單位位置 (秒) @@ -492,7 +492,7 @@ Setear canal al comenzar Définir un canal par défaut 開始時のチャンネルを指定 - 시작시 채널 + 시작 시 채널 설정 设定游戏开始时的聊天频道 設定遊戲開始時的聊天頻道 @@ -507,7 +507,7 @@ Cambiar el canal de marcadores inicial al comenzar la misión Change le canal de communication par défaut au début de la mission. ミッション開始時に使用されるマーカーチャンネルの指定を変更します - 미션 시작시 마커채널을 변경합니다 + 미션 시작 시 마커채널을 변경합니다 更改任务启动时的聊天频道 更改任務啟動時的聊天頻道 diff --git a/addons/map_gestures/XEH_preInit.sqf b/addons/map_gestures/XEH_preInit.sqf index e603e5398a1..42090ac7240 100644 --- a/addons/map_gestures/XEH_preInit.sqf +++ b/addons/map_gestures/XEH_preInit.sqf @@ -8,6 +8,6 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" -GVAR(GroupColorCfgMappingNew) = call CBA_fnc_createNamespace; +GVAR(GroupColorCfgMappingNew) = createHashMap; ADDON = true; diff --git a/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf b/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf index 17a8ffbb045..c5577fb7e88 100644 --- a/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf +++ b/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf @@ -22,10 +22,10 @@ if (!params [["_group", "", [grpNull, ""]], ["_leadColor", [1,1,1,1], [[]], 4], }; TRACE_3("params",_group,_leadColor,_unitColor); -if (_group isEqualType grpNull) then {_group = groupID _group}; +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 2f0c80de3ea..35b462910a8 100644 --- a/addons/map_gestures/functions/fnc_drawMapGestures.sqf +++ b/addons/map_gestures/functions/fnc_drawMapGestures.sqf @@ -41,7 +41,7 @@ private _players = [_positions, FUNC(getProximityPlayers), missionNamespace, QGV }; // If color settings for the group exist, then use those, otherwise fall back to the default colors - private _colorMap = GVAR(GroupColorCfgMappingNew) getVariable [(groupID (group _x)), [GVAR(defaultLeadColor), GVAR(defaultColor)]]; + private _colorMap = GVAR(GroupColorCfgMappingNew) getOrDefault [toLower groupId (group _x), [GVAR(defaultLeadColor), GVAR(defaultColor)]]; private _color = _colorMap select (_x != leader _x); TRACE_2("",_colorMap,_color); diff --git a/addons/map_gestures/functions/fnc_initDisplaySpectator.sqf b/addons/map_gestures/functions/fnc_initDisplaySpectator.sqf index dbbd31ae65c..7c1f09bbf53 100644 --- a/addons/map_gestures/functions/fnc_initDisplaySpectator.sqf +++ b/addons/map_gestures/functions/fnc_initDisplaySpectator.sqf @@ -23,11 +23,11 @@ _mapCtrl ctrlAddEventHandler ["Draw", { private _aceSpectatorFocus = missionNamespace getVariable [QEGVAR(spectator,camFocus), objNull]; if (!isNull _aceSpectatorFocus) then { - _targets pushback [_aceSpectatorFocus, GVAR(maxRange)]; + _targets pushBack [_aceSpectatorFocus, GVAR(maxRange)]; }; private _vanillaSpectatorFocus = uiNamespace getVariable ["RscEGSpectator_focus", objNull]; if (!isNull _vanillaSpectatorFocus) then { - _targets pushback [_vanillaSpectatorFocus, GVAR(maxRange)]; + _targets pushBack [_vanillaSpectatorFocus, GVAR(maxRange)]; }; [_this select 0, _targets] call FUNC(drawMapGestures); }]; diff --git a/addons/map_gestures/functions/fnc_isValidColorArray.sqf b/addons/map_gestures/functions/fnc_isValidColorArray.sqf index 7cc9335800b..bcd5fea38cd 100644 --- a/addons/map_gestures/functions/fnc_isValidColorArray.sqf +++ b/addons/map_gestures/functions/fnc_isValidColorArray.sqf @@ -20,7 +20,7 @@ scopeName "main"; params ["_colorArray"]; if (isNil "_colorArray") exitWith {false}; -if (!(_colorArray isEqualType [])) exitWith {false}; +if !(_colorArray isEqualType []) exitWith {false}; if (count _colorArray != 4) exitWith {false}; { diff --git a/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf b/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf index 07be21fc907..36bef695d51 100644 --- a/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf +++ b/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf @@ -24,9 +24,10 @@ if (!_activated) exitWith {}; // Transcode string setting into usable array. Example: "1,1,1,1" -> [1, 1, 1, 1] private _leadColor = call compile ("[" + (_logic getVariable ["leadColor", ""]) + "]"); -if (!([_leadColor] call FUNC(isValidColorArray))) exitWith {ERROR("leadColor is not a valid color array.")}; +if !([_leadColor] call FUNC(isValidColorArray)) exitWith {ERROR("leadColor is not a valid color array.")}; + private _color = call compile ("[" + (_logic getVariable ["color", ""]) + "]"); -if (!([_color] call FUNC(isValidColorArray))) exitWith {ERROR("color is not a valid color array.")}; +if !([_color] call FUNC(isValidColorArray)) exitWith {ERROR("color is not a valid color array.")}; // Add all synchronized groups and reference custom configuration for them { diff --git a/addons/map_gestures/functions/fnc_moduleSettings.sqf b/addons/map_gestures/functions/fnc_moduleSettings.sqf index b637997af75..22913dceef2 100644 --- a/addons/map_gestures/functions/fnc_moduleSettings.sqf +++ b/addons/map_gestures/functions/fnc_moduleSettings.sqf @@ -29,14 +29,14 @@ if (!_activated) exitWith {}; private _defaultLeadColor = _logic getVariable ["defaultLeadColor", ""]; if (_defaultLeadColor != "") then { _defaultLeadColor = call compile ("[" + _defaultLeadColor + "]"); - if (!([_defaultLeadColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultLeadColor is not a valid color array.")}; + if !([_defaultLeadColor] call FUNC(isValidColorArray)) exitWith {ERROR("defaultLeadColor is not a valid color array.")}; ["CBA_settings_setSettingMission", [QGVAR(defaultLeadColor), _defaultLeadColor, true]] call CBA_fnc_localEvent; }; private _defaultColor = _logic getVariable ["defaultColor", ""]; if (_defaultColor != "") then { _defaultColor = call compile ("[" + _defaultColor + "]"); - if (!([_defaultColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultColor is not a valid color array.")}; + if !([_defaultColor] call FUNC(isValidColorArray)) exitWith {ERROR("defaultColor is not a valid color array.")}; ["CBA_settings_setSettingMission", [QGVAR(defaultColor), _defaultColor, true]] call CBA_fnc_localEvent; }; diff --git a/addons/map_gestures/stringtable.xml b/addons/map_gestures/stringtable.xml index 3b7d7e77dda..94c6d05ef10 100644 --- a/addons/map_gestures/stringtable.xml +++ b/addons/map_gestures/stringtable.xml @@ -11,7 +11,7 @@ Kartenzeichen Gestos en mapa Pointage sur carte - マップ ジェスチャー + マップ ジェスチャ 지도 신호 地图指示 地圖指示器 @@ -43,7 +43,7 @@ Aktiviert die Kartenzeichen. Activar Gestos en Mapa Active le pointage sur carte. - マップ ジェスチャーを有効化 + マップ ジェスチャを有効化 지도 신호 활성화 启用地图指示 啟用地圖指示器 @@ -59,7 +59,7 @@ Maximale Reichweite der Kartenzeichen Máx. dist. para gestos en mapa Portée du pointage sur carte - マップ ジェスチャーの最大範囲 + マップ ジェスチャの最大範囲 지도 신호 최대 거리 地图指示最大范围 地圖指示器最大範圍 @@ -75,7 +75,7 @@ Maximale Reichweite zwischen Spielern um Kartenzeichen anzuzeigen Máxima distancia a la cual pueden verse el indicador de gestos Définit le rayon au-delà duquel un joueur ne verra plus l'indicateur de pointage des autres joueurs. - マップ ジェスチャーのインジケーターを表示可能なプレーヤー間の最大距離 + マップ ジェスチャのインジケータを表示可能なプレーヤー間の最大範囲距離 플레이어간에 지도 신호 표시거리를 설정합니다. 设定地图指示显示的最大范围距离 設定地圖指示器顯示的最大範圍距離 @@ -137,7 +137,7 @@ 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. - マップ ジェスチャーに添えて表示される名前の文字色。 + マップ ジェスチャに添えて表示される名前の文字色。 지도 색상에 표시되는 이름의 색상을 결정합니다. 定义名称文字颜色。使其与地图指示颜色有所区别。 定義名稱文字顏色。使其與地圖指示器顏色有所區別 @@ -228,7 +228,7 @@ Farbwert für Gruppenführer, die mit diesem Modul synchronisiert werden. Color para los líderes de los grupos sincronizados al módulo. Couleur pour les chefs des groupes synchronisés avec ce module. - モジュールで同期されたグループの隊長に設定される色の値を決定します。 + モジュールで同期されたグループの隊長に設定される色の値。 그룹이 이 모듈에 동기화 됐을 때의 리더 색상입니다. 改变与此同步小队队长的指示颜色。 改變與此同步小隊隊長的指示器顏色 @@ -259,7 +259,7 @@ Farbwert für Gruppenmitglieder, die mit diesem Modul synchronisiert werden. Color para los miembros de los grupos sincronizados al módulo. Couleur pour les membres des groupes synchronisés avec ce module. - モジュールで同期されたグループの隊員に設定される色の値を決定します。 + モジュールで同期されたグループの隊員に設定される色の値。 그룹이 이 모듈에 동기화 됐을 때의 멤버 색상입니다. 改变与此同步小队队员的指示颜色 改變與此同步小隊隊員的指示器顏色 @@ -270,7 +270,7 @@ Показывать только союзные жесты 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 @@ -283,7 +283,7 @@ Показывать жесты только от игроков союзной стороны. 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. @@ -308,7 +308,7 @@ 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 @@ -334,7 +334,7 @@ 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 @@ -360,7 +360,7 @@ 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 @@ -386,7 +386,7 @@ 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 @@ -473,7 +473,7 @@ Kartenzeichen - Gruppeneinstellungen Gestos en mapas - Configuración de grupos Pointage sur carte - réglages de groupe - マップ ジェスチャー - グループ設定 + マップ ジェスチャ - グループ設定 지도 신호 - 그룹 설정 地图指示—队伍设定 地圖指示器 - 隊伍設定 @@ -488,7 +488,7 @@ ACE Kartenzeichen ACE Gestos en mapa ACE Pointage sur carte - ACE マップ ジェスチャー + ACE マップ ジェスチャ ACE 지도 신호 ACE 地图指示 ACE 地圖指示器 diff --git a/addons/maptools/functions/fnc_canUseMapGPS.sqf b/addons/maptools/functions/fnc_canUseMapGPS.sqf index 317eee6c425..e9ca813288a 100644 --- a/addons/maptools/functions/fnc_canUseMapGPS.sqf +++ b/addons/maptools/functions/fnc_canUseMapGPS.sqf @@ -15,6 +15,9 @@ * 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_drawLinesOnRoamer.sqf b/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf index 782d8762a07..652edf8768b 100644 --- a/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf +++ b/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf @@ -73,11 +73,11 @@ switch (true) do { GVAR(freeDrawingData) = ["left", _currentMousePos, _currentMousePos]; } else { if ((GVAR(freeDrawingData) select 0) == "left") then { // We are already drawing on this line, find best spot - if ((_currentMousePos distance2d _posTopLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posTopLeft)) then { + 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 { + if ((_currentMousePos distance2D _posBottomLeft) < ((GVAR(freeDrawingData) select 2) distance2D _posBottomLeft)) then { GVAR(freeDrawingData) set [2, _currentMousePos]; }; }; @@ -95,11 +95,11 @@ switch (true) do { GVAR(freeDrawingData) = ["top", _currentMousePos, _currentMousePos]; } else { if ((GVAR(freeDrawingData) select 0) == "top") then { // We are already drawing on this line, find best spot - if ((_currentMousePos distance2d _posTopLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posTopLeft)) then { + 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 { + if ((_currentMousePos distance2D _posTopRight) < ((GVAR(freeDrawingData) select 2) distance2D _posTopRight)) then { GVAR(freeDrawingData) set [2, _currentMousePos]; }; }; @@ -117,11 +117,11 @@ switch (true) do { GVAR(freeDrawingData) = ["right", _currentMousePos, _currentMousePos]; } else { if ((GVAR(freeDrawingData) select 0) == "right") then { // We are already drawing on this line, find best spot - if ((_currentMousePos distance2d _posTopRight) < ((GVAR(freeDrawingData) select 1) distance2d _posTopRight)) then { + 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 { + if ((_currentMousePos distance2D _posBottomRight) < ((GVAR(freeDrawingData) select 2) distance2D _posBottomRight)) then { GVAR(freeDrawingData) set [2, _currentMousePos]; }; }; @@ -139,11 +139,11 @@ switch (true) do { GVAR(freeDrawingData) = ["bottom", _currentMousePos, _currentMousePos]; } else { if ((GVAR(freeDrawingData) select 0) == "bottom") then { // We are already drawing on this line, find best spot - if ((_currentMousePos distance2d _posBottomLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posBottomLeft)) then { + 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 { + if ((_currentMousePos distance2D _posBottomRight) < ((GVAR(freeDrawingData) select 2) distance2D _posBottomRight)) then { GVAR(freeDrawingData) set [2, _currentMousePos]; }; }; diff --git a/addons/maptools/functions/fnc_isInsidePlottingBoard.sqf b/addons/maptools/functions/fnc_isInsidePlottingBoard.sqf index e3e64675080..6dc0d844fff 100644 --- a/addons/maptools/functions/fnc_isInsidePlottingBoard.sqf +++ b/addons/maptools/functions/fnc_isInsidePlottingBoard.sqf @@ -27,12 +27,11 @@ private _isRuler = if (GVAR(plottingBoard_Shown) == 2) then { 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}} + _dist > PLOTTINGBOARD_RULERINNERCIRCLE && {_dist < PLOTTINGBOARD_RULEROUTERCIRCLE && {abs (_rulerAng * DEGTOMILS) < PLOTTINGBOARD_RULEROUTERHALFANGLE}} } else { false }; diff --git a/addons/maptools/functions/fnc_updateMapToolMarkers.sqf b/addons/maptools/functions/fnc_updateMapToolMarkers.sqf index 1a6d83b6985..f26c831b7e8 100644 --- a/addons/maptools/functions/fnc_updateMapToolMarkers.sqf +++ b/addons/maptools/functions/fnc_updateMapToolMarkers.sqf @@ -71,7 +71,7 @@ if (GVAR(plottingBoard_Shown) == 0) then { // Rotate all points of polyline if (_count >= 4) then { // polylines need at least 2 points (2 components per point) - _rotatedPolyline = []; + private _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; diff --git a/addons/maptools/stringtable.xml b/addons/maptools/stringtable.xml index 7f02337a17c..7e1d0cee97f 100644 --- a/addons/maptools/stringtable.xml +++ b/addons/maptools/stringtable.xml @@ -39,13 +39,21 @@ 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 @@ -268,85 +276,141 @@ 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 @@ -394,13 +458,21 @@ 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/XEH_postInit.sqf b/addons/marker_flags/XEH_postInit.sqf index 19011893cca..da13925d9cc 100644 --- a/addons/marker_flags/XEH_postInit.sqf +++ b/addons/marker_flags/XEH_postInit.sqf @@ -15,6 +15,7 @@ private _weapons = (call (uiNamespace getVariable [QGVAR(flagItems), {[]}])) app private _icon = getText (_x >> QGVAR(icon)); GVAR(flagCache) set [_name, [_vehicleClass, _displayName, _icon]]; + //IGNORE_PRIVATE_WARNING ["_player", "_target"]; private _action = [ QGVAR(pickup), LLSTRING(ActionPickUp), diff --git a/addons/marker_flags/XEH_preStart.sqf b/addons/marker_flags/XEH_preStart.sqf index 2a2bc521616..e671b522a4c 100644 --- a/addons/marker_flags/XEH_preStart.sqf +++ b/addons/marker_flags/XEH_preStart.sqf @@ -2,5 +2,5 @@ #include "XEH_PREP.hpp" -private _weapons = (configProperties [configfile >> "CfgWeapons", QUOTE(isClass _x && {isText (_x >> QQGVAR(vehicle))}), true]) apply {configName _x}; +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/markers/XEH_postInit.sqf b/addons/markers/XEH_postInit.sqf index 43a1acbf293..1ae489dd829 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 { diff --git a/addons/markers/XEH_preInit.sqf b/addons/markers/XEH_preInit.sqf index 142dedb89a1..605920b7770 100644 --- a/addons/markers/XEH_preInit.sqf +++ b/addons/markers/XEH_preInit.sqf @@ -12,7 +12,7 @@ PREP_RECOMPILE_END; if (isNil QGVAR(MarkersCache)) then { GVAR(MarkersCache) = []; - private _config = configfile >> "CfgMarkers"; + private _config = configFile >> "CfgMarkers"; for "_a" from 0 to (count _config - 1) do { private _marker = _config select _a; @@ -31,7 +31,7 @@ if (isNil QGVAR(MarkersCache)) then { if (isNil QGVAR(MarkerColorsCache)) then { GVAR(MarkerColorsCache) = []; - private _config = configfile >> "CfgMarkerColors"; + private _config = configFile >> "CfgMarkerColors"; for "_a" from 0 to (count _config - 1) do { private _marker = _config select _a; diff --git a/addons/markers/functions/fnc_initInsertMarker.sqf b/addons/markers/functions/fnc_initInsertMarker.sqf index a102502b24c..2a3804959f2 100644 --- a/addons/markers/functions/fnc_initInsertMarker.sqf +++ b/addons/markers/functions/fnc_initInsertMarker.sqf @@ -19,7 +19,7 @@ #define BORDER 0.005 [{ - disableserialization; + disableSerialization; params ["_display"]; TRACE_1("params",_display); @@ -29,24 +29,24 @@ }; //BIS Controls: - 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; + 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: 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 _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");}; @@ -102,7 +102,7 @@ ctrlSetFocus _text; //--- Background - private _pos = ctrlposition _text; + private _pos = ctrlPosition _text; _pos params ["_posX", "_posY", "_posW", "_posH"]; _posX = _posX + 0.01; _posY = _posY min ((safeZoneH + safeZoneY) - (11 * _posH + 11 * BORDER)); //prevent buttons being placed below bottom edge of screen diff --git a/addons/markers/functions/fnc_mapDisplayInitEH.sqf b/addons/markers/functions/fnc_mapDisplayInitEH.sqf index e5242b9067c..6d26d3dab81 100644 --- a/addons/markers/functions/fnc_mapDisplayInitEH.sqf +++ b/addons/markers/functions/fnc_mapDisplayInitEH.sqf @@ -18,14 +18,14 @@ params ["_display"]; TRACE_1("params",_display); -private _bisShapeLB = _display displayctrl 1091; +private _bisShapeLB = _display displayCtrl 1091; private _curSelShape = missionNamespace getVariable [QGVAR(curSelMarkerShape), 0]; TRACE_2("shape",_bisShapeLB,_curSelShape); _bisShapeLB ctrlAddEventHandler ["LBSelChanged", {_this call FUNC(onLBSelChangedShape)}]; _bisShapeLB lbSetCurSel _curSelShape; -private _bisColorLB = _display displayctrl 1090; +private _bisColorLB = _display displayCtrl 1090; private _curSelColor = missionNamespace getVariable [QGVAR(curSelMarkerColor), 0]; TRACE_2("color",_bisColorLB,_curSelColor); _bisColorLB ctrlAddEventHandler ["LBSelChanged", {_this call FUNC(onLBSelChangedColor)}]; diff --git a/addons/markers/functions/fnc_onMouseButtonDown.sqf b/addons/markers/functions/fnc_onMouseButtonDown.sqf index ce4d637400f..f0130c7c9d9 100644 --- a/addons/markers/functions/fnc_onMouseButtonDown.sqf +++ b/addons/markers/functions/fnc_onMouseButtonDown.sqf @@ -37,5 +37,5 @@ if (_type == "marker" && {_marker find "_USER_DEFINED" != -1 && {_marker call FU GVAR(moving) = true; _marker setMarkerAlphaLocal 0.5; - [FUNC(movePFH), 0, [_marker, _ctrlMap, _originalPos, _originalAlpha]] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(movePFH), 0, [_marker, _ctrlMap, _originalPos, _originalAlpha]] call CBA_fnc_addPerFrameHandler; }; diff --git a/addons/markers/functions/fnc_placeMarker.sqf b/addons/markers/functions/fnc_placeMarker.sqf index fdd758be5e1..1899dff5fd5 100644 --- a/addons/markers/functions/fnc_placeMarker.sqf +++ b/addons/markers/functions/fnc_placeMarker.sqf @@ -35,7 +35,7 @@ if (_closeNum isEqualTo 1) then { private _newestMarkerDist = 1e10; { - private _distX = GVAR(currentMarkerPosition) distance2d (getMarkerPos _x); + private _distX = GVAR(currentMarkerPosition) distance2D (getMarkerPos _x); if (_distX < _newestMarkerDist) then { _newestMarker = _x; _newestMarkerDist = _distX; diff --git a/addons/markers/functions/fnc_removeTimestamp.sqf b/addons/markers/functions/fnc_removeTimestamp.sqf index 073d9ce6132..5d2c7c3c1f3 100644 --- a/addons/markers/functions/fnc_removeTimestamp.sqf +++ b/addons/markers/functions/fnc_removeTimestamp.sqf @@ -43,8 +43,8 @@ private _index = 1; private _keepCheckingDigits = true; private _validTimestamp = true; while {_keepCheckingDigits} do { - if (!(_string select [_index, 1] in DIGITS)) exitWith { _validTimestamp = false; }; - if (!(_string select [_index+1, 1] in DIGITS)) exitWith { _validTimestamp = false; }; + if !(_string select [_index, 1] in DIGITS) exitWith { _validTimestamp = false; }; + if !(_string select [_index+1, 1] in DIGITS) exitWith { _validTimestamp = false; }; switch (_string select [_index+2, 1]) do { case (":"): { _index = _index + 3; @@ -54,7 +54,7 @@ while {_keepCheckingDigits} do { }; case (" "): { _keepCheckingDigits = false; - if (!(_string select [_index+3, 3] in ["am]", "pm]"])) then {_validTimestamp = false; }; + if !(_string select [_index+3, 3] in ["am]", "pm]"]) then {_validTimestamp = false; }; }; default { _keepCheckingDigits = false; diff --git a/addons/markers/functions/fnc_setMarkerJIP.sqf b/addons/markers/functions/fnc_setMarkerJIP.sqf index 8536b90a905..fe4a1b68ae5 100644 --- a/addons/markers/functions/fnc_setMarkerJIP.sqf +++ b/addons/markers/functions/fnc_setMarkerJIP.sqf @@ -27,7 +27,7 @@ TRACE_2("params",_allMapMarkers,_allMapMarkersProperties); private _data = _allMapMarkersProperties select _index; _data params ["_markerClassname", "_colorClassname", "_pos", "_dir", "_scale"]; - private _config = (configfile >> "CfgMarkers") >> _markerClassname; + private _config = (configFile >> "CfgMarkers") >> _markerClassname; if (!isClass _config) then { WARNING("CfgMarker not found, changed to milDot"); @@ -36,7 +36,7 @@ TRACE_2("params",_allMapMarkers,_allMapMarkersProperties); _x setMarkerTypeLocal configName _config; - _config = configfile >> "CfgMarkerColors" >> _colorClassname; + _config = configFile >> "CfgMarkerColors" >> _colorClassname; if (!isClass _config) then { WARNING("CfgMarkerColors not found, changed to Default"); @@ -49,5 +49,4 @@ TRACE_2("params",_allMapMarkers,_allMapMarkersProperties); _x setMarkerDirLocal _dir; _x setMarkerSizeLocal [_scale, _scale]; }; - false -} count allMapMarkers; +} forEach allMapMarkers; diff --git a/addons/markers/functions/fnc_setMarkerNetwork.sqf b/addons/markers/functions/fnc_setMarkerNetwork.sqf index 7d0cc0e8271..94c66f40789 100644 --- a/addons/markers/functions/fnc_setMarkerNetwork.sqf +++ b/addons/markers/functions/fnc_setMarkerNetwork.sqf @@ -21,7 +21,7 @@ params ["_marker", "_data"]; TRACE_2("params",_marker,_data); _data params ["_markerClassname", "_colorClassname", "_pos", "_dir", "_scale"]; -private _config = configfile >> "CfgMarkers" >> _markerClassname; +private _config = configFile >> "CfgMarkers" >> _markerClassname; if (!isClass _config) then { WARNING("CfgMarker not found, changed to milDot"); @@ -30,7 +30,7 @@ if (!isClass _config) then { _marker setMarkerTypeLocal configName _config; -_config = configfile >> "CfgMarkerColors" >> _colorClassname; +_config = configFile >> "CfgMarkerColors" >> _colorClassname; if (!isClass _config) then { WARNING("CfgMarkerColors not found, changed to Default"); diff --git a/addons/markers/stringtable.xml b/addons/markers/stringtable.xml index f08406fce09..2c9dc1531ba 100644 --- a/addons/markers/stringtable.xml +++ b/addons/markers/stringtable.xml @@ -247,6 +247,7 @@ Zona horaria Strefa czasowa Zeitzone + Fuso orario 时区 시간대 @@ -258,6 +259,7 @@ Cambie la zona horaria para la marca de tiempo Zmień strefę czasową dla znaczników czasu Ändern Sie die Zeitzone für den Zeitstempel + Modifica il fuso orario per la marca temporale 更改时间戳的时区 타임스탬프의 시간대를 변경하십시오 @@ -269,6 +271,7 @@ Hora del juego Czas gry Ingame-Zeit + Ora del gioco 游戏内时间 게임 시간 @@ -280,6 +283,7 @@ Hora del sistema Czas systemowy Systemzeit + Ora del sistema 系统时间 시스템 시간 @@ -291,6 +295,7 @@ Hora UTC Czas UTC UTC-Zeit + Tempo-UTC UTC时间 UTC 시간 @@ -302,6 +307,7 @@ Desplazamiento UTC Przesunięcie UTC UTC-Verschiebung + Deviazione-UTC UTC偏移量 UTC 오프셋 @@ -313,17 +319,19 @@ Cambiar el desplazamiento horario para la marca de tiempo UTC Zmień przesunięcie czasu dla sygnatury czasowej UTC Ändere die Zeitverschiebung für den UTC-Zeitstempel + Modifica la deviazione della marca temporale UTC. 更改UTC时间戳的时间偏移量 UTC 타임 스탬프의 시간 오프셋을 변경하십시오 UTC Minutes Offset - UTC Минутное Смещение + UTC Минутное смещение Décalage des minutes UTC UTC分オフセット Desplazamiento de minutos UTC Przesunięcie minut UTC UTC-Minutenversatz + Deviazione Minuti UTC UTC分钟偏移量 UTC 분 오프셋 @@ -335,6 +343,7 @@ Cambiar el desplazamiento de minutos para la marca de tiempo UTC Zmień przesunięcie minut dla sygnatury czasowej UTC Ändere den Minutenversatz für den UTC-Zeitstempel + Modifica la deviazione dei minuti della marca temporale UTC. 更改UTC时间戳的分钟偏移量 UTC 타임 스탬프의 분 오프셋을 변경하십시오 @@ -407,19 +416,23 @@ "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 diff --git a/addons/maverick/ACE_GuidanceConfig.hpp b/addons/maverick/ACE_GuidanceConfig.hpp index 948404b7cce..4360bd4a87d 100644 --- a/addons/maverick/ACE_GuidanceConfig.hpp +++ b/addons/maverick/ACE_GuidanceConfig.hpp @@ -2,6 +2,6 @@ class EGVAR(missileguidance,AttackProfiles) { class maverick { name = "LOAL-DIR"; nameLocked = "LOBL-DIR"; - functionName = QEFUNC(missileguidance,attackProfile_DIR); + functionName = QEFUNC(missileguidance,attackProfile_LIN); }; }; diff --git a/addons/maverick/CfgAmmo.hpp b/addons/maverick/CfgAmmo.hpp index 654c1fbe80c..dbf847b10d6 100644 --- a/addons/maverick/CfgAmmo.hpp +++ b/addons/maverick/CfgAmmo.hpp @@ -1,3 +1,4 @@ +class ace_missileguidance_type_Maverick; class CfgAmmo { class MissileCore; class MissileBase: MissileCore { @@ -5,6 +6,21 @@ class CfgAmmo { }; class Missile_AGM_02_F: MissileBase {}; + class GVAR(D): Missile_AGM_02_F { + author = "Dani (TCVM)"; + missileLockMaxDistance = 14000; + maneuvrability = 0; + class ace_missileguidance: ace_missileguidance_type_Maverick { + enabled = 1; + }; + }; + + class GVAR(G): GVAR(D) { + class ace_missileguidance: ace_missileguidance { + enabled = 1; + }; + }; + class GVAR(L): Missile_AGM_02_F { author = "xrufix"; autoSeekTarget = 0; @@ -13,30 +29,15 @@ class CfgAmmo { manualControl = 0; missileLockMaxDistance = 16000; weaponLockSystem = 4; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Maverick { enabled = 1; - - minDeflection = 0; - maxDeflection = 0.002; - incDeflection = 0.001; - - canVanillaLock = 0; - defaultSeekerType = "SALH"; seekerTypes[] = {"SALH"}; defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = {"LOAL","LOBL"}; - - seekLastTargetPos = 1; - seekerAngle = 60; - seekerAccuracy = 1; + seekerLockModes[] = {"LOAL"}; - seekerMinRange = 1; seekerMaxRange = 16000; - - defaultAttackProfile = "maverick"; - attackProfiles[] = {"maverick"}; }; }; @@ -46,14 +47,10 @@ class CfgAmmo { irLock = 0; missileLockMaxDistance = 10000; weaponLockSystem = 4; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Maverick { enabled = 1; - - minDeflection = 0; - maxDeflection = 0.002; - incDeflection = 0.001; - - canVanillaLock = 0; + pitchRate = 20; + yawRate = 20; defaultSeekerType = "SALH"; seekerTypes[] = {"SALH"}; @@ -61,15 +58,8 @@ class CfgAmmo { defaultSeekerLockMode = "LOAL"; seekerLockModes[] = {"LOAL"}; - seekLastTargetPos = 1; seekerAngle = 40; - seekerAccuracy = 1; - - seekerMinRange = 1; seekerMaxRange = 10000; - - defaultAttackProfile = "maverick"; - attackProfiles[] = {"maverick"}; }; }; }; diff --git a/addons/maverick/CfgMagazines.hpp b/addons/maverick/CfgMagazines.hpp index 705d52010d2..1e51ede8b01 100644 --- a/addons/maverick/CfgMagazines.hpp +++ b/addons/maverick/CfgMagazines.hpp @@ -12,7 +12,71 @@ class CfgMagazines { class PylonRack_Missile_AGM_02_x1: magazine_Missile_AGM_02_x1 {}; class PylonRack_Missile_AGM_02_x2: magazine_Missile_AGM_02_x1 {}; + + // Optical Mavericks + class GVAR(D_magazine): 6Rnd_Missile_AGM_02_F { + ammo = QGVAR(D); + author = "Dani (TCVM)"; + displayName = CSTRING(d_mag_x1); + }; + class GVAR(D_pylonRack_1Rnd): PylonRack_1Rnd_Missile_AGM_02_F { + ammo = QGVAR(D); + author = "Dani (TCVM)"; + displayName = CSTRING(d_mag_x1); + pylonWeapon = QGVAR(D_Launcher); + }; + class GVAR(D_pylonRack_3Rnd): PylonRack_3Rnd_Missile_AGM_02_F { + ammo = QGVAR(D); + author = "Dani (TCVM)"; + displayName = CSTRING(d_mag_x3); + pylonWeapon = QGVAR(D_Launcher); + }; + + class GVAR(G_magazine_x1): magazine_Missile_AGM_02_x1 { + ammo = QGVAR(G); + author = "Dani (TCVM)"; + displayName = CSTRING(g_mag_x1); + }; + class GVAR(G_pylonmissile_x1): PylonMissile_Missile_AGM_02_x1 { + ammo = QGVAR(G); + author = "Dani (TCVM)"; + displayName = CSTRING(g_mag_x1); + pylonWeapon = QGVAR(G_Launcher); + }; + class GVAR(G_pylonmissile_x2): PylonMissile_Missile_AGM_02_x2 { + ammo = QGVAR(G); + author = "Dani (TCVM)"; + displayName = CSTRING(g_mag_x2); + pylonWeapon = QGVAR(G_Launcher); + }; + + class GVAR(G_pylonRack_1Rnd): PylonRack_1Rnd_Missile_AGM_02_F { + ammo = QGVAR(G); + author = "Dani (TCVM)"; + displayName = CSTRING(g_mag_x1); + pylonWeapon = QGVAR(G_Launcher); + }; + class GVAR(G_PylonRack_3Rnd): PylonRack_3Rnd_Missile_AGM_02_F { + ammo = QGVAR(G); + author = "Dani (TCVM)"; + displayName = CSTRING(g_mag_x3); + pylonWeapon = QGVAR(G_Launcher); + }; + + class GVAR(G_PylonRack_x1): PylonRack_Missile_AGM_02_x1 { + ammo = QGVAR(G); + author = "Dani (TCVM)"; + displayName = CSTRING(g_mag_x1); + pylonWeapon = QGVAR(G_Launcher); + }; + class GVAR(G_PylonRack_x2): PylonRack_Missile_AGM_02_x2 { + ammo = QGVAR(G); + author = "Dani (TCVM)"; + displayName = CSTRING(g_mag_x2); + pylonWeapon = QGVAR(G_Launcher); + }; + // Laser Mavericks class GVAR(L_magazine_x1): magazine_Missile_AGM_02_x1 { ammo = QGVAR(L); author = "xrufix"; diff --git a/addons/maverick/CfgWeapons.hpp b/addons/maverick/CfgWeapons.hpp index 1c0ae744efe..a60681a3cf1 100644 --- a/addons/maverick/CfgWeapons.hpp +++ b/addons/maverick/CfgWeapons.hpp @@ -6,6 +6,22 @@ class CfgWeapons { class MissileLauncher: LauncherCore {}; class Missile_AGM_02_Plane_CAS_01_F: MissileLauncher {}; + class GVAR(D_Launcher): Missile_AGM_02_Plane_CAS_01_F { + author = "Dani (TCVM)"; + displayname = CSTRING(D); + magazines[] = {QGVAR(D_magazine), QGVAR(D_pylonRack_1Rnd), QGVAR(D_pylonRack_3Rnd)}; + weaponLockDelay = 0.1; + weaponLockSystem = 2; + }; + + class GVAR(G_Launcher): weapon_AGM_65Launcher { + author = "Dani (TCVM)"; + displayname = CSTRING(G); + magazines[] = {QGVAR(G_magazine_x1), QGVAR(G_pylonmissile_x1), QGVAR(G_pylonmissile_x2), QGVAR(G_pylonRack_1Rnd), QGVAR(G_PylonRack_3Rnd), QGVAR(G_PylonRack_x1), QGVAR(G_PylonRack_x2)}; + weaponLockDelay = 0.1; + weaponLockSystem = 2; + }; + class GVAR(L_Launcher): weapon_AGM_65Launcher { author = "xrufix"; displayname = CSTRING(L); diff --git a/addons/maverick/config.cpp b/addons/maverick/config.cpp index 6d5837f87da..d25878d004d 100644 --- a/addons/maverick/config.cpp +++ b/addons/maverick/config.cpp @@ -9,10 +9,6 @@ class CfgPatches { authors[] = {"xrufix"}; url = ECSTRING(main,URL); VERSION_CONFIG; - ammo[] = { - QGVAR(L), - "ace_kh25ml" - }; magazines[] = { QGVAR(L_magazine_x1), QGVAR(L_pylonmissile_x1), diff --git a/addons/maverick/stringtable.xml b/addons/maverick/stringtable.xml index 6bf1d80e042..88fa026a275 100644 --- a/addons/maverick/stringtable.xml +++ b/addons/maverick/stringtable.xml @@ -6,7 +6,7 @@ AGM-65 Maverick L, Laser Guided Anti-Ground-Missile AGM-65 Maverick L, lasergelenkte Luft-Boden-Rakete AGM-65 Maverick L, Missile Aria-Terra Laserguidato - AGM-65 マーベリック L、レーザー誘導対地ミサイル + AGM-65 マーベリック L、 レーザー誘導対地ミサイル AGM-65"小牛"飛彈L型,雷射導引對地導彈 AGM-65"小牛"L型激光制导对地导弹 AGM-65 매버릭 L, 레이저 유도 대지 미사일 @@ -82,10 +82,10 @@ 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、 レーザー誘導対地ミサイル Kh-25ML, Missile Aria-Terra Laserguidato Kh-25ML, Kierowany laserowo pocisk powietrze-ziemia Х-25МЛ, ракета Воздух-Земля с лазерным наведением @@ -111,6 +111,69 @@ 1x Kh-25ML [ACE] 1x Kh-25ML [ACE] + + AGM-65 Maverick D + AGM-65 Maverick D + AGM-65 Maverick D + AGM-65 マーベリック D + AGM-65 매버릭 D + AGM-65 Maverick D + AGM-65 Maverick D + + + AGM-65 Maverick G + AGM-65 Maverick G + AGM-65 Maverick G + AGM-65 マーベリック G + AGM-65 매버릭 G + AGM-65 Maverick G + AGM-65 Maverick G + + + AGM-65 Maverick D [ACE] + AGM-65 Maverick D [ACE] + AGM-65 Maverick D [ACE] + AGM-65 マーベリック D [ACE] + AGM-65 매버릭 D [ACE] + AGM-65 Maverick D [ACE] + AGM-65 Maverick D [ACE] + + + 3x AGM-65 Maverick D [ACE] + 3x AGM-65 Maverick D [ACE] + 3x AGM-65 Maverick D [ACE] + 3x AGM-65 マーベリック D [ACE] + 3x AGM-65 매버릭 D [ACE] + 3x AGM-65 Maverick D [ACE] + 3x AGM-65 Maverick D [ACE] + + + AGM-65 Maverick G [ACE] + AGM-65 Maverick G [ACE] + AGM-65 Maverick G [ACE] + AGM-65 マーベリック G [ACE] + AGM-65 매버릭 G [ACE] + AGM-65 Maverick G [ACE] + AGM-65 Maverick G [ACE] + + + 2x AGM-65 Maverick G [ACE] + 2x AGM-65 Maverick G [ACE] + 2x AGM-65 Maverick G [ACE] + 2x AGM-65 マーベリック G [ACE] + 2x AGM-65 매버릭 G [ACE] + 2x AGM-65 Maverick G [ACE] + 2x AGM-65 Maverick G [ACE] + + + 3x AGM-65 Maverick G [ACE] + 3x AGM-65 Maverick G [ACE] + 3x AGM-65 Maverick G [ACE] + 3x AGM-65 マーベリック G [ACE] + 3x AGM-65 매버릭 G [ACE] + 3x AGM-65 Maverick G [ACE] + 3x AGM-65 Maverick G [ACE] + diff --git a/addons/medical/dev/test_hitpointConfigs.sqf b/addons/medical/dev/test_hitpointConfigs.sqf index 9de5c5e6868..ff1c3a95b7d 100644 --- a/addons/medical/dev/test_hitpointConfigs.sqf +++ b/addons/medical/dev/test_hitpointConfigs.sqf @@ -10,7 +10,11 @@ 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")}; +private _units = _uniforms apply { + private _unitCfg = _cfgVehicles >> getText (_x >> "ItemInfo" >> "uniformClass"); + if (isNull _unitCfg) then { WARNING_2("%1 has invalid uniformClass %2",configName _x,getText (_x >> "ItemInfo" >> "uniformClass")) }; + _unitCfg +}; 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])); @@ -21,23 +25,17 @@ 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}; - - // _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); + if (_typeOf == "") then { continue }; + 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; }; - if (((_hitpoints findIf {_x == "HitLeftArm"}) == -1) || {(_hitpoints findIf {_x == "HitRightArm"}) == -1} - || {(_hitpoints findIf {_x == "HitLeftLeg"}) == -1} || {(_hitpoints findIf {_x == "HitRightLeg"}) == -1} - || {(_hitpoints findIf {_x == "HitHead"}) == -1} || {(_hitpoints findIf {_x == "HitBody"}) == -1}) then { - WARNING_2("%1 missing ace hitpoints: %2",_typeOf,_hitpoints); - _testPass = false; - }; + // _typeOf createUnit [position player, group player, "z = this"]; + // deleteVehicle z; } forEach _units; _testPass diff --git a/addons/medical/dev/watchVariable.sqf b/addons/medical/dev/watchVariable.sqf index 05cb094ba8a..a0e064595ab 100644 --- a/addons/medical/dev/watchVariable.sqf +++ b/addons/medical/dev/watchVariable.sqf @@ -10,10 +10,10 @@ GVAR(dev_watchVariableRunning) = true; if (!isNull _display) exitWith {"Paused"}; private _unit = cursorTarget; - if (!(_unit isKindOf "CAManBase")) then {_unit = cursorObject}; - if (!(_unit isKindOf "CAManBase")) then {_unit = ACE_player}; + if !(_unit isKindOf "CAManBase") then {_unit = cursorObject}; + if !(_unit isKindOf "CAManBase") then {_unit = ACE_player}; if ((_unit != ACE_player) && {IS_UNCONSCIOUS(ACE_player)}) then {_unit = ACE_player}; - if (!(_unit isKindOf "CAManBase")) exitWith {"No Unit?"}; + if !(_unit isKindOf "CAManBase") exitWith {"No Unit?"}; private _return = []; diff --git a/addons/medical/functions/fnc_addDamageToUnit.sqf b/addons/medical/functions/fnc_addDamageToUnit.sqf index 3d82cbe77aa..e490399c4bf 100644 --- a/addons/medical/functions/fnc_addDamageToUnit.sqf +++ b/addons/medical/functions/fnc_addDamageToUnit.sqf @@ -34,7 +34,7 @@ params [ ]; TRACE_7("addDamageToUnit",_unit,_damageToAdd,_bodyPart,_typeOfDamage,_instigator,_damageSelectionArray,_overrideInvuln); -_bodyPart = toLower _bodyPart; +_bodyPart = toLowerANSI _bodyPart; private _bodyPartIndex = ALL_BODY_PARTS find _bodyPart; if (_bodyPartIndex < 0) then { _bodyPartIndex = ALL_SELECTIONS find _bodyPart; }; // 2nd attempt with selection names ("hand_l", "hand_r", "leg_l", "leg_r") if (_bodyPartIndex < 0) exitWith {ERROR_1("addDamageToUnit - bad selection %1",_this); false}; diff --git a/addons/medical/functions/fnc_deserializeState.sqf b/addons/medical/functions/fnc_deserializeState.sqf index b7846bf9015..6fbb00985db 100644 --- a/addons/medical/functions/fnc_deserializeState.sqf +++ b/addons/medical/functions/fnc_deserializeState.sqf @@ -29,6 +29,7 @@ if (!local _unit) exitWith { ERROR_1("unit [%1] is not local",_unit) }; if !(_unit getVariable [QGVAR(initialized), false]) exitWith { [QEGVAR(medical_status,initialized), { params ["_unit"]; + //IGNORE_PRIVATE_WARNING ["_thisArgs", "_thisId", "_thisType"]; _thisArgs params ["_target"]; if (_unit == _target) then { diff --git a/addons/medical/initSettings.inc.sqf b/addons/medical/initSettings.inc.sqf index 3c54f47cee1..adc53c2ea83 100644 --- a/addons/medical/initSettings.inc.sqf +++ b/addons/medical/initSettings.inc.sqf @@ -34,7 +34,7 @@ "SLIDER", [LSTRING(SpontaneousWakeUpChance_DisplayName), LSTRING(SpontaneousWakeUpChance_Description)], LSTRING(Category), - [0, 1, 0.05, 2, true], + [0, 1, 0.1, 2, true], true ] call CBA_fnc_addSetting; @@ -43,6 +43,6 @@ "SLIDER", [LSTRING(spontaneousWakeUpEpinephrineBoost_DisplayName), LSTRING(spontaneousWakeUpEpinephrineBoost_Description)], LSTRING(Category), - [1, 30, 1, 1], + [1, 30, 1.5, 1], true ] call CBA_fnc_addSetting; diff --git a/addons/medical/stringtable.xml b/addons/medical/stringtable.xml index cfc05e4d751..1a6cb07dbbe 100644 --- a/addons/medical/stringtable.xml +++ b/addons/medical/stringtable.xml @@ -32,12 +32,12 @@ ACE 医疗 界面 ACE 醫療系統 介面 ACE Medikal Arayüz - ACE 医療 インターフェース + ACE 医療 インタフェース Unconscious Wake Up Chance Wahrscheinlichkeit um aufzuwachen - 気絶時の覚醒確率 + 無意識状態時の覚醒確率 Шанс очнуться при потере сознания Chance de reprendre connaissance Chance de recuperar consciência @@ -84,7 +84,7 @@ 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.) diff --git a/addons/medical_ai/XEH_PREP.hpp b/addons/medical_ai/XEH_PREP.hpp index de4ac3c38a3..3cf2b3e2441 100644 --- a/addons/medical_ai/XEH_PREP.hpp +++ b/addons/medical_ai/XEH_PREP.hpp @@ -1,3 +1,4 @@ +PREP(addHealingCommandActions); PREP(canRequestMedic); PREP(healingLogic); PREP(healSelf); diff --git a/addons/medical_ai/XEH_postInit.sqf b/addons/medical_ai/XEH_postInit.sqf index 0b225c7f0b0..22f2fa5f23f 100644 --- a/addons/medical_ai/XEH_postInit.sqf +++ b/addons/medical_ai/XEH_postInit.sqf @@ -2,10 +2,12 @@ ["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 ["ace_firedNonPlayer", { + //IGNORE_PRIVATE_WARNING ["_unit"]; _unit setVariable [QGVAR(lastFired), CBA_missionTime]; }] call CBA_fnc_addEventHandler; @@ -19,6 +21,19 @@ _unit setVariable [QGVAR(lastSuppressed), CBA_missionTime]; }] call CBA_fnc_addClassEventHandler; - #include "stateMachine.inc.sqf" + // Add command actions to command AI medics to treat other units + call FUNC(addHealingCommandActions); + if (GVAR(requireItems) == 2) then { + ["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; + }; + + #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 5725d1e119e..8cdc2ee6ad8 100644 --- a/addons/medical_ai/XEH_preInit.sqf +++ b/addons/medical_ai/XEH_preInit.sqf @@ -13,6 +13,6 @@ if (isNil QGVAR(timeSafe_shoot)) then { GVAR(timeSafe_shoot) = 30; }; if (isNil QGVAR(timeSafe_hit)) then { GVAR(timeSafe_hit) = 30; }; if (isNil QGVAR(timeSafe_suppressed)) then { GVAR(timeSafe_suppressed) = 30; }; -GVAR(itemHash) = uinamespace getVariable QGVAR(itemHash); +GVAR(itemHash) = uiNamespace getVariable QGVAR(itemHash); ADDON = true; diff --git a/addons/medical_ai/XEH_preStart.sqf b/addons/medical_ai/XEH_preStart.sqf index b4d795cbbf6..3782a3eab78 100644 --- a/addons/medical_ai/XEH_preStart.sqf +++ b/addons/medical_ai/XEH_preStart.sqf @@ -20,8 +20,9 @@ private _itemHash = createHashMap; } forEach [ ["@bandage", ["FieldDressing", "PackingBandage", "ElasticBandage", "QuikClot"]], ["@iv", ["SalineIV", "SalineIV_500", "SalineIV_250", "BloodIV", "BloodIV_500", "BloodIV_250", "PlasmaIV", "PlasmaIV_500", "PlasmaIV_250"]], + ["tourniquet", ["ApplyTourniquet"]], ["splint", ["splint"]], ["morphine", ["morphine"]], ["epinephrine", ["epinephrine"]] ]; -uinamespace setVariable [QGVAR(itemHash), compileFinal _itemHash]; +uiNamespace setVariable [QGVAR(itemHash), compileFinal _itemHash]; diff --git a/addons/medical_ai/functions/fnc_addHealingCommandActions.sqf b/addons/medical_ai/functions/fnc_addHealingCommandActions.sqf new file mode 100644 index 00000000000..853fdad8582 --- /dev/null +++ b/addons/medical_ai/functions/fnc_addHealingCommandActions.sqf @@ -0,0 +1,89 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Adds ACE actions for the player to command medics to heal injured units. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_medical_ai_fnc_addHealingCommandActions + * + * Public: No + */ + +if (!hasInterface) exitWith {}; + +//IGNORE_PRIVATE_WARNING ["_player", "_target"]; +private _action = [ + QGVAR(heal), + localize "STR_A3_Task180_name", + "", + {}, + {_player == leader _player}, + { + private _units = units _player; + + (_units select {_x call EFUNC(common,isAwake) && {_x call EFUNC(medical_treatment,isMedic)} && {!(_x call EFUNC(common,isPlayer))}}) apply { + [ + [ + QGVAR(medicHeal_) + str _x, + format ["%1: (%2)", [_x, false, true] call EFUNC(common,getName), groupId _x], + "", + {}, + {true}, + { + (_this select 2) params ["_healer", "_units"]; + + (_units select {_x call FUNC(isInjured)}) apply { + [ + [ + QGVAR(healUnit_) + str _x, + format [localize "str_action_heal_soldier", ([_x, false, true] call EFUNC(common,getName)) + " (" + str groupId _x + ")"], + "", + { + (_this select 2) params ["_healer", "_target"]; + + private _assignedMedic = _target getVariable [QGVAR(assignedMedic), objNull]; + + // Remove from previous medic's queue + if (!isNull _assignedMedic && {_healer != _assignedMedic}) then { + private _healQueue = _assignedMedic getVariable [QGVAR(healQueue), []]; + + _healQueue deleteAt (_healQueue find _target); + + _assignedMedic setVariable [QGVAR(healQueue), _healQueue]; + }; + + _target setVariable [QGVAR(assignedMedic), _healer]; + + // Add to new medic + private _healQueue = _healer getVariable [QGVAR(healQueue), []]; + + _healQueue deleteAt (_healQueue find _target); + _healQueue insert [0, [_target]]; + + _healer setVariable [QGVAR(healQueue), _healQueue]; + }, + {true}, + {}, + [_healer, _x] + ] call EFUNC(interact_menu,createAction), + [], + _x + ] + }; + }, + [_x, _units] + ] call EFUNC(interact_menu,createAction), + [], + _x + ] + }; + } +] call EFUNC(interact_menu,createAction); + +["CAManBase", 1, ["ACE_SelfActions"], _action, true] call EFUNC(interact_menu,addActionToClass); diff --git a/addons/medical_ai/functions/fnc_canRequestMedic.sqf b/addons/medical_ai/functions/fnc_canRequestMedic.sqf index 685bd57f540..5064e1a7321 100644 --- a/addons/medical_ai/functions/fnc_canRequestMedic.sqf +++ b/addons/medical_ai/functions/fnc_canRequestMedic.sqf @@ -4,13 +4,13 @@ * Checks if there is a medic available in the unit's group. * * Arguments: - * None + * Unit * * Return Value: * Can request medic * * Example: - * player call ACE_medical_ai_fnc_canRequestMedic + * player call ace_medical_ai_fnc_canRequestMedic * * Public: No */ diff --git a/addons/medical_ai/functions/fnc_healSelf.sqf b/addons/medical_ai/functions/fnc_healSelf.sqf index 5747637995e..60f2b837124 100644 --- a/addons/medical_ai/functions/fnc_healSelf.sqf +++ b/addons/medical_ai/functions/fnc_healSelf.sqf @@ -4,13 +4,13 @@ * Makes the unit heal itself. * * Arguments: - * None + * Unit * * Return Value: * None * * Example: - * call ACE_medical_ai_fnc_healSelf + * cursorObject call ace_medical_ai_fnc_healSelf * * Public: No */ diff --git a/addons/medical_ai/functions/fnc_healUnit.sqf b/addons/medical_ai/functions/fnc_healUnit.sqf index ad867d25700..6d94749d1f9 100644 --- a/addons/medical_ai/functions/fnc_healUnit.sqf +++ b/addons/medical_ai/functions/fnc_healUnit.sqf @@ -4,16 +4,17 @@ * Makes a medic heal the next unit that needs treatment. * * Arguments: - * None + * Unit * * Return Value: * None * * Example: - * call ACE_medical_ai_fnc_healUnit + * cursorObject call ace_medical_ai_fnc_healUnit * * Public: No */ + // Player will have to do this manually of course if ([_this] call EFUNC(common,isPlayer)) exitWith {}; // Can't heal other units when unconscious @@ -23,10 +24,16 @@ if IS_UNCONSCIOUS(_this) exitWith { // Find next unit to treat private _healQueue = _this getVariable [QGVAR(healQueue), []]; -private _target = _healQueue select 0; +private _target = _healQueue param [0, objNull]; // If unit died or was healed, be lazy and wait for the next tick -if (isNull _target || {!alive _target} || {!(_target call FUNC(isInjured))}) exitWith { +// If the unit can't be healed, go to the next unit to be healed +if (!alive _target || {!(_target call FUNC(isInjured))} || { + private _treatmentEvent = (_this getVariable [QGVAR(currentTreatment), []]) param [2, ""]; + + // Target still needs healing, but the healer doesn't have the required items (only happens if GVAR(requireItems) != 0) or needs to wait + (_treatmentEvent select [0, 6]) == "#needs" +}) exitWith { _this forceSpeed -1; _target forceSpeed -1; _healQueue deleteAt 0; @@ -46,6 +53,10 @@ if (_this distance _target > 2.5) exitWith { _this setVariable [QGVAR(currentTreatment), nil]; if (CBA_missionTime >= (_this getVariable [QGVAR(nextMoveOrder), CBA_missionTime])) then { _this setVariable [QGVAR(nextMoveOrder), CBA_missionTime + 10]; + + // Medic, when doing a lot of treatment, moves away from injured over time (because of animations) + // Need to allow the medic to move back to the injured again + _this forceSpeed -1; _this doMove getPosATL _target; #ifdef DEBUG_MODE_FULL systemChat format ["%1 moving to %2", _this, _target]; diff --git a/addons/medical_ai/functions/fnc_healingLogic.sqf b/addons/medical_ai/functions/fnc_healingLogic.sqf index fa35b49284d..9c7ce1c847f 100644 --- a/addons/medical_ai/functions/fnc_healingLogic.sqf +++ b/addons/medical_ai/functions/fnc_healingLogic.sqf @@ -1,7 +1,9 @@ #include "..\script_component.hpp" /* - * Author: BaerMitUmlaut, PabstMirror - * Applies healing to target + * Author: BaerMitUmlaut, PabstMirror, johnb43 + * Applies healing to target. + * States that contain "needs" are states in which the medic is blocked, either temporairly (HR too high/low) or until resupplied, from treating. + * States that contain "wait" are states where the medic waits temporairly before continuing treatment. * * Arguments: * 0: Healer @@ -11,7 +13,7 @@ * Nothing * * Example: - * [a, b] call ACE_medical_ai_fnc_healingLogic + * [cursorObject, cursorObject] call ace_medical_ai_fnc_healingLogic * * Public: No */ @@ -24,14 +26,58 @@ if (_finishTime > 0) exitWith { if (CBA_missionTime >= _finishTime) then { TRACE_5("treatment finished",_finishTime,_treatmentTarget,_treatmentEvent,_treatmentArgs,_treatmentItem); _healer setVariable [QGVAR(currentTreatment), nil]; + + private _usedItem = ""; + if ((GVAR(requireItems) > 0) && {_treatmentItem != ""}) then { ([_healer, _treatmentItem] call FUNC(itemCheck)) params ["_itemOk", "_itemClassname", "_treatmentClass"]; - if (!_itemOk) exitWith { _treatmentEvent = "#fail"; }; // no item after delay + // No item after treatment done + if (!_itemOk) exitWith { + _treatmentEvent = "#fail"; + }; + _healer removeItem _itemClassname; - if (_treatmentClass != "") then { _treatmentArgs set [2, _treatmentClass]; }; + _usedItem = _itemClassname; + + if (_treatmentClass != "") then { + _treatmentArgs set [2, _treatmentClass]; + }; }; if ((_treatmentTarget == _target) && {(_treatmentEvent select [0, 1]) != "#"}) then { + // There is no event for tourniquet removal, so handle calling function directly + if (_treatmentEvent == QGVAR(tourniquetRemove)) exitWith { + _treatmentArgs call EFUNC(medical_treatment,tourniquetRemove); + }; + [_treatmentEvent, _treatmentArgs, _target] call CBA_fnc_targetEvent; + + // Splints are already logged on their own + switch (_treatmentEvent) do { + case QEGVAR(medical_treatment,bandageLocal): { + [_target, "activity", ELSTRING(medical_treatment,Activity_bandagedPatient), [[_healer, false, true] call EFUNC(common,getName)]] call EFUNC(medical_treatment,addToLog); + }; + case QEGVAR(medical_treatment,ivBagLocal): { + if (_usedItem == "") then { + _usedItem = "ACE_salineIV"; + }; + + [_target, _usedItem] call EFUNC(medical_treatment,addToTriageCard); + [_target, "activity", ELSTRING(medical_treatment,Activity_gaveIV), [[_healer, false, true] call EFUNC(common,getName)]] call EFUNC(medical_treatment,addToLog); + }; + case QEGVAR(medical_treatment,medicationLocal): { + if (_usedItem == "") then { + _usedItem = ["ACE_epinephrine", "ACE_morphine"] select (_treatmentArgs select 2 == "Morphine"); + }; + + [_target, _usedItem] call EFUNC(medical_treatment,addToTriageCard); + [_target, "activity", ELSTRING(medical_treatment,Activity_usedItem), [[_healer, false, true] call EFUNC(common,getName), getText (configFile >> "CfgWeapons" >> _usedItem >> "displayName")]] call EFUNC(medical_treatment,addToLog); + }; + case QEGVAR(medical_treatment,tourniquetLocal): { + [_target, "ACE_tourniquet"] call EFUNC(medical_treatment,addToTriageCard); + [_target, "activity", ELSTRING(medical_treatment,Activity_appliedTourniquet), [[_healer, false, true] call EFUNC(common,getName)]] call EFUNC(medical_treatment,addToLog); + }; + }; + #ifdef DEBUG_MODE_FULL INFO_4("%1->%2: %3 - %4",_healer,_target,_treatmentEvent,_treatmentArgs); systemChat format ["Applying [%1->%2]: %3", _healer, _treatmentTarget, _treatmentEvent]; @@ -40,38 +86,164 @@ if (_finishTime > 0) exitWith { }; }; -private _isMedic = [_healer] call EFUNC(medical_treatment,isMedic); -private _heartRate = GET_HEART_RATE(_target); -private _fractures = GET_FRACTURES(_target); +// Bandage a limb up, then remove the tourniquet on it +private _fnc_removeTourniquet = { + params [["_removeAllTourniquets", false]]; + + // Ignore head & torso if not removing all tourniquets (= administering drugs/IVs) + private _offset = [2, 0] select _removeAllTourniquets; + + // Bandage the least bleeding body part + private _bodyPartBleeding = []; + _bodyPartBleeding resize [[4, 6] select _removeAllTourniquets, -1]; + + { + // Ignore head and torso, if only looking for place to administer drugs/IVs + private _partIndex = (ALL_BODY_PARTS find _x) - _offset; + + if (_partIndex >= 0 && {_tourniquets select _partIndex != 0}) then { + { + _x params ["", "_amountOf", "_bleeding"]; + + // max 0, to set the baseline to 0, as body parts with no wounds are marked with -1 + _bodyPartBleeding set [_partIndex, ((_bodyPartBleeding select _partIndex) max 0) + (_amountOf * _bleeding)]; + } forEach _y; + }; + } forEach GET_OPEN_WOUNDS(_target); + + // If there are no open wounds, check if there are tourniquets on limbs with no open wounds (stitched or fully healed), + // as we know there have to be tourniquets at this point + if (_bodyPartBleeding findIf {_x != -1} == -1) then { + _bodyPartBleeding set [_tourniquets findIf {_x != 0}, 0]; + }; + + // Ignore body parts that don't have open wounds (-1) + private _minBodyPartBleeding = selectMin (_bodyPartBleeding select {_x != -1}); + private _selection = ALL_BODY_PARTS select ((_bodyPartBleeding find _minBodyPartBleeding) + _offset); + + // If not bleeding anymore, remove the tourniquet + if (_minBodyPartBleeding == 0) exitWith { + _treatmentEvent = QGVAR(tourniquetRemove); + _treatmentTime = 7; + _treatmentArgs = [_healer, _target, _selection]; + }; + + // If no bandages available, wait + // If check is done at the start of the scope, it will miss the edge case where the unit ran out of bandages just as they finished bandaging tourniqueted body part + if !(([_healer, "@bandage"] call FUNC(itemCheck)) # 0) exitWith { + _treatmentEvent = "#needsBandage"; + }; + + // Otherwise keep bandaging + _treatmentEvent = QEGVAR(medical_treatment,bandageLocal); + _treatmentTime = 5; + _treatmentArgs = [_target, _selection, "FieldDressing"]; + _treatmentItem = "@bandage"; +}; + +// Find a suitable limb (no tourniquets) for adminstering drugs/IVs +private _fnc_findNoTourniquet = { + private _bodyPart = ""; + + // If all limbs have tourniquets, find the least damaged limb and try to bandage it + if ((_tourniquets select [2]) find 0 == -1) then { + call _fnc_removeTourniquet; + } else { + // Select a random non-tourniqueted limb otherwise + private _bodyParts = ["leftarm", "rightarm", "leftleg", "rightleg"]; + + while {_bodyParts isNotEqualTo []} do { + _bodyPart = selectRandom _bodyParts; + + // If no tourniquet on, use that body part + if (_tourniquets select (ALL_BODY_PARTS find _bodyPart) == 0) exitWith {}; + + _bodyParts deleteAt (_bodyParts find _bodyPart); + }; + }; + + _bodyPart // return +}; + +private _tourniquets = GET_TOURNIQUETS(_target); private _treatmentEvent = "#none"; private _treatmentArgs = []; private _treatmentTime = 6; private _treatmentItem = ""; -switch (true) do { - case ((GET_WOUND_BLEEDING(_target) > 0) - && {([_healer, "@bandage"] call FUNC(itemCheck)) # 0}): { - // Select first bleeding wound and bandage it - private _selection = "?"; + +if (true) then { + if (IS_BLEEDING(_target)) exitWith { + private _hasBandage = ([_healer, "@bandage"] call FUNC(itemCheck)) # 0; + private _hasTourniquet = ([_healer, "tourniquet"] call FUNC(itemCheck)) # 0; + + // Patient is not worth treating if bloodloss can't be stopped + if !(_hasBandage || _hasTourniquet) exitWith { + _treatmentEvent = "#needsBandageOrTourniquet"; + }; + + // Bandage the heaviest bleeding body part + private _bodyPartBleeding = [0, 0, 0, 0, 0, 0]; + { - private _foundBleeding = _y findIf { - _x params ["", "_amount", "_percentage"]; - (_amount * _percentage) > 0 + private _partIndex = ALL_BODY_PARTS find _x; + + // Ignore tourniqueted limbs + if (_tourniquets select _partIndex == 0) then { + { + _x params ["", "_amountOf", "_bleeding"]; + _bodyPartBleeding set [_partIndex, (_bodyPartBleeding select _partIndex) + (_amountOf * _bleeding)]; + } forEach _y; }; - if (_foundBleeding != -1) exitWith { _selection = _x; }; } forEach GET_OPEN_WOUNDS(_target); + + private _maxBodyPartBleeding = selectMax _bodyPartBleeding; + private _bodyPartIndex = _bodyPartBleeding find _maxBodyPartBleeding; + private _selection = ALL_BODY_PARTS select _bodyPartIndex; + + // Apply tourniquet if moderate bleeding or no bandage is available, and if not head and torso + if (_hasTourniquet && {_bodyPartIndex > HITPOINT_INDEX_BODY} && {!_hasBandage || {_maxBodyPartBleeding > 0.3}}) exitWith { + _treatmentEvent = QEGVAR(medical_treatment,tourniquetLocal); + _treatmentTime = 7; + _treatmentArgs = [_target, _selection]; + _treatmentItem = "tourniquet"; + }; + _treatmentEvent = QEGVAR(medical_treatment,bandageLocal); _treatmentTime = 5; _treatmentArgs = [_target, _selection, "FieldDressing"]; _treatmentItem = "@bandage"; }; - case (IN_CRDC_ARRST(_target) && {EGVAR(medical_treatment,cprSuccessChanceMin) > 0}): { + + private _bloodVolume = GET_BLOOD_VOLUME(_target); + private _needsIV = _bloodVolume < MINIMUM_BLOOD_FOR_STABLE_VITALS; + private _canGiveIV = _needsIV && + {_healer call EFUNC(medical_treatment,isMedic)} && + {([_healer, "@iv"] call FUNC(itemCheck)) # 0}; // Has IVs + private _doCPR = IN_CRDC_ARRST(_target) && {EGVAR(medical_treatment,cprSuccessChanceMin) > 0}; + + // If in cardiac arrest, first add some blood to injured if necessary, then do CPR (doing CPR when not enough blood is suboptimal if you have IVs) + // If healer has no IVs, allow AI to do CPR to keep injured alive + if ( + _doCPR && + {!_canGiveIV || {_bloodVolume >= BLOOD_VOLUME_CLASS_3_HEMORRHAGE}} + ) exitWith { _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}): { + + private _bodypart = ""; + + if ( + _canGiveIV && { + // If all limbs are tourniqueted, bandage the one with the least amount of wounds, so that the tourniquet can be removed + _bodyPart = call _fnc_findNoTourniquet; + _bodyPart == "" + } + ) exitWith {}; + + if (_canGiveIV) then { // Check if patient's blood volume + remaining IV volume is enough to allow the patient to wake up private _totalIvVolume = 0; //in ml { @@ -79,57 +251,132 @@ switch (true) do { _totalIvVolume = _totalIvVolume + _volumeRemaining; } forEach (_target getVariable [QEGVAR(medical,ivBags), []]); - if (GET_BLOOD_VOLUME(_target) + (_totalIvVolume / 1000) > MINIMUM_BLOOD_FOR_STABLE_VITALS) exitWith { - _treatmentEvent = "#waitForBlood"; + // Check if the medic has to wait, which allows for a little multitasking + if (_bloodVolume + (_totalIvVolume / 1000) >= MINIMUM_BLOOD_FOR_STABLE_VITALS) then { + _treatmentEvent = "#waitForIV"; + _needsIV = false; + _canGiveIV = false; }; + }; + + if (_canGiveIV) exitWith { _treatmentEvent = QEGVAR(medical_treatment,ivBagLocal); _treatmentTime = 5; - _treatmentArgs = [_target, selectRandom ["leftarm", "rightarm", "leftleg", "rightleg"], "SalineIV"]; + _treatmentArgs = [_target, _bodyPart, "SalineIV"]; _treatmentItem = "@iv"; }; - case ((count (_target getVariable [VAR_MEDICATIONS, []])) >= 6): { - _treatmentEvent = "#tooManyMeds"; - }; - case (((_fractures select 4) == 1) - && {([_healer, "splint"] call FUNC(itemCheck)) # 0}): { + + // Leg fractures + private _index = (GET_FRACTURES(_target) select [4, 2]) find 1; + + if ( + _index != -1 && { + // In case the unit doesn't have a splint, set state here + _treatmentEvent = "#needsSplint"; + + ([_healer, "splint"] call FUNC(itemCheck)) # 0 + } + ) exitWith { _treatmentEvent = QEGVAR(medical_treatment,splintLocal); _treatmentTime = 6; - _treatmentArgs = [_healer, _target, "leftleg"]; + _treatmentArgs = [_healer, _target, ALL_BODY_PARTS select (_index + 4)]; _treatmentItem = "splint"; }; - case (((_fractures select 5) == 1) - && {([_healer, "splint"] call FUNC(itemCheck)) # 0}): { - _treatmentEvent = QEGVAR(medical_treatment,splintLocal); - _treatmentTime = 6; - _treatmentArgs = [_healer, _target, "rightleg"]; - _treatmentItem = "splint"; + + // Wait until the injured has enough blood before administering drugs + // (_needsIV && !_canGiveIV), but _canGiveIV is false here, otherwise IV would be given + if (_needsIV || {_doCPR && {_treatmentEvent == "#waitForIV"}}) exitWith { + // If injured is in cardiac arrest and the healer is doing nothing else, start CPR + if (_doCPR) exitWith { + // Medic remains in this loop until injured is given enough IVs or dies + _treatmentEvent = QEGVAR(medical_treatment,cprLocal); + _treatmentArgs = [_healer, _target]; + _treatmentTime = 15; + }; + + // If the injured needs IVs, but healer can't give it to them, have healder wait + if (_needsIV) exitWith { + _treatmentEvent = "#needsIV"; + }; }; - case ((IS_UNCONSCIOUS(_target) || {_heartRate <= 50}) - && {([_healer, "epinephrine"] call FUNC(itemCheck)) # 0}): { - if (CBA_missionTime < (_target getVariable [QGVAR(nextEpinephrine), -1])) exitWith { + + // These checks are not exitWith, so that the medic can try to bandage up tourniqueted body parts + if ((count (_target getVariable [VAR_MEDICATIONS, []])) >= 6) then { + _treatmentEvent = "#needsFewerMeds"; + }; + + private _heartRate = GET_HEART_RATE(_target); + private _canGiveEpinephrine = !(_treatmentEvent in ["#needsFewerMeds", "#waitForIV"]) && + {IS_UNCONSCIOUS(_target) || {_heartRate <= 50}} && + { + // In case the unit doesn't have a epinephrine injector, set state here + _treatmentEvent = "#needsEpinephrine"; + + ([_healer, "epinephrine"] call FUNC(itemCheck)) # 0 + }; + + // This allows for some multitasking + if (_canGiveEpinephrine) then { + if (CBA_missionTime < (_target getVariable [QGVAR(nextEpinephrine), -1])) then { _treatmentEvent = "#waitForEpinephrineToTakeEffect"; + _canGiveEpinephrine = false; }; - if (_heartRate > 180) exitWith { - _treatmentEvent = "#waitForSlowerHeart"; + + if (_heartRate > 180) then { + _treatmentEvent = "#needsSlowerHeart"; + _canGiveEpinephrine = false; }; + }; + + if (_canGiveEpinephrine) exitWith { + // If all limbs are tourniqueted, bandage the one with the least amount of wounds, so that the tourniquet can be removed + _bodyPart = call _fnc_findNoTourniquet; + + if (_bodyPart == "") exitWith {}; + _target setVariable [QGVAR(nextEpinephrine), CBA_missionTime + 10]; _treatmentEvent = QEGVAR(medical_treatment,medicationLocal); _treatmentTime = 2.5; - _treatmentArgs = [_target, selectRandom ["leftarm", "rightarm", "leftleg", "rightleg"], "Epinephrine"]; + _treatmentArgs = [_target, _bodyPart, "Epinephrine"]; _treatmentItem = "epinephrine"; }; - case (((GET_PAIN_PERCEIVED(_target) > 0.25) || {_heartRate >= 180}) - && {([_healer, "morphine"] call FUNC(itemCheck)) # 0}): { + + // Remove all remaining tourniquets by bandaging all body parts + if (_tourniquets isNotEqualTo DEFAULT_TOURNIQUET_VALUES) then { + true call _fnc_removeTourniquet; + }; + + // If the healer can bandage or remove tourniquets, do that + if (_treatmentEvent in [QEGVAR(medical_treatment,bandageLocal), QGVAR(tourniquetRemove)]) exitWith {}; + + // Otherwise, if the healer is either done or out of bandages, continue + if ( + !(_treatmentEvent in ["#needsFewerMeds", "#waitForIV"]) && + {(GET_PAIN_PERCEIVED(_target) > 0.25) || {_heartRate >= 180}} && + { + // In case the unit doesn't have a morphine injector, set state here + _treatmentEvent = "#needsMorphine"; + + ([_healer, "morphine"] call FUNC(itemCheck)) # 0 + } + ) exitWith { if (CBA_missionTime < (_target getVariable [QGVAR(nextMorphine), -1])) exitWith { _treatmentEvent = "#waitForMorphineToTakeEffect"; }; + if (_heartRate < 60) exitWith { - _treatmentEvent = "#waitForFasterHeart"; + _treatmentEvent = "#needsFasterHeart"; }; + + // If all limbs are tourniqueted, bandage the one with the least amount of wounds, so that the tourniquet can be removed + _bodyPart = call _fnc_findNoTourniquet; + + if (_bodyPart == "") exitWith {}; + _target setVariable [QGVAR(nextMorphine), CBA_missionTime + 30]; _treatmentEvent = QEGVAR(medical_treatment,medicationLocal); _treatmentTime = 2.5; - _treatmentArgs = [_target, selectRandom ["leftarm", "rightarm", "leftleg", "rightleg"], "Morphine"]; + _treatmentArgs = [_target, _bodyPart, "Morphine"]; _treatmentItem = "morphine"; }; }; @@ -137,10 +384,16 @@ switch (true) do { _healer setVariable [QGVAR(currentTreatment), [CBA_missionTime + _treatmentTime, _target, _treatmentEvent, _treatmentArgs, _treatmentItem]]; // Play animation -if ((_treatmentEvent select [0,1]) != "#") then { - private _treatmentClassname = _treatmentArgs select 2; - if (_treatmentEvent == QEGVAR(medical_treatment,splintLocal)) then { _treatmentClassname = "Splint" }; - [_healer, _treatmentClassname, (_healer == _target)] call FUNC(playTreatmentAnim); +if ((_treatmentEvent select [0, 1]) != "#") then { + private _treatmentClassname = switch (_treatmentEvent) do { + case QEGVAR(medical_treatment,splintLocal): {"Splint"}; + case QEGVAR(medical_treatment,cprLocal): {"CPR"}; + case QEGVAR(medical_treatment,tourniquetLocal): {"ApplyTourniquet"}; + case QGVAR(tourniquetRemove): {"RemoveTourniquet"}; + default {_treatmentArgs select 2}; + }; + + [_healer, _treatmentClassname, _healer == _target] call FUNC(playTreatmentAnim); }; #ifdef DEBUG_MODE_FULL diff --git a/addons/medical_ai/functions/fnc_isInjured.sqf b/addons/medical_ai/functions/fnc_isInjured.sqf index a163a4c808b..2a4b6895143 100644 --- a/addons/medical_ai/functions/fnc_isInjured.sqf +++ b/addons/medical_ai/functions/fnc_isInjured.sqf @@ -10,7 +10,7 @@ * Does unit need treatment * * Example: - * player call ACE_medical_ai_fnc_isInjured + * cursorObject call ace_medical_ai_fnc_isInjured * * Public: No */ @@ -24,3 +24,4 @@ if !(alive _this) exitWith {false}; private _fractures = GET_FRACTURES(_this); ((_fractures select 4) == 1) || {(_fractures select 5) == 1} } +|| { GET_TOURNIQUETS(_this) isNotEqualTo DEFAULT_TOURNIQUET_VALUES } diff --git a/addons/medical_ai/functions/fnc_isSafe.sqf b/addons/medical_ai/functions/fnc_isSafe.sqf index 04da058ce0c..21d59a15d63 100644 --- a/addons/medical_ai/functions/fnc_isSafe.sqf +++ b/addons/medical_ai/functions/fnc_isSafe.sqf @@ -10,7 +10,7 @@ * Is unit safe enough * * Example: - * call ACE_medical_ai_fnc_isSafe + * cursorObject call ace_medical_ai_fnc_isSafe * * Public: No */ diff --git a/addons/medical_ai/functions/fnc_itemCheck.sqf b/addons/medical_ai/functions/fnc_itemCheck.sqf index 6d91594ce47..320ae62410c 100644 --- a/addons/medical_ai/functions/fnc_itemCheck.sqf +++ b/addons/medical_ai/functions/fnc_itemCheck.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Checks if AI healer has items + * Checks if AI healer has items. * * Arguments: * 0: Healer @@ -13,7 +13,7 @@ * 2: Treatment (Optional) * * Example: - * [cursorObject, "@bandage"] call ACE_medical_ai_fnc_itemCheck + * [cursorObject, "@bandage"] call ace_medical_ai_fnc_itemCheck * * Public: No */ diff --git a/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf b/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf index f412a718d82..9b663f65b22 100644 --- a/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf +++ b/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf @@ -12,14 +12,15 @@ * None * * Example: - * [bob, true, true] call ACE_medical_ai_fnc_playTreatmentAnim + * [cursorObject, "Splint", true] call ace_medical_ai_fnc_playTreatmentAnim * * Public: No */ + params ["_unit", "_actionName", "_isSelfTreatment"]; TRACE_3("playTreatmentAnim",_unit,_actionName,_isSelfTreatment); -if (vehicle _unit != _unit) exitWith {}; +if (!isNull objectParent _unit) exitWith {}; private _configProperty = "animationMedic"; if (_isSelfTreatment) then { diff --git a/addons/medical_ai/functions/fnc_requestMedic.sqf b/addons/medical_ai/functions/fnc_requestMedic.sqf index 9e59181204d..758fa80a1fd 100644 --- a/addons/medical_ai/functions/fnc_requestMedic.sqf +++ b/addons/medical_ai/functions/fnc_requestMedic.sqf @@ -4,21 +4,24 @@ * Sends a request to the units assigned medic to heal it. * * Arguments: - * None + * Unit * * Return Value: * None * * Example: - * call ACE_medical_ai_fnc_requestMedic + * cursorObject call ace_medical_ai_fnc_requestMedic * * Public: No */ private _assignedMedic = _this getVariable QGVAR(assignedMedic); private _healQueue = _assignedMedic getVariable [QGVAR(healQueue), []]; -_healQueue pushBack _this; -_assignedMedic setVariable [QGVAR(healQueue), _healQueue]; + +// Only update if it was actually changed +if (_healQueue pushBackUnique _this != -1) then { + _assignedMedic setVariable [QGVAR(healQueue), _healQueue]; +}; #ifdef DEBUG_MODE_FULL systemChat format ["%1 requested %2 for medical treatment", _this, _assignedMedic]; diff --git a/addons/medical_ai/functions/fnc_wasRequested.sqf b/addons/medical_ai/functions/fnc_wasRequested.sqf index 3b6c1cf0592..ffb9aa37808 100644 --- a/addons/medical_ai/functions/fnc_wasRequested.sqf +++ b/addons/medical_ai/functions/fnc_wasRequested.sqf @@ -4,13 +4,13 @@ * Checks if the unit was requested to treat another unit. * * Arguments: - * None + * Unit * * Return Value: * Was requested * * Example: - * call ACE_medical_ai_fnc_wasRequested + * cursorObject call ace_medical_ai_fnc_wasRequested * * Public: No */ diff --git a/addons/medical_ai/initSettings.inc.sqf b/addons/medical_ai/initSettings.inc.sqf index a2b06519a48..b8ff7e61346 100644 --- a/addons/medical_ai/initSettings.inc.sqf +++ b/addons/medical_ai/initSettings.inc.sqf @@ -1,7 +1,8 @@ private _categoryArray = [ELSTRING(medical,Category), "STR_TEAM_SWITCH_AI"]; [ - QGVAR(enabledFor), "LIST", + QGVAR(enabledFor), + "LIST", [LLSTRING(enableFor_title), LLSTRING(enableFor_desc)], _categoryArray, [ @@ -15,7 +16,8 @@ private _categoryArray = [ELSTRING(medical,Category), "STR_TEAM_SWITCH_AI"]; ] call CBA_fnc_addSetting; [ - QGVAR(requireItems), "LIST", + QGVAR(requireItems), + "LIST", [LSTRING(requireItems_title), LSTRING(requireItems_desc)], _categoryArray, [ @@ -24,16 +26,6 @@ private _categoryArray = [ELSTRING(medical,Category), "STR_TEAM_SWITCH_AI"]; 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; - }, + {[QGVAR(requireItems), _this] call EFUNC(common,cbaSettings_settingChanged)}, true // Needs mission restart ] call CBA_fnc_addSetting; diff --git a/addons/medical_ai/stateMachine.inc.sqf b/addons/medical_ai/stateMachine.inc.sqf index 03483f49815..73b82f98a9c 100644 --- a/addons/medical_ai/stateMachine.inc.sqf +++ b/addons/medical_ai/stateMachine.inc.sqf @@ -17,13 +17,8 @@ GVAR(stateMachine) = [{call EFUNC(common,getLocalUnits)}, true] call CBA_statema #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; +[GVAR(stateMachine), LINKFUNC(healSelf), {}, {}, "HealSelf"] call CBA_statemachine_fnc_addState; +[GVAR(stateMachine), LINKFUNC(healUnit), {}, {}, "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; diff --git a/addons/medical_ai/stringtable.xml b/addons/medical_ai/stringtable.xml index 7f5680dc3fb..54f0c2714cc 100644 --- a/addons/medical_ai/stringtable.xml +++ b/addons/medical_ai/stringtable.xml @@ -20,7 +20,7 @@ AI will respond to injury and unconsciousness KI reagiert auf Verletzungen und Bewusstlosigkeit - AIが負傷者と気絶している人に対して行動するようになります。 + AIが負傷者と無意識状態の人に対して行動するようになります。 ИИ будет реагировать на травмы и потерю сознания Les unités IA seront sensibles aux blessures, ainsi qu'à la perte de connaissance. A IA irá responder a ferimentos e perdas de consciência @@ -58,6 +58,7 @@ Exigir Itens アイテムを要求 Требуемые предметы + Requerir Objetos AI will only perform medical treatment if they have the necessary items in their inventory. @@ -69,6 +70,7 @@ 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 @@ -80,6 +82,7 @@ Conversão automática de itens para IA AIのアイテムを自動変換 Автоматическое преобразование элементов для ИИ + Auto Convertir Objetos para la IA diff --git a/addons/medical_blood/XEH_postInit.sqf b/addons/medical_blood/XEH_postInit.sqf index 9ef55adf0e0..b08921b441e 100644 --- a/addons/medical_blood/XEH_postInit.sqf +++ b/addons/medical_blood/XEH_postInit.sqf @@ -1,9 +1,7 @@ #include "script_component.hpp" -GVAR(useAceMedical) = ["ace_medical"] call EFUNC(common,isModLoaded); - // To support public API regardless of component settings -[QGVAR(spurt), FUNC(spurt)] call CBA_fnc_addEventHandler; +[QGVAR(spurt), LINKFUNC(spurt)] call CBA_fnc_addEventHandler; if (isServer) then { GVAR(bloodDrops) = []; @@ -21,7 +19,7 @@ if (isServer) then { // Start the cleanup loop if (_index == 0) then { - [FUNC(cleanupLoop), [], GVAR(bloodLifetime)] call CBA_fnc_waitAndExecute; + [LINKFUNC(cleanupLoop), [], GVAR(bloodLifetime)] call CBA_fnc_waitAndExecute; }; }] call CBA_fnc_addEventHandler; }; diff --git a/addons/medical_blood/XEH_preInit.sqf b/addons/medical_blood/XEH_preInit.sqf index 852b4dbe73e..93da039be54 100644 --- a/addons/medical_blood/XEH_preInit.sqf +++ b/addons/medical_blood/XEH_preInit.sqf @@ -8,22 +8,8 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" -// Damage types which do not cause blood spurts -GVAR(noBloodDamageTypes) = createHashMapFromArray (call (uiNamespace getVariable QGVAR(noBloodDamageTypes))); - // 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 d051879f3c7..e2683ff5867 100644 --- a/addons/medical_blood/XEH_preStart.sqf +++ b/addons/medical_blood/XEH_preStart.sqf @@ -4,7 +4,4 @@ // Damage types which do not cause blood spurts private _noBloodDamageTypes = "getNumber (_x >> 'noBlood') == 1" configClasses (configFile >> "ACE_Medical_Injuries" >> "damageTypes"); -uiNamespace setVariable [ - QGVAR(noBloodDamageTypes), - compileFinal str (_noBloodDamageTypes apply {[configName _x, nil]}) -]; +uiNamespace setVariable [QGVAR(noBloodDamageTypes), compileFinal (_noBloodDamageTypes createHashMapFromArray [])]; diff --git a/addons/medical_blood/functions/fnc_createBlood.sqf b/addons/medical_blood/functions/fnc_createBlood.sqf index e6740ef459e..fbff6cc3c66 100644 --- a/addons/medical_blood/functions/fnc_createBlood.sqf +++ b/addons/medical_blood/functions/fnc_createBlood.sqf @@ -21,7 +21,7 @@ params ["_type", "_position", "_source"]; TRACE_3("Creating blood",_type,_position,_source); -private _model = GVAR(models) getVariable _type; +private _model = GVAR(models) get _type; private _bloodDrop = createSimpleObject [_model, [0, 0, 0]]; _bloodDrop setDir random 360; diff --git a/addons/medical_blood/functions/fnc_handleWoundReceived.sqf b/addons/medical_blood/functions/fnc_handleWoundReceived.sqf index 8dfc9c650b6..53d5d2361bf 100644 --- a/addons/medical_blood/functions/fnc_handleWoundReceived.sqf +++ b/addons/medical_blood/functions/fnc_handleWoundReceived.sqf @@ -22,13 +22,13 @@ params ["_unit", "_allDamages", "_shooter", "_damageType"]; (_allDamages select 0) params ["_damage"]; // Don't bleed if damage type does not cause bleeding -if (_damageType in GVAR(noBloodDamageTypes)) exitWith {}; +if (_damageType in (uiNamespace getVariable QGVAR(noBloodDamageTypes))) exitWith {}; // Don't bleed when players only and a non-player unit is wounded if (GVAR(enabledFor) == BLOOD_ONLY_PLAYERS && {!isPlayer _unit && {_unit != ACE_player}}) exitWith {}; // Don't bleed on the ground if in a vehicle -if (vehicle _unit != _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; +if (!isNull objectParent _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; private _bulletDir = if (isNull _shooter) then { random 360 // Cannot calculate the direction properly, pick a random direction diff --git a/addons/medical_blood/functions/fnc_init.sqf b/addons/medical_blood/functions/fnc_init.sqf index 86c0c668c18..6392a6e4515 100644 --- a/addons/medical_blood/functions/fnc_init.sqf +++ b/addons/medical_blood/functions/fnc_init.sqf @@ -60,6 +60,6 @@ private _listCode = if (_mode == BLOOD_ONLY_PLAYERS) then { GVAR(stateMachine) = [_listCode, true] call CBA_statemachine_fnc_create; [GVAR(stateMachine), LINKFUNC(onBleeding), {}, {}, "Bleeding"] call CBA_statemachine_fnc_addState; -GVAR(woundReceivedEH) = [QEGVAR(medical,woundReceived), FUNC(handleWoundReceived)] call CBA_fnc_addEventHandler; +GVAR(woundReceivedEH) = [QEGVAR(medical,woundReceived), LINKFUNC(handleWoundReceived)] call CBA_fnc_addEventHandler; TRACE_3("Set up state machine and wounds event",_mode,GVAR(stateMachine),GVAR(woundReceivedEH)); diff --git a/addons/medical_blood/functions/fnc_isBleeding.sqf b/addons/medical_blood/functions/fnc_isBleeding.sqf index 2d57dcf73b3..a21a50913ae 100644 --- a/addons/medical_blood/functions/fnc_isBleeding.sqf +++ b/addons/medical_blood/functions/fnc_isBleeding.sqf @@ -17,7 +17,7 @@ params ["_unit"]; -if (GVAR(useAceMedical)) exitWith { +if (GETEGVAR(medical,enabled,false)) exitWith { IS_BLEEDING(_unit); }; diff --git a/addons/medical_blood/functions/fnc_onBleeding.sqf b/addons/medical_blood/functions/fnc_onBleeding.sqf index 63ceb3bd294..4963aaa21d4 100644 --- a/addons/medical_blood/functions/fnc_onBleeding.sqf +++ b/addons/medical_blood/functions/fnc_onBleeding.sqf @@ -22,10 +22,10 @@ params ["_unit"]; if !(_unit call FUNC(isBleeding)) exitWith {}; // Don't bleed on the ground if in a vehicle -if (vehicle _unit != _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; +if (!isNull objectParent _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; if (CBA_missionTime > (_unit getVariable [QGVAR(nextTime), -10])) then { - private _bloodLoss = (if (GVAR(useAceMedical)) then {GET_BLOOD_LOSS(_unit) * 2.5} else {getDammage _unit * 2}) min 6; + private _bloodLoss = ([damage _unit * 2, GET_BLOOD_LOSS(_unit) * 2.5] select GETEGVAR(medical,enabled,false)) min 6; _unit setVariable [QGVAR(nextTime), CBA_missionTime + 8 + random 2 - _bloodLoss]; TRACE_2("Creating blood drop for bleeding unit",_unit,_bloodLoss); diff --git a/addons/medical_blood/stringtable.xml b/addons/medical_blood/stringtable.xml index 6c3be0c557e..3167b38ef22 100644 --- a/addons/medical_blood/stringtable.xml +++ b/addons/medical_blood/stringtable.xml @@ -27,7 +27,7 @@ Abilita Chiazze di Sangue 开启血液滴落效果 開啟血液滴落效果 - Разрешить капли крови + Вкл. капли крови Permitir gotas de sangue Povolit kapky krve Habilitar manchas de sangre @@ -37,7 +37,7 @@ Enables the creation of blood drops when units are bleeding or take damage. ユニットが出血や負傷した時に、血痕を残すようにします。 Si une unité saigne, elle laissera des traces de sang derrière elle. - Разрешает создание капель крови при кровотечении или получении урона + Включает создание капель крови при кровотечении или получении урона Permitir a criação de gotas de sangue quando as unidades recebem ferimentos ou estão sangrando. 当单位失血或受伤的时,启用出血效果。 啟用出血效果當單位失血或受傷的時候。 @@ -99,7 +99,7 @@ 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. diff --git a/addons/medical_damage/CfgEventHandlers.hpp b/addons/medical_damage/CfgEventHandlers.hpp index 865276cfba9..f6503c2479b 100644 --- a/addons/medical_damage/CfgEventHandlers.hpp +++ b/addons/medical_damage/CfgEventHandlers.hpp @@ -9,3 +9,9 @@ class Extended_PreInit_EventHandlers { init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/medical_damage/XEH_postInit.sqf b/addons/medical_damage/XEH_postInit.sqf new file mode 100644 index 00000000000..39b1c9301e9 --- /dev/null +++ b/addons/medical_damage/XEH_postInit.sqf @@ -0,0 +1,4 @@ +#include "script_component.hpp" + +// Reload configs (handle functions being compiled after medical_damage's preInit) +call FUNC(parseConfigForInjuries); diff --git a/addons/medical_damage/XEH_preInit.sqf b/addons/medical_damage/XEH_preInit.sqf index 344b9c81ee0..b389a0eaa0c 100644 --- a/addons/medical_damage/XEH_preInit.sqf +++ b/addons/medical_damage/XEH_preInit.sqf @@ -10,11 +10,13 @@ PREP_RECOMPILE_END; call FUNC(parseConfigForInjuries); +/* addMissionEventHandler ["Loaded",{ INFO("Mission Loaded - Reloading medical configs for extension"); // Reload configs into extension (handle full game restart) call FUNC(parseConfigForInjuries); }]; +*/ [QEGVAR(medical,woundReceived), LINKFUNC(woundReceived)] call CBA_fnc_addEventHandler; diff --git a/addons/medical_damage/config.cpp b/addons/medical_damage/config.cpp index 4df519a648e..89ac2955250 100644 --- a/addons/medical_damage/config.cpp +++ b/addons/medical_damage/config.cpp @@ -27,13 +27,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgAmmo.hpp" #include "CfgEden.hpp" - -/* -class ACE_Extensions { - 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 index d17b268c157..a867a654707 100644 --- a/addons/medical_damage/functions/fnc_debug_explosiveTest.sqf +++ b/addons/medical_damage/functions/fnc_debug_explosiveTest.sqf @@ -34,7 +34,7 @@ params [ _distances params [["_min", 1], ["_max", 10], ["_step", 1]]; -if (isNil "_center") exitwith {}; +if (isNil "_center") exitWith {}; _max = _max max _min; private _nSteps = 0 max ceil ((_max - _min) / _step); diff --git a/addons/medical_damage/functions/fnc_interpolatePoints.sqf b/addons/medical_damage/functions/fnc_interpolatePoints.sqf index a84f079f302..b3434178373 100644 --- a/addons/medical_damage/functions/fnc_interpolatePoints.sqf +++ b/addons/medical_damage/functions/fnc_interpolatePoints.sqf @@ -19,7 +19,7 @@ */ params ["_input", "_points", ["_randomRound", false]]; -if (count _points < 1) exitWith { +if (_points isEqualTo []) exitWith { //TODO: sensible default/error value 0 }; diff --git a/addons/medical_damage/functions/fnc_parseWoundHandlersCfg.sqf b/addons/medical_damage/functions/fnc_parseWoundHandlersCfg.sqf index 0dad747c683..010f02b7f5d 100644 --- a/addons/medical_damage/functions/fnc_parseWoundHandlersCfg.sqf +++ b/addons/medical_damage/functions/fnc_parseWoundHandlersCfg.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Pterolatypus - * Read a list of wound handler entries from config, accounting for inheritance + * Read a list of wound handler entries from config, accounting for inheritance. * * Arguments: * 0: The config class containing the entries @@ -10,24 +10,43 @@ * None * * Example: - * [configFile >> "ace_medical_injuries" >> "damageTypes"] call ace_medical_damage_fnc_parseWoundHandlersCfg + * [configFile >> "ace_medical_injuries" >> "damageTypes" >> "woundHandlers"] call ace_medical_damage_fnc_parseWoundHandlersCfg * * Public: No */ + params ["_config"]; -// read all valid entries from config and store +// Read all valid entries from config and store private _entries = []; + { - private _entryResult = call compile getText _x; - if !(isNil "_entryResult") then { - _entries pushBack _entryResult; - } + private _entryResult = getText _x; + + if (_entryResult != "") then { + if (ADDON) then { + // Runs in postInit + _entryResult = call compile _entryResult; + + if (!isNil "_entryResult") then { + if (_entryResult isEqualType {}) then { + _entries pushBack _entryResult; + } else { + ERROR_2("Wound handler '%1' needs to be a function, but is of type %2.",configName _x,toLowerANSI typeName _entryResult); + }; + }; + } else { + // Runs in preInit + // In case function doesn't exist yet, wrap in extra layer + _entries pushBack (compile format ["call %1", _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; +// Recursive call for parent +// Can't use configProperties for inheritance since it returns entries in the wrong order +([_parent] call FUNC(parseWoundHandlersCfg)) + _entries // return diff --git a/addons/medical_damage/functions/fnc_woundReceived.sqf b/addons/medical_damage/functions/fnc_woundReceived.sqf index a7e3861dee1..c31cf5b3789 100644 --- a/addons/medical_damage/functions/fnc_woundReceived.sqf +++ b/addons/medical_damage/functions/fnc_woundReceived.sqf @@ -17,18 +17,23 @@ * * 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); + + // If invalid return, exit + if (isNil "_damageData" || {!(_damageData isEqualType [])} || {(count _damageData) < 3}) exitWith { + TRACE_1("Return invalid, skipping wound handling",_damageData); }; } forEach _woundHandlers; }; diff --git a/addons/medical_damage/functions/fnc_woundsHandlerBase.sqf b/addons/medical_damage/functions/fnc_woundsHandlerBase.sqf index 5df29c77025..92effda9bd5 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerBase.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerBase.sqf @@ -22,7 +22,7 @@ TRACE_3("woundsHandlerBase",_unit,_allDamages,_typeOfDamage); if !(_typeOfDamage in GVAR(damageTypeDetails)) then { - WARNING_1("damage type not found",_typeOfDamage); + WARNING_1("damage type %1 not found",_typeOfDamage); _typeOfDamage = "unknown"; }; @@ -41,7 +41,7 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra // process wounds separately for each body part hit { // forEach _allDamages _x params ["_damage", "_bodyPart"]; - _bodyPart = toLower _bodyPart; + _bodyPart = toLowerANSI _bodyPart; // silently ignore structural damage if (_bodyPart == "#structural") then {continue}; @@ -80,7 +80,7 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra // 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); + WARNING_4("No valid wound types %1-%2-%3-%4",_damage,_dmgPerWound,_typeOfDamage,_bodyPart); continue }; GVAR(woundDetails) get _woundTypeToAdd params ["","_injuryBleedingRate","_injuryPain","_causeLimping","_causeFracture"]; diff --git a/addons/medical_damage/functions/fnc_woundsHandlerBurning.sqf b/addons/medical_damage/functions/fnc_woundsHandlerBurning.sqf index 47c625684ac..1130c8d3f53 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerBurning.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerBurning.sqf @@ -37,7 +37,7 @@ TRACE_3("woundsHandlerBurning",_unit,_allDamages,_typeOfDamage); [{ params ["_unit"]; - _bodyPart = selectRandom ["body", "leftleg", "rightleg"]; + private _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]; diff --git a/addons/medical_damage/stringtable.xml b/addons/medical_damage/stringtable.xml index 63d10dcd355..fa4e1c4ae48 100644 --- a/addons/medical_damage/stringtable.xml +++ b/addons/medical_damage/stringtable.xml @@ -18,9 +18,9 @@ Sets the amount of damage a player can receive before going unconscious (and dying if "Sum of Trauma" is enabled). - プレイヤーが気絶するまでに受けられるダメージ量を設定します。\n("外傷の合計"が有効な場合は死亡するまでに受けられるダメージ量) + プレイヤーが無意識状態に陥るまでに受けられるダメージ量を設定します。\n("外傷の合計"が有効な場合は死亡するまでに受けられるダメージ量) Définit la quantité de dégâts qu'un joueur peut subir avant de perdre connaissance (ou mourir, si l'option "Somme des traumatismes" est sélectionnée). - Устанавливает количество урона, которое может получить игрок, прежде чем потеряет сознание. + Устанавливает количество урона, которое может получить игрок, прежде чем потеряет сознание (и умирает, если включена функция "Сумма травм"). Define a quantidade de dano que um jogador pode receber antes de ficar inconsciente. 設定玩家在無意識前能承受多少傷害。 设置玩家在昏迷前可以承受的伤害量(如果启用了“创伤总和”,则会死亡)。 @@ -36,7 +36,7 @@ AI Critical Damage Threshold AIのクリティカルダメージしきい値 Seuil de dégât critique de l'IA - Порог критического урона AI + Порог критического урона ИИ Limite de Dano Crítico da IA AI重擊承受量 AI 临界伤害阈值 @@ -49,9 +49,9 @@ Sets the amount of damage an AI unit can receive before going unconscious (or dying when "Sum of Trauma" is enabled). - AIが気絶するまでに受けられるダメージ量を設定します。\n("外傷の合計"が有効な場合は死亡するまでに受けられるダメージ量) + AIが無意識状態に陥るまでに受けられるダメージ量を設定します。\n("外傷の合計"が有効な場合は死亡するまでに受けられるダメージ量) Définit la quantité de dégâts qu'une unité IA peut subir avant de perdre connaissance (ou mourir, si l'option "Somme des traumatismes" est sélectionnée). - Устанавливает количество урона, которое может получить ИИ, прежде чем потеряет сознание. + Устанавливает количество урона, которое может получить ИИ, прежде чем потеряет сознание (или умирает, когда включена функция "Сумма травм").. Define a quantidade de dano que uma IA pode receber antes de ficar inconsciente. 設定AI在無意識之前能承受多少傷害 设置 AI 在昏迷前可以承受的伤害量(如果启用了“创伤总和”,则会死亡)。 @@ -625,7 +625,7 @@ Determines what damage can be fatal Определяет какой урон будет смертельным - 致命となるダメージの種類を決定します。 + 致命となるダメージの種類を定義します。 決定何種傷害為致命 确定哪些伤害可能是致命的 Determina quali danni possono essere letali @@ -757,7 +757,7 @@ Legt die Höhe des Schadens fest, den eine Einheit erhalten kann, bevor diese ohnmächtig wird. (0 für Misionsnormalwert) Determina il livello di danni sopportabili da un'unità senza svenire. (0 per il valore predefinito dalla missione) Définit la quantité de dégâts que l'unité peut subir avant de perdre connaissance (ou mourir, si l'option "Somme des traumatismes" est sélectionnée).\n(0 utilise la valeur définie dans la mission.) - このユニットが気絶するまでに受けられるダメージ量を設定します。 (ミッション標準は0) + このユニットが無意識状態に陥るまでに受けられるダメージ量を設定します。 (ミッション標準は0) Určuje kolik poškození může jednotka utrpět než upadne do bezvědomí. (pro použití standardní hodnoty mise zadejte 0) Устанавливает количество урона, которое может получить юнит перед тем, как потерять сознание. (0 для значения миссии) Ustawia próg obrażeń jakie może otrzymać jednostka przed utratą przytomności. (0 jako ustawienie domyślne misji) @@ -772,7 +772,7 @@ Шанс потерять сознание от боли 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 @@ -785,7 +785,7 @@ Шанс, что человек потеряет сознание, когда его боль выше допустимого порога при получении травмы. 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. @@ -798,11 +798,12 @@ Порог боли для потери сознания 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. @@ -814,6 +815,7 @@ 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 diff --git a/addons/medical_engine/XEH_postInit.sqf b/addons/medical_engine/XEH_postInit.sqf index 55578076296..ed660914984 100644 --- a/addons/medical_engine/XEH_postInit.sqf +++ b/addons/medical_engine/XEH_postInit.sqf @@ -6,27 +6,23 @@ [_new] call FUNC(updateDamageEffects); // Run on new controlled unit to update QGVAR(aimFracture) }, true] call CBA_fnc_addPlayerEventHandler; - ["CAManBase", "init", { params ["_unit"]; - // Check if last hit point is our dummy. - private _allHitPoints = getAllHitPointsDamage _unit param [0, []]; - reverse _allHitPoints; - while {(_allHitPoints param [0, ""]) select [0,1] == "#"} do { WARNING_1("Ignoring Reflector hitpoint %1",_allHitPoints deleteAt 0); }; + if (unitIsUAV _unit) exitWith {TRACE_1("ignore UAV AI",typeOf _unit);}; + if (getNumber (configOf _unit >> "isPlayableLogic") == 1) exitWith {TRACE_1("ignore logic unit",typeOf _unit);}; - if (_allHitPoints param [0, ""] != "ACE_HDBracket") then { - 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)}; + 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 @@ -86,15 +82,9 @@ if (!isNull objectParent _unit && {local objectParent _unit}) exitWith { [_unit] call FUNC(lockUnconsciousSeat); }; - - // Prevent second ragdoll of uncon units when they're killed - if (IS_UNCONSCIOUS(_unit) && !isAwake _unit) then { - _unit enableSimulation false; - [{_this enableSimulation true}, _unit, 2] call CBA_fnc_waitAndExecute; - }; }] call CBA_fnc_addEventHandler; -["CAManBase", "deleted", { +["CAManBase", "Deleted", { params ["_unit"]; TRACE_3("unit deleted",_unit,objectParent _unit,local _unit); if ((!isNull objectParent _unit) && {local objectParent _unit}) then { diff --git a/addons/medical_engine/XEH_preInit.sqf b/addons/medical_engine/XEH_preInit.sqf index dab2e7efe32..035b9f4b052 100644 --- a/addons/medical_engine/XEH_preInit.sqf +++ b/addons/medical_engine/XEH_preInit.sqf @@ -19,6 +19,7 @@ if (isNil QUOTE(BLOOD_LOSS_KNOCK_OUT_THRESHOLD)) then {BLOOD_LOSS_KNOCK_OUT_THRE if (isNil QUOTE(PAIN_FADE_TIME)) then {PAIN_FADE_TIME = PAIN_FADE_TIME_DEFAULT}; if (isNil QUOTE(LIMPING_DAMAGE_THRESHOLD)) then {LIMPING_DAMAGE_THRESHOLD = LIMPING_DAMAGE_THRESHOLD_DEFAULT}; if (isNil QUOTE(FRACTURE_DAMAGE_THRESHOLD)) then {FRACTURE_DAMAGE_THRESHOLD = FRACTURE_DAMAGE_THRESHOLD_DEFAULT}; +if (isNil QUOTE(CARDIAC_OUTPUT_MIN)) then {CARDIAC_OUTPUT_MIN = CARDIAC_OUTPUT_MIN_DEFAULT}; // Derive the alternate fatal damage coefficents if (isNil QUOTE(FATAL_SUM_DAMAGE_WEIBULL_K) || isNil QUOTE(FATAL_SUM_DAMAGE_WEIBULL_L)) then { private _x1 = 0.5; @@ -39,11 +40,14 @@ GVAR(armorCache) = createHashMap; // with handle damage not returning full results. GVAR(fixedStatics) = []; -GVAR(animations) = [] call CBA_fnc_createNamespace; -GVAR(animations) setVariable [QUNCON_ANIM(faceUp), [QUNCON_ANIM(2),QUNCON_ANIM(2_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]]; -GVAR(animations) setVariable [QUNCON_ANIM(faceDown), [QUNCON_ANIM(1),QUNCON_ANIM(3),QUNCON_ANIM(4),"unconscious",QUNCON_ANIM(9),QUNCON_ANIM(3_1),QUNCON_ANIM(4_1)]]; -GVAR(animations) setVariable [QUNCON_ANIM(faceLeft), [QUNCON_ANIM(7),QUNCON_ANIM(8),QUNCON_ANIM(1_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1)]]; -GVAR(animations) setVariable [QUNCON_ANIM(faceRight), [QUNCON_ANIM(5),QUNCON_ANIM(6),QUNCON_ANIM(10),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]]; +GVAR(animations) = createHashMapFromArray [ + [toLowerANSI QUNCON_ANIM(faceUp), [QUNCON_ANIM(2),QUNCON_ANIM(2_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]], + [toLowerANSI QUNCON_ANIM(faceDown), [QUNCON_ANIM(1),QUNCON_ANIM(3),QUNCON_ANIM(4),"unconscious",QUNCON_ANIM(9),QUNCON_ANIM(3_1),QUNCON_ANIM(4_1)]], + [toLowerANSI QUNCON_ANIM(faceLeft), [QUNCON_ANIM(7),QUNCON_ANIM(8),QUNCON_ANIM(1_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1)]], + [toLowerANSI QUNCON_ANIM(faceRight), [QUNCON_ANIM(5),QUNCON_ANIM(6),QUNCON_ANIM(10),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]] +]; + +GVAR(customHitpoints) = ["hitleftarm", "hitrightarm", "hitleftleg", "hitrightleg"]; private _fnc_fixStatic = { params ["_vehicle"]; @@ -83,4 +87,7 @@ addMissionEventHandler ["Loaded", { [] call FUNC(disableThirdParty); +// Future-proofing +EGVAR(medical,enabled) = true; // TODO: remove when medical enable setting is implemented + ADDON = true; diff --git a/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf b/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf index db522b2bf72..726a606344a 100644 --- a/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf +++ b/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf @@ -23,7 +23,7 @@ if !(IS_UNCONSCIOUS(_unit) && // do not run if unit is conscio {alive _unit && // do not run if unit is dead {isNull objectParent _unit}}) exitWith {}; // do not run if unit in any vehicle -private _animsArray = GVAR(animations) getVariable [_anim, [""]]; +private _animsArray = GVAR(animations) getOrDefault [toLowerANSI _anim, [""]]; private _random = (toArray (hashValue _unit)) param [0, 0]; private _index = _random % (count _animsArray); private _unconsciousAnimation = _animsArray select _index; diff --git a/addons/medical_engine/functions/fnc_damageBodyPart.sqf b/addons/medical_engine/functions/fnc_damageBodyPart.sqf index c25d83c46c2..f69bce2cae7 100644 --- a/addons/medical_engine/functions/fnc_damageBodyPart.sqf +++ b/addons/medical_engine/functions/fnc_damageBodyPart.sqf @@ -28,7 +28,7 @@ TRACE_3("damageBodyPart",_unit,_selection,_damage); _damage = [0, DAMAGED_MIN_THRESHOLD] select _damage; -switch (toLower _selection) do { +switch (toLowerANSI _selection) do { case ("head"): { _unit setHitPointDamage ["HitHead", _damage]; }; diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index a60816222fb..3e976c28990 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -1,9 +1,9 @@ #include "..\script_component.hpp" /* - * Author: commy2, kymckay + * Author: commy2, kymckay, LinkIsGrim * HandleDamage EH where wound events are raised based on incoming damage. * Be aware that for each source of damage, the EH can fire multiple times (once for each hitpoint). - * We store these incoming damages and compare them on our final hitpoint: "ace_hdbracket". + * We store these incoming damages and compare them on last iteration of the event (_context == 2). * * Arguments: * Handle damage EH @@ -13,15 +13,16 @@ * * Public: No */ -params ["_unit", "_selection", "_damage", "_shooter", "_ammo", "_hitPointIndex", "_instigator", "_hitpoint"]; +params ["_unit", "_selection", "_damage", "_shooter", "_ammo", "_hitPointIndex", "_instigator", "_hitpoint", "_directHit", "_context"]; // HD sometimes triggers for remote units - ignore. if !(local _unit) exitWith {nil}; // Get missing meta info private _oldDamage = 0; +private _structuralDamage = _context == 0; -if (_hitPoint isEqualTo "") then { +if (_structuralDamage) then { _hitPoint = "#structural"; _oldDamage = damage _unit; } else { @@ -31,28 +32,34 @@ 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}; +// Killing units via End key is an edge case (#10375) +if (_structuralDamage && {_damage == 1 && _ammo == "" && isNull _shooter && isNull _instigator}) exitWith {_damage}; + private _newDamage = _damage - _oldDamage; -// Happens occasionally for vehiclehit events (see line 80 onwards) -// Just exit early to save some frametime -if (_newDamage == 0 && {_hitpoint isNotEqualTo "ace_hdbracket"}) 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 (_hitPoint isNotEqualTo "#structural") then { +if (!_structuralDamage) then { private _armorCoef = _armor/_armorScaled; private _damageCoef = linearConversion [0, 1, GVAR(damagePassThroughEffect), 1, _armorCoef]; _newDamage = _newDamage * _damageCoef; }; -TRACE_4("Received hit",_hitpoint,_ammo,_newDamage,_realDamage); +TRACE_6("Received hit",_hitpoint,_ammo,_newDamage,_realDamage,_directHit,_context); -// Drowning doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs +// Drowning doesn't fire the EH for each hitpoint and never triggers _context=2 (LastHitPoint) // Damage occurs in consistent increments if ( - _hitPoint isEqualTo "#structural" && + _structuralDamage && {getOxygenRemaining _unit <= 0.5} && {_damage isEqualTo (_oldDamage + 0.005)} ) exitWith { @@ -64,14 +71,14 @@ if ( // Faster than (vehicle _unit), also handles dead units private _vehicle = objectParent _unit; +private _inVehicle = !isNull _vehicle; +private _environmentDamage = _ammo == ""; -// Crashing a vehicle doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs +// Crashing a vehicle doesn't fire the EH for each hitpoint and never triggers _context=2 (LastHitPoint) // It does fire the EH multiple times, but this seems to scale with the intensity of the crash if ( EGVAR(medical,enableVehicleCrashes) && - {_hitPoint isEqualTo "#structural"} && - {_ammo isEqualTo ""} && - {!isNull _vehicle} && + {_environmentDamage && _inVehicle && _structuralDamage} && {vectorMagnitude (velocity _vehicle) > 5} // todo: no way to detect if stationary and another vehicle hits you ) exitWith { @@ -83,17 +90,14 @@ if ( // Receiving explosive damage inside a vehicle doesn't trigger for each hitpoint // This is the case for mines, explosives, artillery, and catasthrophic vehicle explosions -// Triggers twice, but that doesn't matter as damage is low if ( - _hitPoint isEqualTo "#structural" && - {!isNull _vehicle} && - {_ammo isNotEqualTo ""} && + (!_environmentDamage && _inVehicle && _structuralDamage) && { private _ammoCfg = configFile >> "CfgAmmo" >> _ammo; GET_NUMBER(_ammoCfg >> "explosive",0) > 0 || {GET_NUMBER(_ammoCfg >> "indirectHit",0) > 0} } -) exitwith { +) exitWith { TRACE_5("Vehicle hit",_unit,_shooter,_instigator,_damage,_newDamage); _unit setVariable [QEGVAR(medical,lastDamageSource), _shooter]; @@ -104,9 +108,13 @@ if ( 0 }; -// This hitpoint is set to trigger last, evaluate all the stored damage values -// to determine where wounds are applied -if (_hitPoint isEqualTo "ace_hdbracket") exitWith { +// Damages are stored for last iteration of the HandleDamage event (_context == 2) +_unit setVariable [format [QGVAR($%1), _hitPoint], [_realDamage, _newDamage]]; + +// Ref https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#HandleDamage +// Context 2 means this is the last iteration of HandleDamage, so figure out which hitpoint took the most real damage and send wound event +// Don't exit, as the last iteration can be one of the hitpoints that we need to keep _oldDamage for +if (_context == 2) then { _unit setVariable [QEGVAR(medical,lastDamageSource), _shooter]; _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; @@ -157,10 +165,14 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { // Environmental damage sources all have empty ammo string // No explicit source given, we infer from differences between them - if (_ammo isEqualTo "") then { + if (_environmentDamage) then { // Any collision with terrain/vehicle/object has a shooter // Check this first because burning can happen at any velocity - if !(isNull _shooter) then { + if (isNull _shooter) then { + // Anything else is almost guaranteed to be fire damage + _ammo = "fire"; + TRACE_5("Fire Damage",_unit,_shooter,_instigator,_damage,_allDamages); + } else { /* If shooter != unit then they hit unit, otherwise it could be: - Unit hitting anything at speed @@ -175,10 +187,6 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { _ammo = "collision"; TRACE_5("Collision",_unit,_shooter,_instigator,_damage,_allDamages); }; - } else { - // Anything else is almost guaranteed to be fire damage - _ammo = "fire"; - TRACE_5("Fire Damage",_unit,_shooter,_instigator,_damage,_allDamages); }; }; @@ -199,16 +207,9 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { QGVAR($HitLeftArm),QGVAR($HitRightArm),QGVAR($HitLeftLeg),QGVAR($HitRightLeg), QGVAR($#structural) ]; - - 0 }; -// Damages are stored for "ace_hdbracket" event triggered last -_unit setVariable [format [QGVAR($%1), _hitPoint], [_realDamage, _newDamage]]; - // Engine damage to these hitpoints controls blood visuals, limping, weapon sway // Handled in fnc_damageBodyPart, persist here -if (_hitPoint in ["hithead", "hitbody", "hithands", "hitlegs"]) exitWith {_oldDamage}; - -// We store our own damage values so engine damage is unnecessary -0 +// For all other hitpoints, we store our own damage values, so engine damage is unnecessary +[0, _oldDamage] select (_hitPoint in ["hithead", "hitbody", "hithands", "hitlegs"]) diff --git a/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf b/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf index cc29e75cc1a..8441df4ad83 100644 --- a/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf +++ b/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf @@ -11,7 +11,6 @@ * * Public: No */ -if (missionNamespace getVariable [QGVAR(disableSeatLocking), false]) exitWith {}; params ["_unit"]; private _vehicle = objectParent _unit; @@ -20,6 +19,13 @@ TRACE_3("lockUnconsciousSeat",_unit,_vehicle,lifeState _unit); if (isNull _vehicle) exitWith {}; if (alive _unit && {lifeState _unit != "INCAPACITATED"}) exitWith {}; +private _disable = missionNamespace getVariable [QGVAR(disableSeatLocking), false]; +if (_disable isEqualTo true || { + _disable isEqualType [] && { + (_disable findIf {_vehicle isKindOf _x}) != -1 + } +}) exitWith {}; + switch (true) do { case (_unit isEqualTo (driver _vehicle)): { _vehicle lockDriver true; diff --git a/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf b/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf index 531f5d40622..4ed63253c72 100644 --- a/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf +++ b/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf @@ -33,14 +33,14 @@ if (_isUnconscious) then { }; // set animation inside vehicles - if (vehicle _unit != _unit) then { + if (!isNull objectParent _unit) then { private _unconAnim = _unit call EFUNC(common,getDeathAnim); TRACE_2("inVehicle - playing death anim",_unit,_unconAnim); [_unit, _unconAnim] call EFUNC(common,doAnimation); }; } else { // reset animation inside vehicles - if (vehicle _unit != _unit) then { + if (!isNull objectParent _unit) then { private _awakeAnim = _unit call EFUNC(common,getAwakeAnim); TRACE_2("inVehicle - playing awake anim",_unit,_awakeAnim); [_unit, _awakeAnim, 2] call EFUNC(common,doAnimation); diff --git a/addons/medical_engine/functions/fnc_updateDamageEffects.sqf b/addons/medical_engine/functions/fnc_updateDamageEffects.sqf index 7dc73e04f47..f4a18094a60 100644 --- a/addons/medical_engine/functions/fnc_updateDamageEffects.sqf +++ b/addons/medical_engine/functions/fnc_updateDamageEffects.sqf @@ -67,7 +67,7 @@ if (!_isLimping && {EGVAR(medical,limping) > 0}) then { (_xAmountOf > 0) && {_xDamage > LIMPING_DAMAGE_THRESHOLD} // select _causeLimping from woundDetails - && {(EGVAR(medical_damage,woundDetails) get (_xClassID / 10)) select 3} + && {(EGVAR(medical_damage,woundDetails) get (floor (_xClassID / 10))) select 3} ) exitWith { TRACE_1("limping because of wound",_x); _isLimping = true; diff --git a/addons/medical_engine/script_macros_config.hpp b/addons/medical_engine/script_macros_config.hpp index 611a8ad3569..4c276d7b186 100644 --- a/addons/medical_engine/script_macros_config.hpp +++ b/addons/medical_engine/script_macros_config.hpp @@ -20,13 +20,6 @@ // This used to take the armor values as parameters; it now inherits the values // of `armor`, `passThrough` and `explosionShielding` from the existing hitpoints // for vanilla consistency. -// "ACE_HDBracket" is a special hit point. It is designed in a way where the -// "HandleDamage" event handler will compute it at the end of every damage -// calculation step. This way we can figure out which hit point took the most -// damage from one projectile and should be receiving the ACE medical wound. -// the hit point itself should not take any damage -// It is important that the "ACE_HDBracket" hit point is the last in the config, -// but has the same selection as the first one (always "HitHead" for soldiers). #define ADD_ACE_HITPOINTS\ class HitLeftArm: HitHands {\ material = -1;\ @@ -47,15 +40,4 @@ };\ class HitRightLeg: HitLeftLeg {\ name = "leg_r";\ - };\ - class ACE_HDBracket {\ - armor = 1;\ - material = -1;\ - name = "head";\ - passThrough = 0;\ - radius = 1;\ - explosionShielding = 1;\ - visual = "";\ - minimalHit = 0;\ - depends = "HitHead";\ } diff --git a/addons/medical_engine/script_macros_medical.hpp b/addons/medical_engine/script_macros_medical.hpp index 6f96478406b..167765c5767 100644 --- a/addons/medical_engine/script_macros_medical.hpp +++ b/addons/medical_engine/script_macros_medical.hpp @@ -108,6 +108,10 @@ #define FRACTURE_DAMAGE_THRESHOLD EGVAR(medical,const_fractureDamageThreshold) #define FRACTURE_DAMAGE_THRESHOLD_DEFAULT 0.50 +// Minimum cardiac output +#define CARDIAC_OUTPUT_MIN EGVAR(medical,const_minCardiacOutput) +#define CARDIAC_OUTPUT_MIN_DEFAULT 0.05 + // Minimum body part damage required for blood effect on uniform #define VISUAL_BODY_DAMAGE_THRESHOLD 0.35 diff --git a/addons/medical_engine/stringtable.xml b/addons/medical_engine/stringtable.xml index c79b35ad224..cf197132029 100644 --- a/addons/medical_engine/stringtable.xml +++ b/addons/medical_engine/stringtable.xml @@ -20,7 +20,7 @@ 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. 控制乘员是否受到车辆碰撞的伤害。 @@ -37,6 +37,7 @@ 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! @@ -47,7 +48,8 @@ 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これが何かわからない場合は変更しないことをお勧めします。 - Контролирует эффект "прохождения" брони при нанесении конечного урона. Делает высокие значения брони, подобные тем, которые используются в GL rigs, менее эффективными.n\используйте 0% для поведения брони до версии 3.16.0.n\прикасайтесь к этому, только если знаете, что делаете! + Контролирует эффект `passThrough` при нанесении конечного урона. Делает высокие значения брони, подобные тем, которые используются в GL rigs, менее эффективными.\nИспользуйте 0% для поведения брони до версии 3.16.0.n\Прикасайтесь к этому, только если знаете, что делаете! + Controla el efecto de 'passThrough' de armadura en el daño final. Hace que los valores altos de armadura, como los usados en los chalecos GL, sean menos efectivos.\nUsar 0% para comportamiento de armadura en versiones anteriores a 3.16.0.\nSólo modifica esto si sabes lo que estás haciendo! diff --git a/addons/medical_feedback/XEH_postInit.sqf b/addons/medical_feedback/XEH_postInit.sqf index 96d15dbf21e..f01394e9199 100644 --- a/addons/medical_feedback/XEH_postInit.sqf +++ b/addons/medical_feedback/XEH_postInit.sqf @@ -30,7 +30,7 @@ GVAR(bloodTickCounter) = 0; [false] call FUNC(initEffects); [true] call FUNC(handleEffects); -[FUNC(handleEffects), 1, false] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(handleEffects), 1, false] call CBA_fnc_addPerFrameHandler; ["ace_unconscious", { params ["_unit", "_unconscious"]; @@ -104,7 +104,7 @@ GVAR(bloodTickCounter) = 0; if (ACE_player distance _unit > _distance) exitWith {}; - if (vehicle _unit == _unit) then { + if (isNull objectParent _unit) then { // say3D waits for the previous sound to finish, so use a dummy instead private _dummy = "#dynamicsound" createVehicleLocal [0, 0, 0]; _dummy attachTo [_unit, [0, 0, 0], "camera"]; diff --git a/addons/medical_feedback/functions/fnc_playInjuredSound.sqf b/addons/medical_feedback/functions/fnc_playInjuredSound.sqf index c278e6e08ae..b33b533e25f 100644 --- a/addons/medical_feedback/functions/fnc_playInjuredSound.sqf +++ b/addons/medical_feedback/functions/fnc_playInjuredSound.sqf @@ -6,8 +6,11 @@ * * Arguments: * 0: Unit - * 1: Type (optional) ["hit" (default) or "moan"] - * 2: Severity (optional) [0 (default), 1, 2] + * 1: Type ["hit", "moan"] (default: "hit") + * 2: Severity [0, 1, 2] (default: 0) + * 3: Hit sound distances (default: [50, 60, 70]) + * 4: Moan sound distances (default: [10, 15, 20]) + * 5: Allow unconscious units (default: false) * * Return Value: * None @@ -20,18 +23,18 @@ #define TIME_OUT_HIT 1 #define TIME_OUT_MOAN [12, 7.5, 5] -params [["_unit", objNull, [objNull]], ["_type", "hit", [""]], ["_severity", 0, [0]]]; +params [["_unit", objNull, [objNull]], ["_type", "hit", [""]], ["_severity", 0, [0]], ["_hitDistances", [50, 60, 70], [[]], [3]], ["_moanDistances", [10, 15, 20], [[]], [3]], ["_allowUnconscious", false, [true]]]; // TRACE_3("",_unit,_type,_severity); if (!local _unit) exitWith { ERROR_2("playInjuredSound: Unit not local or null [%1:%2]",_unit,typeOf _unit); }; -if !(_unit call EFUNC(common,isAwake)) exitWith {}; +if (!_allowUnconscious && {!(_unit call EFUNC(common,isAwake))}) exitWith {}; // 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; + _hitDistances select _severity } else { - [10, 15, 20] select _severity; + _moanDistances select _severity }; private _targets = allPlayers inAreaArray [ASLToAGL getPosASL _unit, _distance, _distance, 0, false, _distance]; if (_targets isEqualTo []) exitWith {}; diff --git a/addons/medical_gui/XEH_postInit.sqf b/addons/medical_gui/XEH_postInit.sqf index f2777f6fd40..6d18696b0e7 100644 --- a/addons/medical_gui/XEH_postInit.sqf +++ b/addons/medical_gui/XEH_postInit.sqf @@ -2,6 +2,8 @@ if (!hasInterface) exitWith {}; +#include "initKeybinds.inc.sqf" + GVAR(target) = objNull; GVAR(previousTarget) = objNull; GVAR(selectedBodyPart) = 0; @@ -21,7 +23,7 @@ GVAR(selfInteractionActions) = []; [QEGVAR(interact_menu,newControllableObject), { params ["_type"]; // string of the object's classname - if (!(_type isKindOf "CAManBase")) exitWith {}; + if !(_type isKindOf "CAManBase") exitWith {}; { _x set [0, _type]; _x call EFUNC(interact_menu,addActionToClass); @@ -35,64 +37,6 @@ GVAR(selfInteractionActions) = []; }; }] call CBA_fnc_addEventHandler; -["ACE3 Common", QGVAR(openMedicalMenuKey), localize LSTRING(OpenMedicalMenu), { - // 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 { - 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; - }; - }; - }; - - // Check conditions: canInteract and canOpenMenu - if !([ACE_player, _target, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - if !([ACE_player, _target] call FUNC(canOpenMenu)) exitWith {false}; - - // Statement - [_target] call FUNC(openMenu); - false -}, { - // Close menu if enough time passed from opening - if (CBA_missionTime - GVAR(lastOpenedOn) > 0.5) exitWith { - [objNull] call FUNC(openMenu); - }; - 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; @@ -102,7 +46,7 @@ GVAR(selfInteractionActions) = []; params ["_unit", "_allDamages", ""]; if !(GVAR(peekMedicalOnHit) && {_unit == ACE_player}) exitWith {}; - private _bodypart = toLower (_allDamages select 0 select 1); + private _bodypart = toLowerANSI (_allDamages select 0 select 1); private _bodypartIndex = ALL_BODY_PARTS find _bodypart; [ACE_player, _bodypartIndex] call FUNC(displayPatientInformation); diff --git a/addons/medical_gui/functions/fnc_addTreatmentActions.sqf b/addons/medical_gui/functions/fnc_addTreatmentActions.sqf index 3df89894d2f..b27801766bc 100644 --- a/addons/medical_gui/functions/fnc_addTreatmentActions.sqf +++ b/addons/medical_gui/functions/fnc_addTreatmentActions.sqf @@ -36,14 +36,14 @@ private _fnc_condition = { private _displayName = getText (_x >> "displayName"); private _icon = getText (_x >> "icon"); - private _allowedBodyParts = getArray (_x >> "allowedSelections") apply {toLower _x}; + private _allowedBodyParts = getArray (_x >> "allowedSelections") apply {toLowerANSI _x}; if (_allowedBodyParts isEqualTo ["all"]) then { - _allowedBodyParts = ALL_BODY_PARTS apply {toLower _x}; + _allowedBodyParts = ALL_BODY_PARTS apply {toLowerANSI _x}; }; { private _bodyPart = _x; - private _actionPath = _actionPaths select (ALL_BODY_PARTS find toLower _bodyPart); + private _actionPath = _actionPaths select (ALL_BODY_PARTS find toLowerANSI _bodyPart); private _action = [ _actionName, diff --git a/addons/medical_gui/functions/fnc_countTreatmentItems.sqf b/addons/medical_gui/functions/fnc_countTreatmentItems.sqf index 6e8394c82ff..ac7c4857e6d 100644 --- a/addons/medical_gui/functions/fnc_countTreatmentItems.sqf +++ b/addons/medical_gui/functions/fnc_countTreatmentItems.sqf @@ -42,12 +42,27 @@ private _vehicle = [_patientVehicle, _medicVehicle] select (!isNull _medicVehicl if (!isNull _vehicle) then { _vehicleCount = 0; - (getItemCargo _vehicle) params ["_itemTypes", "_itemCounts"]; + private _magazineItems = []; + private _itemItems = []; { - private _item = _x; - private _index = _itemTypes find _item; - _vehicleCount = _vehicleCount + (_itemCounts param [_index, 0]); + if (isClass (configFile >> "CfgMagazines" >> _x)) then { + _magazineItems pushBack _x; + } else { + _itemItems pushBack _x; + }; } forEach _items; + if (_magazineItems isNotEqualTo []) then { + (getMagazineCargo _vehicle) params ["_itemTypes", "_itemCounts"]; + { + _vehicleCount = _vehicleCount + (_itemCounts param [_itemTypes find _x, 0]); + } forEach _magazineItems; + }; + if (_itemItems isNotEqualTo []) then { + (getItemCargo _vehicle) params ["_itemTypes", "_itemCounts"]; + { + _vehicleCount = _vehicleCount + (_itemCounts param [_itemTypes find _x, 0]); + } forEach _itemItems; + }; }; [_medicCount, _patientCount, _vehicleCount] diff --git a/addons/medical_gui/functions/fnc_displayPatientInformation.sqf b/addons/medical_gui/functions/fnc_displayPatientInformation.sqf index 65660eec798..abea0ec07bb 100644 --- a/addons/medical_gui/functions/fnc_displayPatientInformation.sqf +++ b/addons/medical_gui/functions/fnc_displayPatientInformation.sqf @@ -40,6 +40,7 @@ if (isNull _display) then { if (ACE_player distance _target > MAX_DISTANCE && {vehicle _target != vehicle ACE_player}) exitWith { [_pfhID] call CBA_fnc_removePerFrameHandler; QGVAR(RscPatientInfo) cutFadeOut 0.3; + if (((getPosATL _target) # 2) < -9) exitWith {}; // handle dragging corpse/clone [[ELSTRING(medical,DistanceToFar), _target call EFUNC(common,getName)], 2] call EFUNC(common,displayTextStructured); }; diff --git a/addons/medical_gui/functions/fnc_menuPFH.sqf b/addons/medical_gui/functions/fnc_menuPFH.sqf index b3d51c2dc9c..0e213eaf5ec 100644 --- a/addons/medical_gui/functions/fnc_menuPFH.sqf +++ b/addons/medical_gui/functions/fnc_menuPFH.sqf @@ -23,6 +23,8 @@ if !( closeDialog 0; // Show hint if distance condition failed if ((ACE_player distance GVAR(target) > GVAR(maxDistance)) && {vehicle ACE_player != vehicle GVAR(target)}) then { + if (((getPosATL GVAR(target)) # 2) < -9) exitWith {}; // handle dragging corpse/clone + [[ELSTRING(medical,DistanceToFar), GVAR(target) call EFUNC(common,getName)], 2] call EFUNC(common,displayTextStructured); }; }; diff --git a/addons/medical_gui/functions/fnc_onMenuOpen.sqf b/addons/medical_gui/functions/fnc_onMenuOpen.sqf index e77d92bddd6..12b27b60d90 100644 --- a/addons/medical_gui/functions/fnc_onMenuOpen.sqf +++ b/addons/medical_gui/functions/fnc_onMenuOpen.sqf @@ -41,7 +41,7 @@ if (GVAR(menuPFH) != -1) exitWith { TRACE_1("Menu PFH already running",GVAR(menuPFH)); }; -GVAR(menuPFH) = [FUNC(menuPFH), 0, []] call CBA_fnc_addPerFrameHandler; +GVAR(menuPFH) = [LINKFUNC(menuPFH), 0, []] call CBA_fnc_addPerFrameHandler; // Hide categories if they don't have any actions (airway) private _list = [ diff --git a/addons/medical_gui/functions/fnc_updateBodyImage.sqf b/addons/medical_gui/functions/fnc_updateBodyImage.sqf index 4d22b68a2d8..b8ee8ee240e 100644 --- a/addons/medical_gui/functions/fnc_updateBodyImage.sqf +++ b/addons/medical_gui/functions/fnc_updateBodyImage.sqf @@ -105,3 +105,5 @@ private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0]; [IDC_BODY_LEGLEFT, IDC_BODY_LEGLEFT_S, IDC_BODY_LEGLEFT_T, IDC_BODY_LEGLEFT_B], [IDC_BODY_LEGRIGHT, IDC_BODY_LEGRIGHT_S, IDC_BODY_LEGRIGHT_T, IDC_BODY_LEGRIGHT_B] ]; + +[QGVAR(updateBodyImage), [_ctrlGroup, _target, _selectionN]] call CBA_fnc_localEvent; diff --git a/addons/medical_gui/functions/fnc_updateCategories.sqf b/addons/medical_gui/functions/fnc_updateCategories.sqf index c9917a87581..c2f1d2a11c8 100644 --- a/addons/medical_gui/functions/fnc_updateCategories.sqf +++ b/addons/medical_gui/functions/fnc_updateCategories.sqf @@ -21,8 +21,9 @@ params ["_display"]; _x params ["_idc", "_category"]; private _ctrl = _display displayCtrl _idc; - private _enable = GVAR(actions) findIf {_category == _x select 1 && {call (_x select 2)}} > -1; - if (_category isEqualTo "triage") then {_enable = true}; + private _enable = if (_category == "triage") then { true } else { + GVAR(actions) findIf {_category == _x select 1 && {call (_x select 2)}} > -1 + }; _ctrl ctrlEnable _enable; private _selectedColor = [ diff --git a/addons/medical_gui/functions/fnc_updateInjuryList.sqf b/addons/medical_gui/functions/fnc_updateInjuryList.sqf index 328e80242a2..3219eb025f5 100644 --- a/addons/medical_gui/functions/fnc_updateInjuryList.sqf +++ b/addons/medical_gui/functions/fnc_updateInjuryList.sqf @@ -24,24 +24,31 @@ private _nonissueColor = [1, 1, 1, 0.33]; // Indicate if unit is bleeding at all if (IS_BLEEDING(_target)) then { - // Give a qualitative description of the rate of bleeding - private _cardiacOutput = [_target] call EFUNC(medical_status,getCardiacOutput); - private _bleedRate = GET_BLOOD_LOSS(_target); - private _bleedRateKO = BLOOD_LOSS_KNOCK_OUT_THRESHOLD * (_cardiacOutput max 0.05); - // Use nonzero minimum cardiac output to prevent all bleeding showing as massive during cardiac arrest - - switch (true) do { - case (_bleedRate < _bleedRateKO * BLEED_RATE_SLOW): { - _entries pushBack [localize LSTRING(Bleed_Rate1), [1, 1, 0, 1]]; - }; - 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]]; + 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]]; }; - default { - _entries pushBack [localize LSTRING(Bleed_Rate4), [1, 0, 0, 1]]; + case 2: { + // Give a qualitative description of the rate of bleeding + private _cardiacOutput = [_target] call EFUNC(medical_status,getCardiacOutput); + private _bleedRate = GET_BLOOD_LOSS(_target); + private _bleedRateKO = BLOOD_LOSS_KNOCK_OUT_THRESHOLD * (_cardiacOutput max 0.05); + // Use nonzero minimum cardiac output to prevent all bleeding showing as massive during cardiac arrest + switch (true) do { + case (_bleedRate < _bleedRateKO * BLEED_RATE_SLOW): { + _entries pushBack [localize LSTRING(Bleed_Rate1), [1, 1, 0, 1]]; + }; + case (_bleedRate < _bleedRateKO * BLEED_RATE_MODERATE): { + _entries pushBack [localize LSTRING(Bleed_Rate2), [1, 0.67, 0, 1]]; + }; + case (_bleedRate < _bleedRateKO * BLEED_RATE_SEVERE): { + _entries pushBack [localize LSTRING(Bleed_Rate3), [1, 0.33, 0, 1]]; + }; + default { + _entries pushBack [localize LSTRING(Bleed_Rate4), [1, 0, 0, 1]]; + }; + }; }; }; } else { @@ -70,13 +77,35 @@ if (GVAR(showBloodlossEntry)) then { }; // Show receiving IV volume remaining private _totalIvVolume = 0; +private _saline = 0; +private _blood = 0; +private _plasma = 0; { - _x params ["_volumeRemaining"]; + _x params ["_volumeRemaining", "_type"]; + switch (_type) do { + case "Saline": { + _saline = _saline + _volumeRemaining; + }; + case "Blood": { + _blood = _blood + _volumeRemaining; + }; + case "Plasma": { + _plasma = _plasma + _volumeRemaining; + }; + }; _totalIvVolume = _totalIvVolume + _volumeRemaining; } forEach (_target getVariable [QEGVAR(medical,ivBags), []]); -if (_totalIvVolume >= 1) then { - _entries pushBack [format [localize ELSTRING(medical_treatment,receivingIvVolume), floor _totalIvVolume], [1, 1, 1, 1]]; +if (_totalIvVolume > 0) then { + if (_saline > 0) then { + _entries pushBack [format [localize ELSTRING(medical_treatment,receivingSalineIvVolume), floor _saline], [1, 1, 1, 1]]; + }; + if (_blood > 0) then { + _entries pushBack [format [localize ELSTRING(medical_treatment,receivingBloodIvVolume), floor _blood], [1, 1, 1, 1]]; + }; + if (_plasma > 0) then { + _entries pushBack [format [localize ELSTRING(medical_treatment,receivingPlasmaIvVolume), floor _plasma], [1, 1, 1, 1]]; + }; } else { _entries pushBack [localize ELSTRING(medical_treatment,Status_NoIv), _nonissueColor]; }; @@ -116,6 +145,8 @@ if (_selectionN == -1) exitWith { _ctrl lbSetCurSel -1; }; +[QGVAR(updateInjuryListGeneral), [_ctrl, _target, _selectionN, _entries]] call CBA_fnc_localEvent; + _entries pushBack ["", [1, 1, 1, 1]]; // Add selected body part name @@ -184,6 +215,8 @@ switch (GET_FRACTURES(_target) select _selectionN) do { }; }; +[QGVAR(updateInjuryListPart), [_ctrl, _target, _selectionN, _entries, _bodyPartName]] call CBA_fnc_localEvent; + // Add entries for open, bandaged, and stitched wounds private _woundEntries = []; @@ -216,6 +249,8 @@ private _fnc_processWounds = { [GET_BANDAGED_WOUNDS(_target), "[B] %1", [0.88, 0.7, 0.65, 1]] call _fnc_processWounds; [GET_STITCHED_WOUNDS(_target), "[S] %1", [0.7, 0.7, 0.7, 1]] call _fnc_processWounds; +[QGVAR(updateInjuryListWounds), [_ctrl, _target, _selectionN, _woundEntries, _bodyPartName]] call CBA_fnc_localEvent; + // Handle no wound entries if (_woundEntries isEqualTo []) then { _entries pushBack [localize ELSTRING(medical_treatment,NoInjuriesBodypart), _nonissueColor]; diff --git a/addons/medical_gui/functions/fnc_updateLogList.sqf b/addons/medical_gui/functions/fnc_updateLogList.sqf index d2bb75b63fb..51240705f98 100644 --- a/addons/medical_gui/functions/fnc_updateLogList.sqf +++ b/addons/medical_gui/functions/fnc_updateLogList.sqf @@ -23,6 +23,8 @@ lbClear _ctrl; { _x params ["_message", "_timeStamp", "_arguments"]; + private _unlocalizedMessage = _message; + // Localize message and arguments if (isLocalized _message) then { _message = localize _message; @@ -33,5 +35,7 @@ lbClear _ctrl; // Format message with arguments _message = format ([_message] + _arguments); - _ctrl lbAdd format ["%1 %2", _timeStamp, _message]; + private _row = _ctrl lbAdd format ["%1 %2", _timeStamp, _message]; + + [QGVAR(logListAppended), [_ctrl, _row, _message, _unlocalizedMessage, _timeStamp, _arguments]] call CBA_fnc_localEvent; } forEach _logs; diff --git a/addons/medical_gui/initKeybinds.inc.sqf b/addons/medical_gui/initKeybinds.inc.sqf new file mode 100644 index 00000000000..53c577084e9 --- /dev/null +++ b/addons/medical_gui/initKeybinds.inc.sqf @@ -0,0 +1,55 @@ +["ACE3 Common", QGVAR(openMedicalMenuKey), LLSTRING(OpenMedicalMenu), { + // 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 { + 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; + }; + }; + }; + + // Check conditions: canInteract and canOpenMenu + if !([ACE_player, _target, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, _target] call FUNC(canOpenMenu)) exitWith {false}; + + // Statement + [_target] call FUNC(openMenu); + false +}, { + // Close menu if enough time passed from opening + if (CBA_missionTime - GVAR(lastOpenedOn) > 0.5) exitWith { + [objNull] call FUNC(openMenu); + }; +}, [DIK_H, [false, false, false]], false, 0] call CBA_fnc_addKeybind; + +["ACE3 Common", QGVAR(peekMedicalInfoKey), LLSTRING(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; +}, [DIK_H, [false, true, false]], false, 0] call CBA_fnc_addKeybind; diff --git a/addons/medical_gui/initSettings.inc.sqf b/addons/medical_gui/initSettings.inc.sqf index a0418ca74e5..dfcbe48925a 100644 --- a/addons/medical_gui/initSettings.inc.sqf +++ b/addons/medical_gui/initSettings.inc.sqf @@ -127,6 +127,15 @@ private _categoryColors = [ELSTRING(medical,Interface_Category), format ["| %1 | true // isGlobal ] call CBA_fnc_addSetting; +[ + QGVAR(showBleeding), + "LIST", + [LSTRING(showBleeding_DisplayName), LSTRING(showBleeding_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + [[0, 1, 2], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), LSTRING(ShowBleeding_Rate)], 2], + true // isGlobal +] call CBA_fnc_addSetting; + [ QGVAR(bodyPartOutlineColor), "COLOR", diff --git a/addons/medical_gui/stringtable.xml b/addons/medical_gui/stringtable.xml index 405ee9d9af0..6dfc16f9b95 100644 --- a/addons/medical_gui/stringtable.xml +++ b/addons/medical_gui/stringtable.xml @@ -21,7 +21,7 @@ Enable Medical Actions Aktiviere Sanitätsaktionen 医療インタラクションの有効化 - Разрешить Медицинские действия + Вкл. медицинские действия Activer les actions médicales Ativar Ações Médicas 啟用醫療行為 @@ -36,7 +36,7 @@ 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. @@ -86,7 +86,7 @@ Enable Medical Self Actions Medizinische Selbst-Interaktionen anzeigen - 医療セルフインタラクションの有効化 + 医療セルフ・インタラクションの有効化 Разрешить Медицинские действия на себе Activer les actions médicales sur soi-même Ativar ações médicas em si mesmo @@ -102,7 +102,7 @@ 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. @@ -119,7 +119,7 @@ Enable Medical Menu Aktiviere das Sanitätsmenü 医療メニューを有効化 - Разрешить Медицинское меню + Вкл. медицинское меню Activer le menu médical Ativar Menu Médico 啟用醫療選單 @@ -134,7 +134,7 @@ 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. @@ -151,7 +151,7 @@ Reopen Medical Menu Sanitätsmenü wieder öffnen 医療メニューの再表示 - Открывать меню после лечения + Медицинское меню после лечения Rouvrir le menu médical Reabrir Menu Médico 醫療選單二度開啟 @@ -167,7 +167,7 @@ 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 當治療完成後二度打開醫療選單 @@ -198,7 +198,7 @@ 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. @@ -217,11 +217,12 @@ 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ü 在交互式菜单中显示分诊级别 상호작용 메뉴에서 부상자 카드 보기 + Mostrar Nível de Triagem no Menu de Interação Shows the patient's triage level by changing the color of the main and medical menu actions. @@ -234,6 +235,7 @@ Zeigt die Triage-Einstufung des Patienten durch Ändern der Farbe der Aktionen des Hauptmenüs und des medizinischen Menüs an. 通过改变主菜单和医疗菜单动作的颜色来显示伤员的分诊级别。 환자의 부상자 카드를 상호작용에서 볼 수 있게 합니다. + Mostra o nível de triagem do paciente alterando a cor das ações do menu principal e do menu médico. Medical @@ -292,7 +294,9 @@ Sbircia Info Mediche Medizinische Info anzeigen 医療情報一時表示 - Просмотрите медицинскую информацию + Просмотр медицинской информации + Ojear Información Médica + Visualização rápida das informações médicas Medical Peek Duration @@ -303,6 +307,8 @@ Dauer zum Anzeigen der medizinischen Info 医療情報一時表示の表示時間 Продолжительность медицинского осмотра + Duración del Ojear Información Médica + Duração da visualização geral das informações médicas How long the medical info peek remains open after releasing the key. @@ -313,6 +319,8 @@ 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. + Quanto tempo a visualização rápida das informações médicas permanece aberta após soltar a tecla. Load Patient @@ -566,6 +574,8 @@ Passa a te stesso 自分に切り替え Переключиться на себя + Cambiar a uno mismo + Trocar para si mesmo Switch to target @@ -576,6 +586,8 @@ Passa al paziente 相手に切り替え Переключиться на цель + Cambiar al objetivo + Trocar para paciente Head @@ -1002,6 +1014,8 @@ Nessuna emorragia 出血はしていない Кровотечения нет + Sin sangrado + Sem sangramento Slow bleeding @@ -1012,6 +1026,8 @@ Debole emorragia 出血は穏やか Медленное кровотечение + Sangrado lento + Sangramento lento Moderate bleeding @@ -1022,6 +1038,8 @@ Emorraggia moderata 出血はそこそこ速い Умеренное кровотечение + Sangrado moderado + Sangramento moderado Severe bleeding @@ -1032,6 +1050,8 @@ Forte emorragia 出血は激しい Сильное кровотечение + Sangrado severo + Sangramento grave Massive bleeding @@ -1041,7 +1061,9 @@ Massive Blutung Gravissima emorragia 出血は酷く多い - Сильное кровотечение + Огромное кровотечение + Sangrado masivo + Sangramento massivo in Pain @@ -1116,6 +1138,8 @@ Nessuna perdita di sangue 失血なし Потери крови нет + Sin pérdida de sangre + Sem perda de sangue @@ -1260,6 +1284,7 @@ Información de paciente Patienteninformation 환자 정보 + Informações do paciente Blood Loss Colors @@ -1272,6 +1297,7 @@ 失血颜色 출혈 색상 Colores de pérdida de sangre + Cores de perda de sangue Defines the 10 color gradient used to indicate blood loss in Medical GUIs. @@ -1284,6 +1310,7 @@ 失血颜色,用于医学图形用户界面。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. + Define os 10 gradientes de cores utilizados para indicar perda de sangue nas interfaces médicas. Blood Loss Color %1 @@ -1296,6 +1323,7 @@ 失血颜色 %1 출혈 색상 %1 Color de pérdida de sangre %1 + Cor de perda de sangue %1 Damage Colors @@ -1308,6 +1336,7 @@ 负伤颜色 피해 색상 Colores de daño + Cores de dano Defines the 10 color gradient used to indicate damage in Medical GUIs. @@ -1320,6 +1349,7 @@ 负伤颜色,用于医学图形用户界面。10种渐变颜色。 의료 GUI에 쓰이는 피해 색상입니다. 총 10가지 색상이 있습니다. Define los 10 gradientes de color utilizados para indicar el daño en la interfaz gráfiica del sistema Médico. + Define os 10 gradientes de cor utilizados para indicar dano nas interfaces médicas. Damage Color %1 @@ -1332,6 +1362,7 @@ 负伤颜色 %1 피해 색상 %1 Color de daño %1 + Cor de dano %1 Show Blood Loss @@ -1344,6 +1375,7 @@ Показывать кровопотерю Mostrar pérdida de sangre Afficher les pertes de sang + Mostrar perda de sangue Show qualitative blood loss in the injury list. @@ -1356,6 +1388,40 @@ Показывать тяжесть кровопотери в списке ранений. Mostrar la pérdida de sangre cualitativa en la lista de heridas. Afficher la quantité de sang perdue + Mostrar perda de sangue qualitativa na lista de feridas. + + + 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 @@ -1366,7 +1432,9 @@ Mostra info mediche se colpito Zeige medizinische Info beim Treffer an 被弾時の医療情報一時表示 - Просмотрите медицинскую информацию о попадании + Показать медицинскую информацию о попадании + Ojear Información Médica en Impacto + Visualização rápida das informações médicas durante uma lesão Temporarily show medical info when injured. @@ -1378,6 +1446,8 @@ Bei Verletzungen vorübergehend medizinische Info anzeigen. 被弾時に医療情報を一時的に表示します。 Временно показывать медицинскую информацию при травме. + Temporalmente muestra la información médica cuando es herido. + Mostrar informações médicas temporariamente durante uma lesão. Medical Peek Duration on Hit @@ -1389,6 +1459,8 @@ Dauer der Anzeige bei einem Treffer. 被弾時の医療情報一時表示の表示時間 Продолжительность медицинского осмотра при попадании + Duración de Ojear la Información Médica cuando hay Impacto + Duração da visualização rápida de informações médicas durante uma lesão How long the medical info peek remains open after being injured. @@ -1400,6 +1472,8 @@ 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. + Quanto tempo a visualização rápida de informações médicas permanece aberta após ser ferido. Show Trauma Sustained @@ -1412,6 +1486,7 @@ 显示遭受的创伤 Afficher les traumatismes subis Показать полученную травму + Mostrar Trauma Sostenido Show trauma sustained in the injury list. @@ -1424,6 +1499,7 @@ 在伤情表上显示创伤 Afficher les traumatismes subis dans la liste des blessures. Показать полученную травму в списке травм. + Mostrar trauma sostenido en la lista de heridas Body Part Outline Color @@ -1435,6 +1511,8 @@ Umrissfarbe des Körperteils 身体部位の輪郭表示の色 Цвет контура части тела + Color de Contorno de las Partes del Cuerpo + Cor do contorno da parte do corpo Color of outline around selected body part. @@ -1446,6 +1524,8 @@ Farbe des Umrisses um das ausgewählten Körperteil. 選択した身体部位の輪郭表示の色。 Цвет контура вокруг выбранной части тела. + Color del contorno alrededor de la parte del cuerpo seleccionada. + Cor do contorno em volta da parte do corpo selecionada. Minor Trauma @@ -1458,6 +1538,7 @@ 轻微创伤 Traumatisme mineur Незначительная травма + Trauma Menor Major Trauma @@ -1470,6 +1551,7 @@ 中度创伤 Traumatisme majeur Серьезная травма + Trauma mayor Severe Trauma @@ -1482,6 +1564,7 @@ 重度创伤 Traumatisme grave Тяжелая травма + Trauma Severo Chronic Trauma @@ -1494,6 +1577,7 @@ 慢性创伤 Traumatisme chronique Хроническая травма + Trauma Crónico L @@ -1505,6 +1589,8 @@ L Лево + I + E R @@ -1516,6 +1602,8 @@ R Право + D + D in your inventory @@ -1527,6 +1615,8 @@ im Inventar 個あなたが保有 в вашем инвентаре + en tu inventario + em seu inventário in patient's inventory @@ -1538,6 +1628,8 @@ im Inventar des Patienten 個患者が保有 в инвентаре пациента + en el inventario del paciente + no inventário do paciente in vehicle's inventory @@ -1549,6 +1641,8 @@ Nell'inventario del veicolo 個車両内に保有 в инвентаре транспорта + en el inventario del vehículo + no inventário do veículo No effect until tourniquet removed @@ -1559,6 +1653,8 @@ Nessun effetto fino alla rimozione del laccio emostatico 止血帯を外すまで効果を発揮しません Никакого эффекта до тех пор, пока жгут не будет снят + Sin efecto hasta que se quita el torniquete + Sem efeito até o torniquete ser removido Show Tourniquet Warning @@ -1569,6 +1665,8 @@ Mostra avviso di laccio emostatico 止血帯の警告を表示 Показать предупреждение о наложении жгута + Mostrar Advertencia de Torniquete + Mostrar aviso de torniquete Show a warning tooltip when a tourniquet will interfere with a medical action. @@ -1579,6 +1677,8 @@ 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. + Mostra uma dica de aviso quando um torniquete interfere com uma ação médica. diff --git a/addons/medical_statemachine/CfgEventHandlers.hpp b/addons/medical_statemachine/CfgEventHandlers.hpp index 98c29f77dc8..b9150d85640 100644 --- a/addons/medical_statemachine/CfgEventHandlers.hpp +++ b/addons/medical_statemachine/CfgEventHandlers.hpp @@ -10,6 +10,12 @@ class Extended_PreInit_EventHandlers { }; }; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; + class Extended_Respawn_EventHandlers { class CAManBase { class ADDON { diff --git a/addons/medical_statemachine/XEH_postInit.sqf b/addons/medical_statemachine/XEH_postInit.sqf new file mode 100644 index 00000000000..a7c7740a390 --- /dev/null +++ b/addons/medical_statemachine/XEH_postInit.sqf @@ -0,0 +1,14 @@ +#include "script_component.hpp" + +["ace_killed", { // global event + params ["_unit"]; + + // Prevent second ragdoll of uncon units when they're killed + if ( + IS_UNCONSCIOUS(_unit) && !isAwake _unit // uncon and not ragdolling + && {isPlayer _unit || {_unit getVariable [QGVAR(AIUnconsciousness), GVAR(AIUnconsciousness)]}} + ) then { + _unit enableSimulation false; + [{_this enableSimulation true}, _unit, 2] call CBA_fnc_waitAndExecute; + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf b/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf index 537c3566519..8be1d358df4 100644 --- a/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf +++ b/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf @@ -25,6 +25,7 @@ if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) e TRACE_4("enteredStateDeath",_this,_thisOrigin,_thisTransition,CBA_missionTime); private _causeOfDeath = format ["%1:%2", _thisOrigin, _thisTransition]; +private _source = _unit getVariable [QEGVAR(medical,lastDamageSource), objNull]; private _instigator = _unit getVariable [QEGVAR(medical,lastInstigator), objNull]; -[_unit, _causeOfDeath, _instigator] call EFUNC(medical_status,setDead); +[_unit, _causeOfDeath, _source, _instigator] call EFUNC(medical_status,setDead); diff --git a/addons/medical_statemachine/stringtable.xml b/addons/medical_statemachine/stringtable.xml index 1b29b1c5539..9c1d807bd00 100644 --- a/addons/medical_statemachine/stringtable.xml +++ b/addons/medical_statemachine/stringtable.xml @@ -68,7 +68,7 @@ Controls when AI can receive fatal injuries. A fatal injury is caused by significant damage to the head or troso.\nWhen set to "Always", this effectively produces "AI Instant Death" behaviour as AI will immediately die from any fatal injury.\nNOTE: Any mode other than "Always" requires AI Unconsciousness to be enabled. Controla quando a IA pode receber lesões fatais. Uma lesão fatal é causada por um dano significante na cabeça ou tronco.\nQuando definido para "Sempre", isso efetivamente causa a "Morte Instantânea da IA", pois a IA irá imediatamente morrer para qualquer lesão fatal.\nNOTA: Qualquer opção além de "Sempre" requer que Inconsciência de IA esteja ativada. - AIが致命傷を受けた時の挙動を管理できます。頭部や胸部に受ける大きなダメージは致命傷になります。\n"常に"に設定されていると、いかなる致命傷でも"AIの即死"効果が生まれます。\n注: "常に"以外のモードでは"AIの気絶"を有効化させる必要があります。 + AIが致命傷を受けた時の挙動を管理できます。頭部や胸部に受ける大きなダメージは致命傷になります。\n"常に"に設定されていると、いかなる致命傷でも"AIの即死"効果が生まれます。\n注: "常に"以外のモードでは"AIの無意識状態化"を有効化させる必要があります。 控制當AI受致命傷時是否能救起。致命傷是指對頭部或身體造成可觀傷害所造成的。\n當設置為"總是"時,這會使其與"AI 瞬間死亡"同一個效果,在AI受到致命傷時瞬間死亡。\n備註:選了"總是"以外的選項的話必須開啟「AI無意識」的選項。 控制当 AI 受致命伤时是否能救起。致命伤是指对头部或躯干遭受重大伤害。\n当设置为"总是"时,这将有效地产生"AI 即时死亡"行为,因为 AI 将立即死于任何致命伤。\n注意:"总是"以外的任何模式都需要启用 AI 无意识。 Détermine si les unités IA décèdent en cas de blessure mortelle. Une blessure mortelle est définie par des dommages importants à la tête ou au cœur.\nSi réglé sur "Toujours", cela produit effectivement un comportement de "Mort instantanée" car les unités IA mourront immédiatement de toute blessure mortelle.\nNOTE : Tout mode autre que "Toujours" nécessite l'activation de l'option "Inconscience IA". @@ -92,7 +92,7 @@ Inconscience IA AI eszméletlenség Incoscienza IA - AIの気絶 + AIの無意識状態化 인공지능 기절 AI 无意识 AI無意識 @@ -101,7 +101,7 @@ 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單位有心搏停止可能的話,該選項必須啟用。 控制 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. @@ -132,7 +132,7 @@ 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. @@ -173,6 +173,7 @@ Wykrwawienie podczas zatrzymanej akcji serca 心脏骤停期间失血情况 심정지 중 출혈 + Sangramento durante parada cardíaca Controls whether a person can die in cardiac arrest by blood loss before the cardiac arrest time runs out. @@ -185,6 +186,7 @@ Kontroluje czy śmierć osoby może nastąpić poprzez wykrwawienie zanim wyczerpię się Czas Zatrzymania Akcji Serca. 控制单位是否会在心脏骤停时间耗完之前因失血过多而死亡。 지정한 심정지 시간이 다 되기 전에 출혈로 인해 사망할 수 있는 지를 결정합니다. + Controla se uma pessoa pode morrer em parada cardíaca por perda de sangue antes que o tempo de parada cardíaca acabe. diff --git a/addons/medical_status/functions/fnc_addInventoryActions.sqf b/addons/medical_status/functions/fnc_addInventoryActions.sqf index 8041eb06135..e4e65a31649 100644 --- a/addons/medical_status/functions/fnc_addInventoryActions.sqf +++ b/addons/medical_status/functions/fnc_addInventoryActions.sqf @@ -46,5 +46,6 @@ _unit addAction ["OpenBag", { {!lockedInventory _backpackContainer} && {maxLoad _backpackContainer > 0} && {getNumber (_backpackConfig >> "disableInventory") != 1} && + {!(_target isKindOf QEGVAR(dragging,clone))} && {_target setUserActionText [_actionId, format [localize "STR_ACTION_OPEN_BAG", getText (_backpackConfig >> "displayName")]]; true} }, 2]; diff --git a/addons/medical_status/functions/fnc_getBloodLoss.sqf b/addons/medical_status/functions/fnc_getBloodLoss.sqf index 8ff0fbff3ba..5193ccbb0b0 100644 --- a/addons/medical_status/functions/fnc_getBloodLoss.sqf +++ b/addons/medical_status/functions/fnc_getBloodLoss.sqf @@ -21,6 +21,13 @@ private _woundBleeding = GET_WOUND_BLEEDING(_unit); if (_woundBleeding == 0) exitWith {0}; private _cardiacOutput = [_unit] call FUNC(getCardiacOutput); +private _resistance = _unit getVariable [VAR_PERIPH_RES, DEFAULT_PERIPH_RES]; // can use value directly since this is sum of default and adjustments // 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) * (DEFAULT_PERIPH_RES / _resistance) * 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_setDead.sqf b/addons/medical_status/functions/fnc_setDead.sqf index 9dfc07d1144..138948c0386 100644 --- a/addons/medical_status/functions/fnc_setDead.sqf +++ b/addons/medical_status/functions/fnc_setDead.sqf @@ -7,6 +7,7 @@ * 0: The unit * 1: Reason for death * 2: Killer + * 3: Instigator * * Return Value: * None @@ -14,13 +15,16 @@ * Public: No */ -params ["_unit", ["_reason", "#setDead"], ["_instigator", objNull]]; -TRACE_3("setDead",_unit,_reason,_instigator); +params ["_unit", ["_reason", "#setDead"], ["_source", objNull], ["_instigator", objNull]]; +TRACE_4("setDead",_unit,_reason,_source,_instigator); // No heart rate or blood pressure to measure when dead _unit setVariable [VAR_HEART_RATE, 0, true]; _unit setVariable [VAR_BLOOD_PRESS, [0, 0], true]; +// Clear uncon variable just to be safe +_unit setVariable [VAR_UNCON, nil, true]; + _unit setVariable [QEGVAR(medical,causeOfDeath), _reason, true]; // Send a local event before death @@ -34,7 +38,7 @@ if (_unitState isNotEqualTo "Dead") then { // (#8803) Reenable damage if disabled to prevent having live units in dead state // Keep this after death event for compatibility with third party hooks -if !(isDamageAllowed _unit) then { +if (!isDamageAllowed _unit) then { WARNING_1("setDead executed on unit with damage blocked - %1",_this); _unit allowDamage true; }; @@ -42,6 +46,6 @@ if !(isDamageAllowed _unit) then { // Kill the unit without changing visual apperance private _prevDamage = _unit getHitPointDamage "HitHead"; -_unit setHitPointDamage ["HitHead", 1, true, _instigator]; +_unit setHitPointDamage ["HitHead", 1, true, _source, _instigator]; -_unit setHitPointDamage ["HitHead", _prevDamage]; +_unit setHitPointDamage ["HitHead", _prevDamage, true, _source, _instigator]; diff --git a/addons/medical_status/stringtable.xml b/addons/medical_status/stringtable.xml index 01c2cc21c66..cefc85ff421 100644 --- a/addons/medical_status/stringtable.xml +++ b/addons/medical_status/stringtable.xml @@ -105,7 +105,7 @@ Controls how quickly fluid flows out of IV Bags. The IV Bag volume change is calculated as:\ntime interval (s) * iv change per second (4.1667 mL/s) * flow rate (this coefficient). Wie schnell der Effekt der Transfusion eintritt IV 輸液パックから輸液が流出する速度を制御します。 IV 輸液バッグの容量変化は次のように計算されます:\n時間間隔(秒) x 点滴速度毎秒(4.1667 mL/秒) x 流量(この係数) - Определяет, насколько быстро подействуют эффекты внутривенного переливания + Определяет, насколько быстро подействуют эффекты внутривенного переливания как:\nвременной интервал (s) * изменение внутривенного вливания в секунду (4,1667 мл/с) * скорость потока (этот коэффициент). Définit la vitesse à laquelle le liquide s'écoule des poches de perfusion.\nLa variation du volume de poche IV est calculée selon la formule suivante :\n intervalle de temps (s) * variation IV par seconde (4,1667 ml/s) * débit (ce coefficient). Controla o quão rápido fluidos são extraídos de bolsas de IV. A mudança no volume da bolsa d IV é calculado assim:\nIntervalo de tempo (s) * mudança de iv por segundo (4.1667 mL/s) * Velocidade de transferência (esse valor) 控制從點滴輸入人體的液體流量多快。點滴的體積更改是以\n時間間隔(單位秒)乘上點滴每秒速度(4.1667毫升/秒)乘上流量(該係數)。 @@ -126,6 +126,8 @@ Risque de perte d'arme 武器を落とす確率 Шанс выпадения оружия + Probabilidad de Soltar Arma + Probabilidade de largar a arma Chance for a player to drop their weapon when going unconscious.\nHas no effect on AI. @@ -135,7 +137,9 @@ 플레이어가 기절할 때 무기를 떨어뜨릴 확률입니다.\nAI는 영향을 받지 않습니다. Pourcentage de chances pour un joueur de lâcher son arme lorsqu'il perd connaissance.\nAucun effet sur les IA. プレーヤーが意識を失ったときに武器を落とす可能性。\nAI には影響しません。 - Шанс для игрока выронить свое оружие, когда он теряет сознание.n\Не влияет на ИИ + Шанс для игрока выронить свое оружие, когда он теряет сознание.\nНе влияет на ИИ + Probabilidad del jugador de soltar su arma cuando quedan inconscientes.\nNo tiene efecto sobre la IA. + Chance de um jogador largar sua arma quando ficar inconsciente.\nNão tem efeito sobre a IA. diff --git a/addons/medical_treatment/CfgMagazines.hpp b/addons/medical_treatment/CfgMagazines.hpp new file mode 100644 index 00000000000..c4daafab766 --- /dev/null +++ b/addons/medical_treatment/CfgMagazines.hpp @@ -0,0 +1,16 @@ +class CfgMagazines { + class CA_Magazine; + class ACE_painkillers: CA_Magazine { + scope = 2; + author = ECSTRING(common,ACETeam); + displayName = CSTRING(painkillers_Display); + model = "\A3\Structures_F_EPA\Items\Medical\PainKillers_F.p3d"; + picture = QPATHTOF(ui\painkillers_ca.paa); + descriptionShort = CSTRING(painkillers_Desc_Short); + descriptionUse = CSTRING(painkillers_Desc_Use); + ACE_isMedicalItem = 1; + ACE_asItem = 1; + count = 10; + mass = 1; + }; +}; diff --git a/addons/medical_treatment/CfgVehicles.hpp b/addons/medical_treatment/CfgVehicles.hpp index bcecdb155e4..4f922eb1996 100644 --- a/addons/medical_treatment/CfgVehicles.hpp +++ b/addons/medical_treatment/CfgVehicles.hpp @@ -290,8 +290,8 @@ class CfgVehicles { displayName = CSTRING(painkillers_Display); author = "Alganthe"; vehicleClass = "Items"; - class TransportItems { - MACRO_ADDITEM(ACE_painkillers,1); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_painkillers,1); }; }; @@ -313,9 +313,11 @@ class CfgVehicles { model = QPATHTOF(data\ace_medcrate.p3d); editorPreview = QPATHTOF(data\ACE_medicalSupplyCrate.jpg); author = ECSTRING(common,ACETeam); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_painkillers,25); + }; class TransportItems { MACRO_ADDITEM(ACE_fieldDressing,50); - MACRO_ADDITEM(ACE_painkillers,25); MACRO_ADDITEM(ACE_morphine,25); MACRO_ADDITEM(ACE_epinephrine,25); MACRO_ADDITEM(ACE_bloodIV,15); @@ -357,13 +359,15 @@ class CfgVehicles { }; class ACE_medicalSupplyCrate_advanced: ACE_medicalSupplyCrate { displayName = CSTRING(medicalSupplyCrate_advanced); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_painkillers,15); + }; class TransportItems { MACRO_ADDITEM(ACE_fieldDressing,25); MACRO_ADDITEM(ACE_packingBandage,25); MACRO_ADDITEM(ACE_elasticBandage,25); MACRO_ADDITEM(ACE_tourniquet,15); MACRO_ADDITEM(ACE_splint,15); - MACRO_ADDITEM(ACE_painkillers,15); MACRO_ADDITEM(ACE_morphine,15); MACRO_ADDITEM(ACE_adenosine,15); MACRO_ADDITEM(ACE_epinephrine,15); diff --git a/addons/medical_treatment/CfgWeapons.hpp b/addons/medical_treatment/CfgWeapons.hpp index 31b98bd843d..aae3fbb69cc 100644 --- a/addons/medical_treatment/CfgWeapons.hpp +++ b/addons/medical_treatment/CfgWeapons.hpp @@ -310,15 +310,15 @@ class CfgWeapons { hiddenSelectionsTextures[] = {QPATHTOF(data\bodybagItem_white_co.paa)}; GVAR(bodyBagObject) = "ACE_bodyBagObject_white"; }; - class ACE_painkillers: ACE_ItemCore { - scope = 2; - author = "Alganthe"; + + // Since base game doesn't support misc. items, this is needed to filling inventories in the editor + class ACE_painkillers_Item: ACE_ItemCore { displayName = CSTRING(painkillers_Display); - model = "\A3\Structures_F_EPA\Items\Medical\PainKillers_F.p3d"; - picture = QPATHTOF(ui\painkillers_ca.paa); + author = ECSTRING(common,ACETeam); + scope = 2; + scopeArsenal = 0; descriptionShort = CSTRING(painkillers_Desc_Short); - descriptionUse = CSTRING(painkillers_Desc_Use); - ACE_isMedicalItem = 1; + picture = QPATHTOF(ui\painkillers_ca.paa); class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; diff --git a/addons/medical_treatment/XEH_postInit.sqf b/addons/medical_treatment/XEH_postInit.sqf index 4c7a780fc3b..eda15a4bfcf 100644 --- a/addons/medical_treatment/XEH_postInit.sqf +++ b/addons/medical_treatment/XEH_postInit.sqf @@ -1,5 +1,8 @@ #include "script_component.hpp" +// Pain killers item to magazine +["ACE_painkillers_Item", "ACE_painkillers"] call EFUNC(common,registerItemReplacement); + [QEGVAR(medical_status,initialized), { params ["_unit"]; @@ -69,6 +72,7 @@ if (["ace_trenches"] call EFUNC(common,isModLoaded)) then { LLSTRING(checkHeadstoneName), QPATHTOEF(medical_gui,ui\grave.paa), { + //IGNORE_PRIVATE_WARNING ["_target"]; [ [_target getVariable QGVAR(headstoneData)], true @@ -77,7 +81,7 @@ if (["ace_trenches"] call EFUNC(common,isModLoaded)) then { {!isNil {_target getVariable QGVAR(headstoneData)}} ] call EFUNC(interact_menu,createAction); - [missionNameSpace getVariable [QGVAR(graveClassname), "ACE_Grave"], 0, [], _checkHeadstoneAction] call EFUNC(interact_menu,addActionToClass); + [missionNamespace getVariable [QGVAR(graveClassname), "ACE_Grave"], 0, [], _checkHeadstoneAction] call EFUNC(interact_menu,addActionToClass); }; if (isServer) then { diff --git a/addons/medical_treatment/XEH_preInit.sqf b/addons/medical_treatment/XEH_preInit.sqf index bc01e267c1b..e6210a73729 100644 --- a/addons/medical_treatment/XEH_preInit.sqf +++ b/addons/medical_treatment/XEH_preInit.sqf @@ -14,27 +14,23 @@ PREP_RECOMPILE_END; // adjusting these is trail and error // if the animation is cut of ingame, increase these values // if the unit idles too much, decrease them -GVAR(animDurations) = [] call CBA_fnc_createNamespace; - -{ - GVAR(animDurations) setVariable _x; -} forEach [ - ["AinvPknlMstpSlayWnonDnon_medic", 7.5], - ["AinvPpneMstpSlayWnonDnon_medic", 7], - ["AinvPknlMstpSlayWrflDnon_medic", 7], - ["AinvPpneMstpSlayWrflDnon_medic", 9.5], - ["AinvPknlMstpSlayWlnrDnon_medic", 9], - ["AinvPknlMstpSlayWpstDnon_medic", 9.5], - ["AinvPpneMstpSlayWpstDnon_medic", 10], - ["AinvPknlMstpSlayWnonDnon_medicOther", 8.5], - ["AinvPpneMstpSlayWnonDnon_medicOther", 8.5], - ["AinvPknlMstpSlayWrflDnon_medicOther", 7], - ["AinvPpneMstpSlayWrflDnon_medicOther", 9], - ["AinvPknlMstpSlayWlnrDnon_medicOther", 9], - ["AinvPknlMstpSlayWpstDnon_medicOther", 10], - ["AinvPpneMstpSlayWpstDnon_medicOther", 8.5], - ["AinvPknlMstpSnonWnonDnon_medic1", 10], - ["AinvPknlMstpSnonWnonDr_medic0", 12] +GVAR(animDurations) = createHashMapFromArray [ + ["ainvpknlmstpslaywnondnon_medic", 7.5], + ["ainvppnemstpslaywnondnon_medic", 7], + ["ainvpknlmstpslaywrfldnon_medic", 7], + ["ainvppnemstpslaywrfldnon_medic", 9.5], + ["ainvpknlmstpslaywlnrdnon_medic", 9], + ["ainvpknlmstpslaywpstdnon_medic", 9.5], + ["ainvppnemstpslaywpstdnon_medic", 10], + ["ainvpknlmstpslaywnondnon_medicother", 8.5], + ["ainvppnemstpslaywnondnon_medicother", 8.5], + ["ainvpknlmstpslaywrfldnon_medicother", 7], + ["ainvppnemstpslaywrfldnon_medicother", 9], + ["ainvpknlmstpslaywlnrdnon_medicother", 9], + ["ainvpknlmstpslaywpstdnon_medicother", 10], + ["ainvppnemstpslaywpstdnon_medicother", 8.5], + ["ainvpknlmstpsnonwnondnon_medic1", 10], + ["ainvpknlmstpsnonwnondr_medic0", 12] ]; // class names of medical facilities (config case) diff --git a/addons/medical_treatment/config.cpp b/addons/medical_treatment/config.cpp index 75166a0f0cb..7b340d01091 100644 --- a/addons/medical_treatment/config.cpp +++ b/addons/medical_treatment/config.cpp @@ -12,7 +12,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; 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"}; + 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","ACE_painkillers_Item"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_medical_status", "ace_medical_damage", "ace_apl"}; author = ECSTRING(common,ACETeam); @@ -30,5 +30,6 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" #include "Cfg3DEN.hpp" +#include "CfgMagazines.hpp" #endif diff --git a/addons/medical_treatment/functions/fnc_bandage.sqf b/addons/medical_treatment/functions/fnc_bandage.sqf index a4fb2c76980..8657936a661 100644 --- a/addons/medical_treatment/functions/fnc_bandage.sqf +++ b/addons/medical_treatment/functions/fnc_bandage.sqf @@ -8,6 +8,10 @@ * 1: Patient * 2: Body Part * 3: Treatment + * 4: Item User + * 5: Used Item + * 6: Create litter + * 7: Bandage effectiveness coefficient (default: 1) * * Return Value: * None @@ -18,8 +22,11 @@ * Public: No */ -params ["_medic", "_patient", "_bodyPart", "_classname"]; +_this set [7, _this param [7, 1]]; // set bandage effectiveness coefficient +[QGVAR(bandaged), _this] call CBA_fnc_localEvent; // Raise event with reference so mods can modify this + +params ["_medic", "_patient", "_bodyPart", "_classname", "", "", "", "_bandageEffectiveness"]; [_patient, "activity", LSTRING(Activity_bandagedPatient), [[_medic, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); -[QGVAR(bandageLocal), [_patient, _bodyPart, _classname], _patient] call CBA_fnc_targetEvent; +[QGVAR(bandageLocal), [_patient, _bodyPart, _classname, _bandageEffectiveness], _patient] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_bandageLocal.sqf b/addons/medical_treatment/functions/fnc_bandageLocal.sqf index 0f695c4c611..2c59540fd12 100644 --- a/addons/medical_treatment/functions/fnc_bandageLocal.sqf +++ b/addons/medical_treatment/functions/fnc_bandageLocal.sqf @@ -7,6 +7,7 @@ * 0: Patient * 1: Body Part * 2: Treatment + * 3: Bandage effectiveness coefficient (default: 1) * * Return Value: * None @@ -17,16 +18,16 @@ * Public: No */ -params ["_patient", "_bodyPart", "_bandage"]; -TRACE_3("bandageLocal",_patient,_bodyPart,_bandage); -_bodyPart = toLower _bodyPart; +params ["_patient", "_bodyPart", "_bandage", ["_bandageEffectiveness", 1, [0]]]; +TRACE_4("bandageLocal",_patient,_bodyPart,_bandage,_bandageEffectiveness); +_bodyPart = toLowerANSI _bodyPart; private _openWounds = GET_OPEN_WOUNDS(_patient); private _woundsOnPart = _openWounds getOrDefault [_bodyPart, []]; if (_woundsOnPart isEqualTo []) exitWith {}; // Figure out which injuries for this bodypart are the best choice to bandage -private _targetWounds = [_patient, _bandage, _bodyPart, GVAR(bandageEffectiveness)] call FUNC(findMostEffectiveWounds); +private _targetWounds = [_patient, _bandage, _bodyPart, _bandageEffectiveness * GVAR(bandageEffectiveness)] call FUNC(findMostEffectiveWounds); // Everything is patched up on this body part already if (count _targetWounds == 0) exitWith {}; diff --git a/addons/medical_treatment/functions/fnc_canBandage.sqf b/addons/medical_treatment/functions/fnc_canBandage.sqf index 18fb304d112..808f86b9588 100644 --- a/addons/medical_treatment/functions/fnc_canBandage.sqf +++ b/addons/medical_treatment/functions/fnc_canBandage.sqf @@ -20,7 +20,7 @@ */ params ["_medic", "_patient", "_bodyPart", "_bandage"]; -_bodyPart = toLower _bodyPart; +_bodyPart = toLowerANSI _bodyPart; // If patient is swimming, don't allow bandage actions. if (_patient call EFUNC(common,isSwimming)) exitWith {false}; diff --git a/addons/medical_treatment/functions/fnc_canSplint.sqf b/addons/medical_treatment/functions/fnc_canSplint.sqf index f2fc6fa0346..bc2b235bf88 100644 --- a/addons/medical_treatment/functions/fnc_canSplint.sqf +++ b/addons/medical_treatment/functions/fnc_canSplint.sqf @@ -19,6 +19,6 @@ params ["", "_patient", "_bodyPart"]; -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find toLowerANSI _bodyPart; (GET_FRACTURES(_patient) select _partIndex) == 1 diff --git a/addons/medical_treatment/functions/fnc_canTreat.sqf b/addons/medical_treatment/functions/fnc_canTreat.sqf index 995965dfe5c..3b643afa2b8 100644 --- a/addons/medical_treatment/functions/fnc_canTreat.sqf +++ b/addons/medical_treatment/functions/fnc_canTreat.sqf @@ -28,7 +28,7 @@ private _config = configFile >> QGVAR(actions) >> _classname; ) && { _patient isKindOf "CAManBase" } && { - private _selections = getArray (_config >> "allowedSelections") apply {toLower _x}; + private _selections = getArray (_config >> "allowedSelections") apply {toLowerANSI _x}; "all" in _selections || {_bodyPart in _selections} } && { GET_FUNCTION(_condition,_config >> "condition"); diff --git a/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf b/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf index 3798e64eb4f..bb3efedc221 100644 --- a/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf +++ b/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf @@ -21,7 +21,7 @@ params ["_medic", "_patient", "_bodyPart"]; private _heartRate = 0; -if (!([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo))) then { +if !([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo)) then { _heartRate = switch (true) do { case (alive _patient): { GET_HEART_RATE(_patient) diff --git a/addons/medical_treatment/functions/fnc_checkResponse.sqf b/addons/medical_treatment/functions/fnc_checkResponse.sqf index dc76b1dbfbe..ca95fcb1d16 100644 --- a/addons/medical_treatment/functions/fnc_checkResponse.sqf +++ b/addons/medical_treatment/functions/fnc_checkResponse.sqf @@ -22,6 +22,11 @@ params ["_medic", "_patient"]; private _output = if (_patient call EFUNC(common,isAwake)) then { LSTRING(Check_Response_Responsive) } else { + if (GVAR(advancedDiagnose) == 3) exitWith { + if (IN_CRDC_ARRST(_patient)) exitWith { LSTRING(Check_Response_CardiacArrestDirect) }; + if (!alive _patient) exitWith { LSTRING(Check_Response_DeadDirect) }; + LSTRING(Check_Response_UnresponsiveDirect) + }; if ((GVAR(advancedDiagnose) == 2) && {IN_CRDC_ARRST(_patient)}) exitWith { LSTRING(Check_Response_CardiacArrest) }; if ((GVAR(advancedDiagnose) == 2) && {!alive _patient}) exitWith { LSTRING(Check_Response_Dead) }; LSTRING(Check_Response_Unresponsive) diff --git a/addons/medical_treatment/functions/fnc_cprLocal.sqf b/addons/medical_treatment/functions/fnc_cprLocal.sqf index 228774b2f63..e6b12990270 100644 --- a/addons/medical_treatment/functions/fnc_cprLocal.sqf +++ b/addons/medical_treatment/functions/fnc_cprLocal.sqf @@ -24,9 +24,14 @@ TRACE_2("cprLocal",_medic,_patient); private _bloodVolume = GET_BLOOD_VOLUME(_patient); private _successChance = linearConversion [BLOOD_VOLUME_CLASS_4_HEMORRHAGE, BLOOD_VOLUME_CLASS_2_HEMORRHAGE, _bloodVolume, GVAR(cprSuccessChanceMin), GVAR(cprSuccessChanceMax), true]; if ((random 1) < _successChance) then { + // If SpO2 is too low, it will make HR skyrocket to the point where patient goes back into CA + // Allow 3rd party mods to disable this mechanic + if (missionNamespace getVariable [QGVAR(setSpO2UponCPRSuccess), true] && {GET_SPO2(_patient) < DEFAULT_SPO2 / 2}) then { + _patient setVariable [VAR_SPO2, DEFAULT_SPO2 / 2, true]; + }; + TRACE_2("CPR random success",_bloodVolume,_successChance); [QEGVAR(medical,CPRSucceeded), _patient] call CBA_fnc_localEvent; } else { TRACE_2("CPR random fail",_bloodVolume,_successChance); }; - diff --git a/addons/medical_treatment/functions/fnc_createLitter.sqf b/addons/medical_treatment/functions/fnc_createLitter.sqf index 28269bb4cea..df9c2e7f4de 100644 --- a/addons/medical_treatment/functions/fnc_createLitter.sqf +++ b/addons/medical_treatment/functions/fnc_createLitter.sqf @@ -27,7 +27,7 @@ params ["_medic", "_patient", "_bodyPart", "_classname"]; if (vehicle _medic != _medic || {vehicle _patient != _patient}) exitWith {}; // Determine if treated body part is bleeding -private _index = ALL_BODY_PARTS find toLower _bodyPart; +private _index = ALL_BODY_PARTS find toLowerANSI _bodyPart; private _isBleeding = (GET_OPEN_WOUNDS(_patient) get _bodyPart) findIf { _x params ["", "_amountOf", "_bleeding"]; _amountOf * _bleeding > 0 diff --git a/addons/medical_treatment/functions/fnc_diagnose.sqf b/addons/medical_treatment/functions/fnc_diagnose.sqf index 5605cd27941..258f14617e8 100644 --- a/addons/medical_treatment/functions/fnc_diagnose.sqf +++ b/addons/medical_treatment/functions/fnc_diagnose.sqf @@ -44,6 +44,8 @@ if (alive _patient) then { } else { _messages pushBack LSTRING(noPain); }; +} else { + _messages pushBack ""; }; [_messages, 3] call EFUNC(common,displayTextStructured); diff --git a/addons/medical_treatment/functions/fnc_fullHealLocal.sqf b/addons/medical_treatment/functions/fnc_fullHealLocal.sqf index 7772db0a6ba..42c5866a9af 100644 --- a/addons/medical_treatment/functions/fnc_fullHealLocal.sqf +++ b/addons/medical_treatment/functions/fnc_fullHealLocal.sqf @@ -25,6 +25,9 @@ if ((["ace_fire"] call EFUNC(common,isModLoaded)) && {[_patient] call EFUNC(fire _patient setVariable [QEGVAR(fire,intensity), 0, true]; }; +// Allow mods to heal +[QGVAR(fullHealLocalMod), [_patient]] call CBA_fnc_localEvent; + private _state = GET_SM_STATE(_patient); TRACE_1("start",_state); @@ -74,12 +77,12 @@ _patient setVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true]; // wakeup needs to be done after achieving stable vitals, but before manually reseting unconc var if IS_UNCONSCIOUS(_patient) then { - if (!([_patient] call EFUNC(medical_status,hasStableVitals))) then { ERROR_2("fullheal [unit %1][state %2] did not restore stable vitals",_patient,_state); }; + if !([_patient] call EFUNC(medical_status,hasStableVitals)) then {ERROR_2("fullheal [unit %1][state %2] did not restore stable vitals",_patient,_state);}; TRACE_1("Waking up",_patient); [QEGVAR(medical,WakeUp), _patient] call CBA_fnc_localEvent; _state = GET_SM_STATE(_patient); TRACE_1("after WakeUp",_state); - if IS_UNCONSCIOUS(_patient) then { ERROR_2("fullheal [unit %1][state %2] failed to wake up patient",_patient,_state); }; + if IS_UNCONSCIOUS(_patient) then {ERROR_2("fullheal [unit %1][state %2] failed to wake up patient",_patient,_state);}; }; // Generic medical admin diff --git a/addons/medical_treatment/functions/fnc_getBandageTime.sqf b/addons/medical_treatment/functions/fnc_getBandageTime.sqf index ffe5c81f63b..eb0a3bc5ae1 100644 --- a/addons/medical_treatment/functions/fnc_getBandageTime.sqf +++ b/addons/medical_treatment/functions/fnc_getBandageTime.sqf @@ -20,7 +20,7 @@ params ["_medic", "_patient", "_bodyPart", "_bandage"]; -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find toLowerANSI _bodyPart; if (_partIndex < 0) exitWith { ERROR_1("invalid partIndex - %1",_this); 0 }; private _targetWounds = [_patient, _bandage, _bodyPart] call FUNC(findMostEffectiveWounds); diff --git a/addons/medical_treatment/functions/fnc_hasItem.sqf b/addons/medical_treatment/functions/fnc_hasItem.sqf index e84a79f142b..8faea65652f 100644 --- a/addons/medical_treatment/functions/fnc_hasItem.sqf +++ b/addons/medical_treatment/functions/fnc_hasItem.sqf @@ -25,12 +25,13 @@ 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 + _items findAny _unitItems != -1 }; _medic call _fnc_checkItems || {GVAR(allowSharedEquipment) != 2 && {_patient call _fnc_checkItems}} diff --git a/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf b/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf index 9ef12612388..56477eafee6 100644 --- a/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf +++ b/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf @@ -18,6 +18,6 @@ params ["_unit", "_bodyPart"]; -private _index = ALL_BODY_PARTS find toLower _bodyPart; +private _index = ALL_BODY_PARTS find toLowerANSI _bodyPart; _index >= 0 && {HAS_TOURNIQUET_APPLIED_ON(_unit,_index)} diff --git a/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf b/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf index d04c1497bdb..dfae6782a33 100644 --- a/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf +++ b/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf @@ -18,6 +18,7 @@ #define CHECK_OBJECTS(var) ((var) findIf {typeOf _x in GVAR(facilityClasses) || {_x getVariable [QEGVAR(medical,isMedicalFacility), false]}} != -1) params ["_unit"]; +//IGNORE_PRIVATE_WARNING ["_unit"]; private _fnc_check = { private _position = _unit modelToWorldVisual [0, 0, eyePos _unit select 2]; diff --git a/addons/medical_treatment/functions/fnc_ivBagLocal.sqf b/addons/medical_treatment/functions/fnc_ivBagLocal.sqf index 64eabf844ab..dc416f90c50 100644 --- a/addons/medical_treatment/functions/fnc_ivBagLocal.sqf +++ b/addons/medical_treatment/functions/fnc_ivBagLocal.sqf @@ -23,7 +23,7 @@ params ["_patient", "_bodyPart", "_classname"]; private _bloodVolume = GET_BLOOD_VOLUME(_patient); if (_bloodVolume >= DEFAULT_BLOOD_VOLUME) exitWith {}; -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find toLowerANSI _bodyPart; // Get attributes for the used IV private _defaultConfig = configFile >> QUOTE(ADDON) >> "IV"; diff --git a/addons/medical_treatment/functions/fnc_medication.sqf b/addons/medical_treatment/functions/fnc_medication.sqf index b69a63e9940..dfd08d4de28 100644 --- a/addons/medical_treatment/functions/fnc_medication.sqf +++ b/addons/medical_treatment/functions/fnc_medication.sqf @@ -23,6 +23,7 @@ params ["_medic", "_patient", "_bodyPart", "_classname", "", "_usedItem"]; [_patient, _usedItem] call FUNC(addToTriageCard); -[_patient, "activity", LSTRING(Activity_usedItem), [[_medic, false, true] call EFUNC(common,getName), getText (configFile >> "CfgWeapons" >> _usedItem >> "displayName")]] call FUNC(addToLog); +private _cfg = ["CfgWeapons", "CfgMagazines"] select (isClass (configFile >> "CfgMagazines" >> _usedItem)); +[_patient, "activity", LSTRING(Activity_usedItem), [[_medic, false, true] call EFUNC(common,getName), getText (configFile >> _cfg >> _usedItem >> "displayName")]] call FUNC(addToLog); [QGVAR(medicationLocal), [_patient, _bodyPart, _classname], _patient] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_medicationLocal.sqf b/addons/medical_treatment/functions/fnc_medicationLocal.sqf index 0d0aa735ce6..18ef4e4d680 100644 --- a/addons/medical_treatment/functions/fnc_medicationLocal.sqf +++ b/addons/medical_treatment/functions/fnc_medicationLocal.sqf @@ -19,6 +19,9 @@ // todo: move this macro to script_macros_medical.hpp? #define MORPHINE_PAIN_SUPPRESSION 0.6 +// 0.2625 = 0.6/0.8 * 0.35 +// 0.6 = basic medication morph. pain suppr., 0.8 = adv. medication morph. pain suppr., 0.35 = adv. medication painkillers. pain suppr. +#define PAINKILLERS_PAIN_SUPPRESSION 0.2625 params ["_patient", "_bodyPart", "_classname"]; TRACE_3("medicationLocal",_patient,_bodyPart,_classname); @@ -36,13 +39,17 @@ if (!GVAR(advancedMedication)) exitWith { case "Epinephrine": { [QEGVAR(medical,WakeUp), _patient] call CBA_fnc_localEvent; }; + case "Painkillers": { + private _painSuppress = GET_PAIN_SUPPRESS(_patient); + _patient setVariable [VAR_PAIN_SUPP, (_painSuppress + PAINKILLERS_PAIN_SUPPRESSION) min 1, true]; + }; }; }; TRACE_1("Running treatmentMedicationLocal with Advanced configuration for",_patient); // Handle tourniquet on body part blocking blood flow at injection site -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find toLowerANSI _bodyPart; if (HAS_TOURNIQUET_APPLIED_ON(_patient,_partIndex)) exitWith { TRACE_1("unit has tourniquets blocking blood flow on injection site",_tourniquets); diff --git a/addons/medical_treatment/functions/fnc_placeBodyBagInGrave.sqf b/addons/medical_treatment/functions/fnc_placeBodyBagInGrave.sqf index 82cd2bc080b..55908b1e17d 100644 --- a/addons/medical_treatment/functions/fnc_placeBodyBagInGrave.sqf +++ b/addons/medical_treatment/functions/fnc_placeBodyBagInGrave.sqf @@ -29,7 +29,7 @@ TRACE_2("placeBodyBagInGrave",_bodybag,_medic); if (GVAR(graveDiggingMarker)) then { _graveClassname = missionNamespace getVariable [QGVAR(graveClassname), "ACE_Grave"]; }; - private _graveRotation = missionNameSpace getVariable [QGVAR(graveRotation), 0]; + private _graveRotation = missionNamespace getVariable [QGVAR(graveRotation), 0]; [[_medic, _bodybag], _graveClassname, [0,0,0], _graveRotation, true] call FUNC(placeInBodyBagOrGrave); }, diff --git a/addons/medical_treatment/functions/fnc_placeInBodyBagOrGrave.sqf b/addons/medical_treatment/functions/fnc_placeInBodyBagOrGrave.sqf index b72d0ddda47..fb0536db54f 100644 --- a/addons/medical_treatment/functions/fnc_placeInBodyBagOrGrave.sqf +++ b/addons/medical_treatment/functions/fnc_placeInBodyBagOrGrave.sqf @@ -69,7 +69,7 @@ if (_restingPlaceClass != "") then { // 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; +["ace_placedInBodyBag", [_patient, _restingPlace, _isGrave, _medic]] call CBA_fnc_globalEvent; if (_isGrave) then { - ["ace_placedInGrave", [_patient, _restingPlace]] call CBA_fnc_globalEvent; + ["ace_placedInGrave", [_patient, _restingPlace, _medic]] call CBA_fnc_globalEvent; }; diff --git a/addons/medical_treatment/functions/fnc_placeInGrave.sqf b/addons/medical_treatment/functions/fnc_placeInGrave.sqf index 6bea5c6db96..afc6a1fe4a2 100644 --- a/addons/medical_treatment/functions/fnc_placeInGrave.sqf +++ b/addons/medical_treatment/functions/fnc_placeInGrave.sqf @@ -27,7 +27,7 @@ private _graveClassname = ""; if (GVAR(graveDiggingMarker)) then { _graveClassname = missionNamespace getVariable [QGVAR(graveClassname), "ACE_Grave"]; }; -private _graveRotation = missionNameSpace getVariable [QGVAR(graveRotation), 0]; +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_splintLocal.sqf b/addons/medical_treatment/functions/fnc_splintLocal.sqf index f415d8296fe..4861f428cdd 100644 --- a/addons/medical_treatment/functions/fnc_splintLocal.sqf +++ b/addons/medical_treatment/functions/fnc_splintLocal.sqf @@ -20,7 +20,7 @@ params ["_medic", "_patient", "_bodyPart"]; TRACE_3("splintLocal",_medic,_patient,_bodyPart); -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find toLowerANSI _bodyPart; private _fractures = GET_FRACTURES(_patient); _fractures set [_partIndex, -1]; diff --git a/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf b/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf index 3fe5f4e55de..0ed8afd37c9 100644 --- a/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf +++ b/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf @@ -19,7 +19,7 @@ params ["_patient", "_bodyPart"]; TRACE_2("tourniquetLocal",_patient,_bodyPart); -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find toLowerANSI _bodyPart; private _tourniquets = GET_TOURNIQUETS(_patient); _tourniquets set [_partIndex, CBA_missionTime]; diff --git a/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf b/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf index 5c5cf93dc84..80dab5094cf 100644 --- a/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf +++ b/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf @@ -22,11 +22,13 @@ 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 { - [LSTRING(noTourniquetOnBodyPart), 1.5] call EFUNC(common,displayTextStructured); + if (_medic == ACE_player) then { + [LSTRING(noTourniquetOnBodyPart), 1.5] call EFUNC(common,displayTextStructured); + }; }; _tourniquets set [_partIndex, 0]; @@ -39,8 +41,15 @@ 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); +if (_medic call EFUNC(common,isPlayer)) then { + private _receiver = [_patient, _medic, _medic] select GVAR(allowSharedEquipment); + [_receiver, "ACE_tourniquet"] call EFUNC(common,addToInventory); +} else { + // If the medic is AI, only return tourniquet if enabled + if (missionNamespace getVariable [QEGVAR(medical_ai,requireItems), 0] > 0) then { + [_medic, "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 b7ebbfd8b07..5f6df40e31c 100644 --- a/addons/medical_treatment/functions/fnc_treatment.sqf +++ b/addons/medical_treatment/functions/fnc_treatment.sqf @@ -52,7 +52,7 @@ 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"]; private _isInZeus = !isNull findDisplay 312; @@ -76,7 +76,7 @@ if (_medic isNotEqualTo player || {!_isInZeus}) then { }; // Determine the animation length - private _animDuration = GVAR(animDurations) getVariable _medicAnim; + 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; @@ -155,13 +155,13 @@ if (_callbackProgress isEqualTo {}) then { _callbackProgress = {true}; }; -[_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem] call _callbackStart; +[_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter] call _callbackStart; -["ace_treatmentStarted", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem]] call CBA_fnc_localEvent; +["ace_treatmentStarted", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter]] call CBA_fnc_localEvent; [ _treatmentTime, - [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem], + [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter], FUNC(treatmentSuccess), FUNC(treatmentFailure), getText (_config >> "displayNameProgress"), diff --git a/addons/medical_treatment/functions/fnc_treatmentFailure.sqf b/addons/medical_treatment/functions/fnc_treatmentFailure.sqf index 64d18fa8308..7b3278b2a50 100644 --- a/addons/medical_treatment/functions/fnc_treatmentFailure.sqf +++ b/addons/medical_treatment/functions/fnc_treatmentFailure.sqf @@ -11,6 +11,7 @@ * 3: Treatment * 4: Item User * 5: Used Item + * 6: Create Litter * * Return Value: * None @@ -19,11 +20,15 @@ */ params ["_args"]; -_args params ["_medic", "_patient", "_bodyPart", "_classname", "_itemUser", "_usedItem"]; +_args params ["_medic", "_patient", "_bodyPart", "_classname", "_itemUser", "_usedItem", "_createLitter"]; // Return used item to user (if used) if (!isNull _itemUser) then { - [_itemUser, _usedItem] call EFUNC(common,addToInventory); + if (isClass (configFile >> "CfgMagazines" >> _usedItem)) then { + [_itemUser, _usedItem, 1] call EFUNC(common,adjustMagazineAmmo); + } else { + [_itemUser, _usedItem] call EFUNC(common,addToInventory); + }; }; // Switch medic to end animation immediately @@ -49,4 +54,4 @@ GET_FUNCTION(_callbackFailure,configFile >> QGVAR(actions) >> _classname >> "cal _args call _callbackFailure; -["ace_treatmentFailed", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem]] call CBA_fnc_localEvent; +["ace_treatmentFailed", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter]] call CBA_fnc_localEvent; diff --git a/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf b/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf index 96f0d11ead1..0c39f7646ed 100644 --- a/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf +++ b/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf @@ -11,6 +11,7 @@ * 3: Treatment * 4: Item User * 5: Used Item + * 6: Create Litter * * Return Value: * None @@ -19,7 +20,8 @@ */ params ["_args"]; -_args params ["_medic", "_patient", "_bodyPart", "_classname", "_itemUser", "_usedItem"]; +_args params ["_medic", "_patient", "_bodyPart", "_classname", "_itemUser", "_usedItem", "_createLitter"]; +TRACE_7("",_medic,_patient,_bodyPart,_classname,_itemUser,_usedItem,_createLitter); // Switch medic to end animation immediately private _endInAnim = _medic getVariable QGVAR(endInAnim); @@ -45,7 +47,7 @@ GET_FUNCTION(_callbackSuccess,configFile >> QGVAR(actions) >> _classname >> "cal _args call _callbackSuccess; // Call litter creation handler -_args call FUNC(createLitter); +if (_createLitter) then { _args call FUNC(createLitter); }; // Emit local event for medical API -["ace_treatmentSucceded", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem]] call CBA_fnc_localEvent; +["ace_treatmentSucceded", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter]] call CBA_fnc_localEvent; diff --git a/addons/medical_treatment/functions/fnc_useItem.sqf b/addons/medical_treatment/functions/fnc_useItem.sqf index 1f1d7c8355b..33ac9f98f42 100644 --- a/addons/medical_treatment/functions/fnc_useItem.sqf +++ b/addons/medical_treatment/functions/fnc_useItem.sqf @@ -10,7 +10,7 @@ * 2: Items * * Return Value: - * User and Item + * User and Item and Litter Created * * Example: * [player, cursorObject, ["bandage"]] call ace_medical_treatment_fnc_useItem @@ -29,20 +29,35 @@ scopeName "Main"; private _useOrder = [[_patient, _medic], [_medic, _patient], [_medic]] select GVAR(allowSharedEquipment); { - private _unit = _x; + private _unit = _x; private _unitVehicle = objectParent _unit; - private _unitItems = _x call EFUNC(common,uniqueItems); + private _unitItems = [_x, 0] call EFUNC(common,uniqueItems); + private _unitMagazines = [_x, 2] call EFUNC(common,uniqueItems); + private _vehicleItems = itemCargo _unitVehicle; // [] for objNull + private _vehicleMagazines = magazineCargo _unitVehicle; // same { - if (!isNull _unitVehicle && {_x in (itemCargo _unitVehicle)}) then { - _unitVehicle addItemCargoGlobal [_x, -1]; - [_unit, _x] breakOut "Main"; - }; - if (_x in _unitItems) then { - _unit removeItem _x; - [_unit, _x] breakOut "Main"; + switch (true) do { + case (_x in _vehicleItems): { + _unitVehicle addItemCargoGlobal [_x, -1]; + [_unit, _x, false] breakOut "Main"; + }; + case (_x in _vehicleMagazines): { + [_unitVehicle, _x] call EFUNC(common,adjustMagazineAmmo); + [_unit, _x, false] breakOut "Main"; + }; + case (_x in _unitItems): { + _unit removeItem _x; + [_unit, _x, true] breakOut "Main"; + }; + case (_x in _unitMagazines): { + private _magsStart = count magazines _unit; + [_unit, _x] call EFUNC(common,adjustMagazineAmmo); + private _magsEnd = count magazines _unit; + [_unit, _x, (_magsEnd < _magsStart)] breakOut "Main"; + }; }; } forEach _items; } forEach _useOrder; -[objNull, ""] +[objNull, "", false] diff --git a/addons/medical_treatment/initSettings.inc.sqf b/addons/medical_treatment/initSettings.inc.sqf index fbb1b170c81..7f0fc06764c 100644 --- a/addons/medical_treatment/initSettings.inc.sqf +++ b/addons/medical_treatment/initSettings.inc.sqf @@ -3,7 +3,7 @@ "LIST", [LSTRING(AdvancedDiagnose_DisplayName), LSTRING(AdvancedDiagnose_Description)], [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], - [[0, 1, 2], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), LSTRING(AdvancedDiagnose_DiagnoseCardiacArrest)], 1], + [[0, 1, 2, 3], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), LSTRING(AdvancedDiagnose_DiagnoseCardiacArrest), LSTRING(AdvancedDiagnose_DiagnoseCardiacArrestDirect)], 1], true ] call CBA_fnc_addSetting; @@ -86,7 +86,9 @@ [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 + 1, + {[QGVAR(convertItems), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ diff --git a/addons/medical_treatment/stringtable.xml b/addons/medical_treatment/stringtable.xml index 9008d28e2b0..b0d140d8255 100644 --- a/addons/medical_treatment/stringtable.xml +++ b/addons/medical_treatment/stringtable.xml @@ -70,13 +70,24 @@ 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 + Habilitado e permite diagnosticar morte/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] + Activé & peut diagnostiquer la mort/l'arrêt cardiaque [Direct]. + Habilitado y poder diagnosticar Muerte/Parada cardíaca [Directamente] + Advanced Medication Erweiterte Medikation @@ -153,6 +164,7 @@ Attivi e possono riaprirsi 已启用 & 可以伤口开裂 활성화 및 붕대 풀림 구현 + Habilitado e pode reabrir Wound Reopening Coefficient @@ -167,6 +179,7 @@ Coeficiente de reapertura de heridas 伤口开裂系数 붕대 풀림 계수 + Coeficiente de reabertura de feridas 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. @@ -181,6 +194,7 @@ 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所使用的绷带的具体开裂概率。 붕대가 풀리는 확률 계수를 정합니다. 최종 붕대 풀림 계수는 상처의 종류와 쓰인 붕대의 합의 결과에 계수를 곱한 결과입니다. + Coeficiente para controlar a chance de reabertura da ferida. A chance final de reabertura é determinada multiplicando este valor com a chance específica de reabertura para o tipo de ferida e bandagem usada. Clear Trauma @@ -193,10 +207,11 @@ 清理创伤 상처 제거 Despejar trauma + Remover trauma 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. @@ -205,6 +220,7 @@ 控制伤口治疗后确定受伤部位的受伤情况。 상처가 언제 제거되는 지를 결정합니다. Controla cuando los puntos de daño de las heridas son curados. + Controla quando o dano de pontos de vida de feridas é curado. After Bandage @@ -217,6 +233,7 @@ 包扎后 붕대 묶은 후 Después de vendado + Após fechamento com bandagens After Stitch @@ -229,6 +246,7 @@ 缝合后 상처 봉합 후 Después de sutura + Após sutura Boost medical training when in medical vehicles or facilities. Untrained becomes medic, medic becomes doctor. @@ -264,7 +282,7 @@ 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. @@ -321,11 +339,12 @@ Tempo di utilizzo dell'autoiniettore 自动注射器治疗时间 주사기 사용 시간 + Tempo de tratamento de auto-injetores 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. @@ -333,6 +352,7 @@ Tempo in secondi richiesto per ricevere medicina da un autoiniettore. 使用自动注射器给药所需的时间(秒) 초 단위로 주사기를 사용하는데 걸리는 시간을 정합니다. + Tempo, em segundos, necessário para administrar medicações usando o auto-injetor. Tourniquet Treatment Time @@ -345,18 +365,20 @@ Czas aplikacji stazy 止血带治疗时间 지혈대 사용 시간 + Tempo de tratamento de torniquetes 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. 使用/移除止血带所需的时间(秒) 초 단위로 지혈대를 사용/제거하는 데 걸리는 시간을 정합니다. + Tempo, em segundos, necessário para aplicar/remover um torniquete. IV Bag Treatment Time @@ -365,22 +387,24 @@ Tempo di inserimento EV 点滴の所要時間 Tiempo de tratamiento de bolsa de IV - Время применения пакета внутривенного переливания + Время внутривенного переливания Czas aplikacji IV 静脉输液袋治疗时间 수액용기 사용 시간 + Tempo de tratamento de bolsas de 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. 使用静脉输液所需的时间(秒) 초 단위로 수액용기를 사용하는 데 걸리는 시간을 정합니다. + Tempo, em segundos, necessário para administrar uma bolsa de IV. Splint Treatment Time @@ -393,18 +417,20 @@ Czas aplikacji szyny 夹板治疗时间 부목 사용 시간 + Tempo de tratamento de talas 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. 使用夹板所需的时间(秒) 초 단위로 부목을 사용하는데 걸리는 시간을 정합니다. + Tempo, em segundos, necessário para aplicar uma talas. Body Bag Use Time @@ -417,18 +443,20 @@ Czas użycia worka na ciało 尸袋使用时间 시체 운반용 부대 사용 시간 + Tempo de uso de sacos de cadáver 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. 装入裹尸袋时间 초 단위로 시체 운반용 부대를 사용하는데 걸리는 시간을 정합니다. + Tempo, em segundos, necessário para colocar um paciente em um saco de cadáver. Grave Digging Time @@ -439,6 +467,8 @@ Tempo di scavo tomba 墓掘りの所要時間 Время рытья могилы + Tiempo de Cavado de Tumba + Tempo de escavação de cova Time, in seconds, required to dig a grave for a body. @@ -447,8 +477,10 @@ 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. + Tempo, em segundos, necessário para cavar uma cova para um corpo. Allow Epinephrine @@ -459,7 +491,7 @@ Permetti Epinefrina Povolit epinefrin Permitir Epinefrina - Разрешить Адреналин + Доступ к Адреналину アドレナリンの許可 에피네프린 사용 허가 允许使用肾上腺素 @@ -500,7 +532,7 @@ Controls where epinephrine can be used. - アドレナリンが使える場所を決定します。 + アドレナリンが使える場所を制御します。 Définit les lieux où l'usage d'épinéphrine est autorisé. Контролирует, где можно использовать Адреналин. Controla onde Epinefrina pode ser utilizada. @@ -516,7 +548,7 @@ Allow PAK - Использование Аптечки + Доступ к Аптечке Ograniczenia użycia apteczek osobistych Permitir EPA Erlaube Erste-Hilfe-Set @@ -566,7 +598,7 @@ Controls where a PAK can be used. - PAKが使える場所を決定します。 + PAKが使える場所を制御します。 Définit les lieux où l'usage de la trousse sanitaire est autorisé. Контролирует, где можно использовать Аптечку. Controla onde o KPS pode ser utilizado. @@ -598,7 +630,7 @@ Controls whether a PAK should be consumed after use. - PAKの使用後に消費するかどうかを決定します。 + PAKの使用後に消費するかどうかを制御します。 Définit si la trousse sanitaire doit être à usage unique. Контролирует, следует ли израсходовать Аптечку после использования. Controla se o KPS deve ser descartado/consumido após o uso. @@ -626,6 +658,7 @@ Kendi PAK Kullanımı Usar EPA sobre uno mismo 개인응급키트 자가 사용 + Auto-tratamento com KPS Enables the use of PAKs to heal oneself. @@ -641,6 +674,7 @@ Kendini iyileştirmek için PAK'ların kullanılmasını sağlar. Habilita el uso de EPA para curarse a uno mismo. 개인응급키트를 사용자 본인에게 쓸 수 있는 지를 정합니다. + Permite o uso de KPS para se tratar. Time Coefficient PAK @@ -678,7 +712,7 @@ Allow Surgical Kit 手術キットを許可 Trousse chirurgicale autorisée pour - Разрешить Хирургический набор + Доступ к Хирургическому набору Permitir Kit Cirúrgico 允許使用手術包 允许使用手术包 @@ -724,7 +758,7 @@ 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. @@ -762,7 +796,7 @@ Co powinno zostać zużyte po zastosowaniu. 봉합키트를 1회성 소모품으로 설정할 지 여부를 결정합니다. Ce qui doit être consommé après l'utilisation. - Решите, следует ли использовать набор для наложения швов в качестве одноразового расходного материала. + Контролирует, следует ли израсходовать Хирургический набор или нить после использования Self Stitching @@ -775,7 +809,7 @@ Samo-zašívání Zszywanie własnych ran Selbstnähen - Зашивание своей раны + Зашитие своей раны Auto cosido 봉합키트 자가 사용 @@ -805,11 +839,12 @@ Tempo di suturazione ferita. 伤口缝合时间 상처 봉합 시간 + Tempo de sutura de feridas 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. @@ -817,6 +852,7 @@ Tempo in secondi richiesto per suturare una singola ferita. 缝合一个伤口所需的时间(秒) 초 단위로, 한 상처를 봉합하는데 걸리는 시간을 설정합니다. + Tempo, em segundos, necessário para suturar uma única ferida. Self IV Transfusion @@ -851,19 +887,20 @@ 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 允许昏迷者装入尸袋 기절 인원 시체 운반용 부대에 옮기기 + Permitir inconscientes em sacos de cadáver 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. @@ -871,6 +908,7 @@ Permette l'uso della sacca per morti anche su pazienti che sono solo svenuti (causa la morte del paziente) 能够将昏迷的伤员装入尸袋中。 기절 상태의 인원을 시체 운반용 부대에 옮겨 담을 수 있는 지를 정합니다. + Permite colocar um paciente inconsciente em um saco de cadáver. Allow Grave Digging @@ -881,7 +919,8 @@ Permitir cavar tumbas Autoriser le creusement de tombes 墓掘りを許可 - Разрешить рытье могил + Рытье могил + Permitir escavamento de cova Enables digging graves to dispose of corpses. @@ -893,6 +932,7 @@ Active la possibilité de creuser des tombes pour enterrer les cadavres. 墓を掘って死体を処理できるようになります。 Позволяет рыть могилы для захоронения трупов. + Permite escavar covas para se livrar de cadáveres. Only if dead @@ -904,6 +944,7 @@ Uniquement s'il est mort 死体のみ Только если мертв + Apenas se estiver morto Create Grave Markers @@ -914,7 +955,8 @@ 무덤 마커 생성 Créer des pierres tombales 墓標を作成 - Создайте надгробные знаки + Надгробные знаки + Criar marcadores de covas Enables the creation of grave markers when digging graves. @@ -926,6 +968,7 @@ Active la création de pierres tombales lors de l'enterrement de cadavres. 墓を掘った際、墓標を作成できるようにします。 Позволяет создавать надгробные знаки при рытье могил. + Permite a criação de marcadores de covas ao escavá-las. Allow IV Transfusion @@ -937,9 +980,10 @@ 允许静脉输液 IV 輸液の制限 Povolit IV transfuzi - Разрешить внутривенное переливание + Доступ к внутривенному переливанию Permitir transfusión de IV 수액용기 사용 허가 + Permitir transfusão IV Training level required to transfuse IVs. @@ -954,30 +998,33 @@ Уровень навыка, требуемый для осуществления внутривенного переливания. Nivel de capacitación requerido para transfusiones de IV. 수액용기를 사용하는데 필요한 등급을 정합니다. + Nível de treinamento necessário para transfusões IV. Locations IV Transfusion - IV 輸液の場所制限 + IV輸液の可能な場所 Ubicación para transfusiones IV Lieux perfusions IV - Места введения пакетов внутривенного переливания + Места внутривенного переливания Miejsca do transfuzji IV Orte an denen IV-Transfusionen angelegt werden können Luoghi Fleboclisi EV 静脉输液地点 수액용기 사용 장소 + Locais para transfusão IV Controls where IV transfusions can be performed. - IV 輸液を行える場所を決定できます。 + IV 輸液を行える場所を制御します。 Controla dónde pueden ser realizadas las transfusiones IV. Définit les lieux où la pose de perfusions est autorisée. - Определяет к каким частям тела разрешено применять пакеты внутренного переливания. + Контролирует, где можно использовать внутревенное переливание. Kontroluje w jakich miejscach można robić transfuzje IV. Kontrolliert, wo IV-Transfusionen durchgeführt werden können. Luoghi in cui è possibile applicare Fleboclisi Endovenose. 控制何地可以静脉输液 수액용기를 사용할 수 있는 장소를 정합니다. + Controla onde as transfusões IV podem ser realizadas. Convert Vanilla Items @@ -997,7 +1044,7 @@ 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. @@ -1105,7 +1152,7 @@ Controls the lifetime of litter objects, in seconds. -1 is forever. - 廃棄物の寿命を秒で決定できます。-1 にすると恒久的になります。 + 廃棄物の寿命を秒単位で制御します。-1 にすると恒久的になります。 Définit la durée d'affichage des détritus, en secondes. Durée illimitée : -1. Управляет временем жизни объектов мусора в секундах. -1 означает Навсегда. Controla o tempo de vida de objetos de lixo criados em segundos. -1 é para sempre. @@ -1210,6 +1257,7 @@ 心肺复苏的最低成功率 최소 심폐소생술 성공 가능성 RCP posibilidad mínima de resultado satisfactorio + Probabilidade mínima de sucesso de RCP CPR Success Chance Maximum @@ -1222,6 +1270,7 @@ 心肺复苏的最高成功率 최대 심폐소생술 성공 가능성 RCP posibilidad máxima de resultado satisfactorio + Probabilidade máxima de sucesso de RCP 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. @@ -1234,6 +1283,7 @@ 实施心肺复苏恢复心律的最小可能性。\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. + Probabilidade mínima do RCP restaurar a frequência cardíaca.\nEste valor é usado em pacientes que "perderam uma quantidade fatal de sangue".\nValores entre quantidades extremas de sangue resultam em uma probabilidade interpolada entre a mínima e a máxima. 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. @@ -1246,6 +1296,7 @@ 实施心肺复苏恢复心律的最大可能性。\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. + Probabilidade máxima do RCP restaurar a frequência cardíaca.\nEste valor é usado em pacientes que "perderam pouco sangue".\nValores entre quantidades extremas de sangue resultam em uma probabilidade interpolada entre a mínima e a máxima. CPR Treatment Time @@ -1258,18 +1309,20 @@ HLW Behandlungsdauer 心肺复苏时间 심폐소생술 시행 시간 + Duração do RCP 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)に掛かる時間 (秒) を決定します。 + 心肺蘇生(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. 对伤员实施心肺复苏所需的时间(秒) 초 단위로, 심폐소생술을 진행하는 시간을 결정합니다. + Tempo, em segundos, necessário para realizar RCP em um paciente. Holster Required @@ -1284,6 +1337,7 @@ Необходимость убирать оружие Requiere enfundar 무장여부 + Necessário guardar armas 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. @@ -1298,6 +1352,7 @@ Нужно ли убирать оружие для проведения медицинских действий.\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검사제외 옵션의 경우 맥박 확인, 혈압 확인, 반응 확인은 앞선 옵션에 구애받지 않고 사용할 수 있습니다. + Controla se as armas devem ser guardadas/abaixadas para realizar ações médicas.\n"Exceto exame" faz com que ações de verificação de pulso, pressão arterial e resposta sejam permitidas a qualquer momento. Lowered or Holstered @@ -1312,6 +1367,7 @@ Опущено или убрано Bajada o enfundada 내리거나 집어넣기 + Abaixada ou guardada Lowered or Holstered (Except Exam) @@ -1326,6 +1382,7 @@ Опущено или убрано (Проверка разрешена) Bajada o enfundada (excepto examen) 내리거나 집어넣기(검사 제외) + Abaixada ou guardada (exceto exame) Holstered Only @@ -1340,6 +1397,7 @@ Только убрано Solo enfundada 집어넣기 + Guardada apenas Holstered Only (Except Exam) @@ -1354,6 +1412,7 @@ Только убрано (Проверка разрешена) Solo enfundada (excepto examen) 집어넣기(검사 제외) + Guardada apenas (exceto exame) [ACE] Medical Supply Crate (Basic) @@ -1366,7 +1425,7 @@ [ACE] Caisse médicale (basique) [ACE] Orvosi láda (Alap) [ACE] Cassa Rifornimenti Medici (Basici) - [ACE] 医療物資箱 (ベーシック) + [ACE] 医療物資箱 (基本) [ACE] 의료 물자 (기본) [ACE] 医疗补给箱(基础) [ACE] 醫療補給箱(基本) @@ -1383,7 +1442,7 @@ [ACE] Caisse médicale (avancée) [ACE] Orvosi láda (Fejlett) [ACE] Cassa Rifornimenti Medici (Avanzati) - [ACE] 医療物資箱 (アドバンスド) + [ACE] 医療物資箱 (高度) [ACE] 의료 물자 (고급) [ACE] 医疗补给箱(高级) [ACE] 醫療補給箱(進階) @@ -1817,7 +1876,7 @@ Auto-morfin Morfium autoinjektor Autoiniettore di Morfina - Auto-injetor de morfina + Autoinjetor de Morfina モルヒネ自動注射器 자동주사기 (모르핀) 吗啡自动注射器 @@ -1864,7 +1923,7 @@ Auto-injecteur d'adénosine Autoiniettore di Adenosina Auto-adenosine - Auto-injetor de Adenosina + Autoinjetor de Adenosina Аденозин в пневмошприце アデノシン自動注射器 자동주사기 (아데노신) @@ -1912,7 +1971,7 @@ Auto-atropine Atropin autoinjektor Autoiniettore di Atropina - Auto-injetor de Atropina + Autoinjetor de Atropina アトロピン自動注射器 자동주사기 (아트로핀) 阿托品自动注射器 @@ -1961,7 +2020,7 @@ Auto-adrenalin Epinefrin autoinjektor Autoiniettore di Epinefrina - Auto-injetor de epinefrina + Autoinjetor de Epinefrina アドレナリン自動注射器 자동주사기 (에피네프린) 肾上腺素自动注射器 @@ -2375,7 +2434,7 @@ Operationsset Sebészeti készlet Kit chirurgico - Kit Cirurgico + Kit Cirúrgico Chirurgická sada 手術キット 봉합 키트 @@ -2392,7 +2451,7 @@ Operationsset für fortgeschrittene medizinische Feldversorgung 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 + Kit Cirúrgico 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 手術キットは戦場で高度な処置をする為に用いる 야전 상황에서 고급 의료 처치를 위해 사용되는 봉합 키트 @@ -2409,7 +2468,7 @@ 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. + Kit Cirúrgico 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 手術キットは戦場で高度な処置をする為に用いる 야전 상황에서 고급 의료 처치를 위해 사용되는 봉합 키트 @@ -2444,6 +2503,7 @@ 봉합술 Suture Нить + Sutura Surgical Suture for stitching injuries. @@ -2455,6 +2515,7 @@ 상처를 꿰메는 수술용 봉합술. Suture chirurgicale pour suturer les blessures. Хирургическая нить для зашивания травм. + Sutura cirúrgica para fechar feridas. Surgical Suture for stitching injuries. @@ -2466,6 +2527,7 @@ 상처를 꿰메는 수술용 봉합술. Suture chirurgicale pour suturer les blessures. Хирургическая нить для зашивания травм. + Sutura cirúrgica para fechar feridas. Bodybag @@ -3506,6 +3568,7 @@ Kein Schmerz 痛みはない Нет боли + Sin dolor In mild pain @@ -3570,21 +3633,53 @@ 軍用止血帶 Turnike [CAT] - - Receiving IV [%1ml] - Erhalte IV [%1ml] - Recibiendo IV [%1ml] - Принимается переливание [%1 мл] - Otrzymywanie IV [pozostało %1ml] - Transfusion : [%1 ml] - Přijímání transfúze [%1ml] - Infúzióra kötve [%1ml] - Ricevendo EV [%1ml] - Recebendo IV [%1ml] - IV [%1ml] を投与中 - IV로 [%1ml] 수혈중 - 正在接受静脉注射 [%1毫升] - 接收靜脈注射液中 [%1毫升] + + Receiving Saline IV [%1ml] + Erhalte Saline IV [%1ml] + Recibiendo Salina IV [%1ml] + Принимается физраствор [%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 @@ -3595,6 +3690,7 @@ Kein IV IV なし Нет капельницы + Sin IV Blood Pressure @@ -3642,7 +3738,7 @@ %1 zkontroloval krevní tlak: %2 %1 verificou pressão arterial: %2 %1 が血圧を確認: %2 - %1 (이)가 혈압을 측정했습니다: %2 + %1(이)가 혈압을 측정했습니다: %2 %1 测得血压为 %2 已由%1確認血壓: %2 @@ -3895,7 +3991,7 @@ %1 zkontroloval srdeční tep: %2 %1 verificou a frequência cardíaca: %2 %1 が心拍を確認: %2 - %1 (이)가 맥박을 측정했습니다: %2 + %1(이)가 맥박을 측정했습니다: %2 %1 测得心率为 %2 已由%1確認心跳: %2 @@ -3979,7 +4075,7 @@ A Frequência Cardíaca é de %2 Nahmatal jsi srdeční tep u %2 計測した心拍数は %2 でした - 맥박이 %2 입니다 + 맥박은 %2 입니다 心率为 %2 心跳為%2 @@ -4095,7 +4191,7 @@ %1 está respondendo %1 odpovídá %1 は反応している - %1 은 반응이 있습니다 + %1은(는) 반응이 있습니다 %1 有反应 %1 有反應 %1 tepki veriyor @@ -4103,7 +4199,7 @@ %1 is not responsive %1 не реагирует на раздражители - %1 est inconscient. + %1 ne répond pas aux stimuli %1 no reacciona %1 jest nieprzytomny %1 ist nicht ansprechbar @@ -4112,11 +4208,21 @@ %1 não está respondendo %1 neodpovídá %1 は反応していない - %1 은 반응이 없습니다 + %1은(는) 반응이 없습니다 %1 没有反应 %1 沒有反應 %1 tepki vermiyor + + %1 is unconscious + %1 は意識がない + %1 находится без сознания + %1은(는) 의식불명입니다 + %1 ist bewusstlos + %1 è privo di sensi + %1 est inconscient + %1 está inconsciente + %1 is not responsive, taking shallow gasps and convulsing %1 est inconscient, respire par intermittence et convulse. @@ -4128,6 +4234,17 @@ %1 은 반응이 없고, 얕은 헐떡임과 경련증세를 보입니다 %1 не реагирует на раздражители, поверхностно дышит, в конвульсиях %1 no responde, dando pequeñas bocanadas y convulsionando + %1 está inconsciente, com respiração curta e convulsionando + + + %1 is in cardiac arrest + %1 は心停止している + У %1 произошла остановка сердца + %1은(는) 심정지 상태입니다 + %1 ist im Herzstillstand + %1 è in arresto cardiaco + %1 est en arrêt cardiaque + %1 en parada cardíaca %1 is not responsive, motionless and cold @@ -4140,6 +4257,17 @@ %1 은 반응이 없고, 움직임이 없으며 차갑습니다 %1 не реагирует на раздражители, не шевелится и холодный %1 no responde, sin movimiento y frío + %1 está inconsciente, sem movimento e frio + + + %1 is dead + %1 は死亡している + %1 мертв + %1은(는) 사망했습니다 + %1 ist tod + %1 è morto + %1 est mort + %1 está muerto You checked %1 @@ -4571,7 +4699,7 @@ Vücudu siyah ceset torbasına yerleştir 遺体袋 (黒) に入れる 시체를 검은 시체가방에 놓기 - Положите тело в черный мешок для тела + Положить тело в черный мешок для тела Place body in blue bodybag @@ -4584,7 +4712,7 @@ Vücudu mavi ceset torbasına yerleştir 遺体袋 (青) に入れる 시체를 파란 시체가방에 놓기 - Положите тело в синий мешок для тела + Положить тело в синий мешок для тела Place body in white bodybag @@ -4597,7 +4725,7 @@ Vücudu beyaz ceset torbasına yerleştir 遺体袋 (白) に入れる 시체를 흰 시체가방에 놓기 - Положите тело в белый мешок для тела + Положить тело в белый мешок для тела Placing body in bodybag... @@ -4625,6 +4753,8 @@ Scava tomba per cadavere 墓を掘る Выкопать могилу для тела + Cavar tumba para cuerpo + Escavar cova para cadáver Digging grave for body... @@ -4634,7 +4764,9 @@ Grab für Leichnam ausheben ... Scavando tomba per cadavere... 墓を掘っています - Рою могилу для тела... + Рытьё могилы для тела... + Cavando tumba para cuerpo... + Escavando cova para cadáver... %1 has bandaged patient @@ -4805,7 +4937,7 @@ Heal fully bandaged hitpoints Lecz w pełni zabandażowane hitpointy Curar miembros totalmente vendados - Исцелять полностью перебинтованные части тела + Исцелить полностью перебинтованные части тела Curar membros totalmente enfaixados Heal fully bandaged hitpoints Cura hitpoints completamente bendati @@ -4877,6 +5009,7 @@ Der Körper zuckte und kann nicht tot sein! 身体抽搐了一下,可能还没死! 꿈틀대는걸 보니 죽은 것 같지는 않습니다! + O corpo se retorceu e pode não estar morto! Check name on headstone @@ -4887,6 +5020,8 @@ Controlla nome sulla lapide 墓石の名前を確認 Проверьте имя на надгробии + Comprobar nombre en la lápida + Checar nome na lápide Bandage Rollover @@ -4896,7 +5031,9 @@ Pansement de plaies multiples Srotolamento Bendaggi 包帯の繰り越し - Переворачивание бинта + Перевязка множественных ран + Vendaje múltiple + Bandagem de Múltiplas Feridas If enabled, bandages can close different types of wounds on the same body part.\nBandaging multiple injuries will scale bandaging time accordingly. @@ -4906,7 +5043,9 @@ 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\При перевязке нескольких повреждений время перевязки будет увеличено соответствующим образом. + Если эта функция включена, бинты могут закрывать различные типы ран на одной и той же части тела.\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. + Se habilitado, bandagens podem fechar diferentes tipos de ferimento na mesma parte do corpo.\nO fechamento de múltiplas feridas modificará o tempo de aplicação proporcionalmente. Bandage Effectiveness Coefficient @@ -4916,7 +5055,9 @@ Coefficient d'efficacité des bandages Coefficiente di efficacia bendaggi 包帯有効性係数 - Коэффициент эффективности повязки + Коэф. эффективности повязки + Coeficiente de Efectividad de Vendado + Coeficiente de Eficácia da Bandagem Determines how effective bandages are at closing wounds. @@ -4925,8 +5066,10 @@ 붕대가 상처를 치료하는 데 얼마나 효과적으로 지속되는지 결정합니다. 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. + Determina o quão efetivas as bandagens são em fechar ferimentos. Medical Items @@ -4941,6 +5084,7 @@ Medizinisches Material 医療品 Objetos médicos + Objetos médicos Zeus Treatment Time Coefficient @@ -4948,7 +5092,9 @@ Zeit-Koeffizient für Zeus Behandlungen Zeus治療時間係数 제우스 치료 시간 계수 - Коэффициент времени обработки Zeus + Коэф. времени обработки Zeus + Coeff. de temps + Coeficiente de Tiempo del Tratamiento de Zeus Multiply all treatment times with this coefficient when in Zeus. @@ -4957,6 +5103,8 @@ Zeus操作中は、すべての治療時間にこの係数を掛けます。 제우스일 때 모든 치료 시간에 이 계수를 곱합니다. Умножьте все время лечения на этот коэффициент, когда вы находитесь в Zeus. + Coefficient de temps de traitement Zeus + Multiplica los tiempos de tratamientos por este coeficiente cuando se está en Zeus Painkillers @@ -4976,23 +5124,43 @@ 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_vitals/functions/fnc_handleUnitVitals.sqf b/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf index c284b00701d..77aec7fd621 100644 --- a/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf +++ b/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf @@ -85,17 +85,17 @@ if (_adjustments isNotEqualTo []) then { private _timeInSystem = CBA_missionTime - _timeAdded; if (_timeInSystem >= _maxTimeInSystem) then { _deleted = true; - _adjustments set [_forEachIndex, objNull]; + _adjustments deleteAt _forEachIndex; } else { 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 (_flowAdjust != 0) then { _peripheralResistanceAdjustment = _peripheralResistanceAdjustment + _flowAdjust * _effectRatio; }; }; - } forEach _adjustments; + } forEachReversed _adjustments; if (_deleted) then { - _unit setVariable [VAR_MEDICATIONS, _adjustments - [objNull], true]; + _unit setVariable [VAR_MEDICATIONS, _adjustments, true]; _syncValues = true; }; }; diff --git a/addons/medical_vitals/functions/fnc_updateHeartRate.sqf b/addons/medical_vitals/functions/fnc_updateHeartRate.sqf index 187a8ffe58e..0390a9ad076 100644 --- a/addons/medical_vitals/functions/fnc_updateHeartRate.sqf +++ b/addons/medical_vitals/functions/fnc_updateHeartRate.sqf @@ -40,13 +40,9 @@ if IN_CRDC_ARRST(_unit) then { 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 { diff --git a/addons/medical_vitals/functions/fnc_updatePeripheralResistance.sqf b/addons/medical_vitals/functions/fnc_updatePeripheralResistance.sqf index 30f8038d80f..05056fa0a33 100644 --- a/addons/medical_vitals/functions/fnc_updatePeripheralResistance.sqf +++ b/addons/medical_vitals/functions/fnc_updatePeripheralResistance.sqf @@ -20,4 +20,4 @@ params ["_unit", "_peripheralResistanceAdjustment", "_deltaT", "_syncValue"]; -_unit setVariable [VAR_PERIPH_RES, 0 max (DEFAULT_PERIPH_RES + _peripheralResistanceAdjustment), _syncValue]; +_unit setVariable [VAR_PERIPH_RES, 1 max (DEFAULT_PERIPH_RES + _peripheralResistanceAdjustment), _syncValue]; diff --git a/addons/medical_vitals/stringtable.xml b/addons/medical_vitals/stringtable.xml index b62f7f1d090..25b278732ea 100644 --- a/addons/medical_vitals/stringtable.xml +++ b/addons/medical_vitals/stringtable.xml @@ -4,18 +4,35 @@ 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 + Habilitar simulação de 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. + Habilita a saturação de oxigênio, tornando variáveis o batimento cardíaco e demanda de oxigênio baseados em atividade física e altitude. Necessário para o gerenciamento de vias aéreas. diff --git a/addons/metis/CfgAmmo.hpp b/addons/metis/CfgAmmo.hpp index 1f613a36b18..4a6fe513d23 100644 --- a/addons/metis/CfgAmmo.hpp +++ b/addons/metis/CfgAmmo.hpp @@ -1,3 +1,4 @@ +class ace_missileguidance_type_Metis; class CfgAmmo { class M_Vorona_HEAT; class GVAR(HEAT): M_Vorona_HEAT { @@ -7,35 +8,8 @@ class CfgAmmo { airLock = 0; lockType = 0; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Metis { 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"}; }; }; @@ -47,35 +21,8 @@ class CfgAmmo { airLock = 0; lockType = 0; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Metis { 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/microdagr/CfgUIGrids.hpp b/addons/microdagr/CfgUIGrids.hpp index 5d7b921800a..3c5379f879d 100644 --- a/addons/microdagr/CfgUIGrids.hpp +++ b/addons/microdagr/CfgUIGrids.hpp @@ -3,7 +3,7 @@ class CfgUIGrids { class Presets { class Arma3 { class Variables { - grid_ACE_microDagr[] = {{"(safezoneX + safezoneW - 11 * (((safezoneW / safezoneH) min 1.2) / 40))","(safezoneY + safezoneH - 15 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))","(10 * (((safezoneW / safezoneH) min 1.2) / 40))","(10 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))"},"(((safezoneW / safezoneH) min 1.2) / 40)","((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"}; + grid_ACE_microDagr[] = {{"(safeZoneX + safeZoneW - 11 * (((safeZoneW / safeZoneH) min 1.2) / 40))","(safeZoneY + safeZoneH - 15 * ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25))","(10 * (((safeZoneW / safeZoneH) min 1.2) / 40))","(10 * ((((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/microdagr/XEH_clientInit.sqf b/addons/microdagr/XEH_clientInit.sqf index 8a5db92e0bd..c17914ad4b6 100644 --- a/addons/microdagr/XEH_clientInit.sqf +++ b/addons/microdagr/XEH_clientInit.sqf @@ -35,7 +35,7 @@ private _closeCode = { }, ""] call CBA_fnc_addKeybind; //Add Eventhandler: -[QEGVAR(vector,rangefinderData), {_this call FUNC(recieveRangefinderData)}] call CBA_fnc_addEventHandler; +[QEGVAR(vector,rangefinderData), LINKFUNC(recieveRangefinderData)] call CBA_fnc_addEventHandler; //Global Variables to default: GVAR(gpsPositionASL) = [0,0,0]; diff --git a/addons/microdagr/functions/fnc_showApplicationPage.sqf b/addons/microdagr/functions/fnc_showApplicationPage.sqf index 75f817ad3f3..daa5edd28a5 100644 --- a/addons/microdagr/functions/fnc_showApplicationPage.sqf +++ b/addons/microdagr/functions/fnc_showApplicationPage.sqf @@ -57,8 +57,8 @@ if (GVAR(currentApplicationPage) == APP_MODE_INFODISPLAY) then { (_display displayCtrl IDC_MAPDETAILS) ctrlShow ((GVAR(currentApplicationPage) == APP_MODE_MAP) && {GVAR(mapShowTexture)}); if (GVAR(currentApplicationPage) == APP_MODE_MAP) then { - _theMap = if (!GVAR(mapShowTexture)) then {_display displayCtrl IDC_MAPPLAIN} else {_display displayCtrl IDC_MAPDETAILS}; - _mapSize = (ctrlPosition _theMap) select 3; + private _theMap = if (GVAR(mapShowTexture)) then {_display displayCtrl IDC_MAPDETAILS} else {_display displayCtrl IDC_MAPPLAIN}; + private _mapSize = (ctrlPosition _theMap) select 3; _theMap ctrlMapAnimAdd [0, (GVAR(mapZoom) / _mapSize), GVAR(mapPosition)]; ctrlMapAnimCommit _theMap; if (GVAR(mapAutoTrackPosition)) then { diff --git a/addons/microdagr/functions/fnc_updateDisplay.sqf b/addons/microdagr/functions/fnc_updateDisplay.sqf index 3e5775b86dc..e5de2b2fe49 100644 --- a/addons/microdagr/functions/fnc_updateDisplay.sqf +++ b/addons/microdagr/functions/fnc_updateDisplay.sqf @@ -24,7 +24,7 @@ if (isNull _display) exitWith {ERROR("No Display");}; private _daylight = [] call EFUNC(common,ambientBrightness); (_display displayCtrl IDC_MICRODAGRSHELL) ctrlSetTextColor [_daylight, _daylight, _daylight, 1]; -(_display displayCtrl IDC_CLOCKTEXT) ctrlSetText ([daytime, "HH:MM"] call bis_fnc_timeToString); +(_display displayCtrl IDC_CLOCKTEXT) ctrlSetText ([dayTime, "HH:MM"] call bis_fnc_timeToString); private _waypoints = [] call FUNC(deviceGetWaypoints); @@ -61,7 +61,7 @@ case (APP_MODE_INFODISPLAY): { private _dayString = if ((date select 2) < 10) then {"0" + str (date select 2)} else {str (date select 2)}; (_display displayCtrl IDC_MODEDISPLAY_TIMEDISPLAYGREEN1) ctrlSetText format ["%1-%2-%3", _yearString, _monthSring, _dayString]; //"18-Feb-2010"; - (_display displayCtrl IDC_MODEDISPLAY_TIMEDISPLAYGREEN2) ctrlSetText ([daytime, "HH:MM:SS"] call bis_fnc_timeToString); + (_display displayCtrl IDC_MODEDISPLAY_TIMEDISPLAYGREEN2) ctrlSetText ([dayTime, "HH:MM:SS"] call bis_fnc_timeToString); } else { private _targetPosName = ""; private _targetPosLocationASL = []; diff --git a/addons/microdagr/gui.hpp b/addons/microdagr/gui.hpp index 1404f6b81db..2a3f52deb43 100644 --- a/addons/microdagr/gui.hpp +++ b/addons/microdagr/gui.hpp @@ -40,8 +40,8 @@ class GVAR(RscText): RscText { }; //Redfine Scaling for the Dialog -#define X_PART(num) QUOTE((((60 - 25)/2) + (num)) * (safeZoneH / 64) + (safezoneX + (safezoneW - safeZoneH)/2)) -#define Y_PART(num) QUOTE((0 + (num)) * (safeZoneH / 36) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2)) +#define X_PART(num) QUOTE((((60 - 25)/2) + (num)) * (safeZoneH / 64) + (safeZoneX + (safeZoneW - safeZoneH)/2)) +#define Y_PART(num) QUOTE((0 + (num)) * (safeZoneH / 36) + (safeZoneY + (safeZoneH - (safeZoneH / 1.2))/2)) #define W_PART(num) QUOTE((num) * (safeZoneH / 64)) #define H_PART(num) QUOTE((num) * (safeZoneH / 36)) diff --git a/addons/microdagr/initSettings.inc.sqf b/addons/microdagr/initSettings.inc.sqf index 8810939302d..aacc5fd24bc 100644 --- a/addons/microdagr/initSettings.inc.sqf +++ b/addons/microdagr/initSettings.inc.sqf @@ -15,7 +15,5 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(itemName) [LSTRING(WaypointPrecision_DisplayName), LSTRING(WaypointPrecision_Description)], _category, [[1, 2, 3], [LSTRING(WaypointPrecision_medium), LSTRING(WaypointPrecision_close), LSTRING(WaypointPrecision_exact)], 2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(waypointPrecision), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // require mission restart + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/microdagr/stringtable.xml b/addons/microdagr/stringtable.xml index c8e0b16d348..79b66e18ebb 100644 --- a/addons/microdagr/stringtable.xml +++ b/addons/microdagr/stringtable.xml @@ -29,7 +29,7 @@ MicroDAGR fejlett GPS vevőegység Ricevitore GPS avanzato MicroDAGR Receptor GPS avançado MicroDAGR - MicroDAGRは改良された高度なGPS受信機です + MicroDAGRは高機能なGPS受信機です 마이크로DAGR 고급 위성항법 수신기 微型军用高级防御 GPS 接收器 微型軍用高級防禦GPS接收器 @@ -357,7 +357,7 @@ 切換微型軍用GPS接收器顯示模式 - Show MicoDAGR + Show MicroDAGR Zeige MicroDAGR Mostrar MicroDAGR Показать MicroDAGR @@ -447,7 +447,7 @@ Mennyi térképadatot tartalmaz a MicroDAGR Сколько данных должно отображаться на карте MicroDAGR Quanti dati cartografici sono mostrati sulla mappa del MicroDAGR - MicroDAGR で表示する地図情報を決定します + MicroDAGR で表示される地図の情報量 얼마나 많은 데이터를 마이크로DAGR가 보여주는지를 결정합니다 有多少地图数据会显示在微型军用 GPS 接收器 有多少地圖數據會顯示在微型軍用GPS接收器 @@ -519,7 +519,7 @@ Controls how precise the waypointdistance can be displayed Legt die Genauigkeit der Entfernung von Wegpunkten fest 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 @@ -589,7 +589,7 @@ 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 cartografici vengono caricati sui MicroDAGR. Meno dati permetteranno la visualizzazione di meno informazioni sulla minimappa. - アイテム上で表示されるデータ量を決定します。設定を減らすと地図上での情報が少なくなります。 + microDAGRの項目に入力されるデータの量を制御します。データを少なくすると、マップビューが制限され、ミニマップの表示量が少なくなります。 마이크로DAGR에 얼마나 많은 데이터가 들어있는지 정합니다. 적을 수록 지도상에도 비춰지는게 적어집니다. 设定有多少数据会显示在微型军用 GPS 接收器上。这些资料的多寡会反映在迷你地图的显示上。 設定有多少數據會顯示在微型軍用GPS接收器上。這些資料的多寡會反映在迷你地圖的顯示上。 @@ -605,6 +605,7 @@ MicroDAGR - Poprzedni Tryb 微型 GPS 接收器—上一个模式 마이크로DAGR - 이전 모드 + MicroDAGR - Modo Anterior MicroDAGR - Next Mode @@ -617,6 +618,7 @@ MicroDAGR - Kolejny Tryb 微型 GPS 接收器—下一个模式 마이크로DAGR - 다음 모드 + MicroDAGR - Modo Seguinte diff --git a/addons/minedetector/XEH_postInit.sqf b/addons/minedetector/XEH_postInit.sqf index 0b8a521155c..0671699f9e8 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 @@ -25,9 +16,9 @@ addMissionEventHandler ["Draw3D", { { private _name = format ["%1@%2", typeOf _x, (floor ((_x distance _detectorPointAGL) * 10)) / 10]; 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"]; + 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"]; + 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"]; }; } forEach _mines; }]; diff --git a/addons/minedetector/XEH_preInit.sqf b/addons/minedetector/XEH_preInit.sqf index b47cf6628db..3641c78b702 100644 --- a/addons/minedetector/XEH_preInit.sqf +++ b/addons/minedetector/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +GVAR(detectableClasses) = +(uiNamespace getVariable QGVAR(detectableClasses)); + ADDON = true; diff --git a/addons/minedetector/XEH_preStart.sqf b/addons/minedetector/XEH_preStart.sqf index 48f003d08e3..046c0373640 100644 --- a/addons/minedetector/XEH_preStart.sqf +++ b/addons/minedetector/XEH_preStart.sqf @@ -15,5 +15,5 @@ private _detectableClasses = []; }; } forEach (configProperties [configFile >> "CfgAmmo", "isClass _x", true]); -TRACE_1("compiled",count _detectableClasses); -uiNamespace setVariable [QGVAR(detectableClasses), compileFinal str _detectableClasses]; +TRACE_1("built cache",count _detectableClasses); +uiNamespace setVariable [QGVAR(detectableClasses), compileFinal (_detectableClasses createHashMapFromArray [])]; diff --git a/addons/minedetector/functions/fnc_enableDetector.sqf b/addons/minedetector/functions/fnc_enableDetector.sqf index b6731760865..55b58dcf3a6 100644 --- a/addons/minedetector/functions/fnc_enableDetector.sqf +++ b/addons/minedetector/functions/fnc_enableDetector.sqf @@ -31,4 +31,4 @@ if (_unit == ACE_player) then { [QGVAR(detectorEnabled), [_unit, _detectorType]] call CBA_fnc_localEvent; private _config = [_detectorType] call FUNC(getDetectorConfig); -[FUNC(detectorLoop), 0.05, [_unit, _detectorType, _config, CBA_missionTime - 0.25]] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(detectorLoop), 0.05, [_unit, _detectorType, _config, CBA_missionTime - 0.25]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/minedetector/functions/fnc_getDetectedObject.sqf b/addons/minedetector/functions/fnc_getDetectedObject.sqf index 810e4d4ff46..8cc95ac4226 100644 --- a/addons/minedetector/functions/fnc_getDetectedObject.sqf +++ b/addons/minedetector/functions/fnc_getDetectedObject.sqf @@ -38,15 +38,13 @@ 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 GVAR(detectableClasses)) exitWith { + _isDetectable = true; _distance = _detectorPointAGL distance _x; _mine = _x; TRACE_3("return",_isDetectable,_mine,_distance); diff --git a/addons/minedetector/functions/fnc_getDetectorConfig.sqf b/addons/minedetector/functions/fnc_getDetectorConfig.sqf index fe7a888ebf3..a5566cbfbfc 100644 --- a/addons/minedetector/functions/fnc_getDetectorConfig.sqf +++ b/addons/minedetector/functions/fnc_getDetectorConfig.sqf @@ -19,18 +19,15 @@ params ["_detectorType"]; if (_detectorType isEqualTo "") exitWith {[]}; -private _detectorConfig = GVAR(detectorConfigs) getVariable _detectorType; -if (isNil "_detectorConfig") then { +GVAR(detectorConfigs) getOrDefaultCall [_detectorType, { private _cfgEntry = (configFile >> "ACE_detector" >> "detectors" >> _detectorType); if (isClass _cfgEntry) then { - _detectorConfig = [ + [ _detectorType, getNumber (_cfgEntry >> "radius"), getArray (_cfgEntry >> "sounds") ]; } else { - _detectorConfig = []; + [] }; - GVAR(detectorConfigs) setVariable [_detectorType, _detectorConfig]; -}; -_detectorConfig +}, true] diff --git a/addons/missile_gbu/$PBOPREFIX$ b/addons/missile_gbu/$PBOPREFIX$ new file mode 100644 index 00000000000..3249d48864f --- /dev/null +++ b/addons/missile_gbu/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\missile_gbu \ No newline at end of file diff --git a/addons/missile_gbu/CfgAmmo.hpp b/addons/missile_gbu/CfgAmmo.hpp new file mode 100644 index 00000000000..9521c8566d1 --- /dev/null +++ b/addons/missile_gbu/CfgAmmo.hpp @@ -0,0 +1,22 @@ +class EGVAR(missileguidance,type_Paveway); +class EGVAR(missileguidance,type_KAB); +class CfgAmmo { + class Bo_GBU12_LGB; + class GVAR(12): Bo_GBU12_LGB { + maneuvrability = 0; // no maneuvrability so that default guidance doesnt work + airFriction = 0.25; // bombs have high drag who woulda thunk + class ace_missileguidance: EGVAR(missileguidance,type_Paveway) { + enabled = 1; + }; + }; + + class Bomb_03_F; + class GVAR(FAB250): Bomb_03_F { + maneuvrability = 0; // no maneuvrability so that default guidance doesnt work + airFriction = 0.25; // bombs have high drag who woulda thunk + class ace_missileguidance: EGVAR(missileguidance,type_KAB) { + enabled = 1; + }; + }; +}; + diff --git a/addons/missile_gbu/CfgMagazines.hpp b/addons/missile_gbu/CfgMagazines.hpp new file mode 100644 index 00000000000..2841a3006eb --- /dev/null +++ b/addons/missile_gbu/CfgMagazines.hpp @@ -0,0 +1,87 @@ +class CfgMagazines { + class 2Rnd_GBU12_LGB; + // GBU + class GVAR(2Rnd_12): 2Rnd_GBU12_LGB { + displayName = CSTRING(12_2x); + author = "Dani (TCVM)"; + ammo = QGVAR(12); + }; + + class 4Rnd_Bomb_04_F; + class GVAR(4Rnd_GBU12): 4Rnd_Bomb_04_F { + displayName = CSTRING(12_4x); + author = "Dani (TCVM)"; + ammo = QGVAR(12); + }; + + class magazine_Bomb_GBU12_x1; + class GVAR(gbu12): magazine_Bomb_GBU12_x1 { + displayName = CSTRING(12_1x); + author = "Dani (TCVM)"; + ammo = QGVAR(12); + }; + + class PylonMissile_1Rnd_Bomb_04_F; + class GVAR(1_PylonMissile_1Rnd_12): PylonMissile_1Rnd_Bomb_04_F { + displayName = CSTRING(12_1x); + author = "Dani (TCVM)"; + ammo = QGVAR(12); + pylonWeapon = QGVAR(12); + }; + + class 2Rnd_GBU12_LGB_MI10; + class GVAR(2Rnd_GBU12_LGB_MI10): 2Rnd_GBU12_LGB_MI10 { + displayName = CSTRING(12_2x); + author = "Dani (TCVM)"; + ammo = QGVAR(12); + pylonWeapon = QGVAR(12); + }; + + class PylonMissile_Bomb_GBU12_x1; + class GVAR(PylonMissile_Bomb_GBU12_x1): PylonMissile_Bomb_GBU12_x1 { + displayName = CSTRING(12_1x); + author = "Dani (TCVM)"; + ammo = QGVAR(12); + pylonWeapon = QGVAR(12); + }; + + class PylonRack_Bomb_GBU12_x2; + class GVAR(PylonRack_Bomb_GBU12_x2): PylonRack_Bomb_GBU12_x2 { + displayName = CSTRING(12_2x); + author = "Dani (TCVM)"; + ammo = QGVAR(12); + pylonWeapon = QGVAR(12); + }; + + // KAB + class magazine_Bomb_KAB250_x1; + class GVAR(1Rnd_FAB250): magazine_Bomb_KAB250_x1 { + displayName = CSTRING(fab250_1x); + author = "Dani (TCVM)"; + ammo = QGVAR(FAB250); + }; + + class PylonMissile_Bomb_KAB250_x1; + class GVAR(1_PylonMissile_1Rnd_FAB250): PylonMissile_Bomb_KAB250_x1 { + displayName = CSTRING(fab250_1x); + author = "Dani (TCVM)"; + ammo = QGVAR(FAB250); + pylonWeapon = QGVAR(FAB250); + }; + + class 2Rnd_Bomb_03_F; + class GVAR(2Rnd_FAB250): 2Rnd_Bomb_03_F { + displayName = CSTRING(fab250_2x); + author = "Dani (TCVM)"; + ammo = QGVAR(FAB250); + }; + + class PylonMissile_1Rnd_Bomb_03_F; + class GVAR(PylonMissile_1Rnd_FAB250): PylonMissile_1Rnd_Bomb_03_F { + displayName = CSTRING(fab250_1x); + author = "Dani (TCVM)"; + ammo = QGVAR(FAB250); + pylonWeapon = QGVAR(FAB250); + }; +}; + diff --git a/addons/missile_gbu/CfgWeapons.hpp b/addons/missile_gbu/CfgWeapons.hpp new file mode 100644 index 00000000000..0728f93f7c2 --- /dev/null +++ b/addons/missile_gbu/CfgWeapons.hpp @@ -0,0 +1,32 @@ +class CfgWeapons { + class weapon_LGBLauncherBase; + class GVAR(12): weapon_LGBLauncherBase { + displayName = CSTRING(12); + magazines[] = { + QGVAR(2Rnd_12), + QGVAR(2Rnd_GBU12_LGB_MI10), + QGVAR(4Rnd_GBU12), + QGVAR(gbu12), + QGVAR(1_PylonMissile_1Rnd_12), + QGVAR(PylonMissile_Bomb_GBU12_x1), + QGVAR(PylonRack_Bomb_GBU12_x2) + }; + + EGVAR(laser,canSelect) = 1; // can ace_laser lock (allows switching laser code) + EGVAR(laser,showHud) = 1; // show attack profile / lock on hud + }; + + class GVAR(FAB250): weapon_LGBLauncherBase { + displayName = CSTRING(fab250); + magazines[] = { + QGVAR(1Rnd_FAB250), + QGVAR(2Rnd_FAB250), + QGVAR(1_PylonMissile_1Rnd_FAB250), + QGVAR(PylonMissile_1Rnd_FAB250) + }; + + EGVAR(laser,canSelect) = 1; // can ace_laser lock (allows switching laser code) + EGVAR(laser,showHud) = 1; // show attack profile / lock on hud + }; +}; + diff --git a/addons/missile_gbu/README.md b/addons/missile_gbu/README.md new file mode 100644 index 00000000000..07eb5ca8e95 --- /dev/null +++ b/addons/missile_gbu/README.md @@ -0,0 +1,4 @@ +ace_missile_gbu +=================== + +Adds GBU-12 LGB diff --git a/addons/missile_gbu/config.cpp b/addons/missile_gbu/config.cpp new file mode 100644 index 00000000000..6b84b38bb70 --- /dev/null +++ b/addons/missile_gbu/config.cpp @@ -0,0 +1,20 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common","ace_missileguidance"}; + author = ECSTRING(common,ACETeam); + authors[] = {"Dani (TCVM)"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" + diff --git a/addons/missile_gbu/script_component.hpp b/addons/missile_gbu/script_component.hpp new file mode 100644 index 00000000000..707200109d0 --- /dev/null +++ b/addons/missile_gbu/script_component.hpp @@ -0,0 +1,18 @@ +#define COMPONENT missile_gbu +#define COMPONENT_BEAUTIFIED Guided Bomb Unit +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_MISSILE_GBU + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_MISSILE_GBU + #define DEBUG_SETTINGS DEBUG_SETTINGS_MISSILE_GBU +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + diff --git a/addons/missile_gbu/stringtable.xml b/addons/missile_gbu/stringtable.xml new file mode 100644 index 00000000000..cee2b448c60 --- /dev/null +++ b/addons/missile_gbu/stringtable.xml @@ -0,0 +1,61 @@ + + + + + GBU-12 [ACE] + GBU-12 [ACE] + GBU-12 [ACE] + GBU-12 [ACE] + GBU-12 [ACE] + GBU-12 [ACE] + + + FAB-250M-54 [ACE] + FAB-250M-54 [ACE] + FAB-250M-54 [ACE] + FAB-250M-54 [ACE] + FAB-250M-54 [ACE] + ФАБ-250M-54 [ACE] + + + 1x GBU-12 [ACE] + 1x GBU-12 [ACE] + 1x GBU-12 [ACE] + 1x GBU-12 [ACE] + 1x GBU-12 [ACE] + 1x GBU-12 [ACE] + + + 2x GBU-12 [ACE] + 2x GBU-12 [ACE] + 2x GBU-12 [ACE] + 2x GBU-12 [ACE] + 2x GBU-12 [ACE] + 2x GBU-12 [ACE] + + + 4x GBU-12 [ACE] + 4x GBU-12 [ACE] + 4x GBU-12 [ACE] + 4x GBU-12 [ACE] + 4x GBU-12 [ACE] + 4x GBU-12 [ACE] + + + 1x FAB-250M-54 [ACE] + 1x FAB-250M-54 [ACE] + 1x FAB-250M-54 [ACE] + 1x FAB-250M-54 [ACE] + 1x FAB-250M-54 [ACE] + 1x ФАБ-250M-54 [ACE] + + + 2x FAB-250M-54 [ACE] + 2x FAB-250M-54 [ACE] + 2x FAB-250M-54 [ACE] + 2x FAB-250M-54 [ACE] + 2x FAB-250M-54 [ACE] + 2x ФАБ-250M-54 [ACE] + + + diff --git a/addons/missile_vikhr/$PBOPREFIX$ b/addons/missile_vikhr/$PBOPREFIX$ new file mode 100644 index 00000000000..4522cea1660 --- /dev/null +++ b/addons/missile_vikhr/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\missile_vikhr \ No newline at end of file diff --git a/addons/missile_vikhr/CfgAmmo.hpp b/addons/missile_vikhr/CfgAmmo.hpp new file mode 100644 index 00000000000..544b9d53a5d --- /dev/null +++ b/addons/missile_vikhr/CfgAmmo.hpp @@ -0,0 +1,17 @@ +class EGVAR(missileguidance,type_Vikhr); +class CfgAmmo { + class M_Scalpel_AT; + class GVAR(9k121): M_Scalpel_AT { + author = "Dani (TCVM)"; + maneuvrability = 0; + + irLock = 0; + laserLock = 0; + manualControl = 0; + + class ace_missileguidance: EGVAR(missileguidance,type_Vikhr) { + enabled = 1; + }; + }; +}; + diff --git a/addons/missile_vikhr/CfgMagazines.hpp b/addons/missile_vikhr/CfgMagazines.hpp new file mode 100644 index 00000000000..93084a98737 --- /dev/null +++ b/addons/missile_vikhr/CfgMagazines.hpp @@ -0,0 +1,53 @@ +class CfgMagazines { + class 2Rnd_LG_scalpel; + class 6Rnd_LG_scalpel; + class 8Rnd_LG_scalpel; + class PylonRack_1Rnd_LG_scalpel; + class PylonMissile_1Rnd_LG_scalpel; + class PylonRack_3Rnd_LG_scalpel; + class PylonRack_4Rnd_LG_scalpel; + + class GVAR(2Rnd): 2Rnd_LG_scalpel { + author = "Dani (TCVM)"; + displayName = CSTRING(2x); + ammo = QGVAR(9k121); + }; + + class GVAR(6Rnd): 6Rnd_LG_scalpel { + author = "Dani (TCVM)"; + displayName = CSTRING(6x); + ammo = QGVAR(9k121); + }; + + class GVAR(8Rnd): 8Rnd_LG_scalpel { + author = "Dani (TCVM)"; + displayName = CSTRING(8x); + ammo = QGVAR(9k121); + }; + + class GVAR(PylonRack_1Rnd): PylonRack_1Rnd_LG_scalpel { + author = "Dani (TCVM)"; + displayName = CSTRING(1x); + ammo = QGVAR(9k121); + pylonWeapon = QGVAR(9k121); + }; + class GVAR(PylonMissile_1Rnd): PylonMissile_1Rnd_LG_scalpel { + author = "Dani (TCVM)"; + displayName = CSTRING(1x); + ammo = QGVAR(9k121); + pylonWeapon = QGVAR(9k121); + }; + class GVAR(PylonRack_3Rnd): PylonRack_3Rnd_LG_scalpel { + author = "Dani (TCVM)"; + displayName = CSTRING(3x); + ammo = QGVAR(9k121); + pylonWeapon = QGVAR(9k121); + }; + class GVAR(PylonRack_4Rnd): PylonRack_4Rnd_LG_scalpel { + author = "Dani (TCVM)"; + displayName = CSTRING(4x); + ammo = QGVAR(9k121); + pylonWeapon = QGVAR(9k121); + }; +}; + diff --git a/addons/missile_vikhr/CfgWeapons.hpp b/addons/missile_vikhr/CfgWeapons.hpp new file mode 100644 index 00000000000..3db46a69ab0 --- /dev/null +++ b/addons/missile_vikhr/CfgWeapons.hpp @@ -0,0 +1,17 @@ +class CfgWeapons { + class missiles_SCALPEL; + class GVAR(9k121): missiles_SCALPEL { + author = "Dani (TCVM)"; + displayName = CSTRING(9k121); + magazines[] = { + QGVAR(2Rnd), + QGVAR(6Rnd), + QGVAR(8Rnd), + QGVAR(PylonRack_1Rnd), + QGVAR(PylonMissile_1Rnd), + QGVAR(PylonRack_3Rnd), + QGVAR(PylonRack_4Rnd) + }; + }; +}; + diff --git a/addons/missile_vikhr/README.md b/addons/missile_vikhr/README.md new file mode 100644 index 00000000000..104d449fd9c --- /dev/null +++ b/addons/missile_vikhr/README.md @@ -0,0 +1,4 @@ +ace_missile_vikhr +=================== + +Adds Vikhr beam-riding ATGM diff --git a/addons/missile_vikhr/config.cpp b/addons/missile_vikhr/config.cpp new file mode 100644 index 00000000000..6b84b38bb70 --- /dev/null +++ b/addons/missile_vikhr/config.cpp @@ -0,0 +1,20 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common","ace_missileguidance"}; + author = ECSTRING(common,ACETeam); + authors[] = {"Dani (TCVM)"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" + diff --git a/addons/missile_vikhr/script_component.hpp b/addons/missile_vikhr/script_component.hpp new file mode 100644 index 00000000000..41f554e77f9 --- /dev/null +++ b/addons/missile_vikhr/script_component.hpp @@ -0,0 +1,18 @@ +#define COMPONENT missile_vikhr +#define COMPONENT_BEAUTIFIED Vikhr +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_MISSILE_VIKHR + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_MISSILE_VIKHR + #define DEBUG_SETTINGS DEBUG_SETTINGS_MISSILE_VIKHR +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + diff --git a/addons/missile_vikhr/stringtable.xml b/addons/missile_vikhr/stringtable.xml new file mode 100644 index 00000000000..622bb3af757 --- /dev/null +++ b/addons/missile_vikhr/stringtable.xml @@ -0,0 +1,61 @@ + + + + + 9k121 Vikhr [ACE] + 9k121 Vikhr [ACE] + 9k121 Vikhr [ACE] + 9k121 ヴィーフリ [ACE] + 9K121 비흐르 [ACE] + 9k121 Вихрь [ACE] + + + 1x 9k121 Vikhr [ACE] + 1x 9k121 Vikhr [ACE] + 1x 9k121 Vikhr [ACE] + 1x 9k121 ヴィーフリ [ACE] + 1x 9K121 비흐르 [ACE] + 1x 9k121 Вихрь [ACE] + + + 2x 9k121 Vikhr [ACE] + 2x 9k121 Vikhr [ACE] + 2x 9k121 Vikhr [ACE] + 2x 9k121 ヴィーフリ [ACE] + 2x 9K121 비흐르 [ACE] + 2x 9k121 Вихрь [ACE] + + + 3x 9k121 Vikhr [ACE] + 3x 9k121 Vikhr [ACE] + 3x 9k121 Vikhr [ACE] + 3x 9k121 ヴィーフリ [ACE] + 3x 9K121 비흐르 [ACE] + 3x 9k121 Вихрь [ACE] + + + 4x 9k121 Vikhr [ACE] + 4x 9k121 Vikhr [ACE] + 4x 9k121 Vikhr [ACE] + 4x 9k121 ヴィーフリ [ACE] + 4x 9K121 비흐르 [ACE] + 4x 9k121 Вихрь [ACE] + + + 6x 9k121 Vikhr [ACE] + 6x 9k121 Vikhr [ACE] + 6x 9k121 Vikhr [ACE] + 6x 9k121 ヴィーフリ [ACE] + 6x 9K121 비흐르 [ACE] + 6x 9k121 Вихрь [ACE] + + + 8x 9k121 Vikhr [ACE] + 8x 9k121 Vikhr [ACE] + 8x 9k121 Vikhr [ACE] + 8x 9k121 ヴィーフリ [ACE] + 8x 9K121 비흐르 [ACE] + 8x 9k121 Вихрь [ACE] + + + diff --git a/addons/missileguidance/ACE_GuidanceConfig.hpp b/addons/missileguidance/ACE_GuidanceConfig.hpp index 3628c9eec04..131beee3398 100644 --- a/addons/missileguidance/ACE_GuidanceConfig.hpp +++ b/addons/missileguidance/ACE_GuidanceConfig.hpp @@ -6,6 +6,11 @@ class GVAR(AttackProfiles) { functionName = QFUNC(attackProfile_LIN); }; + // empty classes for backwards compat + class MID: LIN { + }; + class HI: LIN { + }; class DIR { name = ""; visualName = ""; @@ -13,21 +18,14 @@ class GVAR(AttackProfiles) { functionName = QFUNC(attackProfile_DIR); }; - class MID { - name = ""; - visualName = ""; - description = ""; - - functionName = QFUNC(attackProfile_MID); - }; - class HI { + class LOFT { name = ""; visualName = ""; description = ""; - functionName = QFUNC(attackProfile_HI); + functionName = QFUNC(attackProfile_LOFT); }; - class JAV_DIR { + class JAV_DIR { name = ""; visualName = ""; description = ""; @@ -82,12 +80,39 @@ class GVAR(SeekerTypes) { functionName = QFUNC(seekerType_SACLOS); onFired = QFUNC(SACLOS_onFired); }; - class ARH { + class MillimeterWaveRadar { name = ""; visualName = ""; description = ""; - functionName = QFUNC(seekerType_ARH); - onFired = QFUNC(ahr_onFired); + functionName = QFUNC(seekerType_MWR); + onFired = QFUNC(mwr_onFired); + }; +}; + +class GVAR(NavigationTypes) { + class Direct { + functionName = QFUNC(navigationType_direct); + onFired = ""; + }; + class Line { + functionName = QFUNC(navigationType_line); + onFired = QFUNC(line_onFired); + }; + class LineOfSight { + functionName = QFUNC(navigationType_lineOfSight); + onFired = QFUNC(proNav_onFired); + }; + class ProportionalNavigation { + functionName = QFUNC(navigationType_proNav); + onFired = QFUNC(proNav_onFired); + }; + class AugmentedProportionalNavigation { + functionName = QFUNC(navigationType_augmentedProNav); + onFired = QFUNC(proNav_onFired); + }; + class ZeroEffortMiss { + functionName = QFUNC(navigationType_zeroEffortMiss); + onFired = QFUNC(proNav_onFired); }; }; diff --git a/addons/missileguidance/CfgAmmo.hpp b/addons/missileguidance/CfgAmmo.hpp index a2b07b7fff1..44e35d40811 100644 --- a/addons/missileguidance/CfgAmmo.hpp +++ b/addons/missileguidance/CfgAmmo.hpp @@ -17,31 +17,8 @@ class CfgAmmo { EGVAR(rearm,caliber) = 70; - class ADDON { + class ADDON: GVAR(type_Dagr) { enabled = 1; - - minDeflection = 0.0005; // Minium flap deflection for guidance - maxDeflection = 0.0025; // 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 = "SALH"; - seekerTypes[] = { "SALH", "LIDAR", "SARH", "Optic", "Thermal", "GPS", "SACLOS", "MCLOS" }; - - defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = { "LOAL", "LOBL" }; - - seekerAngle = 90; // Angle in front of the missile which can be searched - seekerAccuracy = 1; // seeker accuracy multiplier - - seekerMinRange = 1; - seekerMaxRange = 2500; // Range from the missile which the seeker can visually search - - // Attack profile type selection - defaultAttackProfile = "LIN"; - attackProfiles[] = { "LIN", "DIR", "MID", "HI" }; }; }; @@ -66,34 +43,8 @@ class CfgAmmo { initTime = 0.5; // Begin ACE guidance Configs - class ADDON { + class ADDON: GVAR(type_Javelin) { 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; }; }; class ACE_Javelin_FGM148_static: ACE_Javelin_FGM148 { @@ -102,6 +53,8 @@ class CfgAmmo { effectsMissileInit = "RocketBackEffectsStaticRPG"; //Explicity add guidance config - class ADDON: ADDON {}; + class ADDON: ADDON { + enabled = 1; + }; }; }; diff --git a/addons/missileguidance/CfgEventhandlers.hpp b/addons/missileguidance/CfgEventhandlers.hpp index 449681e8dfb..a288a933999 100644 --- a/addons/missileguidance/CfgEventhandlers.hpp +++ b/addons/missileguidance/CfgEventhandlers.hpp @@ -7,13 +7,13 @@ class Extended_PreStart_EventHandlers { class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_SCRIPT(XEH_pre_init)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_SCRIPT(XEH_post_init)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/missileguidance/CfgMagazines.hpp b/addons/missileguidance/CfgMagazines.hpp index 74d75e8d4ae..c7ef48004ca 100644 --- a/addons/missileguidance/CfgMagazines.hpp +++ b/addons/missileguidance/CfgMagazines.hpp @@ -4,24 +4,40 @@ class CfgMagazines { class 6Rnd_ACE_Hydra70_DAGR: 12Rnd_PG_missiles { ammo = "ACE_Hydra70_DAGR"; count = 12; - displayName = "6 Round DAGR"; - displayNameShort = "6 Round DAGR"; - descriptionShort = "6 Round DAGR"; + displayName = CSTRING(Hydra70_DAGR_6x); weight = 36; }; class 12Rnd_ACE_Hydra70_DAGR: 6Rnd_ACE_Hydra70_DAGR { count = 12; - displayName = "16 Round DAGR"; - displayNameShort = "16 Round DAGR"; - descriptionShort = "16 Round DAGR"; + displayName = CSTRING(Hydra70_DAGR_12x); weight = 72; }; class 24Rnd_ACE_Hydra70_DAGR: 6Rnd_ACE_Hydra70_DAGR { count = 24; - displayName = "24 Round DAGR"; - displayNameShort = "24 Round DAGR"; - descriptionShort = "24 Round DAGR"; + displayName = CSTRING(Hydra70_DAGR_24x); weight = 72; }; + + class PylonRack_12Rnd_PG_missiles; + class PylonRack_6Rnd_ACE_DAGR: PylonRack_12Rnd_PG_missiles { + ammo = "ACE_Hydra70_DAGR"; + displayName = CSTRING(Hydra70_DAGR_6x); + count = 6; + pylonWeapon = QGVAR(dagr); + }; + + class PylonRack_12Rnd_ACE_DAGR: PylonRack_12Rnd_PG_missiles { + ammo = "ACE_Hydra70_DAGR"; + displayName = CSTRING(Hydra70_DAGR_12x); + count = 12; + pylonWeapon = QGVAR(dagr); + }; + + class PylonRack_24Rnd_ACE_DAGR: PylonRack_12Rnd_PG_missiles { + ammo = "ACE_Hydra70_DAGR"; + displayName = CSTRING(Hydra70_DAGR_24x); + count = 24; + pylonWeapon = QGVAR(dagr); + }; }; diff --git a/addons/missileguidance/CfgMissileTypesNato.hpp b/addons/missileguidance/CfgMissileTypesNato.hpp new file mode 100644 index 00000000000..87730b5ed0c --- /dev/null +++ b/addons/missileguidance/CfgMissileTypesNato.hpp @@ -0,0 +1,716 @@ +class GVAR(type_AMRAAM) { + enabled = 0; + + pitchRate = 30; // Minium flap deflection for guidance + yawRate = 30; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "DopplerRadar"; + seekerTypes[] = { "DopplerRadar" }; + lockableTypes[] = {"Air"}; + + minimumSpeedFilter = 25; // filter out targets that have a closing velocity less than this + minimumTimeFilter = 0.0001; // filter out targets that are this close to the ground (speed of light) + maxTerrainCheck = 16000; // How far we should check for terrain + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 50; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR", "LOFT"}; + useModeForAttackProfile = 1; +}; + +class GVAR(type_ASRAAM) { + enabled = 0; + + pitchRate = 100; // Minium flap deflection for guidance + yawRate = 100; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 50; + flareAngleFilter = 0.8; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 120; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.98; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 8000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_Dagr) { + enabled = 0; + + pitchRate = 40; // degrees per second + yawRate = 40; + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SALH"; + seekerTypes[] = { "SALH" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekerAngle = 90; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 1; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "LIN"; + attackProfiles[] = { "LIN", "DIR", "MID", "HI" }; +}; + +class GVAR(type_Dragon) { + enabled = 0; + + pitchRate = 0; + yawRate = 0; + + canVanillaLock = 0; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "LineOfSight"; + navigationTypes[] = { "LineOfSight" }; + + seekLastTargetPos = 0; + seekerAngle = 30; + seekerAccuracy = 1; + + seekerMinRange = 65; + seekerMaxRange = 1000; + + correctionDistance = 30; + missileLeadDistance = 0; + offsetFromCrosshair[] = { 0, 0, 0 }; + + serviceInterval = 0.33; // how many seconds between pops + serviceCharges = 32; // how many charges are in this missile + serviceChargeAcceleration = 6.5; + dragonSpeed = 100; // meters per second + + defaultAttackProfile = "DRAGON"; + attackProfiles[] = {"DRAGON"}; +}; + +class GVAR(type_ESSM) { + enabled = 0; + + pitchRate = 15; // Minium flap deflection for guidance + yawRate = 15; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "DopplerRadar"; + seekerTypes[] = { "DopplerRadar" }; + lockableTypes[] = {"Air"}; + + minimumSpeedFilter = 20; // filter out targets that have a closing velocity less than this + minimumTimeFilter = 0.00001; // filter out targets that are this close to the ground (speed of light) + maxTerrainCheck = 16000; // How far we should check for terrain + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 50; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_Hellfire) { + enabled = 0; + + pitchRate = 30; // degrees per second + yawRate = 30; + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SALH"; + seekerTypes[] = { "SALH" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Direct"; + navigationTypes[] = { "Direct", "ZeroEffortMiss" }; + + seekLastTargetPos = 1; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 70; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 1; + seekerMaxRange = 8000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "hellfire"; + attackProfiles[] = {"hellfire", "hellfire_hi", "hellfire_lo"}; + + class navigationStates { + class initial { + transitionCondition = QEFUNC(hellfire,midCourseTransition); + navigationType = "Direct"; + }; + class terminal { + transitionCondition = ""; + navigationType = "ZeroEffortMiss"; + }; + // transitions from initial -> termimal + states[] = {"initial", "terminal"}; + }; +}; + +class GVAR(type_Hot) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 7; + lineGainD = 6; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 4000; // Range from the missile which the seeker can visually search + + 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 GVAR(type_Javelin) { + enabled = 0; + + pitchRate = 120; // degrees per second + yawRate = 120; + stabilityCoefficient = 0.2; + bangBangGuidance = 0; + + canVanillaLock = 0; + + // Guidance type for munitions + defaultSeekerType = "Optic"; + seekerTypes[] = { "Optic" }; + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "Direct"; + navigationTypes[] = { "Direct", "ZeroEffortMiss" }; + + navigationGain = 3; + + 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; + + class navigationStates { + class initial { + transitionCondition = QFUNC(javelin_midCourseTransition); + navigationType = "Direct"; + }; + class terminal { + transitionCondition = ""; + navigationType = "ZeroEffortMiss"; + }; + // transitions from initial -> termimal + states[] = {"initial", "terminal"}; + }; +}; + +class GVAR(type_Jdam) { + enabled = 0; + + pitchRate = 15; + yawRate = 20; + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "GPS"; + seekerTypes[] = { "GPS" }; + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "LINE"; + navigationTypes[] = { "LINE" }; + + lineGainP = 50; + lineGainD = 0; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 60; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 5; + seekerMaxRange = 4000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "JDAM"; + attackProfiles[] = {"JDAM"}; +}; + +class GVAR(type_Maverick) { + enabled = 0; + + pitchRate = 15; + yawRate = 15; + + canVanillaLock = 1; + + defaultSeekerType = "Optic"; + seekerTypes[] = {"Optic"}; + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = {"LOBL"}; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 1; + seekerAngle = 60; + seekerAccuracy = 1; + + seekerMinRange = 1; + seekerMaxRange = 14000; + + defaultAttackProfile = "maverick"; + attackProfiles[] = {"maverick"}; +}; + +class GVAR(type_Milan) { + enabled = 0; + + pitchRate = 60; // Minium flap deflection for guidance + yawRate = 60; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 0; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 25; + lineGainD = 12; + + initialPitch = -0.4; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 5; // Angle from the shooter's view that can track the missile, implemented + seekerAccuracy = 1; // seeker accuracy multiplier, not implemented? + + seekerMinRange = 100; + seekerMaxRange = 2000; // Range from the missile which the seeker can visually search + + 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 GVAR(type_Nlaw) { + enabled = 0; + + pitchRate = 5; // Minium flap deflection for guidance + yawRate = 10; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = QEGVAR(nlaw,seeker); + seekerTypes[] = {QEGVAR(nlaw,seeker)}; + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = {"LOBL"}; + + defaultNavigationType = QEGVAR(nlaw,PLOS); + navigationTypes[] = { QEGVAR(nlaw,PLOS) }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 0; + seekerMaxRange = 10; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = QEGVAR(nlaw,directAttack); + attackProfiles[] = {QEGVAR(nlaw,directAttack), QEGVAR(nlaw,overflyTopAttack)}; + useModeForAttackProfile = 1; + showHintOnCycle = 1; + + // Run once at fired event + onFired = QEFUNC(nlaw,onFired); +}; + +class GVAR(type_Patriot) { + enabled = 0; + + pitchRate = 30; // Minium flap deflection for guidance + yawRate = 30; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "DopplerRadar"; + seekerTypes[] = { "DopplerRadar" }; + lockableTypes[] = {"Air"}; + + minimumSpeedFilter = 10; // filter out targets that have a closing velocity less than this + minimumTimeFilter = 0.00001; // filter out targets that are this close to the ground (speed of light) + maxTerrainCheck = 16000; // How far we should check for terrain + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 50; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_Paveway) { + enabled = 0; + + pitchRate = 5; + yawRate = 5; + + bangBangGuidance = 1; + stabilityCoefficient = 0.4; // how much this projectile likes to "weathervane" (keep direction toward velocity) + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SALH"; + seekerTypes[] = { "SALH" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL" }; + + defaultNavigationType = "Direct"; + navigationTypes[] = { "Direct" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 60; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 5; + seekerMaxRange = 4000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_RAM) { + enabled = 0; + + pitchRate = 50; // Minium flap deflection for guidance + yawRate = 50; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 100; + flareAngleFilter = 0.5; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.8; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_RBS70) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 20; + lineGainD = 16; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + correctionDistance = 30; // 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 = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Redeye) { + enabled = 0; + + pitchRate = 27; // Minium flap deflection for guidance + yawRate = 27; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 100; + flareAngleFilter = 2.0; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "ProportionalNavigation"; + navigationTypes[] = { "ProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.4; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 4500; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_Sidewinder) { + enabled = 0; + + pitchRate = 25; // Minium flap deflection for guidance + yawRate = 25; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 100; + flareAngleFilter = 1.6; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.8; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_Stinger) { + enabled = 0; + + pitchRate = 42; // Minium flap deflection for guidance + yawRate = 42; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 100; + flareAngleFilter = 1.3; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.8; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_TOW) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 20; + lineGainD = 7; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 65; + seekerMaxRange = 3750; // Range from the missile which the seeker can visually search + + correctionDistance = 30; // 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"}; +}; \ No newline at end of file diff --git a/addons/missileguidance/CfgMissileTypesWarsaw.hpp b/addons/missileguidance/CfgMissileTypesWarsaw.hpp new file mode 100644 index 00000000000..180d8a98954 --- /dev/null +++ b/addons/missileguidance/CfgMissileTypesWarsaw.hpp @@ -0,0 +1,901 @@ +class GVAR(type_Ataka) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 10.44; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 6000; // Range from the missile which the seeker can visually search + + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Bastion) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 10.44; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 6000; // Range from the missile which the seeker can visually search + + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Drakon) { + enabled = 0; + + pitchRate = 25; // Minium flap deflection for guidance + yawRate = 25; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 9.5; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 3300; // Range from the missile which the seeker can visually search + + correctionDistance = 30; // 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 = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Fagot) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 10.44; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 2000; // Range from the missile which the seeker can visually search + + correctionDistance = 30; // 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 = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Falanga) { + enabled = 0; + + pitchRate = 15; // Minium flap deflection for guidance + yawRate = 15; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "MCLOS"; + seekerTypes[] = { "MCLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 5; + lineGainD = 0; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 0; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + correctionDistance = 0; // 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 GVAR(type_Fleyta) { + enabled = 0; + + pitchRate = 15; // Minium flap deflection for guidance + yawRate = 15; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "MCLOS"; + seekerTypes[] = { "MCLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 5; + lineGainD = 0; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 0; + seekerMaxRange = 3000; // Range from the missile which the seeker can visually search + + correctionDistance = 0; // 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 GVAR(type_Igla) { + enabled = 0; + + pitchRate = 30; // Minium flap deflection for guidance + yawRate = 43; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 100; + flareAngleFilter = 1.1; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.76; // seeker accuracy multiplier + + seekerMinRange = 5; + seekerMaxRange = 5200; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_KAB) { + enabled = 0; + + pitchRate = 8; + yawRate = 8; + + bangBangGuidance = 1; + stabilityCoefficient = 0.4; // how much this projectile likes to "weathervane" (keep direction toward velocity) + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SALH"; + seekerTypes[] = { "SALH" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL" }; + + defaultNavigationType = "Direct"; + navigationTypes[] = { "Direct" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 60; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 5; + seekerMaxRange = 4000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_KH25) { + enabled = 0; + + pitchRate = 20; + yawRate = 20; + + canVanillaLock = 0; + + defaultSeekerType = "SALH"; + seekerTypes[] = {"SALH"}; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = {"LOAL"}; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 1; + seekerAngle = 40; + seekerAccuracy = 1; + + seekerMinRange = 1; + seekerMaxRange = 10000; + + defaultAttackProfile = "maverick"; + attackProfiles[] = {"maverick"}; +}; + +class GVAR(type_KH29) { + enabled = 0; + + pitchRate = 20; + yawRate = 20; + + canVanillaLock = 0; + + defaultSeekerType = "SALH"; + seekerTypes[] = {"SALH"}; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = {"LOAL"}; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 1; + seekerAngle = 40; + seekerAccuracy = 1; + + seekerMinRange = 1; + seekerMaxRange = 10000; + + defaultAttackProfile = "maverick"; + attackProfiles[] = {"maverick"}; +}; + +class GVAR(type_Kobra) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 9.5; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + correctionDistance = 30; // 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 = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Konkurs) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 10; + lineGainD = 8.5; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 4000; // Range from the missile which the seeker can visually search + + 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 GVAR(type_Kornet) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 10.44; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + correctionDistance = 30; // 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 = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Malyutka) { + enabled = 0; + + pitchRate = 15; // Minium flap deflection for guidance + yawRate = 15; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "MCLOS"; + seekerTypes[] = { "MCLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 5; + lineGainD = 0; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 0; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + correctionDistance = 0; // 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 GVAR(type_Metis) { + enabled = 0; + + pitchRate = 50; // Minium flap deflection for guidance + yawRate = 50; // Maximum flap deflection for guidance + initialPitch = 2; + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 10.44; + + 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 = 1000; // 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 GVAR(type_Molniya) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 50; + flareAngleFilter = 0.8; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 40; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.85; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_R73) { + enabled = 0; + + pitchRate = 35; // Minium flap deflection for guidance + yawRate = 35; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 50; + flareAngleFilter = 0.8; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 40; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.85; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_R74) { + enabled = 1; + + pitchRate = 50; // Minium flap deflection for guidance + yawRate = 50; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 50; + flareAngleFilter = 0.8; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 75; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.95; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 8000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_R77) { + enabled = 0; + + pitchRate = 40; // Minium flap deflection for guidance + yawRate = 40; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "DopplerRadar"; + seekerTypes[] = { "DopplerRadar" }; + lockableTypes[] = {"Air"}; + + minimumSpeedFilter = 15; // filter out targets that have a closing velocity less than this + minimumTimeFilter = 0.00005; // filter out targets that are this close to the ground (speed of light) + maxTerrainCheck = 16000; // How far we should check for terrain + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 50; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR", "LOFT"}; + useModeForAttackProfile = 1; +}; + +class GVAR(type_Refleks) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 10.44; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + correctionDistance = 30; // 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 = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_S400) { + enabled = 0; + + pitchRate = 25; // Minium flap deflection for guidance + yawRate = 25; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "DopplerRadar"; + seekerTypes[] = { "DopplerRadar" }; + lockableTypes[] = {"Air"}; + + minimumSpeedFilter = 5; // filter out targets that have a closing velocity less than this + minimumTimeFilter = 0.000001; // filter out targets that are this close to the ground (speed of light) + maxTerrainCheck = 16000; // How far we should check for terrain + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 50; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_Shturm) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 10.44; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 4000; // Range from the missile which the seeker can visually search + + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Strela) { + enabled = 0; + + pitchRate = 30; // Minium flap deflection for guidance + yawRate = 30; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 100; + flareAngleFilter = 1.6; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "ProportionalNavigation"; + navigationTypes[] = { "ProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.6; // seeker accuracy multiplier + + seekerMinRange = 10; + seekerMaxRange = 3700; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_Vikhr) { + enabled = 0; + showTrail = 1; + + pitchRate = 60; // Minium flap deflection for guidance + yawRate = 60; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 20; + lineGainD = 16; + correctionDistance = 5; + + 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 = 30; + seekerMaxRange = 12000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Vympel) { + enabled = 0; + + pitchRate = 35; // Minium flap deflection for guidance + yawRate = 35; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 50; + flareAngleFilter = 0.8; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 40; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.85; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; \ No newline at end of file diff --git a/addons/missileguidance/CfgWeapons.hpp b/addons/missileguidance/CfgWeapons.hpp index b03628e7776..d88cf27b539 100644 --- a/addons/missileguidance/CfgWeapons.hpp +++ b/addons/missileguidance/CfgWeapons.hpp @@ -2,8 +2,13 @@ class CfgWeapons { class missiles_DAGR; class GVAR(dagr): missiles_DAGR { + EGVAR(laser,canSelect) = 1; // can ace_laser lock (allows switching laser code) + EGVAR(laser,showHud) = 1; // show attack profile / lock on hud + magazines[] = {"6Rnd_ACE_Hydra70_DAGR","12Rnd_ACE_Hydra70_DAGR","24Rnd_ACE_Hydra70_DAGR","PylonRack_6Rnd_ACE_DAGR","PylonRack_12Rnd_ACE_DAGR","PylonRack_24Rnd_ACE_DAGR"}; + + autoFire = 0; canLock = 0; - magazines[] = {"6Rnd_ACE_Hydra70_DAGR","12Rnd_ACE_Hydra70_DAGR","24Rnd_ACE_Hydra70_DAGR"}; + weaponLockSystem = 0; lockingTargetSound[] = {"",0,1}; lockedTargetSound[] = {"",0,1}; }; diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index 075f2f03c59..daff5b502b5 100644 --- a/addons/missileguidance/XEH_PREP.hpp +++ b/addons/missileguidance/XEH_PREP.hpp @@ -6,6 +6,8 @@ PREP(changeMissileDirection); PREP(checkSeekerAngle); PREP(checkLos); +PREP(dev_ProjectileCamera); + PREP(onFired); PREP(onIncomingMissile); @@ -16,28 +18,45 @@ PREP(doSeekerSearch); PREP(doHandoff); PREP(handleHandoff); +//re-enable after feature merge - PREP(shouldFilterRadarHit); + // Attack Profiles PREP(attackProfile_AIR); PREP(attackProfile_DIR); -PREP(attackProfile_HI); PREP(attackProfile_LIN); -PREP(attackProfile_MID); +PREP(attackProfile_LOFT); PREP(attackProfile_WIRE); PREP(attackProfile_BEAM); +//re-enable after feature merge - PREP(attackProfile_JDAM); // Javelin profiles PREP(attackProfile_JAV_DIR); PREP(attackProfile_JAV_TOP); +PREP(javelin_midCourseTransition); + +// Navigation Profiles +PREP(navigationType_zeroEffortMiss); +PREP(navigationType_augmentedProNav); +PREP(navigationType_proNav); +PREP(navigationType_lineOfSight); +PREP(navigationType_line); +PREP(navigationType_direct); // Seeker search functions PREP(seekerType_SALH); PREP(seekerType_Optic); PREP(seekerType_SACLOS); -PREP(seekerType_ARH); +//re-enable after feature merge - PREP(seekerType_Doppler); +PREP(seekerType_MWR); // Attack Profiles OnFired PREP(wire_onFired); // Seeker OnFired PREP(SACLOS_onFired); -PREP(ahr_onFired); +PREP(mwr_onFired); + +// Navigation OnFired +PREP(proNav_onFired); +PREP(line_onFired); + diff --git a/addons/missileguidance/XEH_post_init.sqf b/addons/missileguidance/XEH_postInit.sqf similarity index 71% rename from addons/missileguidance/XEH_post_init.sqf rename to addons/missileguidance/XEH_postInit.sqf index cc09b1f0ac7..e0fc98ba1ba 100644 --- a/addons/missileguidance/XEH_post_init.sqf +++ b/addons/missileguidance/XEH_postInit.sqf @@ -1,13 +1,11 @@ #include "script_component.hpp" -[QGVAR(handoff), {_this call FUNC(handleHandoff)}] call CBA_fnc_addEventHandler; +[QGVAR(handoff), LINKFUNC(handleHandoff)] call CBA_fnc_addEventHandler; -["ACE3 Weapons", QGVAR(cycleFireMode), localize LSTRING(CycleFireMode), -{ +["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_pre_init.sqf b/addons/missileguidance/XEH_preInit.sqf similarity index 64% rename from addons/missileguidance/XEH_pre_init.sqf rename to addons/missileguidance/XEH_preInit.sqf index 0798fed2e43..9b1a85e37c7 100644 --- a/addons/missileguidance/XEH_pre_init.sqf +++ b/addons/missileguidance/XEH_preInit.sqf @@ -11,4 +11,15 @@ PREP_RECOMPILE_END; // As weapons take config changes, there is little point in being able to disable guidance if (isNil QGVAR(enabled)) then { GVAR(enabled) = 2; }; +GVAR(debug_enableMissileCamera) = false; +GVAR(debug_drawGuidanceInfo) = false; + +#ifdef DRAW_GUIDANCE_INFO +GVAR(debug_drawGuidanceInfo) = true; +#endif + +#ifdef ENABLE_PROJECTILE_CAMERA +GVAR(debug_enableMissileCamera) = true; +#endif + ADDON = true; diff --git a/addons/missileguidance/config.cpp b/addons/missileguidance/config.cpp index e98d99ebcbb..4e1f2e3e1f1 100644 --- a/addons/missileguidance/config.cpp +++ b/addons/missileguidance/config.cpp @@ -15,6 +15,8 @@ class CfgPatches { #include "ACE_GuidanceConfig.hpp" +#include "CfgMissileTypesNato.hpp" +#include "CfgMissileTypesWarsaw.hpp" #include "CfgEventhandlers.hpp" #include "CfgAmmo.hpp" #include "CfgMagazines.hpp" diff --git a/addons/missileguidance/dev/getAmmoProperties.sqf b/addons/missileguidance/dev/getAmmoProperties.sqf new file mode 100644 index 00000000000..9c416c228fd --- /dev/null +++ b/addons/missileguidance/dev/getAmmoProperties.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" + +private _configs = configProperties [configFile >> "CfgAmmo", QUOTE((isClass _x) && { isClass (_x >> QUOTE(QUOTE(ADDON)))})]; + +private _seekerTypes = createHashMap; +private _navigationTypes = createHashMap; +private _attackProfiles = createHashMap; +{ + private _seekerType = getText (_x >> QUOTE(ADDON) >> "defaultSeekerType"); + private _navigationType = getText (_x >> QUOTE(ADDON) >> "defaultNavigationType"); + private _attackProfile = getText (_x >> QUOTE(ADDON) >> "defaultAttackProfile"); + + private _seekers = _seekerTypes getOrDefault [_seekerType, []]; + private _navigations = _navigationTypes getOrDefault [_navigationType, []]; + private _attacks = _attackProfiles getOrDefault [_attackProfile, []]; + + _seekers pushBack configName _x; + _navigations pushBack configName _x; + _attacks pushBack configName _x; + + _seekerTypes set [_seekerType, _seekers]; + _navigationTypes set [_navigationType, _navigations]; + _attackProfiles set [_attackProfile, _attacks]; +} forEach _configs; + +[_seekerTypes, _navigationTypes, _attackProfiles] diff --git a/addons/missileguidance/functions/fnc_SACLOS_onFired.sqf b/addons/missileguidance/functions/fnc_SACLOS_onFired.sqf index 299ec6f236c..f48b4a95713 100644 --- a/addons/missileguidance/functions/fnc_SACLOS_onFired.sqf +++ b/addons/missileguidance/functions/fnc_SACLOS_onFired.sqf @@ -32,4 +32,3 @@ _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_attackProfile_BEAM.sqf b/addons/missileguidance/functions/fnc_attackProfile_BEAM.sqf index 5aaff9d7f8d..fd86b571045 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_BEAM.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_BEAM.sqf @@ -17,31 +17,26 @@ * Public: No */ params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; -_args params ["_firedEH"]; +_args params ["_firedEH", "", "", "", "", "_targetData"]; _firedEH params ["_shooter","","","","","","_projectile"]; -_attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_randomVector", "_crosshairOffset", "_seekerMaxRangeSqr", "_seekerMinRangeSqr", "_wireCutSource", "_distanceAheadOfMissile"]; +_attackProfileStateParams params ["_maxCorrectableDistance", "_wireCut", "_lastInput", "_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]) +if ((_distanceToProjectile > _seekerMaxRangeSqr) || { _wireCut }) exitWith { + // wire snap, random direction + if !(_wireCut) then { + _attackProfileStateParams set [1, true]; + }; + _lastInput }; -private _relativeCorrection = _projectile vectorWorldToModel (_projectilePos vectorDiff _seekerTargetPos); -_relativeCorrection = _relativeCorrection vectorDiff _crosshairOffset; +private _final = _seekerTargetPos vectorAdd _crosshairOffset; +_attackProfileStateParams set [2, _final]; -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 +_targetData set [0, _projectilePos vectorFromTo _final]; -// 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) +_final diff --git a/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf b/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf index 80499a85da8..d2a2c0616c9 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf @@ -1,8 +1,8 @@ #include "..\script_component.hpp" /* - * Author: jaynus / nou + * Author: tcvm * Attack profile: DIR - * TODO: falls back to Linear + * Returns target position with no modifications * * Arguments: * 0: Seeker Target PosASL @@ -18,4 +18,5 @@ * Public: No */ -_this call FUNC(attackProfile_LIN); +params ["_seekerTargetPos"]; +_seekerTargetPos diff --git a/addons/missileguidance/functions/fnc_attackProfile_HI.sqf b/addons/missileguidance/functions/fnc_attackProfile_HI.sqf deleted file mode 100644 index 92413f59d07..00000000000 --- a/addons/missileguidance/functions/fnc_attackProfile_HI.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: jaynus / nou - * Attack profile: HI - * TODO: falls back to Linear - * - * 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_HI; - * - * Public: No - */ - -_this call FUNC(attackProfile_LIN); diff --git a/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf b/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf index b690ab2075e..64895a3e54a 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf @@ -22,6 +22,9 @@ #define STAGE_COAST 3 #define STAGE_TERMINAL 4 +#define CLIMB_ANGLE 12 +#define ATTACK_ANGLE 2 + params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; _args params ["_firedEH"]; _firedEH params ["_shooter","","","","","","_projectile"]; @@ -30,6 +33,7 @@ if (_seekerTargetPos isEqualTo [0,0,0]) exitWith {_seekerTargetPos}; if (_attackProfileStateParams isEqualTo []) then { _attackProfileStateParams set [0, STAGE_LAUNCH]; + _attackProfileStateParams set [1, 0]; }; private _shooterPos = getPosASL _shooter; @@ -44,23 +48,28 @@ TRACE_2("",_distanceToTarget,_distanceToShooter); // Add height depending on distance for compensate private _returnTargetPos = _seekerTargetPos; +private _attackDirection = _seekerTargetPos vectorDiff _projectilePos; +private _horizon = velocity _projectile; +_horizon set [2, 0]; +_horizon = vectorNormalized _horizon; +private _attackAngle = acos (_horizon vectorCos _attackDirection); + switch (_attackProfileStateParams select 0) do { case STAGE_LAUNCH: { TRACE_1("STAGE_LAUNCH",""); - if (_distanceToShooter < 10) then { - _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*2]; + if (_distanceToShooter < 6) then { + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,5]; } else { _attackProfileStateParams set [0, STAGE_CLIMB]; }; }; case STAGE_CLIMB: { TRACE_1("STAGE_CLIMB",""); - private _cruisAlt = 60 * (_distanceShooterToTarget/2000); - - if ( ((ASLToAGL _projectilePos) select 2) - ((ASLToAGL _seekerTargetPos) select 2) >= _cruisAlt) then { + if (_attackAngle >= ATTACK_ANGLE) then { _attackProfileStateParams set [0, STAGE_TERMINAL]; } else { - _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*1.5]; + private _height = _distanceShooterToTarget * tan CLIMB_ANGLE; + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_height]; }; }; case STAGE_TERMINAL: { @@ -69,5 +78,7 @@ switch (_attackProfileStateParams select 0) do { }; }; +_attackProfileStateParams set [2, _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 f1f360e403a..a3ae233eba0 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf @@ -22,6 +22,10 @@ #define STAGE_COAST 3 #define STAGE_TERMINAL 4 +#define CRUISE_ALT 160 +#define CLIMB_ANGLE 22 +#define ATTACK_ANGLE 12 + params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; _args params ["_firedEH"]; _firedEH params ["_shooter","","","","","","_projectile"]; @@ -30,6 +34,7 @@ if (_seekerTargetPos isEqualTo [0,0,0]) exitWith {_seekerTargetPos}; if (_attackProfileStateParams isEqualTo []) then { _attackProfileStateParams set [0, STAGE_LAUNCH]; + _attackProfileStateParams set [1, 0]; }; private _shooterPos = getPosASL _shooter; @@ -44,39 +49,44 @@ TRACE_2("",_distanceToTarget,_distanceToShooter); // Add height depending on distance for compensate private _returnTargetPos = _seekerTargetPos; +private _attackDirection = _seekerTargetPos vectorDiff _projectilePos; +private _horizon = velocity _projectile; +_horizon set [2, 0]; +_horizon = vectorNormalized _horizon; +private _attackAngle = acos (_horizon vectorCos _attackDirection); + switch( (_attackProfileStateParams select 0) ) do { case STAGE_LAUNCH: { TRACE_1("STAGE_LAUNCH",""); if (_distanceToShooter < 10) then { - _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*2]; + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,5]; } else { _attackProfileStateParams set [0, STAGE_CLIMB]; }; }; case STAGE_CLIMB: { TRACE_1("STAGE_CLIMB",""); - private _cruisAlt = 140; - if (_distanceShooterToTarget < 1250) then { - _cruisAlt = 140 * (_distanceShooterToTarget/1250); - TRACE_1("_cruisAlt",_cruisAlt); - }; - if ( ((ASLToAGL _projectilePos) select 2) - ((ASLToAGL _seekerTargetPos) select 2) >= _cruisAlt) then { - if (_cruisAlt < 140) then { - _attackProfileStateParams set [0, STAGE_TERMINAL]; - } else { + private _altitude = (ASLToAGL _projectilePos) select 2; + switch (true) do { + case (_altitude >= CRUISE_ALT): { _attackProfileStateParams set [0, STAGE_COAST]; }; - } else { - _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*1.5]; - }; + case (_attackAngle >= ATTACK_ANGLE): { + _attackProfileStateParams set [0, STAGE_TERMINAL]; + }; + default { + private _height = _distanceShooterToTarget * tan CLIMB_ANGLE; + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_height]; + } + } }; case STAGE_COAST: { TRACE_1("STAGE_COAST",""); - TRACE_1("",((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2)); - if (_distanceToTarget < ( ((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2) ) * 2) then { + TRACE_1("",_attackAngle); + if (_attackAngle >= ATTACK_ANGLE) then { _attackProfileStateParams set [0, STAGE_TERMINAL]; } else { - _returnTargetPos = _seekerTargetPos vectorAdd [0,0,(_projectilePos select 2)]; + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,(_projectilePos select 2) min CRUISE_ALT]; }; }; case STAGE_TERMINAL: { @@ -86,5 +96,7 @@ switch( (_attackProfileStateParams select 0) ) do { }; }; +_attackProfileStateParams set [2, _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 e346b16eb66..cc823b1e8c3 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf @@ -18,8 +18,10 @@ */ params ["_seekerTargetPos", "_args"]; -_args params ["_firedEH"]; +_args params ["_firedEH", "_launchParams"]; _firedEH params ["_shooter","","","","","","_projectile"]; +_launchParams params ["","_targetLaunchParams"]; +_targetLaunchParams params ["", "", "_launchPos"]; if (_seekerTargetPos isEqualTo [0,0,0]) exitWith {_seekerTargetPos}; @@ -30,29 +32,31 @@ private _distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; private _distanceToShooter = _projectilePos vectorDistance _shooterPos; private _distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; +private _ttgo = _distanceToTarget / (vectorMagnitude velocity _projectile); + TRACE_2("",_distanceToTarget,_distanceToShooter); // Add height depending on distance for compensate private _addHeight = [0,0,0]; -// Always climb an arc on initial launch if we are close to the round -if ((((ASLtoAGL _projectilePos) select 2) < 5) && {_distanceToShooter < 15}) then { - _addHeight = _addHeight vectorAdd [0,0,_distanceToTarget]; - TRACE_1("climb - near shooter",_addHeight); +private _2dDistance = (800 + (_projectilePos distance2D _launchPos)) / (_projectilePos distance2D _seekerTargetPos); + +if (_2dDistance <= 1) then { + _addHeight = [0, 0, (_projectilePos#2) + 8]; } else { - // If we are below the target, increase the climbing arc - if (((_projectilePos select 2) < (_seekerTargetPos select 2)) && {_distanceToTarget > 100}) then { - _addHeight = _addHeight vectorAdd [0,0, ((_seekerTargetPos select 2) - (_projectilePos select 2))]; - TRACE_1("climb - below target and far",_addHeight); + // Always climb an arc on initial launch if we are close to the round + if ((((ASLToAGL _projectilePos) select 2) < 5) && {_distanceToShooter < 15}) then { + _addHeight = _addHeight vectorAdd [0,0,_distanceToTarget]; + TRACE_1("climb - near shooter",_addHeight); + } else { + // If we are below the target, increase the climbing arc + if (((_projectilePos select 2) < (_seekerTargetPos select 2)) && {_distanceToTarget > 100}) then { + _addHeight = _addHeight vectorAdd [0,0, ((_seekerTargetPos select 2) - (_projectilePos select 2))]; + TRACE_1("climb - below target and far",_addHeight); + }; }; }; -// Projectile above target -if ((_projectilePos select 2) > (_seekerTargetPos select 2)) then { - TRACE_1("above - far",_addHeight); - _addHeight = _addHeight vectorAdd [0,0, _distanceToTarget / 50]; -}; - private _returnTargetPos = _seekerTargetPos vectorAdd _addHeight; TRACE_2("Adjusted target position",_returnTargetPos,_addHeight); diff --git a/addons/missileguidance/functions/fnc_attackProfile_LOFT.sqf b/addons/missileguidance/functions/fnc_attackProfile_LOFT.sqf new file mode 100644 index 00000000000..934ac04123a --- /dev/null +++ b/addons/missileguidance/functions/fnc_attackProfile_LOFT.sqf @@ -0,0 +1,53 @@ +#include "..\script_component.hpp" +/* + * Author: jaynus / nou + * Attack profile: AIR + * TODO: falls back to Linear + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Seeker State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_AIR; + * + * Public: No + */ + +params ["_seekerTargetPos", "_args"]; +_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; +_firedEH params ["_shooter","","","","_ammo","","_projectile"]; +_launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; +_targetLaunchParams params ["_target", "_targetPos", "_launchPos", "_launchDir", "_launchTime"]; +_flightParams params ["_pitchRate", "_yawRate", "_isBangBangGuidance"]; +_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState","_navigationParams"]; +_seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; + +if (_seekerTargetPos isEqualTo [0, 0, 0]) exitWith { + _seekerTargetPos +}; + +private _projectilePos = getPosASLVisual _projectile; +private _distanceToTarget2d = _projectilePos distance2D _seekerTargetPos; + +private _closingRate = vectorMagnitude velocity _projectile; +private _timeToGo = (_projectilePos distance _seekerTargetPos) / _closingRate; + +// we could do stuff like desired attack angle, but I'm not going that far today +private _los = vectorNormalized (_seekerTargetPos vectorDiff _projectilePos); + +private _angleToTarget = acos ((vectorDir _projectile) vectorCos _los); +private _atMinRotationAngle = _angleToTarget >= (0.5 * _pitchRate * _timeToGo); + +private _returnTargetPos = _seekerTargetPos; + +if (!_atMinRotationAngle && _distanceToTarget2d >= 500 && _timeToGo >= 10) then { + // 10 degree pitch up + _returnTargetPos = _seekerTargetPos vectorAdd [0, 0, (_projectilePos distance _seekerTargetPos) * sin 10]; +}; + +_returnTargetPos diff --git a/addons/missileguidance/functions/fnc_attackProfile_MID.sqf b/addons/missileguidance/functions/fnc_attackProfile_MID.sqf deleted file mode 100644 index 2ca9eef77f3..00000000000 --- a/addons/missileguidance/functions/fnc_attackProfile_MID.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: jaynus / nou - * Attack profile: MID - * TODO: falls back to Linear - * - * 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_MID; - * - * Public: No - */ - -_this call FUNC(attackProfile_LIN); diff --git a/addons/missileguidance/functions/fnc_attackProfile_WIRE.sqf b/addons/missileguidance/functions/fnc_attackProfile_WIRE.sqf index 443fe1bb975..1733ad10153 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_WIRE.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_WIRE.sqf @@ -17,47 +17,27 @@ * Public: No */ params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; -_args params ["_firedEH"]; +_args params ["_firedEH", "", "", "", "", "_targetData"]; _firedEH params ["_shooter","","","","","","_projectile"]; -_attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_randomVector", "_crosshairOffset", "_seekerMaxRangeSqr", "_seekerMinRangeSqr", "_wireCutSource", "_distanceAheadOfMissile"]; +_attackProfileStateParams params ["_maxCorrectableDistance", "_wireCut", "_lastInput", "_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; + if !(_wireCut) then { _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]; + 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]) + _lastInput }; -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; +private _final = _seekerTargetPos vectorAdd _crosshairOffset; +_attackProfileStateParams set [2, _final]; +_targetData set [0, _projectilePos vectorFromTo _final]; -_relativeCorrection = (vectorNormalized _relativeCorrection) vectorMultiply _correction; -private _returnPos = _projectilePos vectorDiff (_projectile vectorModelToWorld _relativeCorrection); -_returnPos vectorAdd (_shooterDir vectorMultiply _distanceAheadOfMissile) +_final diff --git a/addons/missileguidance/functions/fnc_changeMissileDirection.sqf b/addons/missileguidance/functions/fnc_changeMissileDirection.sqf index 21884c16938..77858401ba8 100644 --- a/addons/missileguidance/functions/fnc_changeMissileDirection.sqf +++ b/addons/missileguidance/functions/fnc_changeMissileDirection.sqf @@ -2,6 +2,7 @@ /* * Author: jaynus / nou * Change a projectile's direction, maintaing speed + * No longer used in guidancePFH, kept for backwards compatibility * * Arguments: * 0: Projectile @@ -16,10 +17,9 @@ * Public: No */ -params ["_projectile", "_v"]; +params ["_projectile", "_pitch", "_yaw", "_roll"]; -private _l = sqrt ((_v select 0) ^ 2 + (_v select 1) ^ 2); -private _r = -(_v select 2) / _l; +private _dir = [sin _yaw * cos _pitch, cos _yaw * cos _pitch, sin _pitch]; +private _up = [[sin _roll, -sin _pitch, cos _roll * cos _pitch], -_yaw] call BIS_fnc_rotateVector2D; -_projectile setVectorDirAndUp [ _v, [(_v select 0) * _r,(_v select 1) * _r, _l] ]; -_projectile setVelocity (_v vectorMultiply (vectorMagnitude (velocity _projectile))); +_projectile setVectorDirAndUp [_dir, _up]; diff --git a/addons/missileguidance/functions/fnc_checkLos.sqf b/addons/missileguidance/functions/fnc_checkLos.sqf index 1fadc5510e8..152c7c24074 100644 --- a/addons/missileguidance/functions/fnc_checkLos.sqf +++ b/addons/missileguidance/functions/fnc_checkLos.sqf @@ -25,7 +25,7 @@ if (_checkVisibilityTest) exitWith { _visibility > 0.001 }; if ((isNil "_seeker") || {isNil "_target"}) exitWith { - ERROR_2("nil",_seeker,_target); + ERROR_2("nil [%1]->[%2]",_seeker,_target); false }; @@ -34,13 +34,12 @@ private _targetAimPos = aimPos _target; private _seekerPos = getPosASL _seeker; private _return = true; -if (!((terrainIntersectASL [_seekerPos, _targetPos]) && {terrainIntersectASL [_seekerPos, _targetAimPos]})) then { +if ((terrainIntersectASL [_seekerPos, _targetPos]) && {terrainIntersectASL [_seekerPos, _targetAimPos]}) then { + _return = false; +} else { if (lineIntersects [_seekerPos, _targetPos, _seeker, _target]) then { _return = false; }; -} else { - _return = false; }; _return - diff --git a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf index d25d2bc2b78..f8494e474c5 100644 --- a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf +++ b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf @@ -18,7 +18,7 @@ TRACE_1("cycle fire mode",_this); if (!alive ACE_player) exitWith {}; -if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith {}; +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {}; private _currentShooter = objNull; @@ -76,7 +76,7 @@ private _nextFireMode = _attackProfiles select _index; TRACE_4("",_currentFireMode,_nextFireMode,_index,_attackProfiles); -private _currentFireMode = if (_useModeForAttackProfile) then { +if (_useModeForAttackProfile) then { TRACE_2("setting fire mode",_weaponStateToken,_nextFireMode); { _x params ["_xIndex", "", "_xWeapon", "", "_xMode"]; diff --git a/addons/missileguidance/functions/fnc_dev_ProjectileCamera.sqf b/addons/missileguidance/functions/fnc_dev_ProjectileCamera.sqf new file mode 100644 index 00000000000..bf3a5af67c5 --- /dev/null +++ b/addons/missileguidance/functions/fnc_dev_ProjectileCamera.sqf @@ -0,0 +1,61 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * tracks a projectile until it explodes + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No + */ +params ["_projectile"]; + +private _camera = "camera" camCreate getPosATL _projectile; +_camera camPrepareFov 0.7; +_camera cameraEffect ["internal", "back"]; + +_camera camCommitPrepared 0; + +GVAR(debug_camera_close) = false; +private _displayEH = (findDisplay 46) displayAddEventHandler ["KeyDown", { + params ["_displayorcontrol", "_key", "_shift", "_ctrl", "_alt"]; + GVAR(debug_camera_close) = (_key == 1); + true +}]; + +[{ + params ["_args", "_pfh"]; + _args params ["_projectile", "_camera", "_projectilePos", "_displayEH"]; + if (!alive _projectile || GVAR(debug_camera_close)) exitWith { + private _delay = 1.5; + if (GVAR(debug_camera_close)) then { + _delay = 0; + }; + + (findDisplay 46) displayRemoveEventHandler ["KeyDown", _displayEH]; + + [{ + params ["_camera"]; + + _camera cameraEffect ["terminate", "back"]; + _camera camCommitPrepared 0; + camDestroy _camera; + }, [_camera], _delay] call CBA_fnc_waitAndExecute; + + _camera camPrepareTarget _projectilePos; + _camera camCommitPrepared 0; + + [_pfh] call CBA_fnc_removePerFrameHandler; + }; + + private _currentProjectilePos = getPosATLVisual _projectile; + + _camera camPrepareTarget _projectile; + _camera camPrepareRelPos [0, -5, 1]; + _camera camCommitPrepared 0; + + _args set [2, getPosATL _projectile]; +}, 0, [_projectile, _camera, getPosATL _projectile, _displayEH]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/missileguidance/functions/fnc_doAttackProfile.sqf b/addons/missileguidance/functions/fnc_doAttackProfile.sqf index cafbadf69c6..d6dde00f91b 100644 --- a/addons/missileguidance/functions/fnc_doAttackProfile.sqf +++ b/addons/missileguidance/functions/fnc_doAttackProfile.sqf @@ -22,18 +22,17 @@ _args params ["", "_launchParams"]; _launchParams params ["", "", "", "_attackProfileName"]; private _attackProfileFunction = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfileName >> "functionName"); - private _attackProfilePos = _this call (missionNamespace getVariable _attackProfileFunction); if ((isNil "_attackProfilePos") || {_attackProfilePos isEqualTo [0,0,0]}) exitWith { - ERROR_1("attack profile returned bad pos",_attackProfilePos); + // ERROR_2("attack profile [%1] returned bad pos %2",_attackProfileName,_attackProfilePos); [0,0,0] }; -#ifdef DRAW_GUIDANCE_INFO -drawLine3D [(ASLtoAGL _attackProfilePos), (ASLtoAGL _seekerTargetPos), [0,1,1,1]]; -drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,0,1,1], ASLtoAGL _attackProfilePos, 0.5, 0.5, 0, _attackProfileName, 1, 0.025, "TahomaB"]; -#endif +if (GVAR(debug_drawGuidanceInfo)) then { + drawLine3D [(ASLToAGL _attackProfilePos), (ASLToAGL _seekerTargetPos), [0,1,1,1]]; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,0,1,1], ASLToAGL _attackProfilePos, 0.5, 0.5, 0, _attackProfileName, 1, 0.025, "TahomaB"]; +}; TRACE_2("return",_attackProfilePos,_attackProfileName); _attackProfilePos; diff --git a/addons/missileguidance/functions/fnc_doSeekerSearch.sqf b/addons/missileguidance/functions/fnc_doSeekerSearch.sqf index 6008725b4c0..fe915d1bb4f 100644 --- a/addons/missileguidance/functions/fnc_doSeekerSearch.sqf +++ b/addons/missileguidance/functions/fnc_doSeekerSearch.sqf @@ -30,9 +30,9 @@ if ((isNil "_seekerTargetPos") || {_seekerTargetPos isEqualTo [0,0,0]}) then { / 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 - drawIcon3D ["\A3\ui_f\data\map\markers\military\unknown_CA.paa", [1,1,0,1], ASLtoAGL _lastKnownPos, 0.25, 0.25, 0, "LastKnownPos", 1, 0.02, "TahomaB"]; - #endif + if (GVAR(debug_drawGuidanceInfo)) then { + drawIcon3D ["\A3\ui_f\data\map\markers\military\unknown_CA.paa", [1,1,0,1], ASLToAGL _lastKnownPos, 0.25, 0.25, 0, "LastKnownPos", 1, 0.02, "TahomaB"]; + }; } else { TRACE_1("seeker returned no pos",_seekerTargetPos); _seekerTargetPos = [0,0,0]; @@ -44,9 +44,9 @@ if ((isNil "_seekerTargetPos") || {_seekerTargetPos isEqualTo [0,0,0]}) then { / }; }; -#ifdef DRAW_GUIDANCE_INFO -drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,1,0,1], ASLtoAGL _seekerTargetPos, 0.5, 0.5, 0, _seekerTypeName, 1, 0.025, "TahomaB"]; -#endif +if (GVAR(debug_drawGuidanceInfo)) then { + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,1,0,1], ASLToAGL _seekerTargetPos, 0.5, 0.5, 0, _seekerTypeName, 1, 0.025, "TahomaB"]; +}; TRACE_2("return",_seekerTargetPos,_seekerTypeName); _seekerTargetPos; diff --git a/addons/missileguidance/functions/fnc_guidancePFH.sqf b/addons/missileguidance/functions/fnc_guidancePFH.sqf index 0620e9e3c03..82d3d57a35f 100644 --- a/addons/missileguidance/functions/fnc_guidancePFH.sqf +++ b/addons/missileguidance/functions/fnc_guidancePFH.sqf @@ -15,100 +15,192 @@ * * Public: No */ +#define TRAIL_COLOUR(multiplier) [1 * multiplier, 1 * multiplier, 0.3 * multiplier, 0.7 * multiplier] BEGIN_COUNTER(guidancePFH); -#define TIMESTEP_FACTOR 0.01 - params ["_args", "_pfID"]; -_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; +_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateParams"]; _firedEH params ["_shooter","","","","_ammo","","_projectile"]; -_launchParams params ["","_targetLaunchParams"]; -_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; +_launchParams params ["","_targetLaunchParams","","","","","_navigationType"]; +_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_navigationParameters", "_guidanceParameters"]; +_navigationStateParams params ["_currentState", "_navigationStateData"]; +_flightParams params ["_pitchRate", "_yawRate", "_isBangBangGuidance", "_stabilityCoefficient", "_showTrail"]; if (!alive _projectile || isNull _projectile || isNull _shooter) exitWith { [_pfID] call CBA_fnc_removePerFrameHandler; END_COUNTER(guidancePFH); }; -private _runtimeDelta = diag_tickTime - _lastRunTime; -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)); -} else { - _adjustTime = 0; +if (_showTrail) then { + drop ["\a3\data_f\kouleSvetlo", "", "Billboard", 100, 0.03, _projectile modelToWorld [0, 0, 0], + [0, 0, 0], 0, 1.25, 1, 0.05, [0.5], [TRAIL_COLOUR(1)], [0], 0, 0, "", "", "", 0, false, -1, [TRAIL_COLOUR(10000)]]; }; -private _minDeflection = ((_flightParams select 0) - ((_flightParams select 0) * _adjustTime)) max 0; -private _maxDeflection = (_flightParams select 1) * _adjustTime; -// private _incDeflection = _flightParams select 2; // todo - -private _projectilePos = getPosASL _projectile; +private _timestep = diag_deltaTime * accTime; // Run seeker function: -private _seekerTargetPos = [[0,0,0], _args, _seekerStateParams, _lastKnownPosState] call FUNC(doSeekerSearch); - +private _seekerTargetPos = [[0,0,0], _args, _seekerStateParams, _lastKnownPosState, _timestep] call FUNC(doSeekerSearch); // Run attack profile function: -private _profileAdjustedTargetPos = [_seekerTargetPos, _args, _attackProfileStateParams] call FUNC(doAttackProfile); +_seekerTargetPos = AGLToASL ASLToAGL _seekerTargetPos; +private _profileAdjustedTargetPos = [_seekerTargetPos, _args, _attackProfileStateParams, _timestep] call FUNC(doAttackProfile); + +private _projectilePos = getPosASLVisual _projectile; +_targetData set [1, _projectilePos vectorFromTo _profileAdjustedTargetPos]; // 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 isNotEqualTo [0,0,0]}) then { +if ((_pitchRate != 0 || {_yawRate != 0}) && {_profileAdjustedTargetPos isNotEqualTo [0,0,0]}) then { + private _navigationFunction = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "functionName"); + if (_navigationStateData isNotEqualTo []) then { + (_navigationStateData select _currentState) params ["_transitionCondition"]; + private _transition = ([_args, _timestep] call (missionNamespace getVariable [_transitionCondition, { false }])); + if (_transition) then { + _currentState = _currentState + 1; + _navigationStateParams set [0, _currentState]; + }; - private _targetVector = _projectilePos vectorFromTo _profileAdjustedTargetPos; - private _adjustVector = _targetVector vectorDiff (vectorDir _projectile); - _adjustVector params ["_adjustVectorX", "_adjustVectorY", "_adjustVectorZ"]; + _navigationType = (_navigationStateData select _currentState) select 1; + _navigationFunction = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "functionName"); - private _yaw = 0; - private _pitch = 0; - private _roll = 0; + _navigationParameters = (_navigationStateData select _currentState) select 2; + _stateParams set [4, _navigationParameters]; + }; + private _commandedAcceleration = [_args, _timestep, _seekerTargetPos, _profileAdjustedTargetPos, _targetData, _navigationParameters] call (missionNamespace getVariable _navigationFunction); + + if (isNil "_commandedAcceleration") exitWith { + systemChat format ["Error in %1 Missile Type %2 Seeker Pos %3", _navigationFunction, typeOf _projectile, _seekerTargetPos]; + ERROR_MSG_3("_commandedAcceleration is nil! Guidance cancelled [%1 %2 %3]",_navigationFunction,typeOf _projectile,_seekerTargetPos); + }; - if (_adjustVectorX < 0) then { - _yaw = - ( (_minDeflection max ((abs _adjustVectorX) min _maxDeflection) ) ); - } else { - if (_adjustVectorX > 0) then { - _yaw = ( (_minDeflection max (_adjustVectorX min _maxDeflection) ) ); - }; + if (GVAR(debug_drawGuidanceInfo)) then { + private _projectilePosAGL = ASLToAGL _projectilePos; + private _cmdAccelLocal = _projectile vectorWorldToModelVisual _commandedAcceleration; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], _projectilePosAGL vectorAdd [0, 0, 1], 0.75, 0.75, 0, format ["cmdPitch: %1 cmdYaw %2", _cmdAccelLocal#2, _cmdAccelLocal#0], 1, 0.025, "TahomaB"]; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,0,1], _projectilePosAGL vectorAdd [0, 0, 2], 0.75, 0.75, 0, _navigationType, 1, 0.025, "TahomaB"]; + drawLine3D [_projectilePosAGL, _projectilePosAGL vectorAdd _commandedAcceleration, [1, 0, 1, 1]]; }; - if (_adjustVectorY < 0) then { - _roll = - ( (_minDeflection max ((abs _adjustVectorY) min _maxDeflection) ) ); - } else { - if (_adjustVectorY > 0) then { - _roll = ( (_minDeflection max (_adjustVectorY min _maxDeflection) ) ); + + // activate missile servos and change direction + if (!isGamePaused && accTime > 0) then { + _guidanceParameters params ["_yaw", "_roll", "_pitch"]; + + _commandedAcceleration = _projectile vectorWorldToModelVisual _commandedAcceleration; + _commandedAcceleration params ["_yawChange", "", "_pitchChange"]; + + if (isNil "_yawChange") then { + _yawChange = 0; }; - }; - if (_adjustVectorZ < 0) then { - _pitch = - ( (_minDeflection max ((abs _adjustVectorZ) min _maxDeflection) ) ); - } else { - if (_adjustVectorZ > 0) then { - _pitch = ( (_minDeflection max (_adjustVectorZ min _maxDeflection) ) ); + if (isNil "_pitchChange") then { + _pitchChange = 0; }; - }; - private _finalAdjustVector = [_yaw, _roll, _pitch]; - TRACE_3("",_pitch,_yaw,_roll); - TRACE_3("",_targetVector,_adjustVector,_finalAdjustVector); + private _clampedPitch = (_pitchChange min _pitchRate) max -_pitchRate; + private _clampedYaw = (_yawChange min _yawRate) max -_yawRate; + + // controls are either on or off, no proportional + if (_isBangBangGuidance) then { + private _pitchSign = if (_clampedPitch == 0) then { + 0 + } else { + _clampedPitch / abs _clampedPitch + }; + private _yawSign = if (_clampedYaw == 0) then { + 0 + } else { + _clampedYaw / abs _clampedYaw + }; + _clampedPitch = _pitchSign * _pitchRate; + _clampedYaw = _yawSign * _yawRate; + }; + + TRACE_9("pitch/yaw/roll",_pitch,_yaw,_roll,_yawChange,_pitchChange,_pitchRate,_yawRate,_clampedPitch,_clampedYaw); + // directional stability + private _localVelocity = _projectile vectorWorldToModelVisual (velocity _projectile); + + private _velocityAngleYaw = (_localVelocity#0) atan2 (_localVelocity#1); + private _velocityAnglePitch = (_localVelocity#2) atan2 (_localVelocity#1); + + // bastardized version of direction stability https://en.wikipedia.org/wiki/Directional_stability#Steering_forces + private _forceYaw = _stabilityCoefficient * _velocityAngleYaw + _clampedYaw; + private _forcePitch = _stabilityCoefficient * _velocityAnglePitch + _clampedPitch; + + _pitch = _pitch + _forcePitch * _timestep; + _yaw = _yaw + _forceYaw * _timestep; - if (accTime > 0) then { - private _changeVector = (vectorDir _projectile) vectorAdd _finalAdjustVector; - TRACE_2("",_projectile,_changeVector); - [_projectile, _changeVector] call FUNC(changeMissileDirection); + TRACE_3("new pitch/yaw/roll",_pitch,_yaw,_roll); + + private _multiplyQuat = { + params ["_qLHS", "_qRHS"]; + _qLHS params ["_lhsX", "_lhsY", "_lhsZ", "_lhsW"]; + _qRHS params ["_rhsX", "_rhsY", "_rhsZ", "_rhsW"]; + + private _lhsImaginary = [_lhsX, _lhsY, _lhsZ]; + private _rhsImaginary = [_rhsX, _rhsY, _rhsZ]; + + private _scalar = _lhsW * _rhsW - (_lhsImaginary vectorDotProduct _rhsImaginary); + private _imginary = (_rhsImaginary vectorMultiply _lhsW) vectorAdd (_lhsImaginary vectorMultiply _rhsW) vectorAdd (_lhsImaginary vectorCrossProduct _rhsImaginary); + + _imginary + [_scalar] + }; + + private _multiplyVector = { + params ["_quaternion", "_vector"]; + + private _real = _quaternion#3; + private _imaginary = [ + _quaternion#0, + _quaternion#1, + _quaternion#2 + ]; + + private _vectorReturn = _vector vectorAdd (( + _imaginary vectorCrossProduct ( + (_imaginary vectorCrossProduct _vector) vectorAdd ( + _vector vectorMultiply _real + ) + ) + ) vectorMultiply 2); + + _vectorReturn + }; + + private _quaternion = [0, 0, 0, 1]; + + private _temp = [0, 0, sin (-_yaw / 2), cos (-_yaw / 2)]; + _quaternion = [_quaternion, _temp] call _multiplyQuat; + + _temp = [sin (_pitch / 2), 0, 0, cos (_pitch / 2)]; + _quaternion = [_quaternion, _temp] call _multiplyQuat; + + private _dir = [_quaternion, [0, 1, 0]] call _multiplyVector; + private _up = [_quaternion, [0, 0, 1]] call _multiplyVector; + + _projectile setVectorDirAndUp [_dir, _up]; + + _guidanceParameters set [0, _yaw]; + _guidanceParameters set [2, _pitch]; + + _stateParams set [5, _guidanceParameters]; }; + + _stateParams set [4, _navigationParameters]; + _args set [4, _stateParams]; }; -#ifdef DRAW_GUIDANCE_INFO -TRACE_3("",_projectilePos,_seekerTargetPos,_profileAdjustedTargetPos); -drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLtoAGL _projectilePos, 0.75, 0.75, 0, _ammo, 1, 0.025, "TahomaB"]; +if (GVAR(debug_drawGuidanceInfo)) then { + TRACE_3("",_projectilePos,_seekerTargetPos,_profileAdjustedTargetPos); + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLToAGL _projectilePos, 0.75, 0.75, 0, _ammo, 1, 0.025, "TahomaB"]; -private _ps = "#particlesource" createVehicleLocal (ASLtoAGL _projectilePos); -_PS setParticleParams [["\A3\Data_f\cl_basic", 8, 3, 1], "", "Billboard", 1, 3.0141, [0, 0, 2], [0, 0, 0], 1, 1.275, 1, 0, [1, 1], [[1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1]], [1], 1, 0, "", "", nil]; -_PS setDropInterval 3.0; -#endif + if (!isGamePaused && accTime > 0) then { + private _ps = "#particlesource" createVehicleLocal (ASLToAGL _projectilePos); + _PS setParticleParams [["\A3\Data_f\cl_basic", 8, 3, 1], "", "Billboard", 1, 3.0141, [0, 0, 0], [0, 0, 0], 1, 1.275, 1, 0, [1, 1], [[1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1]], [1], 1, 0, "", "", nil]; + _PS setDropInterval 1.0; + }; + + drawLine3D [ASLToAGL _projectilePos, (ASLToAGL _projectilePos) vectorAdd velocity _projectile, [1, 1, 1, 1]]; +}; _stateParams set [0, diag_tickTime]; END_COUNTER(guidancePFH); - diff --git a/addons/missileguidance/functions/fnc_handleHandoff.sqf b/addons/missileguidance/functions/fnc_handleHandoff.sqf index 9c6e299d01e..785071da01c 100644 --- a/addons/missileguidance/functions/fnc_handleHandoff.sqf +++ b/addons/missileguidance/functions/fnc_handleHandoff.sqf @@ -19,4 +19,4 @@ params ["_target", "_args"]; if (isNil "_target" || {isNull _target} || {!local _target} ) exitWith { false }; -[FUNC(guidancePFH), 0, _args] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(guidancePFH), 0, _args] call CBA_fnc_addPerFrameHandler; diff --git a/addons/missileguidance/functions/fnc_javelin_midCourseTransition.sqf b/addons/missileguidance/functions/fnc_javelin_midCourseTransition.sqf new file mode 100644 index 00000000000..58995dee31d --- /dev/null +++ b/addons/missileguidance/functions/fnc_javelin_midCourseTransition.sqf @@ -0,0 +1,48 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Condition to switch to next navigation profile + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * None + * + * Example: + * [] call ace_missileguidance_fnc_javelin_midCourseTransition + * + * Public: No + */ +#define STAGE_LAUNCH 1 +#define STAGE_CLIMB 2 +#define STAGE_COAST 3 +#define STAGE_TERMINAL 4 + +#define REQUIRED_STABLE_TIME 0.2 +#define REQUIRED_ANGLE 1 + +params ["_args", "_timestep"]; +_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateData"]; +_firedEH params ["_shooter","","","","_ammo","","_projectile"]; +_launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; +_targetLaunchParams params ["_target", "_targetPos", "_launchPos", "_launchDir", "_launchTime"]; +_flightParams params ["_pitchRate", "_yawRate", "_isBangBangGuidance"]; +_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState","_navigationParams", "_guidanceParameters"]; +_seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; +_targetData params ["_targetDirection", "_attackProfileDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"]; + +_attackProfileStateParams params ["_state", "_stableTime", "_target"]; +private _projectileDirection = vectorNormalized velocity _projectile; +private _targetDistance = _target vectorDistance getPosASLVisual _projectile; +private _targetDirection = (getPosASLVisual _projectile) vectorFromTo _target; +private _angle = _projectileDirection vectorCos _targetDirection; +if (_angle > cos REQUIRED_ANGLE) then { + _stableTime = _stableTime + _timestep; +} else { + _stableTime = 0; +}; + +_attackProfileStateParams set [1, _stableTime]; +_state isEqualTo STAGE_TERMINAL && _stableTime > REQUIRED_STABLE_TIME + diff --git a/addons/missileguidance/functions/fnc_line_onFired.sqf b/addons/missileguidance/functions/fnc_line_onFired.sqf new file mode 100644 index 00000000000..6093dc27384 --- /dev/null +++ b/addons/missileguidance/functions/fnc_line_onFired.sqf @@ -0,0 +1,35 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Sets up line state arrays (called from missileGuidance's onFired). + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * None + * + * Example: + * [] call ace_missileguidance_fnc_line_onFired + * + * Public: No + */ +params ["_firedEH", "", "", "", "_stateParams"]; +_firedEH params ["","","","","","","_projectile"]; + +private _ammoConfig = configOf _projectile; +private _p = getNumber (_ammoConfig >> QUOTE(ADDON) >> "lineGainP"); +private _d = getNumber (_ammoConfig >> QUOTE(ADDON) >> "lineGainD"); +private _correctionDistance = getNumber (_ammoConfig >> QUOTE(ADDON) >> "correctionDistance"); + +if (_correctionDistance == 0) then { + _correctionDistance = 1; +}; + +private _navigationParams = [ + _p, 0, _d, + 0, + 0, + _correctionDistance +]; +_navigationParams diff --git a/addons/missileguidance/functions/fnc_ahr_onFired.sqf b/addons/missileguidance/functions/fnc_mwr_onFired.sqf similarity index 92% rename from addons/missileguidance/functions/fnc_ahr_onFired.sqf rename to addons/missileguidance/functions/fnc_mwr_onFired.sqf index 0618c046ad4..845b81cda64 100644 --- a/addons/missileguidance/functions/fnc_ahr_onFired.sqf +++ b/addons/missileguidance/functions/fnc_mwr_onFired.sqf @@ -10,7 +10,7 @@ * None * * Example: - * [] call ace_missileguidance_fnc_ahr_onFired + * [] call ace_missileguidance_fnc_mwr_onFired * * Public: No */ @@ -38,6 +38,8 @@ private _activeRadarDistance = [_config >> "activeRadarEngageDistance", "NUMBER" private _projectileThrust = [_projectileConfig >> "thrust", "NUMBER", 0] call CBA_fnc_getConfigEntry; private _projectileThrustTime = [_projectileConfig >> "thrustTime", "NUMBER", 0] call CBA_fnc_getConfigEntry; +private _lockTypes = [_config >> "lockableTypes", "ARRAY", ["Air", "LandVehicle", "Ship"]] call CBA_fnc_getConfigEntry; + private _velocityAtImpact = _projectileThrust * _projectileThrustTime; private _timeToActive = 0; if (!isNil "_target" && _velocityAtImpact > 0) then { @@ -70,4 +72,4 @@ _seekerStateParams set [6, false]; _seekerStateParams set [7, [0, 0, 0]]; _seekerStateParams set [8, CBA_missionTime]; _seekerStateParams set [9, isNull _target]; - +_seekerStateParams set [10, _lockTypes]; diff --git a/addons/missileguidance/functions/fnc_navigationType_augmentedProNav.sqf b/addons/missileguidance/functions/fnc_navigationType_augmentedProNav.sqf new file mode 100644 index 00000000000..f8f1e6c0f42 --- /dev/null +++ b/addons/missileguidance/functions/fnc_navigationType_augmentedProNav.sqf @@ -0,0 +1,50 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Determine path for projectile to take in accordance to proportional navigation, takes target acceleration into account + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Commanded acceleration normal to LOS in world space + * + * Example: + * [] call ace_missileguidance_fnc_navigationType_augmentedProNav + * + * Public: No + */ +params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos"]; +_args params ["_firedEH", "", "", "", "_stateParams", "_targetData"]; +_firedEH params ["","","","","","","_projectile"]; +_stateParams params ["", "", "", "","_navigationParams"]; +_navigationParams params ["_lastMissileFrame", "_navigationGain"]; +_lastMissileFrame params ["_lastLineOfSight"]; +_targetData params ["_targetDirection", "_attackProfileDirection", "", "_targetVelocity", "_targetAcceleration"]; + +// Proportional navigation implemented via "Fundamentals of proportional navigation" by Stephen Murtaugh and Harry Criel +private _closingVelocity = _targetVelocity vectorDiff velocity _projectile; + +private _targetAccelerationProjected = _attackProfileDirection vectorMultiply (_targetAcceleration vectorDotProduct _attackProfileDirection); +_targetAcceleration = _targetAcceleration vectorDiff _targetAccelerationProjected; + +private _losDelta = (vectorNormalized _attackProfileDirection) vectorDiff (vectorNormalized _lastLineOfSight); +private _losRate = if (_timestep == 0) then { + 0 +} else { + 1 * (vectorMagnitude _losDelta) / _timestep; +}; + +private _lateralAcceleration = _navigationGain * _losRate; +private _commandedAcceleration = _closingVelocity vectorMultiply _lateralAcceleration; +_commandedAcceleration = _commandedAcceleration vectorAdd (_losDelta vectorMultiply (0.5 * _navigationGain * vectorMagnitude _targetAcceleration)); + +// we need acceleration normal to our LOS +private _commandedAccelerationProjected = _attackProfileDirection vectorMultiply (_commandedAcceleration vectorDotProduct _attackProfileDirection); +_commandedAcceleration = _commandedAcceleration vectorDiff _commandedAccelerationProjected; + +if (accTime > 0) then { + _navigationParams set [0, [_seekerTargetPos, _targetVelocity, _attackProfileDirection]]; +}; + +_commandedAcceleration vectorMultiply _timestep diff --git a/addons/missileguidance/functions/fnc_navigationType_direct.sqf b/addons/missileguidance/functions/fnc_navigationType_direct.sqf new file mode 100644 index 00000000000..5681c85b9ae --- /dev/null +++ b/addons/missileguidance/functions/fnc_navigationType_direct.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Points directly toward attack profile positon + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Commanded acceleration normal to LOS in world space + * + * Example: + * [] call ace_missileguidance_fnc_navigationType_direct + * + * Public: No + */ +params ["_args", "_timestep", "", "_profileAdjustedTargetPos"]; +_args params ["_firedEH", "", "_flightParams"]; +_flightParams params ["_pitchRate", "_yawRate"]; +_firedEH params ["","","","","","","_projectile"]; + +private _projectilePos = getPosASLVisual _projectile; + +private _targetDirection = _projectilePos vectorFromTo _profileAdjustedTargetPos; +private _projectileDirection = vectorNormalized velocity _projectile; + +private _deltaDirection = _targetDirection vectorDiff _projectileDirection; +_deltaDirection = _projectile vectorWorldToModelVisual _deltaDirection; +_deltaDirection = _deltaDirection vectorMultiply [_yawRate, 0, _pitchRate]; +_deltaDirection = _projectile vectorModelToWorldVisual _deltaDirection; + +private _iTimestep = 0; +if (_timestep != 0) then { + _iTimestep = 1 / _timestep; +}; +_deltaDirection vectorMultiply _iTimestep // return diff --git a/addons/missileguidance/functions/fnc_navigationType_line.sqf b/addons/missileguidance/functions/fnc_navigationType_line.sqf new file mode 100644 index 00000000000..c9a3870c58b --- /dev/null +++ b/addons/missileguidance/functions/fnc_navigationType_line.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Assumes targetDir is pointing toward line we want to stay on + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Commanded acceleration normal to LOS in world space + * + * Example: + * [] call ace_missileguidance_fnc_navigationType_line + * + * Public: No + */ +params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos", "_targetData", "_navigationParams"]; +_args params ["", "", "_flightParams"]; +_targetData params ["", "_targetDir", "_distance"]; +_flightParams params ["_pitchRate", "_yawRate"]; + +_navigationParams params ["_proportionalGain", "", "_derivativeGain", "_lastErrorX", "_lastErrorY", "_correctionDistance"]; +private _relativeTargetDirection = [0, (velocityModelSpace _projectile) select 1, 0] vectorAdd (_projectile vectorWorldToModelVisual (_targetDir vectorMultiply _distance)); + +private _angleX = ((_relativeTargetDirection select 0) atan2 (_relativeTargetDirection select 1)); +private _angleY = ((_relativeTargetDirection select 2) atan2 (_relativeTargetDirection select 1)); + +private _pX = _proportionalGain * _angleX; +private _dX = 0; +if (_timestep > 0) then { + _dX = _derivativeGain * (_angleX - _lastErrorX) / _timestep; +}; + +private _pY = _proportionalGain * _angleY; +private _dY = 0; +if (_timestep > 0) then { + _dY = _derivativeGain * (_angleY - _lastErrorY) / _timestep; +}; + +private _accelerationX = _pX + _dX; +private _accelerationY = _pY + _dY; + +private _commandedAcceleration = [ + _accelerationX, + 0, + _accelerationY +]; + +_navigationParams set [3, _angleX]; +_navigationParams set [4, _angleY]; + +_projectile vectorModelToWorldVisual _commandedAcceleration; diff --git a/addons/missileguidance/functions/fnc_navigationType_lineOfSight.sqf b/addons/missileguidance/functions/fnc_navigationType_lineOfSight.sqf new file mode 100644 index 00000000000..5056d837228 --- /dev/null +++ b/addons/missileguidance/functions/fnc_navigationType_lineOfSight.sqf @@ -0,0 +1,48 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Accelerates toward LOS + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Commanded acceleration normal to LOS in world space + * + * Example: + * [] call ace_missileguidance_fnc_navigationType_lineOfSight + * + * Public: No + */ +params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos"]; +_args params ["_firedEH", "", "", "", "_stateParams", "_targetData"]; +_firedEH params ["","","","","","","_projectile"]; +_stateParams params ["", "", "", "","_navigationParams"]; +_navigationParams params ["_onLaunch"]; +_onLaunch params ["_lastLineOfSight"]; +_targetData params ["_targetDirection", "_attackProfileDirection", "", "_targetVelocity", ""]; + +// Semi-proportional navigation implemented via "Fundamentals of proportional navigation" by Stephen Murtaugh and Harry Criel + +// the los rate is tiny, so we multiply by a constant of a power of ten to get more aggressive acceleration +// this is just due to how we measure our LOS delta, the vectors involved are _tiny_ +private _losDelta = _attackProfileDirection vectorDiff _lastLineOfSight; +private _losRate = if (_timestep == 0) then { + 0 +} else { + 10 * (vectorMagnitude _losDelta) / _timestep; +}; + +private _closingVelocity = _targetVelocity vectorDiff (velocity _projectile); + +private _commandedAcceleration = _closingVelocity vectorMultiply _losRate; + +// we need acceleration normal to our LOS +private _commandedAccelerationProjected = _attackProfileDirection vectorMultiply (_commandedAcceleration vectorDotProduct _attackProfileDirection); +_commandedAcceleration = _commandedAcceleration vectorDiff _commandedAccelerationProjected; + +if (accTime > 0) then { + _navigationParams set [0, [_attackProfileDirection]]; +}; + +_targetDirection diff --git a/addons/missileguidance/functions/fnc_navigationType_proNav.sqf b/addons/missileguidance/functions/fnc_navigationType_proNav.sqf new file mode 100644 index 00000000000..45052689b05 --- /dev/null +++ b/addons/missileguidance/functions/fnc_navigationType_proNav.sqf @@ -0,0 +1,46 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Determine path for projectile to take in accordance to proportional navigation + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Commanded acceleration normal to LOS in world space + * + * Example: + * [] call ace_missileguidance_fnc_navigationType_proNav + * + * Public: No + */ +params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos"]; +_args params ["_firedEH", "", "", "", "_stateParams", "_targetData"]; +_firedEH params ["","","","","","","_projectile"]; +_stateParams params ["", "", "", "","_navigationParams"]; +_navigationParams params ["_lastMissileFrame", "_navigationGain"]; +_lastMissileFrame params ["_lastLineOfSight"]; +_targetData params ["_targetDirection", "_attackProfileDirection", "", "_targetVelocity", ""]; + +// Proportional navigation implemented via "Fundamentals of proportional navigation" by Stephen Murtaugh and Harry Criel +private _closingVelocity = _targetVelocity vectorDiff velocity _projectile; + +private _losDelta = (vectorNormalized _attackProfileDirection) vectorDiff (vectorNormalized _lastLineOfSight); +private _losRate = if (_timestep == 0) then { + 0 +} else { + 1 * (vectorMagnitude _losDelta) / _timestep; +}; + +private _lateralAcceleration = _navigationGain * _losRate; +private _commandedAcceleration = _closingVelocity vectorMultiply _lateralAcceleration; + +// we need acceleration normal to our LOS +private _commandedAccelerationProjected = _attackProfileDirection vectorMultiply (_commandedAcceleration vectorDotProduct _attackProfileDirection); +_commandedAcceleration = _commandedAcceleration vectorDiff _commandedAccelerationProjected; + +if (accTime > 0) then { + _navigationParams set [0, [_seekerTargetPos, _targetVelocity, _attackProfileDirection]]; +}; + +_commandedAcceleration vectorMultiply _timestep diff --git a/addons/missileguidance/functions/fnc_navigationType_zeroEffortMiss.sqf b/addons/missileguidance/functions/fnc_navigationType_zeroEffortMiss.sqf new file mode 100644 index 00000000000..293bede8bf2 --- /dev/null +++ b/addons/missileguidance/functions/fnc_navigationType_zeroEffortMiss.sqf @@ -0,0 +1,38 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Determine path for projectile to take in accordance to zero-effort miss pro-nav, takes target acceleration into account. Super deadly + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Commanded acceleration normal to LOS in world space + * + * Example: + * [] call ace_missileguidance_fnc_navigationType_zeroEffortMiss + * + * Public: No + */ +params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos"]; +_args params ["_firedEH", "", "", "", "_stateParams", "_targetData"]; +_firedEH params ["","","","","","","_projectile"]; +_stateParams params ["", "", "", "","_navigationParams"]; +_navigationParams params ["", "_navigationGain"]; +_targetData params ["_targetDirection", "_attackProfileDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"]; + +private _vectorToTarget = _attackProfileDirection vectorMultiply _targetRange; +private _closingVelocity = _targetVelocity vectorDiff velocity _projectile; +private _timeToGo = _targetRange / vectorMagnitude _closingVelocity; + +if (_timeToGo == 0) then { + _timeToGo = 0.001; +}; + +private _zeroEffortMiss = _vectorToTarget vectorAdd (_closingVelocity vectorMultiply _timeToGo); +private _zeroEffortMissProjectiled = _attackProfileDirection vectorMultiply (_zeroEffortMiss vectorDotProduct _attackProfileDirection); +private _zeroEffortMissNormal = _zeroEffortMiss vectorDiff _zeroEffortMissProjectiled; + +private _commandedAcceleration = _zeroEffortMissNormal vectorMultiply (_navigationGain / (_timeToGo * _timeToGo)); + +_commandedAcceleration diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index 1f3519f8c9c..9cc91f300a9 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -19,9 +19,6 @@ params ["_shooter","_weapon","","_mode","_ammo","","_projectile"]; -// Bail on not missile -if (!(_ammo isKindOf "MissileBase")) exitWith {}; - // Bail if guidance is disabled for this ammo if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "enabled")) != 1) exitWith {}; @@ -44,6 +41,7 @@ private _target = _shooter getVariable [QGVAR(target), nil]; private _targetPos = _shooter getVariable [QGVAR(targetPosition), nil]; private _seekerType = _shooter getVariable [QGVAR(seekerType), nil]; private _attackProfile = _shooter getVariable [QGVAR(attackProfile), nil]; +private _navigationType = _shooter getVariable [QGVAR(navigationType), nil]; if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "useModeForAttackProfile")) == 1) then { _attackProfile = getText (configFile >> "CfgWeapons" >> _weapon >> _mode >> QGVAR(attackProfile)) }; @@ -52,7 +50,7 @@ private _lockMode = _shooter getVariable [QGVAR(lockMode), nil]; private _laserCode = _shooter getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; private _laserInfo = [_laserCode, ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_WAVELENGTH]; -TRACE_6("getVars",_target,_targetPos,_seekerType,_attackProfile,_lockMode,_laserCode); +TRACE_7("getVars",_target,_targetPos,_seekerType,_attackProfile,_lockMode,_laserCode,_navigationType); private _launchPos = getPosASL (vehicle _shooter); @@ -65,6 +63,14 @@ if (isNil "_attackProfile" || {!(_attackProfile in (getArray (_config >> "attack if (isNil "_lockMode" || {!(_lockMode in (getArray (_config >> "seekerLockModes")))}) then { _lockMode = getText (_config >> "defaultSeekerLockMode"); }; +if (isNil "_navigationType" || {!(_navigationType in (getArray (_config >> "navigationTypes")))}) then { + _navigationType = getText (_config >> "defaultNavigationType"); +}; + +if (isNil "_navigationType" || _navigationType isEqualTo "") then { + // most missiles use ProNav by default + _navigationType = "ProportionalNavigation"; +}; // If we didn't get a target, try to fall back on tab locking if (isNil "_target") then { @@ -76,7 +82,7 @@ if (isNil "_target") then { private _canUseLock = getNumber (_config >> "canVanillaLock"); // @TODO: Get vanilla target if (_canUseLock > 0 || difficulty < 1) then { - private _vanillaTarget = cursorTarget; + private _vanillaTarget = missileTarget _projectile; TRACE_1("Using Vanilla Locking",_vanillaTarget); if (!isNil "_vanillaTarget") then { @@ -85,6 +91,7 @@ if (isNil "_target") then { }; }; }; +_targetPos = getPosASLVisual _target; // Array for seek last target position private _seekLastTargetPos = (getNumber ( _config >> "seekLastTargetPos")) == 1; @@ -95,19 +102,66 @@ if (_seekLastTargetPos && {!isNil "_target"}) then { _lastKnownPosState set [1, [0,0,0]]; }; -TRACE_4("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile); +private _navigationParameters = [ + // set up in navigation type onFired function +]; + +// default config values to make sure there is backwards compat +private _pitchRate = 30; +private _yawRate = 30; +private _bangBang = false; +if (isNumber (_config >> "pitchRate")) then { + _pitchRate = getNumber ( _config >> "pitchRate" ); + _yawRate = getNumber ( _config >> "yawRate" ); + _bangBang = (1 == getNumber (_config >> "bangBangGuidance")); +}; + +// How much this projectile likes to stay toward current velocity +private _stabilityCoefficient = getNumber (_config >> "stabilityCoefficient"); + +// show a light trail in flight +private _showTrail = (1 == getNumber (_config >> "showTrail")); + +private _navigationStateSubclass = _config >> "navigationStates"; +private _states = getArray (_navigationStateSubclass >> "states"); + +private _navigationStateData = []; +private _initialState = ""; + +if (_states isNotEqualTo []) then { + _initialState = _states select 0; + { + private _stateClass = _navigationStateSubclass >> _x; + _navigationStateData pushBack [ + getText (_stateClass >> "transitionCondition"), + getText (_stateClass >> "navigationType"), + [] + ]; + } forEach _states; +}; + +private _initialRoll = getNumber (_config >> "initialRoll"); +private _initialYaw = getNumber (_config >> "initialYaw"); +private _initialPitch = getNumber (_config >> "initialPitch"); + +private _yawRollPitch = (vectorDir _projectile) call CBA_fnc_vect2Polar; + +TRACE_5("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile,_navigationType); private _args = [_this, [ _shooter, - [_target, _targetPos, _launchPos], + [_target, _targetPos, _launchPos, vectorDirVisual vehicle _shooter, CBA_missionTime], _seekerType, _attackProfile, _lockMode, - _laserInfo + _laserInfo, + _navigationType ], [ - getNumber ( _config >> "minDeflection" ), - getNumber ( _config >> "maxDeflection" ), - getNumber ( _config >> "incDeflection" ) + _pitchRate, + _yawRate, + _bangBang, + _stabilityCoefficient, + _showTrail ], [ getNumber ( _config >> "seekerAngle" ), @@ -115,37 +169,70 @@ private _args = [_this, getNumber ( _config >> "seekerMaxRange" ), getNumber ( _config >> "seekerMinRange" ) ], - [ diag_tickTime, [], [], _lastKnownPosState] + [ diag_tickTime, [], [], _lastKnownPosState, _navigationParameters, [_initialYaw + (_yawRollPitch select 1), _initialRoll, _initialPitch + (_yawRollPitch select 2)]], + [ + // target data from missile. Must be filled by seeker for navigation to work + [0, 0, 0], // direction to target + [0, 0, 0], // direction to attack profile + 0, // range to target + [0, 0, 0], // target velocity + [0, 0, 0] // target acceleration + ], + [0, _navigationStateData] ]; private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); -TRACE_1("",_onFiredFunc); +TRACE_1("seeker on fired",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; _onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); -TRACE_1("",_onFiredFunc); +TRACE_1("attack on fired",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; +if (_states isEqualTo []) then { + _onFiredFunc = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "onFired"); + TRACE_1("navigation on fired",_onFiredFunc); + if (_onFiredFunc != "") then { + private _navState = (_args call (missionNamespace getVariable _onFiredFunc)); + (_args select 4) set [4, _navState]; + }; +} else { + { + _onFiredFunc = getText (configFile >> QGVAR(NavigationTypes) >> _x >> "onFired"); + TRACE_1("navigation on fired",_onFiredFunc); + if (_onFiredFunc != "") then { + private _navState = (_args call (missionNamespace getVariable _onFiredFunc)); + (_navigationStateData select _forEachIndex) set [2, _navState]; + }; + } forEach getArray (_config >> "navigationTypes"); +}; + // Run the "onFired" function passing the full guidance args array _onFiredFunc = getText (_config >> "onFired"); -TRACE_1("",_onFiredFunc); +TRACE_1("general on fired",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; // Reverse: -// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; +// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateData"]; // _firedEH params ["_shooter","","","","_ammo","","_projectile"]; -// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo"]; -// _targetLaunchParams params ["_target", "_targetPos", "_launchPos"]; -// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; +// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; +// _targetLaunchParams params ["_target", "_targetPos", "_launchPos", "_launchDir", "_launchTime"]; +// _flightParams params ["_pitchRate", "_yawRate", "_isBangBangGuidance"]; +// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_navigationParams", "_guidanceParameters"]; // _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; +// _targetData params ["_targetDirection", "_attackProfileDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"]; + +[LINKFUNC(guidancePFH),0, _args ] call CBA_fnc_addPerFrameHandler; -[FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; +if (GVAR(debug_enableMissileCamera)) then { + [_projectile] call FUNC(dev_ProjectileCamera); +}; /* Clears locking settings diff --git a/addons/missileguidance/functions/fnc_proNav_onFired.sqf b/addons/missileguidance/functions/fnc_proNav_onFired.sqf new file mode 100644 index 00000000000..c297d3ce59a --- /dev/null +++ b/addons/missileguidance/functions/fnc_proNav_onFired.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Sets up proportional navigation state arrays (called from missileGuidance's onFired). + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * None + * + * Example: + * [] call ace_missileguidance_fnc_proNav_onFired + * + * Public: No + */ +params ["_firedEH", "", "", "", "_stateParams"]; +_firedEH params ["_shooter","","","","_ammo","","_projectile"]; +_launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; +_targetLaunchParams params ["_target", "_targetPos", "_launchPos"]; +_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; +_seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; + +private _ammoConfig = configOf _projectile; +private _navigationGain = getNumber (_ammoConfig >> QUOTE(ADDON) >> "navigationGain"); +if (_navigationGain == 0) then { + _navigationGain = 3; +}; + +private _navigationParams = [ + [ // Last Missile Frame + [0, 0, 0] // Last line of sight + ], + _navigationGain // navigation gain of missile. Set in the navigation onFired function +]; +_navigationParams diff --git a/addons/missileguidance/functions/fnc_seekerType_ARH.sqf b/addons/missileguidance/functions/fnc_seekerType_MWR.sqf similarity index 78% rename from addons/missileguidance/functions/fnc_seekerType_ARH.sqf rename to addons/missileguidance/functions/fnc_seekerType_MWR.sqf index 20571e3d658..1b7eef07ee7 100644 --- a/addons/missileguidance/functions/fnc_seekerType_ARH.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_MWR.sqf @@ -11,16 +11,16 @@ * Seeker Pos * * Example: - * [] call call ace_missileguidance_fnc_seekerType_ARH; + * [] call call ace_missileguidance_fnc_seekerType_MWR; * * Public: No */ -params ["", "_args", "_seekerStateParams"]; -_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams"]; +params ["", "_args", "_seekerStateParams", "", "_timestep"]; +_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams", "_targetData"]; _firedEH params ["_shooter","","","","","","_projectile"]; _launchParams params ["_target","","","",""]; _seekerParams params ["_seekerAngle", "", "_seekerMaxRange"]; -_seekerStateParams params ["_isActive", "_activeRadarEngageDistance", "_timeWhenActive", "_expectedTargetPos", "_lastTargetPollTime", "_shooterHasRadar", "_wasActive", "_lastKnownVelocity", "_lastTimeSeen", "_doesntHaveTarget"]; +_seekerStateParams params ["_isActive", "_activeRadarEngageDistance", "_timeWhenActive", "_expectedTargetPos", "_lastTargetPollTime", "_shooterHasRadar", "_wasActive", "_lastKnownVelocity", "_lastTimeSeen", "_doesntHaveTarget", "_lockTypes"]; if (_isActive || { CBA_missionTime >= _timeWhenActive }) then { if !(_isActive) then { @@ -60,8 +60,7 @@ if (_isActive || { CBA_missionTime >= _timeWhenActive }) then { _seekerBaseRadiusAdjusted = _seekerBaseRadiusAtGround; }; // Look in front of seeker for any targets - private _nearestObjects = nearestObjects [ASLtoAGL _searchPos, ["Air", "LandVehicle", "Ship"], _seekerBaseRadiusAdjusted, false]; - + private _nearestObjects = nearestObjects [ASLToAGL _searchPos, _lockTypes, _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 { @@ -72,14 +71,15 @@ if (_isActive || { CBA_missionTime >= _timeWhenActive }) then { }; _nearestObjects = _nearestObjects select { !isNull _x }; // Select closest object to the expected position to be the current radar target - if ((count _nearestObjects) <= 0) exitWith { + if (_nearestObjects isEqualTo []) exitWith { _projectile setMissileTarget objNull; + _seekerStateParams set [3, _searchPos]; _searchPos }; private _closestDistance = _seekerBaseRadiusAtGround; { - if ((_x distance2d _searchPos) < _closestDistance) then { - _closestDistance = _x distance2d _searchPos; + if ((_x distance2D _searchPos) < _closestDistance) then { + _closestDistance = _x distance2D _searchPos; _target = _x; }; } forEach _nearestObjects; @@ -89,9 +89,9 @@ if (_isActive || { CBA_missionTime >= _timeWhenActive }) then { _projectile setMissileTarget _target; } else { - #ifdef DRAW_GUIDANCE_INFO - _seekerTypeName = "AHR - EXT"; - #endif + if (GVAR(debug_drawGuidanceInfo)) then { + _seekerTypeName = "MWR - EXT"; + }; // 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; @@ -104,17 +104,30 @@ if (_isActive || { CBA_missionTime >= _timeWhenActive }) then { }; }; +if (GVAR(debug_drawGuidanceInfo)) then { + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLToAGL _expectedTargetPos, 0.75, 0.75, 0, "expected target pos", 1, 0.025, "TahomaB"]; +}; + if !(isNull _target) then { private _centerOfObject = getCenterOfMass _target; - private _targetAdjustedPos = _target modelToWorldWorld _centerOfObject; + private _targetAdjustedPos = _target modelToWorldVisualWorld _centerOfObject; _expectedTargetPos = _targetAdjustedPos; - _seekerStateParams set [3, _expectedTargetPos]; _seekerStateParams set [7, velocity _target]; _seekerStateParams set [8, CBA_missionTime]; _seekerStateParams set [9, false]; + + _targetData set [2, _projectile distance _target]; + _targetData set [3, velocity _target]; + + if (_timestep != 0) then { + private _acceleration = ((velocity _target) vectorDiff _lastKnownVelocity) vectorMultiply (1 / _timestep); + _targetData set [4, _acceleration]; + }; }; +_targetData set [0, (getPosASLVisual _projectile) vectorFromTo _expectedTargetPos]; + +_seekerStateParams set [3, _expectedTargetPos]; _launchParams set [0, _target]; _expectedTargetPos - diff --git a/addons/missileguidance/functions/fnc_seekerType_Optic.sqf b/addons/missileguidance/functions/fnc_seekerType_Optic.sqf index bac01d05b4d..0507bc2c11d 100644 --- a/addons/missileguidance/functions/fnc_seekerType_Optic.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_Optic.sqf @@ -17,7 +17,7 @@ */ params ["", "_args"]; -_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams"]; +_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams", "_targetData"]; _firedEH params ["","","","","","","_projectile"]; _launchParams params ["", "_targetParams"]; _targetParams params ["_target"]; @@ -25,7 +25,7 @@ _seekerParams params ["_seekerAngle", "", "_seekerMaxRange"]; if (isNil "_target") exitWith {[0,0,0]}; -private _foundTargetPos = aimPos _target; +private _foundTargetPos = _target modelToWorldVisualWorld getCenterOfMass _target; // @TODO: This is seeker LOS and angle checks for LOAL only; LOBL does not need visual private _angleOkay = [_projectile, _foundTargetPos, _seekerAngle] call FUNC(checkSeekerAngle); @@ -40,14 +40,11 @@ TRACE_2("",_angleOkay,_losOkay); if (!_angleOkay || !_losOkay) exitWith {[0,0,0]}; TRACE_2("",_target,_foundTargetPos); -// @TODO: Configurable lead for seekers -private _projectileSpeed = (vectorMagnitude velocity _projectile); private _distanceToTarget = (getPosASL _projectile) vectorDistance _foundTargetPos; -private _eta = _distanceToTarget / _projectileSpeed; -private _adjustDistance = (velocity _target) vectorMultiply _eta; -TRACE_3("leading target",_distanceToTarget,_eta,_adjustDistance); -_foundTargetPos = _foundTargetPos vectorAdd _adjustDistance; +_targetData set [0, (getPosASL _projectile) vectorFromTo _foundTargetPos]; +_targetData set [2, _distanceToTarget]; +_targetData set [3, velocity _target]; TRACE_2("return",_foundTargetPos,(aimPos _target) distance _foundTargetPos); _foundTargetPos; diff --git a/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf b/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf index da9549c3ae5..d9fd444043f 100644 --- a/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf @@ -16,16 +16,19 @@ * Public: No */ params ["", "_args"]; -_args params ["_firedEH", "", "", "_seekerParams", "_stateParams"]; +_args params ["_firedEH", "", "", "_seekerParams", "_stateParams", "_targetData"]; _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 _shooterPos = AGLToASL (_shooter modelToWorldVisual (_shooter selectionPosition _memoryPointGunnerOptics)); private _projPos = getPosASL _projectile; -private _lookDirection = if !(_shooter isKindOf "CAManBase" || {_shooter isKindOf "StaticWeapon"}) then { +private _lookDirection = if (_shooter isKindOf "CAManBase" || {_shooter isKindOf "StaticWeapon"}) then { + _shooterPos = eyePos _shooter; + _shooter weaponDirection _weapon +} else { private _finalLookDirection = if (_usePilotCamera) then { _shooterPos = _shooter modelToWorldVisualWorld getPilotCameraPosition _shooter; private _trackingTarget = getPilotCameraTarget _shooter; @@ -37,14 +40,12 @@ private _lookDirection = if !(_shooter isKindOf "CAManBase" || {_shooter isKindO _shooter vectorModelToWorldVisual getPilotCameraDirection _shooter; }; } else { - private _gBody = -deg(_shooter animationPhase _animationSourceBody); - private _gGun = deg(_shooter animationPhase _animationSourceGun); + // use animationSourcePhase + private _gBody = -deg(_shooter animationSourcePhase _animationSourceBody); + private _gGun = deg(_shooter animationSourcePhase _animationSourceGun); _shooter vectorModelToWorldVisual ([1, _gBody, _gGun] call CBA_fnc_polar2vect); }; _finalLookDirection -} else { - _shooterPos = eyePos _shooter; - _shooter weaponDirection _weapon }; private _distanceToProj = _shooterPos vectorDistance _projPos; @@ -58,5 +59,9 @@ if ((_testDotProduct < (cos _seekerAngle)) || {_testIntersections isNotEqualTo [ [0, 0, 0] }; -_shooterPos vectorAdd (_lookDirection vectorMultiply _distanceToProj); +private _returnPos = _shooterPos vectorAdd (_lookDirection vectorMultiply _distanceToProj); + +_targetData set [0, _projPos vectorFromTo _returnPos]; +_targetData set [2, _returnPos vectorDistance getPosASLVisual _projectile]; +_returnPos diff --git a/addons/missileguidance/functions/fnc_seekerType_SALH.sqf b/addons/missileguidance/functions/fnc_seekerType_SALH.sqf index a16c58ce5fa..8772d73178f 100644 --- a/addons/missileguidance/functions/fnc_seekerType_SALH.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_SALH.sqf @@ -16,17 +16,58 @@ * * Public: No */ +#define MAX_AVERAGES 15 +#define MINIMUM_DISTANCE_UNTIL_NEW_POS 1 -params ["", "_args"]; -_args params ["_firedEH", "_launchParams", "", "_seekerParams"]; +params ["", "_args", "", "", "_timestep"]; +_args params ["_firedEH", "_launchParams", "", "_seekerParams", "", "_targetData"]; _firedEH params ["","","","","","","_projectile"]; _launchParams params ["","","","","","_laserParams"]; -_seekerParams params ["_seekerAngle", "", "_seekerMaxRange"]; +_seekerParams params ["_seekerAngle", "", "_seekerMaxRange", "", ["_lastPositions", []], ["_lastPositionIndex", 0], ["_lastPositionSum", [0, 0, 0]]]; _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); -_foundTargetPos; +if (isNil "_foundTargetPos") exitWith { + [0, 0, 0] +}; + +// average out any error from laser jump +private _positionSum = [0, 0, 0]; +{ + _positionSum = _positionSum vectorAdd _x; +} forEach _lastPositions; + +if (_foundTargetPos isNotEqualTo [0, 0, 0]) then { + _lastPositions set [_lastPositionIndex % MAX_AVERAGES, _foundTargetPos]; + _seekerParams set [4, _lastPositions]; + _seekerParams set [5, _lastPositionIndex + 1]; +}; + +private _aproximateVelocity = [0, 0, 0]; +_positionSum = _positionSum vectorAdd _foundTargetPos; +if (MAX_AVERAGES == count _lastPositions) then { + _positionSum = _positionSum vectorMultiply (1 / (1 + count _lastPositions)); + + // if we are within a meter of the previous average, just use the previous average + if (_positionSum distanceSqr _lastPositionSum < MINIMUM_DISTANCE_UNTIL_NEW_POS * MINIMUM_DISTANCE_UNTIL_NEW_POS) then { + _positionSum = _lastPositionSum; + }; + + if (_timestep != 0) then { + _aproximateVelocity = (_positionSum vectorDiff _lastPositionSum) vectorMultiply (1 / _timestep); + }; +} else { + _positionSum = _positionSum vectorMultiply (1 / count _lastPositions); +}; + +_seekerParams set [6, _positionSum]; + +_targetData set [0, (getPosASL _projectile) vectorFromTo _positionSum]; +_targetData set [3, _aproximateVelocity]; + +TRACE_3("laser target found",_foundTargetPos,_positionSum,count _lastPositions); + +_positionSum diff --git a/addons/missileguidance/functions/fnc_wire_onFired.sqf b/addons/missileguidance/functions/fnc_wire_onFired.sqf index 0cfa90ff99e..870754c5091 100644 --- a/addons/missileguidance/functions/fnc_wire_onFired.sqf +++ b/addons/missileguidance/functions/fnc_wire_onFired.sqf @@ -45,4 +45,3 @@ _attackProfileStateParams set [4, _maxDistanceSqr]; // max distance squared used _attackProfileStateParams set [5, _minDistanceSqr]; _attackProfileStateParams set [6, _wireCutSource]; _attackProfileStateParams set [7, _distanceAheadOfMissile]; - diff --git a/addons/missileguidance/script_component.hpp b/addons/missileguidance/script_component.hpp index 2b43be42f3c..47f0e83e034 100644 --- a/addons/missileguidance/script_component.hpp +++ b/addons/missileguidance/script_component.hpp @@ -3,6 +3,7 @@ #include "\z\ace\addons\main\script_mod.hpp" // #define DRAW_GUIDANCE_INFO +// #define ENABLE_PROJECTILE_CAMERA // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS @@ -28,4 +29,3 @@ #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 aacdd472d69..6b758810831 100644 --- a/addons/missileguidance/stringtable.xml +++ b/addons/missileguidance/stringtable.xml @@ -12,7 +12,7 @@ Orientação avançada de Míssil Fejlett rakétairányító Продвинутое наведение ракет - アドバンスドミサイル誘導 + 高度なミサイル誘導 고급 미사일 유도 进阶导弹制导 進階飛彈制導 @@ -29,7 +29,7 @@ A fejlett rakétairányító (vagy AMG) többféle módosítást tartalmaz a rakéták célkövetéséhez és tüzeléséhez. Ez egy szükséges keresztrendszer a rakéta-alapú fegyverekhez. Orientação avançada de mísseis ou OAM, fornece vários aprimoramentos para travamento de mísseis e disparos. Também é um sistema requerido para disparar armas que utilizem mísseis. Pokočilé navádění raket (AMG) poskytuje několik vylepšení pro lepší zaměření a následnou střelbu. Je to prvek vyžadovaný u typu zbraní jako jsou rakety. - アドバンスドミサイル誘導 (AMG) は、ミサイルの捕捉と発射に複数の機能強化を提供します。 これは、ミサイル兵器の種類に必要なフレームワークでもあります。 + 高度なミサイル誘導 (AMG) は、ミサイルの捕捉と発射に複数の機能強化を提供します。 これは、ミサイル兵器の種類に必要なフレームワークでもあります。 고급 미사일 유도 혹은 AMG는 표적 획득 및 발사를 위한 여러 기능을 제공합니다. 미사일 종류에 따라 체계가 필요합니다. 进阶导弹制导增强了多种导弹锁定和射击的能力。此系统适用于所有导弹类型的武器。 進階飛彈制導增強了多種導彈鎖定和射擊的能力。此系統適用於所有飛彈類型的武器 @@ -205,5 +205,32 @@ 循環切換開火模式 Ateşleme Modunu Değiştir + + 6x DAGR [ACE] + 6x DAGR [ACE] + 6x DAGR [ACE] + 6x DAGR [ACE] + 6x DAGR [ACE] + 6x DAGR [ACE] + 6x DAGR [ACE] + + + 12x DAGR [ACE] + 12x DAGR [ACE] + 12x DAGR [ACE] + 12x DAGR [ACE] + 12x DAGR [ACE] + 12x DAGR [ACE] + 12x DAGR [ACE] + + + 24x DAGR [ACE] + 24x DAGR [ACE] + 24x DAGR [ACE] + 24x DAGR [ACE] + 24x DAGR [ACE] + 24x DAGR [ACE] + 24x DAGR [ACE] + diff --git a/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf b/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf index 63465a65884..86a14a8c8d0 100644 --- a/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf +++ b/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf @@ -48,18 +48,16 @@ private _missionRoot = str missionConfigFile select [0, count str missionConfigF }; } else { if (isClass (configFile >> "CfgSounds" >> _x)) then { - _soundPath = (getArray(configFile >> "CfgSounds" >> _x >> "sound")) param [0, ""]; + private _soundPath = (getArray(configFile >> "CfgSounds" >> _x >> "sound")) param [0, ""]; if ((_soundPath select [0, 1]) == "\") then {_soundPath = _soundPath select [1];}; _ambianceSounds pushBack _soundPath; } else { 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,14 +80,14 @@ 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. private _targetUnit = selectRandom _allUnits; - AGLtoASL (_targetUnit getPos [_minimalDistance + random (_maximalDistance - _minimalDistance), random 360]); + AGLToASL (_targetUnit getPos [_minimalDistance + random (_maximalDistance - _minimalDistance), random 360]); } else { - AGLtoASL (_logic getPos [_minimalDistance + random (_maximalDistance - _minimalDistance), random 360]); + AGLToASL (_logic getPos [_minimalDistance + random (_maximalDistance - _minimalDistance), random 360]); }; TRACE_1("",_newPosASL); diff --git a/addons/mk6mortar/CfgMagazines.hpp b/addons/mk6mortar/CfgMagazines.hpp index 0d5c1d57038..e0626479c4a 100644 --- a/addons/mk6mortar/CfgMagazines.hpp +++ b/addons/mk6mortar/CfgMagazines.hpp @@ -1,10 +1,11 @@ -class cfgMagazines { +class CfgMagazines { class 8Rnd_82mm_Mo_shells; class ACE_1Rnd_82mm_Mo_HE: 8Rnd_82mm_Mo_shells { count = 1; scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_HE_displayName); displayNameShort = ""; @@ -19,6 +20,7 @@ class cfgMagazines { scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_Smoke_displayName); displayNameShort = ""; @@ -33,6 +35,7 @@ class cfgMagazines { scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_Illum_displayName); displayNameShort = ""; @@ -47,6 +50,7 @@ class cfgMagazines { scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_HE_Guided_displayName); displayNameShort = ""; @@ -61,6 +65,7 @@ class cfgMagazines { scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_HE_LaserGuided_displayName); displayNameShort = ""; diff --git a/addons/mk6mortar/XEH_postInit.sqf b/addons/mk6mortar/XEH_postInit.sqf index 9f24a12a3b2..280e16cf799 100644 --- a/addons/mk6mortar/XEH_postInit.sqf +++ b/addons/mk6mortar/XEH_postInit.sqf @@ -1,16 +1,17 @@ #include "script_component.hpp" if (hasInterface) then { - ["ace_infoDisplayChanged", FUNC(turretDisplayLoaded)] call CBA_fnc_addEventHandler; + #include "initKeybinds.inc.sqf" + ["ace_infoDisplayChanged", LINKFUNC(turretDisplayLoaded)] call CBA_fnc_addEventHandler; }; ["CBA_settingsInitialized", { TRACE_4("CBA_settingsInitialized",GVAR(airResistanceEnabled),GVAR(allowComputerRangefinder),GVAR(allowCompass),GVAR(useAmmoHandling)); - ["vehicle", FUNC(handlePlayerVehicleChanged), true] call CBA_fnc_addPlayerEventHandler; + ["vehicle", LINKFUNC(handlePlayerVehicleChanged), true] call CBA_fnc_addPlayerEventHandler; if (!GVAR(airResistanceEnabled)) exitWith {}; if (EGVAR(artillerytables,advancedCorrections)) exitWith { TRACE_1("defer firedEH to artillerytables",_this); }; - ["Mortar_01_base_F", "fired", {call FUNC(handleFired)}] call CBA_fnc_addClassEventHandler; + ["Mortar_01_base_F", "fired", LINKFUNC(handleFired)] call CBA_fnc_addClassEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/mk6mortar/functions/fnc_handleFired.sqf b/addons/mk6mortar/functions/fnc_handleFired.sqf index c09c96f7773..8ea2984b794 100644 --- a/addons/mk6mortar/functions/fnc_handleFired.sqf +++ b/addons/mk6mortar/functions/fnc_handleFired.sqf @@ -24,11 +24,11 @@ params ["_vehicle", "", "", "", "", "", "_projectile"]; // Large enough distance to not simulate any wind deflection -if (_vehicle distance ACE_player > 8000) exitWith {false}; +if (_vehicle distance ACE_player > 8000) exitWith {}; //AI will have no clue how to use: private _shooterMan = gunner _vehicle; -if (!([_shooterMan] call EFUNC(common,isPlayer))) exitWith {false}; +if !([_shooterMan] call EFUNC(common,isPlayer)) exitWith {}; //Calculate air density: private _altitude = (getPosASL _vehicle) select 2; diff --git a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf index 216bab43bc8..c3dcc2cfe49 100644 --- a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf +++ b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Handles player getting into new vehicle. Loads PFEG for mortar display if it is a mortar. + * Handles player getting into new vehicle. Loads PFEG for mortar display if it is a mortar. * * Arguments: * 0: Player @@ -11,7 +11,7 @@ * None * * Example: - * [bob, mortar] call ace_mk6mortar_fnc_handlePlayerVehicleChanged; + * [player, cursorObject] call ace_mk6mortar_fnc_handlePlayerVehicleChanged * * Public: No */ @@ -19,88 +19,83 @@ params ["_player", "_newVehicle"]; if (isNull _newVehicle) exitWith {}; -if (!(_newVehicle isKindOf "Mortar_01_base_F")) exitWith {}; +if !(_newVehicle isKindOf "Mortar_01_base_F") exitWith {}; private _tubeWeaponName = (weapons _newVehicle) select 0; private _fireModes = getArray (configFile >> "CfgWeapons" >> _tubeWeaponName >> "modes"); -//Restore last firemode: -private _lastFireMode = _newVehicle getVariable [QGVAR(lastFireMode), -1]; -if (_lastFireMode != -1) then { - _player action ["SwitchWeapon", _newVehicle, _player, _lastFireMode]; +// Restore last firemode +private _lastSavedWeaponsInfo = _newVehicle getVariable QGVAR(lastFireMode); + +if (!isNil "_lastSavedWeaponsInfo") then { + _newVehicle selectWeaponTurret [_lastSavedWeaponsInfo select 0, [0], _lastSavedWeaponsInfo select 1, _lastSavedWeaponsInfo select 2]; }; [{ - params ["_args", "_pfID"]; - _args params ["_mortarVeh", "_fireModes"]; + params ["_mortarVeh", "_pfhID"]; - if ((vehicle ACE_player) != _mortarVeh) then { - [_pfID] call CBA_fnc_removePerFrameHandler; - } else { + if ((vehicle ACE_player) != _mortarVeh) exitWith { + _pfhID call CBA_fnc_removePerFrameHandler; + }; - private _useMils = _mortarVeh getVariable [QGVAR(useMils), true]; + // Save firemode ('charge' from weaponstate) on vehicle + _mortarVeh setVariable [QGVAR(lastFireMode), (weaponState [_mortarVeh, [0]]) select [0, 3]]; - //Compute: 'charge' from weaponstate - private _currentFireMode = (weaponState [_mortarVeh, [0]]) select 2; - private _currentChargeMode = _fireModes find _currentFireMode; + if (shownArtilleryComputer && {!GVAR(allowComputerRangefinder)}) then { + // Don't like this solution, but it works + closeDialog 0; + [parseText "Computer Disabled"] call EFUNC(common,displayTextStructured); + }; - //Save firemode on vehicle: - _mortarVeh setVariable [QGVAR(lastFireMode), _currentChargeMode]; + private _display = uiNamespace getVariable ["ACE_Mk6_RscWeaponRangeArtillery", displayNull]; - if (shownArtilleryComputer && {!GVAR(allowComputerRangefinder)}) then { - //Don't like this solution, but it works - closeDialog 0; - [parseText "Computer Disabled"] call EFUNC(common,displayTextStructured); - }; + if (isNull _display) exitWith {}; // It may be null for the first frame - private _display = uiNamespace getVariable ["ACE_Mk6_RscWeaponRangeArtillery", displayNull]; - if (isNull _display) exitWith {}; //It may be null for the first frame + // Hud should hidden in 3rd person + private _notGunnerView = cameraView != "GUNNER"; + private _useMils = _mortarVeh getVariable [QGVAR(useMils), true]; - //Hud should hidden in 3rd person - private _notGunnerView = cameraView != "GUNNER"; + // Get aiming values from ace_artillerytables + // Note: it also handles displaying the "charge" level + private _realAzimuth = missionNamespace getVariable [QEGVAR(artillerytables,predictedAzimuth), -1]; + private _realElevation = missionNamespace getVariable [QEGVAR(artillerytables,predictedElevation), -1]; - // Get aiming values from ace_artillerytables - // Note: it also handles displaying the "charge" level - private _realAzimuth = missionNamespace getVariable [QEGVAR(artillerytables,predictedAzimuth), -1]; - private _realElevation = missionNamespace getVariable [QEGVAR(artillerytables,predictedElevation), -1]; - - //Update Heading Display: - if (_notGunnerView || (!GVAR(allowCompass))) then { - (_display displayCtrl 80156) ctrlSetText ""; + // Update Heading Display + if (_notGunnerView || !GVAR(allowCompass)) then { + (_display displayCtrl 80156) ctrlSetText ""; + } else { + if (_useMils) then { + (_display displayCtrl 80156) ctrlSetText str (((round (_realAzimuth * 6400 / 360)) + 6400) % 6400); } else { - if (_useMils) then { - (_display displayCtrl 80156) ctrlSetText str (((round (_realAzimuth * 6400 / 360)) + 6400) % 6400); - } else { - (_display displayCtrl 80156) ctrlSetText str ((round (_realAzimuth + 360)) % 360); - }; + (_display displayCtrl 80156) ctrlSetText str ((round (_realAzimuth + 360)) % 360); }; + }; - //Update CurrentElevation Display - if (_notGunnerView) then { - (_display displayCtrl 80175) ctrlSetText ""; + // Update CurrentElevation Display + if (_notGunnerView) then { + (_display displayCtrl 80175) ctrlSetText ""; + } else { + if (_useMils) then { + (_display displayCtrl 80175) ctrlSetText str ((round (_realElevation * 6400 / 360)) % 6400); } else { - if (_useMils) then { - (_display displayCtrl 80175) ctrlSetText str ((round (_realElevation * 6400 / 360)) % 6400); - } else { - (_display displayCtrl 80175) ctrlSetText str (((round (_realElevation * 100)) / 100) % 360); - }; + (_display displayCtrl 80175) ctrlSetText str (((round (_realElevation * 100)) / 100) % 360); }; + }; - //Update ElevationNeeded Display: - if (_notGunnerView || (!GVAR(allowComputerRangefinder))) then { - (_display displayCtrl 80176) ctrlSetText ""; + // Update ElevationNeeded Display + if (_notGunnerView || !GVAR(allowComputerRangefinder)) then { + (_display displayCtrl 80176) ctrlSetText ""; + } else { + private _elevDeg = parseNumber ctrlText (_display displayCtrl 176); + if (_elevDeg <= 0) then { // Bad data means "----" out of range + (_display displayCtrl 80176) ctrlSetText (ctrlText (_display displayCtrl 176)); } else { - private _elevDeg = parseNumber ctrlText (_display displayCtrl 176); - if (_elevDeg <= 0) then { //Bad data means "----" out of range - (_display displayCtrl 80176) ctrlSetText (ctrlText (_display displayCtrl 176)); + _elevDeg = _elevDeg + (_realElevation - (parseNumber ctrlText (_display displayCtrl 175))); + if (_useMils) then { + (_display displayCtrl 80176) ctrlSetText str round ((round (_elevDeg * 6400 / 360)) % 6400); } else { - _elevDeg = _elevDeg + (_realElevation - (parseNumber ctrlText (_display displayCtrl 175))); - if (_useMils) then { - (_display displayCtrl 80176) ctrlSetText str round ((round (_elevDeg * 6400 / 360)) % 6400); - } else { - (_display displayCtrl 80176) ctrlSetText str (((round (_elevDeg * 100)) / 100) % 360); - }; + (_display displayCtrl 80176) ctrlSetText str (((round (_elevDeg * 100)) / 100) % 360); }; }; }; -}, 0, [_newVehicle, _fireModes]] call CBA_fnc_addPerFrameHandler; +}, 0, _newVehicle] call CBA_fnc_addPerFrameHandler; diff --git a/addons/mk6mortar/initKeybinds.inc.sqf b/addons/mk6mortar/initKeybinds.inc.sqf new file mode 100644 index 00000000000..0e3a53c1d95 --- /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 index fc900295626..15047dee296 100644 --- a/addons/mk6mortar/initSettings.inc.sqf +++ b/addons/mk6mortar/initSettings.inc.sqf @@ -3,41 +3,41 @@ private _category = [format ["ACE %1", localize "str_a3_cfgmarkers_nato_art"], localize LSTRING(DisplayName)]; [ - QGVAR(airResistanceEnabled), "CHECKBOX", + QGVAR(airResistanceEnabled), + "CHECKBOX", [LSTRING(airResistanceEnabled_DisplayName), LSTRING(airResistanceEnabled_Description)], _category, false, // default value - true, // isGlobal + 1, // isGlobal {[QGVAR(airResistanceEnabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, true // Needs mission restart ] call CBA_fnc_addSetting; [ - QGVAR(allowComputerRangefinder), "CHECKBOX", + 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 + 1 // isGlobal ] call CBA_fnc_addSetting; [ - QGVAR(allowCompass), "CHECKBOX", + 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 + 1 // isGlobal ] call CBA_fnc_addSetting; [ - QGVAR(useAmmoHandling), "CHECKBOX", + QGVAR(useAmmoHandling), + "CHECKBOX", [LSTRING(useAmmoHandling_DisplayName), LSTRING(useAmmoHandling_Description)], _category, false, // default value - true, // isGlobal + 1, // 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 a0d8612aa58..186cd926849 100644 --- a/addons/mk6mortar/stringtable.xml +++ b/addons/mk6mortar/stringtable.xml @@ -46,7 +46,7 @@ Abrir tabela de distâncias para 82mm Otevřít 82mm Rangetable Apri la tavola di tiro 82mm - 82mm用射表を開く + 82mm用 射表 を開く 82mm 사거리표 열기 开启82 mm 迫击炮射表 開啟82毫米迫擊炮射表 @@ -120,10 +120,10 @@ Hava Direnci - For Player Shots, Model Air Resistance and Wind Effects + Simulates air resistance and wind effects for player shots. 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, modelo de resistencia al aire y efectos de viento - Für Spielerschüsse, Luftwiderstand und Windeffekte + Simuliert Luftwiderstand und Windeffekte für Spielerschüsse. 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 des joueurs, simule la résistance de l'air et les effets du vent. @@ -163,7 +163,7 @@ 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) Показывает компьютер и дальномер (это НУЖНО отключить, если вы включаете сопротивление воздуха) Consenti l'utilizzo del Computer Balistico e del Telemetro (questi DEVONO essere disabilitati se vuoi abilitare la resistenza dell'aria) - 砲撃コンピュータと距離計を表示します (空気抵抗を仕様する場合は必ず無効化する必要があります) + 砲撃コンピュータと距離計を表示します (空気抵抗を有効化する場合はこれらを取り除く必要があります) 탄도계산컴퓨터와 거리측정기를 보여줍니다(공기저항을 활성화했을 경우 이 항목은 비활성화 되어야 합니다) 显示弹道计算机和测距仪(如果有启用空气阻力功能时,须停用此项功能) 顯示射控電腦和測距儀 (如果有啟用空氣阻力功能時,須停用此項功能) @@ -233,19 +233,19 @@ 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. - 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射擊的迫擊砲 - 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. + Removes mortar magazines, requiring individual rounds to be loaded by the gunner or loader. + Enfernt das Magzin des Mörsers. Es ist nun erforderlich, die einzelnen Patronen manuell zu laden. + Elimina los cargadores del mortero, requiriendo al artillero o cargador la carga manual de cada rondas. + Usuwa magazynki moździerza, wymagając ładowania pojedynczych pocisków przez strzelca lub ładowniczego. + Enlève les chargeurs de mortier, ce qui oblige le tireur ou le servant à charger les obus manuellement. + Rimuove i caricatori di colpi dal mortaio. Un operatore dovrà caricare proiettili singoli prima di poter fare fuoco. + Elimina os carregadores do morteiro, requerendo que o atirador ou carregador utilize de forma individual a munição. + Удаляет артиллерийские магазины, требует загрузку отдельных снарядов стрелком или заряжающим. + 迫撃砲から弾倉を除去します。一発ずつ射手か装填手によって装填される必要があります。 + 박격포 탄창을 제거합니다, 사수나 장전수가 개별적으로 탄환을 넣어줘야 합니다. + 开启此功能时。迫击炮的弹药需由炮手与装填手共同合作来进行装填 + 開啟此功能時。迫擊砲的彈藥需由砲手與裝填手共同合作來進行裝填 + 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. Remove Round @@ -257,7 +257,7 @@ Odstranit náboj Remover munição Извлечь снаряд - 弾薬を除去 + 砲弾を取り除く 탄약 제거 卸除弹头 卸除彈頭 @@ -273,7 +273,7 @@ Nabít minomet Carregar morteiro Зарядить миномет - 弾薬を装填 + 砲弾を装填 탄약 장전 装载弹头 裝載彈頭 @@ -288,7 +288,7 @@ Togliendo Proiettile Descarregar munição Извлечение снаряда - 弾薬を除去しています + 砲弾を取り除いています 탄약 제거 중 正在卸除弹头 卸除彈頭中 @@ -305,7 +305,7 @@ Připavuji náboj Preparar munição Подготовка снаряда - 砲弾を事前装填 + 砲弾を準備 탄약 준비 중 正在准备弹头 準備彈頭中 @@ -544,7 +544,7 @@ [ACE] Bedna se standardní 82mm municí [ACE] Caixa de Munição 82mm Padrão [ACE] Ящик снарядов 82мм (стандартный) - [ACE] 82mm 保管箱 + [ACE] 82mm 標準砲弾セット入り弾薬箱 [ACE] 82mm 기본 장비 상자 [ACE] 82 mm 预设弹药箱 [ACE] 82毫米預設彈藥箱 diff --git a/addons/movement/XEH_postInit.sqf b/addons/movement/XEH_postInit.sqf index f64b92603ba..4d7cc5ba120 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_handleClimb.sqf b/addons/movement/functions/fnc_handleClimb.sqf index 1325f2f021e..a54007862e3 100644 --- a/addons/movement/functions/fnc_handleClimb.sqf +++ b/addons/movement/functions/fnc_handleClimb.sqf @@ -24,5 +24,5 @@ private _pos = _unit modelToWorldVisual (_unit selectionPosition "camera"); _pos = _pos vectorDiff (_unit selectionPosition "camera"); -_unit setPosASL (AGLtoASL _pos); -TRACE_2("",AGLtoASL _pos,getPosASL _unit); +_unit setPosASL (AGLToASL _pos); +TRACE_2("",AGLToASL _pos,getPosASL _unit); diff --git a/addons/nametags/XEH_postInit.sqf b/addons/nametags/XEH_postInit.sqf index 85115690b48..a3fb7307f2e 100644 --- a/addons/nametags/XEH_postInit.sqf +++ b/addons/nametags/XEH_postInit.sqf @@ -50,7 +50,7 @@ if (missionNamespace getVariable [QGVAR(useFactionIcons), true]) then { { if (isArray (_x >> QGVAR(rankIcons))) then { private _faction = configName _x; - if (!isNil {GVAR(factionRanks) getVariable _faction}) exitWith {}; // don't overwrite if already set + if (_faction in GVAR(factionRanks)) exitWith {}; // don't overwrite if already set private _icons = getArray (_x >> QGVAR(rankIcons)); [_faction, _icons] call FUNC(setFactionRankIcons); }; diff --git a/addons/nametags/functions/fnc_drawNameTagIcon.sqf b/addons/nametags/functions/fnc_drawNameTagIcon.sqf index 428cf037d5b..ea6f16ebc39 100644 --- a/addons/nametags/functions/fnc_drawNameTagIcon.sqf +++ b/addons/nametags/functions/fnc_drawNameTagIcon.sqf @@ -25,7 +25,7 @@ TRACE_1("drawName:",_this); params ["", "_target", "", "_heightOffset"]; -_fnc_parameters = { +private _fnc_parameters = { params ["_player", "_target", "_alpha", "_heightOffset", "_drawName", "_drawRank", "_drawSoundwave"]; //Set Icon: @@ -42,13 +42,13 @@ _fnc_parameters = { default { private _targetFaction = _target getVariable [QGVAR(faction), faction _target]; - private _customRankIcons = GVAR(factionRanks) getVariable _targetFaction; + private _customRankIcons = GVAR(factionRanks) get _targetFaction; - if (!isNil "_customRankIcons") then { - _customRankIcons param [ALL_RANKS find rank _target, ""] // return - } else { + if (isNil "_customRankIcons") then { // default rank icons format ["\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa", rank _target] // return + } else { + _customRankIcons param [ALL_RANKS find rank _target, ""] // return }; }; }; diff --git a/addons/nametags/functions/fnc_initIsSpeaking.sqf b/addons/nametags/functions/fnc_initIsSpeaking.sqf index 5bae931e60c..db2bf30ac37 100644 --- a/addons/nametags/functions/fnc_initIsSpeaking.sqf +++ b/addons/nametags/functions/fnc_initIsSpeaking.sqf @@ -41,14 +41,14 @@ switch (true) do { INFO("ACRE Detected."); DFUNC(isSpeaking) = { params ["_unit"]; - ([_unit] call acre_api_fnc_isSpeaking) && {!(_unit getVariable ["ACE_isUnconscious", false])} + ([_unit] call acre_api_fnc_isSpeaking) && {_unit call EFUNC(common,isAwake)} }; }; case (["task_force_radio"] call EFUNC(common,isModLoaded)): { INFO("TFAR Detected."); DFUNC(isSpeaking) = { params ["_unit"]; - (_unit getVariable ["tf_isSpeaking", false]) && {!(_unit getVariable ["ACE_isUnconscious", false])} + (_unit getVariable ["tf_isSpeaking", false]) && {_unit call EFUNC(common,isAwake)} }; }; default { @@ -65,7 +65,7 @@ switch (true) do { DFUNC(isSpeaking) = { params ["_unit"]; - (_unit getVariable [QGVAR(isSpeakingInGame), false]) && {!(_unit getVariable ["ACE_isUnconscious", false])} + (_unit getVariable [QGVAR(isSpeakingInGame), false]) && {_unit call EFUNC(common,isAwake)} }; }; }; diff --git a/addons/nametags/functions/fnc_onDraw3d.sqf b/addons/nametags/functions/fnc_onDraw3d.sqf index 7e9d1560147..75a24e528d8 100644 --- a/addons/nametags/functions/fnc_onDraw3d.sqf +++ b/addons/nametags/functions/fnc_onDraw3d.sqf @@ -37,17 +37,17 @@ if (GVAR(showPlayerNames) == 4) then { private _camPosAGL = positionCameraToWorld [0, 0, 0]; if !((_camPosAGL select 0) isEqualType 0) exitWith {}; // handle RHS / bugged vehicle slots -private _camPosASL = AGLtoASL _camPosAGL; +private _camPosASL = AGLToASL _camPosAGL; // Show nametag for the unit behind the cursor or its commander if (_enabledTagsCursor) then { private _target = cursorTarget; if !(_target isKindOf "CAManBase") then { // When cursorTarget is on a vehicle show the nametag for the commander. - if !(_target in allUnitsUAV) then { - _target = effectiveCommander _target; - } else { + if (_target in allUnitsUAV) then { _target = objNull; + } else { + _target = effectiveCommander _target; }; }; if (isNull _target) exitWith {}; @@ -78,6 +78,7 @@ if (_enabledTagsCursor) then { if (_enabledTagsNearby) then { // Find valid targets and cache them private _targets = [[], { + //IGNORE_PRIVATE_WARNING ["_camPosAGL", "_maxDistance"]; private _nearMen = _camPosAGL nearObjects ["CAManBase", _maxDistance + 7]; _nearMen = _nearMen select { _x != ACE_player && @@ -115,7 +116,7 @@ if (_enabledTagsNearby) then { private _screenPos = worldToScreen (_target modelToWorld (_target selectionPosition "head")); if (_screenPos isNotEqualTo []) then { // Distance from center / half of screen width - _centerOffsetFactor = 1 - ((_screenPos distance2D [0.5, 0.5]) / (safezoneW / 3)); + _centerOffsetFactor = 1 - ((_screenPos distance2D [0.5, 0.5]) / (safeZoneW / 3)); } else { _centerOffsetFactor = 0; }; @@ -138,8 +139,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 88fd8808333..42d3ed40cbc 100644 --- a/addons/nametags/functions/fnc_setFactionRankIcons.sqf +++ b/addons/nametags/functions/fnc_setFactionRankIcons.sqf @@ -25,7 +25,7 @@ */ if (isNil QGVAR(factionRanks)) then { - GVAR(factionRanks) = [] call CBA_fnc_createNamespace; + GVAR(factionRanks) = createHashMap; }; params [["_faction", "", [""]], ["_icons", [], [[]], [7]]]; @@ -33,6 +33,11 @@ TRACE_2("setFactionRankIcons",_faction,_icons); if !(_faction != "" && {_icons isEqualTypeAll ""}) exitWith {false}; -GVAR(factionRanks) setVariable [_faction, _icons]; +_faction = configName (configFile >> "CfgFactionClasses" >> _faction); + +// Faction doesn't exist +if (_faction == "") exitWith {false}; + +GVAR(factionRanks) set [_faction, _icons]; true diff --git a/addons/nametags/stringtable.xml b/addons/nametags/stringtable.xml index 9f410c6a75b..1aed143b18e 100644 --- a/addons/nametags/stringtable.xml +++ b/addons/nametags/stringtable.xml @@ -29,7 +29,7 @@ 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 - このモジュールを使用すると、ネーム タグの設定と範囲を調整できます。 + このモジュールを使用すると、ネーム タグの範囲と設定を調整できます。 이 모듈은 당신이 이름표의 범위를 임의로 수정할 수 있게 해줍니다. 这个模块允许您设定名字和显示范围等设定 這個模塊允許您設定名稱和顯示範圍等設定 diff --git a/addons/nightvision/ACE_Arsenal_Stats.hpp b/addons/nightvision/ACE_Arsenal_Stats.hpp index 0b42d136f6f..e6d2a87c892 100644 --- a/addons/nightvision/ACE_Arsenal_Stats.hpp +++ b/addons/nightvision/ACE_Arsenal_Stats.hpp @@ -3,7 +3,7 @@ class EGVAR(arsenal,stats) { class GVAR(generation): statBase { scope = 2; priority = 1.6; - condition = QUOTE('nvg' in (getArray ((_this select 1) >> 'visionMode') apply {toLower _x})); + condition = QUOTE('nvg' in (getArray ((_this select 1) >> 'visionMode') apply {toLowerANSI _x})); displayName = CSTRING(NVGeneration); showText = 1; textStatement = QUOTE(call FUNC(statTextStatement_NVGeneration)); diff --git a/addons/nightvision/RscTitles.hpp b/addons/nightvision/RscTitles.hpp index 1a4d030e015..f3b1d1870f6 100644 --- a/addons/nightvision/RscTitles.hpp +++ b/addons/nightvision/RscTitles.hpp @@ -28,13 +28,13 @@ class RscTitles { idc = 1002; text = "#(argb,8,8,3)color(0,0,0,1)"; x = "safeZoneXAbs"; - Y = "safezoneY"; - W = "(safezoneX - safeZoneXAbs) * ((getResolution select 4)/(16/3))"; + Y = "safeZoneY"; + W = "(safeZoneX - safeZoneXAbs) * ((getResolution select 4)/(16/3))"; H = "safeZoneH"; }; class trippleHeadRight: trippleHeadLeft { idc = 1003; - x = "safeZoneXAbs + safeZoneWAbs - (safezoneX - safeZoneXABS) * ((getResolution select 4)/(16/3))"; + x = "safeZoneXAbs + safeZoneWAbs - (safeZoneX - safeZoneXABS) * ((getResolution select 4)/(16/3))"; }; }; }; diff --git a/addons/nightvision/XEH_postInit.sqf b/addons/nightvision/XEH_postInit.sqf index 9bfee4d166c..2933877771c 100644 --- a/addons/nightvision/XEH_postInit.sqf +++ b/addons/nightvision/XEH_postInit.sqf @@ -21,6 +21,9 @@ GVAR(ppeffectRadialBlur) = -1; GVAR(ppeffectColorCorrect) = -1; GVAR(ppeffectBlur) = -1; +if (isNil QGVAR(const_MaxBrightness)) then { GVAR(const_MaxBrightness) = 0; }; +if (isNil QGVAR(const_MinBrightness)) then { GVAR(const_MinBrightness) = -6; }; + GVAR(isUsingMagnification) = false; ["CBA_settingsInitialized", { @@ -61,7 +64,7 @@ if (!isNil QGVAR(serverPriorFog)) then {[] call FUNC(nonDedicatedFix);}; // If v if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSitting", "isNotRefueling"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if ((currentVisionMode ACE_player != 1)) exitWith {false}; - if (!(missionNamespace getVariable [QGVAR(allowBrightnessControl), true])) exitWith {false}; // just a mission setVar (not ace_setting) + if !(missionNamespace getVariable [QGVAR(allowBrightnessControl), true]) exitWith {false}; // just a mission setVar (not ace_setting) // Statement [ACE_player, 1] call FUNC(changeNVGBrightness); @@ -73,7 +76,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/functions/fnc_changeNVGBrightness.sqf b/addons/nightvision/functions/fnc_changeNVGBrightness.sqf index 1697fa907e8..d0b210fe295 100644 --- a/addons/nightvision/functions/fnc_changeNVGBrightness.sqf +++ b/addons/nightvision/functions/fnc_changeNVGBrightness.sqf @@ -23,7 +23,7 @@ private _effectsEnabled = GVAR(effectScaling) != 0; private _defaultBrightness = [-3, 0] select _effectsEnabled; private _brightness = _player getVariable [QGVAR(NVGBrightness), _defaultBrightness]; -_brightness = ((_brightness + _changeInBrightness) min 0) max -6; +_brightness = ((_brightness + _changeInBrightness) min GVAR(const_MaxBrightness)) max GVAR(const_MinBrightness); _player setVariable [QGVAR(NVGBrightness), _brightness, false]; // Display default setting as 0 diff --git a/addons/nightvision/functions/fnc_onCameraViewChanged.sqf b/addons/nightvision/functions/fnc_onCameraViewChanged.sqf index 2cbec4d16e7..6f03c2a3af4 100644 --- a/addons/nightvision/functions/fnc_onCameraViewChanged.sqf +++ b/addons/nightvision/functions/fnc_onCameraViewChanged.sqf @@ -23,7 +23,7 @@ TRACE_2("onCameraViewChanged",_unit,_cameraView); call FUNC(refreshGoggleType); if (GVAR(disableNVGsWithSights) && {(hmd _unit) != ""}) then { - if ((vehicle _unit == _unit) + if ((isNull objectParent _unit) || {isTurnedOut _unit} || {!([_unit] call EFUNC(common,hasHatch)) && {[_unit] call EFUNC(common,getTurretIndex) in ([vehicle _unit] call EFUNC(common,getTurretsFFV))} diff --git a/addons/nightvision/functions/fnc_onVisionModeChanged.sqf b/addons/nightvision/functions/fnc_onVisionModeChanged.sqf index 1913454f3f7..8086b2d1a0c 100644 --- a/addons/nightvision/functions/fnc_onVisionModeChanged.sqf +++ b/addons/nightvision/functions/fnc_onVisionModeChanged.sqf @@ -21,7 +21,7 @@ TRACE_2("onVisionModeChanged",_unit,_visionMode); // Handle disableNVGsWithSights setting: if (GVAR(disableNVGsWithSights) && {(hmd _unit) != ""}) then { - if ((vehicle _unit == _unit) + if ((isNull objectParent _unit) || {isTurnedOut _unit} || {!([_unit] call EFUNC(common,hasHatch)) && {[_unit] call EFUNC(common,getTurretIndex) in ([vehicle _unit] call EFUNC(common,getTurretsFFV))} diff --git a/addons/nightvision/functions/fnc_pfeh.sqf b/addons/nightvision/functions/fnc_pfeh.sqf index dbd101631cd..9d5f6e93bb8 100644 --- a/addons/nightvision/functions/fnc_pfeh.sqf +++ b/addons/nightvision/functions/fnc_pfeh.sqf @@ -163,7 +163,9 @@ if (CBA_missionTime < GVAR(nextEffectsUpdate)) then { }; _fogApply = linearConversion [0, 1, GVAR(priorFog) select 0, (GVAR(fogScaling) * _fogApply), 1]; // mix in old fog if present - GVAR(nvgFog) = [_fogApply, 0, 0]; + GVAR(nvgFog) = fogParams; + GVAR(nvgFog) set [0, _fogApply]; + 0 setFog GVAR(nvgFog) }; diff --git a/addons/nightvision/functions/fnc_refreshGoggleType.sqf b/addons/nightvision/functions/fnc_refreshGoggleType.sqf index ccfbd017b6f..2c7dedaa834 100644 --- a/addons/nightvision/functions/fnc_refreshGoggleType.sqf +++ b/addons/nightvision/functions/fnc_refreshGoggleType.sqf @@ -106,7 +106,7 @@ if (_borderImage == "") then { _borderImageCtrl ctrlSetFade ([.15, 0] select _eyeCups); #define BORDER_SIZE 3 - GVAR(defaultPositionBorder) = [safezoneX - (((BORDER_SIZE * 0.75) * safezoneH) - safezoneW) / 2, safezoneY - ((BORDER_SIZE - 1) / 2) * safezoneH, (BORDER_SIZE * 0.75) * safezoneH, BORDER_SIZE * safezoneH]; + GVAR(defaultPositionBorder) = [safeZoneX - (((BORDER_SIZE * 0.75) * safeZoneH) - safeZoneW) / 2, safeZoneY - ((BORDER_SIZE - 1) / 2) * safeZoneH, (BORDER_SIZE * 0.75) * safeZoneH, BORDER_SIZE * safeZoneH]; [_borderImageCtrl, GVAR(defaultPositionBorder), _scale] call FUNC(scaleCtrl); }; @@ -119,7 +119,7 @@ if (_hideHex) then { _hexCtrl ctrlSetText QPATHTOF(data\nvg_mask_hexes_thin.paa); #define HEX_SIZE 1.5 - GVAR(defaultPositionHex) = [safezoneX - (((HEX_SIZE * 0.75) * safezoneH) - safezoneW) / 2, safezoneY - ((HEX_SIZE - 1) / 2) * safezoneH, (HEX_SIZE * 0.75) * safezoneH, HEX_SIZE * safezoneH]; + GVAR(defaultPositionHex) = [safeZoneX - (((HEX_SIZE * 0.75) * safeZoneH) - safeZoneW) / 2, safeZoneY - ((HEX_SIZE - 1) / 2) * safeZoneH, (HEX_SIZE * 0.75) * safeZoneH, HEX_SIZE * safeZoneH]; [_hexCtrl, GVAR(defaultPositionHex), _scale] call FUNC(scaleCtrl); }; diff --git a/addons/nightvision/stringtable.xml b/addons/nightvision/stringtable.xml index e1345ec44ec..1911681dd68 100644 --- a/addons/nightvision/stringtable.xml +++ b/addons/nightvision/stringtable.xml @@ -28,6 +28,7 @@ 夜视仪(一代,棕色) 아투경 (1세대, 갈색) Gafas de visión nocturna (Gen1, Marrón) + Óculos de Visão Noturna (Gen1, Marrom) NV Goggles (Gen1, Black) @@ -40,6 +41,7 @@ 夜视仪(一代,黑色) 아투경 (1세대, 검정) Gafas de visión nocturna (Gen1, Negro) + Óculos de Visão Noturna (Gen1, Preto) NV Goggles (Gen1, Green) @@ -52,6 +54,7 @@ 夜视仪(一代,绿色) 아투경 (1세대, 녹색) Gafas de visión nocturna (Gen1, Verde) + Óculos de Visão Noturna (Gen1, Verde) NV Goggles (Gen2, Brown) @@ -64,6 +67,7 @@ 夜视仪(二代,棕色) 아투경 (2세대, 갈색) Gafas de visión nocturna (Gen2, Marrón) + Óculos de Visão Noturna (Gen2, Marrom) NV Goggles (Gen2, Black) @@ -76,6 +80,7 @@ 夜视仪(二代,黑色) 아투경 (2세대, 검정) Gafas de visión nocturna (Gen2, Negro) + Óculos de Visão Noturna (Gen2, Preto) NV Goggles (Gen2, Green) @@ -88,6 +93,7 @@ 夜视仪(二代,绿色) 아투경 (2세대, 녹색) Gafas de visión nocturna (Gen2, Verde) + Óculos de Visão Noturna (Gen2, Verde) NV Goggles (Gen3) @@ -96,7 +102,7 @@ NS-Brille (3. Gen.) Visore Notturno (Gen3) Gogle noktowizyjne (Gen3) - Óculos de visão noturna (Gen3) + Óculos de Visão Noturna (Gen3) ПНВ (Gen3) Gafas de visión nocturna (Gen3) Éjjellátó szemüveg (3. Gen.) @@ -113,7 +119,7 @@ NS-Brille (3. Gen., braun) Visore Notturno (Gen3, Marrone) Gogle noktowizyjne (Gen3, Brązowe) - Óculos de visão noturna (Gen3, marrons) + Óculos de Visão Noturna (Gen3, Marrom) ПНВ (Gen3, Коричневый) Gafas de visión nocturna (Gen3, Marrón) Éjjellátó szemüveg (3. Gen., barna) @@ -132,6 +138,8 @@ 야투경 (3세대, 갈색, 백색광) JVN (Gen3, marron, WP) ПНВ (Gen3, Коричневый, БФ) + Gafas de visión nocturna (Gen3, Marrón, FB) + Óculos de Visão Noturna (Gen3, Marrom, FB) Night Vision Goggles, White Phosphor @@ -142,6 +150,8 @@ 백색광 야투경 Jumelles Vision Nocturne, Phosphore blanc Очки ночного видения, белый фосфор + Gafas de Visión Nocturna, Fósforo Blanco + Óculos de Visão Nortuna, Fósforo Branco NV Goggles (Gen3, Green) @@ -150,7 +160,7 @@ NS-Brille (3. Gen., grün) Visore Notturno (Gen3, Verde) Gogle noktowizyjne (Gen3, Zielone) - Óculos de visão noturna (Gen3, verdes) + Óculos de Visão Noturna (Gen3, verdes) ПНВ (Gen3, Зелёный) Gafas de visión nocturna (Gen3, Verde) Éjjellátó szemüveg (3. Gen., zöld) @@ -169,6 +179,8 @@ 야투경 (3세대, 녹색, 백색광) JVN (Gen3, vertes, WP) ПНВ (Gen3, Зелёный, БФ) + Gafas de visión nocturna (Gen3, Verde, FB) + Óculos de Visão Noturna (Gen3, Verde, FB) NV Goggles (Gen3, Black) @@ -177,7 +189,7 @@ NS-Brille (3. Gen., schwarz) Visore Notturno (Gen3, Nero) Gogle noktowizyjne (Gen3, Czarne) - Óculos de visão noturna (Gen3, pretos) + Óculos de Visão Noturna (Gen3, Preto) ПНВ (Gen3, Чёрный) Gafas de visión nocturna (Gen3, Negro) Éjjellátó szemüveg (3. Gen., fekete) @@ -196,6 +208,8 @@ 야투경 (3세대, 검정, 백색광) JVN (Gen3, noires, WP) ПНВ (Gen3, Чёрный, БФ) + Gafas de visión nocturna (Gen3, Negro, FB) + Óculos de Visão Noturna (Gen3, Preto, FB) NV Goggles (Gen4, Brown) @@ -208,6 +222,7 @@ 夜视仪(四代,棕色) 야투경 (4세대, 갈색) Gafas de visión nocturna (Gen4, Marrón) + Óculos de Visão Noturna (Gen4, Marrom) NV Goggles (Gen4, Brown, WP) @@ -218,6 +233,8 @@ 야투경 (4세대, 갈색, 백색광) JVN (Gen4, marron, WP) ПНВ (Gen4, Коричневый, БФ) + Gafas de visión nocturna (Gen4, Marrón, FB) + Óculos de Visão Noturna (Gen4, Marrom, FB) NV Goggles (Gen4, Black) @@ -230,6 +247,7 @@ 夜视仪(四代,黑色) 야투경 (4세대, 검정) Gafas de visión nocturna (Gen4, Negro) + Óculos de Visão Noturna (Gen4, Preto) NV Goggles (Gen4, Black, WP) @@ -240,6 +258,8 @@ 야투경 (4세대, 검정, 백색광) JVN (Gen4, noires, WP) ПНВ (Gen4, Чёрный, БФ) + Gafas de visión nocturna (Gen4, Negro, FB) + Óculos de Visão Noturna (Gen4, Preto, FB) NV Goggles (Gen4, Green) @@ -252,6 +272,7 @@ 夜视仪(四代,绿色) 야투경 (4세대, 녹색) Gafas de visión nocturna (Gen4, Verde) + Óculos de Visão Noturna (Gen4, Verde) NV Goggles (Gen4, Green, WP) @@ -262,6 +283,8 @@ 야투경 (4세대, 녹색, 백색광) JVN (Gen4, vertes, WP) ПНВ (Gen4, Зелёный, БФ) + Gafas de visión nocturna (Gen4, Verde, FB) + Óculos de Visão Noturna (Gen4, Verde, FB) NV Goggles (Wide, Brown) @@ -274,6 +297,7 @@ 夜视仪(宽,棕色) 야투경 (넓음, 갈색) Gafas de visión nocturna (Panorámicas, Marrón) + Óculos de Visão Noturna (Panorâmico, Marrom) NV Goggles (Wide, Brown, WP) @@ -284,6 +308,8 @@ 야투경 (넓음, 갈색, 백색광) JVN (Large, marron, WP) ПНВ (Широкий, Коричневый, БФ) + Gafas de visión nocturna (Panorámicas, Marrón, FB) + Óculos de Visão Noturna (Panorâmico, Marrom, FB) NV Goggles (Wide, Black) @@ -296,6 +322,7 @@ 夜视仪(宽,黑色) 야투경 (넓음, 검정) Gafas de visión nocturna (Panorámicas, Negro) + Óculos de Visão Noturna (Panorâmico, Preto) NV Goggles (Wide, Black, WP) @@ -306,6 +333,8 @@ 야투경 (넓음, 검정, 백색광) JVN (Large, noires, WP) ПНВ (Широкий, Чёрный, БФ) + Gafas de visión nocturna (Panorámicas, Negro, FB) + Óculos de Visão Noturna (Panorâmico, Preto, FB) NV Goggles (Wide, Green) @@ -318,6 +347,7 @@ 夜视仪(宽,绿色) 야투경 (넓음, 녹색) Gafas de visión nocturna (Panorámicas, Verde) + Óculos de Visão Noturna (Panorâmico, Verde) NV Goggles (Wide, Green, WP) @@ -328,6 +358,8 @@ 야투경 (넓음, 녹색, 백색광) JVN (Large, vertes, WP) ПНВ (Широкий, Зелёный, БФ) + Gafas de visión nocturna (Panorámicas, Verde, FB) + Óculos de Visão Noturna (Panorâmico, Verde, FB) Brightness: %1 @@ -355,7 +387,7 @@ Augmenter la luminosité des JVN Увеличить яркость ПНВ Éjjellátó fényerejének növelése - Aumentar Luminosidade do EVN + Aumentar Luminosidade do OVN Aumenta la luminosità dell'NVG 暗視装置の明度を上げる 야투경 밝기 높이기 @@ -372,7 +404,7 @@ Abaisser la luminosité des JVN Уменьшить яркость ПНВ Éjjellátó fényerejének csökkentése - Diminuir Luminosidade do EVN + Diminuir Luminosidade do OVN Riduci la luminosità dell'NVG 暗視装置の明度を下げる 야투경 밝기 줄이기 @@ -587,6 +619,8 @@ 야투경 세대 Génération de jumelles de vision nocturne Генерация ночного видения + Generación de Visión Nocturna + Geração de Visão Noturna Gen %1 @@ -597,6 +631,8 @@ %1세대 Gen %1 Генерация %1 + Gen %1 + Gen %1 diff --git a/addons/nlaw/ACE_GuidanceConfig.hpp b/addons/nlaw/ACE_GuidanceConfig.hpp index e04753d6816..6003586fe86 100644 --- a/addons/nlaw/ACE_GuidanceConfig.hpp +++ b/addons/nlaw/ACE_GuidanceConfig.hpp @@ -12,3 +12,9 @@ class EGVAR(missileguidance,SeekerTypes) { functionName = QFUNC(seeker); }; }; +class EGVAR(missileguidance,NavigationTypes) { + class GVAR(PLOS) { + functionName = QFUNC(navigation); + onFired = QFUNC(navigation_onFired); + }; +}; diff --git a/addons/nlaw/CfgAmmo.hpp b/addons/nlaw/CfgAmmo.hpp index b579ebeb065..650fa148873 100644 --- a/addons/nlaw/CfgAmmo.hpp +++ b/addons/nlaw/CfgAmmo.hpp @@ -1,39 +1,11 @@ +class ace_missileguidance_type_Nlaw; class CfgAmmo { class M_NLAW_AT_F; class ACE_NLAW: M_NLAW_AT_F { hit = 400; // Default was 500 indirectHit = 20; // Default was 15 - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Nlaw { enabled = 1; - - minDeflection = 0.0005; // Minium flap deflection for guidance - maxDeflection = 0.01; // 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 = QGVAR(seeker); - seekerTypes[] = {QGVAR(seeker)}; - - defaultSeekerLockMode = "LOBL"; - seekerLockModes[] = {"LOBL"}; - - seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] - seekerAngle = 45; // Angle in front of the missile which can be searched - seekerAccuracy = 1; // seeker accuracy multiplier - - seekerMinRange = 0; - seekerMaxRange = 10; // Range from the missile which the seeker can visually search - - // Attack profile type selection - defaultAttackProfile = QGVAR(directAttack); - attackProfiles[] = {QGVAR(directAttack), QGVAR(overflyTopAttack)}; - useModeForAttackProfile = 1; - showHintOnCycle = 1; - - // Run once at fired event - onFired = QFUNC(onFired); }; }; diff --git a/addons/nlaw/XEH_PREP.hpp b/addons/nlaw/XEH_PREP.hpp index aad1e57efb2..1cd8dbc3c59 100644 --- a/addons/nlaw/XEH_PREP.hpp +++ b/addons/nlaw/XEH_PREP.hpp @@ -4,3 +4,5 @@ PREP(attackProfile); PREP(keyDown); PREP(onFired); PREP(seeker); +PREP(navigation); +PREP(navigation_onFired); diff --git a/addons/nlaw/XEH_postInit.sqf b/addons/nlaw/XEH_postInit.sqf index 885e2d5e2f2..5e3f35572c8 100644 --- a/addons/nlaw/XEH_postInit.sqf +++ b/addons/nlaw/XEH_postInit.sqf @@ -22,24 +22,28 @@ GVAR(pitchChange) = 0; // Visual debuging, idealy used with a moving vehicle called "testTarget" #ifdef DRAW_NLAW_INFO +GVAR(debug_firedPrediction) = []; addMissionEventHandler ["Draw3d", { + // BLACK - On fired path prediction + { drawIcon3D _x; } forEach GVAR(debug_firedPrediction); + // GREEN - Draw an object called "testTarget"'s aim pos and 1 sec aimpos predicted by velocity if ((!isNil "testTarget") && {!isNull testTarget}) then { { - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,1,0,1], ASLtoAGL ((aimPos testTarget) vectorAdd ((velocity testTarget) vectorMultiply _x)), 0.75, 0.75, 0, format ["%1", _x], 1, 0.025, "TahomaB"]; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,1,0,1], ASLToAGL ((aimPos testTarget) vectorAdd ((velocity testTarget) vectorMultiply _x)), 0.75, 0.75, 0, format ["%1", _x], 1, 0.025, "TahomaB"]; } forEach [0, 1, 2, 3]; }; // RED - If lock key is down, draw weapon dir and predicted path at various times if (GVAR(yawChange) != 0) then { { - private _viewASL = AGLtoASL positionCameraToWorld [0,0,0]; + private _viewASL = AGLToASL positionCameraToWorld [0,0,0]; private _viewDir = ACE_player weaponDirection (currentWeapon ACE_player); (_viewDir call CBA_fnc_vect2Polar) params ["", "_yaw", "_pitch"]; private _realYaw = _yaw + GVAR(yawChange) * _x; private _realPitch = _pitch + GVAR(pitchChange) * _x; private _returnTargetPos = _viewASL vectorAdd ([1000, _realYaw, _realPitch] call CBA_fnc_polar2vect); - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLtoAGL _returnTargetPos, 0.75, 0.75, 0, format ["%1", _x], 1, 0.025, "TahomaB"]; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLToAGL _returnTargetPos, 0.75, 0.75, 0, format ["%1", _x], 1, 0.025, "TahomaB"]; } forEach [0, 1, 2, 3]; }; }]; diff --git a/addons/nlaw/functions/fnc_attackProfile.sqf b/addons/nlaw/functions/fnc_attackProfile.sqf index 9628974800c..8f06e26f9c4 100644 --- a/addons/nlaw/functions/fnc_attackProfile.sqf +++ b/addons/nlaw/functions/fnc_attackProfile.sqf @@ -18,14 +18,13 @@ */ params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; + +#ifdef DRAW_NLAW_INFO _args params ["_firedEH", "_launchParams"]; _launchParams params ["","_targetLaunchParams", "", "_attackProfile"]; _targetLaunchParams params ["", "", "_launchPos"]; _firedEH params ["","","","","","","_projectile"]; -// Use seeker (if terminal) -if (_seekerTargetPos isNotEqualTo [0,0,0]) exitWith {_seekerTargetPos}; - _attackProfileStateParams params ["_startTime", "_startLOS", "_yawChange", "_pitchChange"]; (_startLOS call CBA_fnc_vect2Polar) params ["", "_yaw", "_pitch"]; @@ -36,25 +35,16 @@ private _flightTime = CBA_missionTime - _startTime; private _realYaw = _yaw + _yawChange * _flightTime; private _realPitch = _pitch + _pitchChange * _flightTime; -private _returnTargetPos = _launchPos vectorAdd ([_distanceFromLaunch, _realYaw, _realPitch] call CBA_fnc_polar2vect); - -if (_attackProfile == QGVAR(overflyTopAttack)) then { // Add 2m height in OTA attack mode - _returnTargetPos = _returnTargetPos vectorAdd [0,0,2]; -}; - - -#ifdef DRAW_NLAW_INFO -drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,1,1], ASLtoAGL _launchPos, 0.75, 0.75, 0, "LAUNCH", 1, 0.025, "TahomaB"]; -drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,1,1,1], ASLtoAGL (_launchPos vectorAdd (_startLOS vectorMultiply (_distanceFromLaunch + 50))), 0.75, 0.75, 0, "Original LOS", 1, 0.025, "TahomaB"]; -drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,0,1], ASLtoAGL (_launchPos vectorAdd ([_distanceFromLaunch + 50, _realYaw, _realPitch] call CBA_fnc_polar2vect)), 0.75, 0.75, 0, format ["Predicted @%1sec",(floor(_flightTime * 10)/10)], 1, 0.025, "TahomaB"]; -drawLine3D [ASLtoAGL _launchPos, ASLtoAGL (_launchPos vectorAdd (_startLOS vectorMultiply (_distanceFromLaunch + 50))), [1,0,0,1]]; -drawLine3D [ASLtoAGL _launchPos, ASLtoAGL (_launchPos vectorAdd ([_distanceFromLaunch + 50, _realYaw, _realPitch] call CBA_fnc_polar2vect)), [1,1,0,1]]; +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,1,1], ASLToAGL _launchPos, 0.75, 0.75, 0, "LAUNCH", 1, 0.025, "TahomaB"]; +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,1,1,1], ASLToAGL (_launchPos vectorAdd (_startLOS vectorMultiply (_distanceFromLaunch + 50))), 0.75, 0.75, 0, "Original LOS", 1, 0.025, "TahomaB"]; +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,0,1], ASLToAGL (_launchPos vectorAdd ([_distanceFromLaunch + 50, _realYaw, _realPitch] call CBA_fnc_polar2vect)), 0.75, 0.75, 0, format ["Predicted @%1sec",(floor(_flightTime * 10)/10)], 1, 0.025, "TahomaB"]; +drawLine3D [ASLToAGL _launchPos, ASLToAGL (_launchPos vectorAdd (_startLOS vectorMultiply (_distanceFromLaunch + 50))), [1,0,0,1]]; +drawLine3D [ASLToAGL _launchPos, ASLToAGL (_launchPos vectorAdd ([_distanceFromLaunch + 50, _realYaw, _realPitch] call CBA_fnc_polar2vect)), [1,1,0,1]]; private _test = lineIntersectsSurfaces [_launchPos, _launchPos vectorAdd (_startLOS vectorMultiply 3000), player, _projectile]; if ((count _test) > 0) then { - private _posAGL = ASLtoAGL ((_test select 0) select 0); + private _posAGL = ASLToAGL ((_test select 0) select 0); drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], _posAGL, 0.75, 0.75, 0, "Original Impact", 1, 0.025, "TahomaB"]; }; #endif -// TRACE_1("Adjusted target position",_returnTargetPos); -_returnTargetPos; +[0, 0, 1] diff --git a/addons/nlaw/functions/fnc_keyDown.sqf b/addons/nlaw/functions/fnc_keyDown.sqf index 60ac4bf3d8f..aee9739474b 100644 --- a/addons/nlaw/functions/fnc_keyDown.sqf +++ b/addons/nlaw/functions/fnc_keyDown.sqf @@ -19,8 +19,8 @@ TRACE_1("lock key down",GVAR(isLockKeyDown)); if (!alive ACE_player) exitWith {}; -if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith {}; -if (!(ACE_player call CBA_fnc_canUseWeapon)) exitWith {}; +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {}; +if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {}; if ((getNumber (configFile >> "CfgWeapons" >> (currentWeapon ACE_player) >> QGVAR(enabled))) == 0) exitWith {}; if (GVAR(isLockKeyDown)) exitWith {ERROR("already running?");}; @@ -74,7 +74,7 @@ playSound "ACE_Sound_Click"; _args set [1, _yaw]; _args set [2, _pitch]; - #ifdef DEBUG_MODE_FULL + #ifdef DRAW_NLAW_INFO hintSilent format ["Instantaneous\nYaw: %1\n Pitch: %2\nGVAR\nYaw: %3\nPitch: %4", _yawChange, _pitchChange, GVAR(yawChange), GVAR(pitchChange)]; #endif }, .25, [CBA_missionTime, _yaw, _pitch, true]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/nlaw/functions/fnc_navigation.sqf b/addons/nlaw/functions/fnc_navigation.sqf new file mode 100644 index 00000000000..7572b44d6f3 --- /dev/null +++ b/addons/nlaw/functions/fnc_navigation.sqf @@ -0,0 +1,78 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Attempts to hold angle as fed to by seeker. Does so with a simple proportional controller + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Commanded acceleration normal to LOS in world space + * + * Example: + * [] call ace_missileguidance_fnc_navigationType_line + * + * Public: No + */ +// arbitrary constant +#define PROPORTIONALITY_CONSTANT 20 +params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos", "_targetData", "_navigationParams"]; +_args params ["_firedEH"]; +_firedEH params ["","","","","","","_projectile"]; + +_navigationParams params ["_yawChange", "_pitchChange", "_lastPitch", "_lastYaw", "_initialPitch", "_pitchUp", "_lastYawRateDifference"]; + +// for some reason we need to multiply this. I don't know why, but it just works +_pitchChange = _pitchChange * 1.5; +_yawChange = _yawChange * 1.5; + +((velocity _projectile) call CBA_fnc_vect2polar) params ["", "_currentYaw", "_currentPitch"]; + +private _pitchRate = if (_timestep == 0) then { + 0 +} else { + (_currentPitch - _lastPitch) / _timestep +}; +_navigationParams set [2, _currentPitch]; + +private _pitchModifier = if (_pitchChange == 0) then { + 1 +} else { + abs (_pitchRate / _pitchChange) +}; +private _desiredPitchChange = (_pitchChange - _pitchRate) * PROPORTIONALITY_CONSTANT * _pitchModifier; +_desiredPitchChange = _desiredPitchChange + _pitchUp * (_initialPitch - _currentPitch) * PROPORTIONALITY_CONSTANT * _pitchModifier; + +private _yawRate = if (_timestep == 0) then { + 0 +} else { + (_currentYaw - _lastYaw) / _timestep +}; +_navigationParams set [3, _currentYaw]; + +private _yawModifier = if (_yawChange == 0) then { + 1 +} else { + abs (_yawRate / _yawChange) +}; + +private _yawRateDifference = _yawChange - _yawRate; +private _yawChangeDerivative = if (_timestep == 0) then { + 0 +} else { + (_yawRateDifference - _lastYawRateDifference) / _timestep +}; +_navigationParams set [6, _yawRateDifference]; + +private _desiredYawChange = _yawRateDifference * PROPORTIONALITY_CONSTANT + _yawRateDifference * 2; + +#ifdef DRAW_NLAW_INFO +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,1,1], ASLToAGL getPosASLVisual _projectile, 0.75, 0.75, 0, format ["dP [%1] dY: [%2]", _desiredPitchChange, _desiredYawChange], 1, 0.025, "TahomaB"]; +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,1,1], [0, 0, 1] vectorAdd ASLToAGL getPosASLVisual _projectile, 0.75, 0.75, 0, format ["pitch proportional [%1] yaw proportional [%2]", _pitchModifier, _yawModifier], 1, 0.025, "TahomaB"]; +#endif + +TRACE_4("nlaw pitch/yaw info",_currentPitch,_lastPitch,_currentYaw,_lastYaw); +TRACE_6("nlaw navigation",_yawChange,_desiredYawChange,_pitchChange,_desiredPitchChange,_yawRate,_pitchRate); + +_projectile vectorModelToWorldVisual [_yawChange + _desiredYawChange, 0, _pitchChange + _desiredPitchChange] + diff --git a/addons/nlaw/functions/fnc_navigation_onFired.sqf b/addons/nlaw/functions/fnc_navigation_onFired.sqf new file mode 100644 index 00000000000..895d5ff78b3 --- /dev/null +++ b/addons/nlaw/functions/fnc_navigation_onFired.sqf @@ -0,0 +1,70 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Sets up missile guidance state arrays (called from missileGuidance's onFired). + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Navigation Parameters + * + * Example: + * [] call ace_nlaw_fnc_onFired + * + * Public: No + */ + +params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; +_firedEH params ["_shooter","","","","","","_projectile"]; +_launchParams params ["","_targetLaunchParams","","_attackProfile"]; +_targetLaunchParams params ["_target"]; +_stateParams params ["", "", "", "", "_navigationParams"]; + +// Reset _launchPos origin as projectile's height instead of player's foot +_targetLaunchParams set [2, getPosASL _projectile]; + +// Get state params: +TRACE_3("start of attack profile",_attackProfile,_shooter,vectorDir _projectile); + +private _firedLOS = _shooter weaponDirection (currentWeapon _shooter); +private _yawChange = 0; +private _pitchChange = 0; + +if (_shooter == ACE_player) then { + TRACE_2("isPlayer",GVAR(yawChange),GVAR(pitchChange)); + _yawChange = GVAR(yawChange); + _pitchChange = GVAR(pitchChange); + TRACE_1("los check",_firedLOS call CBA_fnc_vect2Polar); +} else { + if ((!isNil "_target") && {!isNull _target}) then { + _firedLOS = (getPosASL _projectile) vectorFromTo (aimPos _target); + (((eyePos _shooter) vectorFromTo (aimPos _target)) call CBA_fnc_vect2Polar) params ["", "_startYaw", "_startPitch"]; + // Add some random error to AI's velocity prediction: + private _random = random [(_shooter skillFinal "aimingAccuracy") min 0.9, 1, 2-((_shooter skillFinal "aimingAccuracy") min 0.9)]; + (((eyePos _shooter) vectorFromTo ((aimPos _target) vectorAdd ((velocity _target) vectorMultiply (_random)))) call CBA_fnc_vect2Polar) params ["", "_predictedYaw", "_predictedPitch"]; + _yawChange = ([_predictedYaw - _startYaw] call CBA_fnc_simplifyAngle180); + _pitchChange = ([_predictedPitch - _startPitch] call CBA_fnc_simplifyAngle180); + TRACE_1("AI",_target); + } else { + TRACE_1("AI - no target",_target); + }; +}; + +// Limit Max Deflection +//_yawChange = -10 max _yawChange min 10; +//_pitchChange = -10 max _pitchChange min 10; + +((velocity _projectile) call CBA_fnc_vect2polar) params ["", "_currentYaw", "_currentPitch"]; +((ACE_player weaponDirection (currentWeapon ACE_player)) call CBA_fnc_vect2Polar) params ["", "_yaw", "_pitch"]; + +TRACE_5("attackProfileStateParams",_firedLOS,_yawChange,_pitchChange,_currentPitch,_currentYaw); +_navigationParams set [0, _yawChange]; +_navigationParams set [1, _pitchChange]; +_navigationParams set [2, _currentPitch]; // last pitch +_navigationParams set [3, _currentYaw]; // last yaw +_navigationParams set [4, _pitch]; // initial pitch +_navigationParams set [5, 0]; // whether or not to zero out the pitch +_navigationParams set [6, 0]; +_navigationParams + diff --git a/addons/nlaw/functions/fnc_onFired.sqf b/addons/nlaw/functions/fnc_onFired.sqf index 11b38a1da03..cbaa2cfc0a4 100644 --- a/addons/nlaw/functions/fnc_onFired.sqf +++ b/addons/nlaw/functions/fnc_onFired.sqf @@ -19,7 +19,7 @@ params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_statePa _firedEH params ["_shooter","","","","","","_projectile"]; _launchParams params ["","_targetLaunchParams","","_attackProfile"]; _targetLaunchParams params ["_target"]; -_stateParams params ["", "", "_attackProfileStateParams"]; +_stateParams params ["", "_seekerStateParams", "_attackProfileStateParams"]; // Reset _launchPos origin as projectile's height instead of player's foot _targetLaunchParams set [2, getPosASL _projectile]; @@ -27,7 +27,7 @@ _targetLaunchParams set [2, getPosASL _projectile]; // Get state params: TRACE_3("start of attack profile",_attackProfile,_shooter,vectorDir _projectile); -private _firedLOS = _shooter weaponDirection (currentWeapon _shooter); +private _firedLOS = vectorDir _projectile; private _yawChange = 0; private _pitchChange = 0; @@ -36,6 +36,23 @@ if (_shooter == ACE_player) then { _yawChange = GVAR(yawChange); _pitchChange = GVAR(pitchChange); TRACE_1("los check",_firedLOS call CBA_fnc_vect2Polar); + + #ifdef DRAW_NLAW_INFO + systemChat format ["YAW [%1]", _yawChange]; + systemChat format ["PITCH [%1]", _pitchChange]; + GVAR(debug_firedPrediction) = []; + private _debugPos = getPosASL _projectile; + ((ACE_player weaponDirection (currentWeapon ACE_player)) call CBA_fnc_vect2Polar) params ["", "_debugYaw", "_debugPitch"]; + private _distance = 0; + for "_x" from 0 to 6 step 0.1 do { + private _debugAproxVel = linearConversion [0, 1, 5, 40, 170, true]; + _distance = _distance + _debugAproxVel * 0.1; + private _debugYaw = _debugYaw + _yawChange * _x; + private _debugPitch = _debugPitch + _pitchChange * _x; + private _debugPos = _debugPos vectorAdd ([_distance, _debugYaw, _debugPitch] call CBA_fnc_polar2vect); + GVAR(debug_firedPrediction) pushBack ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,0,0,1], ASLToAGL _debugPos, 0.5, 0.5, 0, format ["%1", _x], 1, 0.025, "TahomaB"]; + }; + #endif } else { if ((!isNil "_target") && {!isNull _target}) then { _firedLOS = (getPosASL _projectile) vectorFromTo (aimPos _target); @@ -55,6 +72,10 @@ if (_shooter == ACE_player) then { _yawChange = -10 max _yawChange min 10; _pitchChange = -10 max _pitchChange min 10; +_seekerStateParams set [2, _yawChange]; +_seekerStateParams set [3, _pitchChange]; +_seekerStateParams set [4, CBA_missionTime]; + TRACE_3("attackProfileStateParams",_firedLOS,_yawChange,_pitchChange); _attackProfileStateParams set [0, CBA_missionTime]; _attackProfileStateParams set [1, _firedLOS]; diff --git a/addons/nlaw/functions/fnc_seeker.sqf b/addons/nlaw/functions/fnc_seeker.sqf index e5de6d320ca..a77b7ecb3b6 100644 --- a/addons/nlaw/functions/fnc_seeker.sqf +++ b/addons/nlaw/functions/fnc_seeker.sqf @@ -16,14 +16,27 @@ * * Public: No */ +#define PITCH_UP_TIME 1 -params ["", "_args", "_seekerStateParams"]; +params ["", "_args", "_seekerStateParams", "", "", "_targetData"]; _args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams"]; _firedEH params ["","","","","","","_projectile"]; _launchParams params ["", "_targetLaunchParams", "", "_attackProfile"]; _targetLaunchParams params ["", "", "_launchPos"]; +_stateParams params ["", "", "", "", "_navigationParams"]; -if (_attackProfile == QGVAR(directAttack)) exitWith {[0,0,0]}; +if (_attackProfile == QGVAR(directAttack)) exitWith { + _navigationParams set [5, 1]; + [0,0,0] +}; + +_seekerStateParams params ["", "", "", "_originalPitchRate", "_startTime"]; +_navigationParams params ["", "_pitchRate"]; + +// pitch up for the first second of flight to begin an over-fly trajectory +private _pitchChange = linearConversion [0, PITCH_UP_TIME, CBA_missionTime - _startTime, 2, 0, true]; +_navigationParams set [1, _originalPitchRate + _pitchChange]; +_navigationParams set [5, ((CBA_missionTime - _startTime) min PITCH_UP_TIME) / PITCH_UP_TIME]; private _projPos = getPosASL _projectile; @@ -49,7 +62,7 @@ if ((_projPos distance _launchPos) >= 20) then { // This represents a position that the missile was at between the last frame and now private _virtualPos = _lastPos vectorAdd (_vectorDir vectorMultiply _stepSize); #ifdef DRAW_NLAW_INFO - drawLine3D [ASLtoAGL _virtualPos, ASLtoAGL (_virtualPos vectorAdd [0,0,-5]), [1,0,_stepSize/(_frameDistance max 0.1),1]]; + drawLine3D [ASLToAGL _virtualPos, ASLToAGL (_virtualPos vectorAdd [0,0,-5]), [1,0,_stepSize/(_frameDistance max 0.1),1]]; #endif // Limit scan to 5 meters directly down (shaped charge jet has a very limited range) @@ -58,7 +71,7 @@ if ((_projPos distance _launchPos) >= 20) 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); - TRACE_2("",_target worldToModel (ASLtoAGL _virtualPos),boundingBoxReal _target); + TRACE_2("",_target worldToModel (ASLToAGL _virtualPos),boundingBoxReal _target); _virtualPos = _virtualPos vectorAdd (_vectorDir vectorMultiply 1.25); deleteVehicle _projectile; diff --git a/addons/noradio/stringtable.xml b/addons/noradio/stringtable.xml index d1cf51f0e6a..d41827ebfad 100644 --- a/addons/noradio/stringtable.xml +++ b/addons/noradio/stringtable.xml @@ -12,6 +12,7 @@ Нет рации No Radio Pas de radio + Sem Rádio Mute Player diff --git a/addons/novehicleclanlogo/stringtable.xml b/addons/novehicleclanlogo/stringtable.xml index d3f01899a90..1e07c85ce8c 100644 --- a/addons/novehicleclanlogo/stringtable.xml +++ b/addons/novehicleclanlogo/stringtable.xml @@ -5,23 +5,25 @@ 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 + Remover logo do clã de veículos 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. + Previne o logo do clã de ser mostrado em veículos controlados por jogadores. diff --git a/addons/optics/CfgEventHandlers.hpp b/addons/optics/CfgEventHandlers.hpp deleted file mode 100644 index f6503c2479b..00000000000 --- a/addons/optics/CfgEventHandlers.hpp +++ /dev/null @@ -1,17 +0,0 @@ -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/optics/CfgOpticsEffect.hpp b/addons/optics/CfgOpticsEffect.hpp deleted file mode 100644 index 30c372fdac4..00000000000 --- a/addons/optics/CfgOpticsEffect.hpp +++ /dev/null @@ -1,7 +0,0 @@ -class CfgOpticsEffect { - class ACE_OpticsRadBlur1 { - type = "radialblur"; - params[] = {0.015, 0, 0.14, 0.2}; - priority = 950; - }; -}; diff --git a/addons/optics/CfgPreloadTextures.hpp b/addons/optics/CfgPreloadTextures.hpp index 1354f91e18e..b4bf27f76ff 100644 --- a/addons/optics/CfgPreloadTextures.hpp +++ b/addons/optics/CfgPreloadTextures.hpp @@ -1,49 +1,38 @@ -#define MACRO_PRELOAD \ - GVAR(BodyDay) = "*"; \ - GVAR(BodyNight) = "*"; \ - GVAR(ReticleDay) = "*"; \ - GVAR(ReticleNight) = "*" - class PreloadTextures { class CfgWeapons { class ACE_optic_Hamr_2D { - MACRO_PRELOAD; + PRELOAD; }; - class ACE_optic_Hamr_PIP { - MACRO_PRELOAD; + PRELOAD; }; class ACE_optic_Arco_2D { - MACRO_PRELOAD; + PRELOAD; }; - class ACE_optic_Arco_PIP { - MACRO_PRELOAD; + PRELOAD; }; class ACE_optic_MRCO_2D { - MACRO_PRELOAD; + PRELOAD; }; - class ACE_optic_MRCO_PIP { - MACRO_PRELOAD; + PRELOAD; }; class ACE_optic_SOS_2D { - MACRO_PRELOAD; + PRELOAD; }; - class ACE_optic_SOS_PIP { - MACRO_PRELOAD; + PRELOAD; }; class ACE_optic_LRPS_2D { - MACRO_PRELOAD; + PRELOAD; }; - class ACE_optic_LRPS_PIP { - MACRO_PRELOAD; + PRELOAD; }; }; }; diff --git a/addons/optics/CfgRscTitles.hpp b/addons/optics/CfgRscTitles.hpp deleted file mode 100644 index bb01281a22f..00000000000 --- a/addons/optics/CfgRscTitles.hpp +++ /dev/null @@ -1,204 +0,0 @@ -class RscOpticsValue; -class RscMapControl; -class RscText; - -class RscInGameUI { - class RscUnitInfo; - class RscWeaponZeroing: RscUnitInfo { - class CA_Zeroing; - }; - - class ACE_RscWeaponZeroing: RscWeaponZeroing { - controls[] = {"CA_Zeroing", "CA_FOVMode", "ACE_DrawReticleHelper", "ACE_ScriptedReticle"}; - - class CA_FOVMode: RscOpticsValue { // Idea by Taosenai. Apparently this can be used via isNil check to determine wheter the scope or the kolimator is used - idc = 154; - style = 2; - colorText[] = {0, 0, 0, 0}; - x = 0; - y = 0; - w = 0; - h = 0; - }; - - class ACE_DrawReticleHelper: RscMapControl { - onDraw = QUOTE([ctrlParent (_this select 0)] call DFUNC(onDrawScope)); - idc = -1; - w = 0; - h = 0; - }; - - class ACE_ScriptedReticle: RscText { - idc = 1713154; - style = 48; - size = 1; - sizeEx = 0; - text = QPATHTOF(reticles\ace_shortdot_reticle_1.paa); - w = 0; - h = 0; - }; - }; - - class ACE_RscWeapon_base: RscWeaponZeroing { - controls[] = {"CA_Zeroing", "CA_FOVMode", "ACE_DrawReticleHelper", "ReticleDay", "ReticleNight", "BodyNight", "BodyDay", "trippleHeadLeft", "trippleHeadRight"}; // Don't change this order - - class CA_FOVMode: RscOpticsValue { // Idea by Taosenai. Apparently this can be used via isNil check to determine wheter the scope or the kolimator is used - idc = 154; - style = 2; - colorText[] = {0, 0, 0, 0}; - x = 0; - y = 0; - w = 0; - h = 0; - }; - - class ACE_DrawReticleHelper: RscMapControl { - onDraw = QUOTE([ctrlParent (_this select 0)] call DFUNC(onDrawScope2D)); - idc = -1; - w = 0; - h = 0; - }; - - #define SIZEX 0.75/(getResolution select 5) - class ReticleDay: RscText { - idc = 1713001; - style = 48; - size = 0; - sizeEx = 1; - text = ""; - colorText[] = {1, 1, 1, 0}; - colorBackground[] = {0, 0, 0, 0}; - 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 { - idc = 1713002; - text = ""; - }; - - #undef SIZEX - #define SIZEX 2*0.75/(getResolution select 5) - class BodyDay: ReticleDay { - idc = 1713005; - text = ""; - 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 { - idc = 1713006; - text = ""; - }; - - // These are just black side panels to cover the areas that the optics p3d doesn't cover - // It will ONLY effect tripple head users as (safezoneX == safeZoneXAbs) for everyone else - // Reference PR #1156: - class trippleHeadLeft: RscText { - idc = 1713010; - x = "safeZoneXAbs"; - Y = "safezoneY"; - W = "(safezoneX - safeZoneXAbs) * ((getResolution select 4) / (16 / 3))"; - H = "safeZoneH"; - colorBackground[] = {0, 0, 0, 1}; - }; - class trippleHeadRight: trippleHeadLeft { - idc = 1713011; - x = "safeZoneXAbs + safeZoneWAbs - (safezoneX - safeZoneXABS) * ((getResolution select 4) / (16 / 3))"; - colorBackground[] = {0, 0, 0, 1}; - }; - }; - - class ACE_RscWeapon_Hamr: ACE_RscWeapon_base { - class ReticleDay: ReticleDay { - text = QPATHTOF(reticles\hamr-reticle65_ca.paa); - }; - - class ReticleNight: ReticleNight { - text = QPATHTOF(reticles\hamr-reticle65Illum_ca.paa); - }; - - class BodyDay: BodyDay { - text = QPATHTOF(reticles\hamr-body_ca.paa); - }; - - class BodyNight: BodyNight { - text = QPATHTOF(reticles\hamr-bodyNight_ca.paa); - }; - }; - - class ACE_RscWeapon_Arco: ACE_RscWeapon_base { - class ReticleDay: ReticleDay { - text = QPATHTOF(reticles\arco-reticle65_ca.paa); - }; - - class ReticleNight: ReticleNight { - text = QPATHTOF(reticles\arco-reticle65Illum_ca.paa); - }; - - class BodyDay: BodyDay { - text = QPATHTOF(reticles\arco-body_ca.paa); - }; - - class BodyNight: BodyNight { - text = QPATHTOF(reticles\arco-bodyNight_ca.paa); - }; - }; - - class ACE_RscWeapon_MRCO: ACE_RscWeapon_base { - class ReticleDay: ReticleDay { - text = QPATHTOF(reticles\mrco-reticle556_ca.paa); - }; - - class ReticleNight: ReticleNight { - text = QPATHTOF(reticles\mrco-reticle556Illum_ca.paa); - }; - - class BodyDay: BodyDay { - text = QPATHTOF(reticles\mrco-body_ca.paa); - }; - - class BodyNight: BodyNight { - text = QPATHTOF(reticles\mrco-bodyNight_ca.paa); - }; - }; - - class ACE_RscWeapon_SOS: ACE_RscWeapon_base { - class ReticleDay: ReticleDay { - text = QPATHTOF(reticles\sos-reticleMLR_ca.paa); - }; - - class ReticleNight: ReticleNight { - text = QPATHTOF(reticles\sos-reticleMLRIllum_ca.paa); - }; - - class BodyDay: BodyDay { - text = QPATHTOF(reticles\sos-body_ca.paa); - }; - - class BodyNight: BodyNight { - text = QPATHTOF(reticles\sos-bodyNight_ca.paa); - }; - }; -}; - -/* - -_ctrl = (D displayCtrl 1713006); - -_sizeX = 1.54 / (getResolution select 5); -_sizeY = _sizeX * safezoneW / safezoneH; - -_ctrl ctrlSetPosition [ - safezoneX + 0.5 * safezoneW - 0.5 * _sizeX, - safezoneY + 0.5 * safezoneH - 0.5 * _sizeY, - _sizeX, - _sizeY -]; -_ctrl ctrlCommit 0 - - */ diff --git a/addons/optics/CfgVehicles.hpp b/addons/optics/CfgVehicles.hpp index eda9a3d930c..41e2d8ab039 100644 --- a/addons/optics/CfgVehicles.hpp +++ b/addons/optics/CfgVehicles.hpp @@ -3,16 +3,10 @@ class CfgVehicles { class ACE_Box_Misc: Box_NATO_Support_F { class TransportItems { MACRO_ADDITEM(ACE_optic_Hamr_2D,2); - MACRO_ADDITEM(ACE_optic_Hamr_PIP,2); MACRO_ADDITEM(ACE_optic_Arco_2D,2); - MACRO_ADDITEM(ACE_optic_Arco_PIP,2); MACRO_ADDITEM(ACE_optic_MRCO_2D,2); - //MACRO_ADDITEM(ACE_optic_MRCO_PIP,2); MACRO_ADDITEM(ACE_optic_SOS_2D,2); - MACRO_ADDITEM(ACE_optic_SOS_PIP,2); MACRO_ADDITEM(ACE_optic_LRPS_2D,2); - MACRO_ADDITEM(ACE_optic_LRPS_PIP,2); - //MACRO_ADDITEM(ACE_optic_DMS,2); }; }; }; diff --git a/addons/optics/CfgWeapons.hpp b/addons/optics/CfgWeapons.hpp index 8088a5fcd36..90cccb32866 100644 --- a/addons/optics/CfgWeapons.hpp +++ b/addons/optics/CfgWeapons.hpp @@ -1,110 +1,62 @@ class CfgWeapons { class ItemCore; class InventoryOpticsItem_Base_F; - class Default; - - class Binocular: Default { - forceOptics = 0; // Allow using compass with Binocular - opticsZoomMin = 0.056889; // 5.25x power - opticsZoomMax = 0.056889; // 9 px/mil - modelOptics = "\z\ace\addons\optics\models\NWD_M22_5x"; // 7 degrees horizontal field of view - visionMode[] = {"Normal"}; // Can't use nvgs with binoculars any more than you can with scopes - // Fix AI using Binocs on short range - #18737 - // minRange = 300; // 300 = uses Rangefinder often (runs a few meters, stops, uses RF, repeats) - minRange = 500; //500 = seem almost never use it..? - minRangeProbab = 0.001; - midRange = 1000; - midRangeProbab = 0.01; - maxRange = 5000; - maxRangeProbab = 0.01; - }; - // zooming reticle scopes - class optic_DMS: ItemCore { + // HAMR + class optic_Hamr: ItemCore { class ItemInfo: InventoryOpticsItem_Base_F { class OpticsModes { - class Snip; - class Iron; + class Hamr2Scope; + class Hamr2Collimator; }; }; }; - /*class ACE_optic_DMS: optic_DMS { + class ACE_optic_Hamr_2D: optic_Hamr { author = ECSTRING(common,ACETeam); - _generalMacro = "ACE_optic_DMS"; - scope = 1; - displayName = "LOCALIZE ACE DMS"; - //descriptionShort = "$STR_A3_CFGWEAPONS_ACC_DMS1"; - weaponInfoType = "ACE_RscWeaponZeroing"; + scope = 2; + displayName = CSTRING(hamr); - class ItemInfo: ItemInfo { - modelOptics = QPATHTOF(models\ace_shortdot_optics.p3d); + class CBA_ScriptedOptic { + opticsPPEffects[] = {"CBA_OpticsRadBlur3"}; - class OpticsModes: OpticsModes { - class Snip: Snip { - opticsZoomMin = 0.05; - opticsZoomMax = 0.3; - opticsZoomInit = 0.3; - discretefov[] = {}; - modelOptics[] = {}; - }; + reticleTexture = QPATHTOF(reticles\hamr-reticle65_ca.paa); + reticleTextureNight = QPATHTOF(reticles\hamr-reticle65Illum_ca.paa); + reticleTextureSize = 6 / 25 * 4; // At 25x using https://github.com/CBATeam/CBA_A3/wiki/Scripted-Optics#debug-reticle, the best choice is 6 - class Iron: Iron {}; - }; - }; - };*/ + bodyTexture = QPATHTOF(reticles\hamr-body_ca.paa); + bodyTextureNight = QPATHTOF(reticles\hamr-bodyNight_ca.paa); + bodyTextureSize = 2.2; - // PIP scopes - class optic_Hamr: ItemCore { - class ItemInfo: InventoryOpticsItem_Base_F { - class OpticsModes { - class Hamr2Collimator; - class Hamr2Scope; - }; + hideMagnification = 1; }; - }; - - class ACE_optic_Hamr_2D: optic_Hamr { - GVAR(BodyDay) = QPATHTOF(reticles\hamr-body_ca.paa); - GVAR(BodyNight) = QPATHTOF(reticles\hamr-bodyNight_ca.paa); - GVAR(ReticleDay) = QPATHTOF(reticles\hamr-reticle65_ca.paa); - GVAR(ReticleNight) = QPATHTOF(reticles\hamr-reticle65Illum_ca.paa); - - author = ECSTRING(common,ACETeam); - _generalMacro = "ACE_optic_Hamr_2D"; - displayName = CSTRING(hamr); - weaponInfoType = "ACE_RscWeapon_Hamr"; + weaponInfoType = "CBA_ScriptedOptic"; class ItemInfo: ItemInfo { - modelOptics = QPATHTOF(models\ace_optics_reticle90.p3d); + modelOptics = "\x\cba\addons\optics\cba_optic_big_90.p3d"; class OpticsModes: OpticsModes { - class Hamr2Collimator: Hamr2Collimator {}; - class Hamr2Scope: Hamr2Scope { useModelOptics = 1; - opticsZoomInit = 0.0872664626; - opticsZoomMax = 0.0872664626; - opticsZoomMin = 0.0872664626; - opticsPPEffects[] = {"OpticsCHAbera5", "OpticsBlur5", "ACE_OpticsRadBlur1"}; - opticsDisablePeripherialVision = 0; - visionMode[] = {"Normal", "NVG"}; + opticsZoomInit = 0.25 / 4; + opticsZoomMax = 0.25 / 4; + opticsZoomMin = 0.25 / 4; }; + class Hamr2Collimator: Hamr2Collimator {}; }; }; }; - class ACE_optic_Hamr_PIP: ACE_optic_Hamr_2D { author = ECSTRING(common,ACETeam); - _generalMacro = "ACE_optic_Hamr_PIP"; - //scopeArsenal = 1; + scope = 1; displayName = CSTRING(hamr_pip); class ItemInfo: ItemInfo { - modelOptics = QPATHTOF(models\ace_optics_pip.p3d); + modelOptics = "\x\cba\addons\optics\cba_optic_big_pip.p3d"; }; }; + // ARCO class optic_Arco: ItemCore { class ItemInfo: InventoryOpticsItem_Base_F { class OpticsModes { @@ -115,95 +67,104 @@ class CfgWeapons { }; class ACE_optic_Arco_2D: optic_Arco { - GVAR(BodyDay) = QPATHTOF(reticles\arco-body_ca.paa); - GVAR(BodyNight) = QPATHTOF(reticles\arco-bodyNight_ca.paa); - GVAR(ReticleDay) = QPATHTOF(reticles\arco-reticle65_ca.paa); - GVAR(ReticleNight) = QPATHTOF(reticles\arco-reticle65Illum_ca.paa); - author = ECSTRING(common,ACETeam); - _generalMacro = "ACE_optic_Arco_2D"; + scope = 2; displayName = CSTRING(arco); - weaponInfoType = "ACE_RscWeapon_Arco"; + + class CBA_ScriptedOptic { + opticsPPEffects[] = {"CBA_OpticsRadBlur3"}; + + reticleTexture = QPATHTOF(reticles\arco-reticle65_ca.paa); + reticleTextureNight = QPATHTOF(reticles\arco-reticle65Illum_ca.paa); + reticleTextureSize = 6.4 / 25 * 4; // At 25x using https://github.com/CBATeam/CBA_A3/wiki/Scripted-Optics#debug-reticle, the best choice is 6.4 + + bodyTexture = QPATHTOF(reticles\arco-body_ca.paa); + bodyTextureNight = QPATHTOF(reticles\arco-bodyNight_ca.paa); + bodyTextureSize = 2.2; + + hideMagnification = 1; + }; + weaponInfoType = "CBA_ScriptedOptic"; class ItemInfo: ItemInfo { - modelOptics = QPATHTOF(models\ace_optics_reticle90.p3d); + modelOptics = "\x\cba\addons\optics\cba_optic_big_90.p3d"; class OpticsModes: OpticsModes { - class ARCO2collimator: ARCO2collimator {}; class ARCO2scope: ARCO2scope { useModelOptics = 1; - opticsZoomInit = 0.0872664626; - opticsZoomMax = 0.0872664626; - opticsZoomMin = 0.0872664626; - opticsPPEffects[] = {"OpticsCHAbera5", "OpticsBlur5", "ACE_OpticsRadBlur1"}; - opticsDisablePeripherialVision = 0; - visionMode[] = {"Normal"}; + opticsZoomInit = 0.25 / 4; + opticsZoomMax = 0.25 / 4; + opticsZoomMin = 0.25 / 4; }; + class ARCO2collimator: ARCO2collimator {}; }; }; }; - class ACE_optic_Arco_PIP: ACE_optic_Arco_2D { author = ECSTRING(common,ACETeam); - _generalMacro = "ACE_optic_Arco_PIP"; - //scopeArsenal = 1; + scope = 1; displayName = CSTRING(arco_pip); class ItemInfo: ItemInfo { - modelOptics = QPATHTOF(models\ace_optics_pip.p3d); + modelOptics = "\x\cba\addons\optics\cba_optic_big_pip.p3d"; }; }; + // MRCO class optic_MRCO: ItemCore { class ItemInfo: InventoryOpticsItem_Base_F { class OpticsModes { - class MRCOcq; class MRCOscope; + class MRCOcq; }; }; }; class ACE_optic_MRCO_2D: optic_MRCO { - GVAR(BodyDay) = QPATHTOF(reticles\mrco-body_ca.paa); - GVAR(BodyNight) = QPATHTOF(reticles\mrco-bodyNight_ca.paa); - GVAR(ReticleDay) = QPATHTOF(reticles\mrco-reticle556_ca.paa); - GVAR(ReticleNight) = QPATHTOF(reticles\mrco-reticle556Illum_ca.paa); - author = ECSTRING(common,ACETeam); - _generalMacro = "ACE_optic_MRCO_2D"; - displayName = CSTRING(valdada); - weaponInfoType = "ACE_RscWeapon_MRCO"; + scope = 2; + displayName = CSTRING(mrco); + + class CBA_ScriptedOptic { + opticsPPEffects[] = {"CBA_OpticsRadBlur3"}; + + reticleTexture = QPATHTOF(reticles\mrco-reticle556_ca.paa); + reticleTextureNight = QPATHTOF(reticles\mrco-reticle556Illum_ca.paa); + reticleTextureSize = 6.4 / 25 * 4; // At 25x using https://github.com/CBATeam/CBA_A3/wiki/Scripted-Optics#debug-reticle, the best choice is 6.4 + + bodyTexture = QPATHTOF(reticles\mrco-body_ca.paa); + bodyTextureNight = QPATHTOF(reticles\mrco-bodyNight_ca.paa); + bodyTextureSize = 2.2; + + hideMagnification = 1; + }; + weaponInfoType = "CBA_ScriptedOptic"; class ItemInfo: ItemInfo { - modelOptics = QPATHTOF(models\ace_optics_reticle90.p3d); + modelOptics = "\x\cba\addons\optics\cba_optic_big_90.p3d"; class OpticsModes: OpticsModes { - class MRCOcq: MRCOcq {}; class MRCOscope: MRCOscope { useModelOptics = 1; - opticsZoomInit = 0.0872664626; - opticsZoomMax = 0.0872664626; - opticsZoomMin = 0.0872664626; - opticsPPEffects[] = {"OpticsCHAbera5", "OpticsBlur5", "ACE_OpticsRadBlur1"}; - opticsDisablePeripherialVision = 0; - visionMode[] = {"Normal"}; + opticsZoomInit = 0.25 / 4; + opticsZoomMax = 0.25 / 4; + opticsZoomMin = 0.25 / 4; }; + class MRCOcq: MRCOcq {}; }; }; }; - class ACE_optic_MRCO_PIP: ACE_optic_MRCO_2D { author = ECSTRING(common,ACETeam); - _generalMacro = "ACE_optic_MRCO_PIP"; scope = 1; - //scopeArsenal = 1; - displayName = CSTRING(valdada_pip); + displayName = CSTRING(mrco_pip); class ItemInfo: ItemInfo { - modelOptics = QPATHTOF(models\ace_optics_pip.p3d); + modelOptics = "\x\cba\addons\optics\cba_optic_big_pip.p3d"; }; }; + // SOS class optic_SOS: ItemCore { class ItemInfo: InventoryOpticsItem_Base_F { class OpticsModes { @@ -214,49 +175,53 @@ class CfgWeapons { }; class ACE_optic_SOS_2D: optic_SOS { - GVAR(BodyDay) = QPATHTOF(reticles\sos-body_ca.paa); - GVAR(BodyNight) = QPATHTOF(reticles\sos-bodyNight_ca.paa); - GVAR(ReticleDay) = QPATHTOF(reticles\sos-reticleMLR_ca.paa); - GVAR(ReticleNight) = QPATHTOF(reticles\sos-reticleMLRIllum_ca.paa); - author = ECSTRING(common,ACETeam); - _generalMacro = "ACE_optic_SOS_2D"; + scope = 2; displayName = CSTRING(sos); - weaponInfoType = "ACE_RscWeapon_SOS"; + + class CBA_ScriptedOptic { + opticsPPEffects[] = {"CBA_OpticsRadBlur3"}; + + reticleTexture = QPATHTOF(reticles\sos-reticleMLR_ca.paa); + reticleTextureNight = QPATHTOF(reticles\sos-reticleMLRIllum_ca.paa); + reticleTextureSize = 0.76; // At 22x using https://github.com/CBATeam/CBA_A3/wiki/Scripted-Optics#debug-reticle, the best choice is 0.76 + + bodyTexture = QPATHTOF(reticles\sos-body_ca.paa); + bodyTextureNight = QPATHTOF(reticles\sos-bodyNight_ca.paa); + bodyTextureSize = 1.55; + }; + weaponInfoType = "CBA_ScriptedOptic"; class ItemInfo: ItemInfo { class OpticsModes: OpticsModes { class Snip: Snip { - modelOptics[] = {QPATHTOF(models\ace_optics_reticle90.p3d), QPATHTOF(models\ace_optics_reticle90.p3d)}; + opticsZoomMin = "5.5 call (uiNamespace getVariable 'cba_optics_fnc_setOpticMagnificationHelper')"; + opticsZoomMax = "2.75 call (uiNamespace getVariable 'cba_optics_fnc_setOpticMagnificationHelper')"; + opticsZoomInit = "2.75 call (uiNamespace getVariable 'cba_optics_fnc_setOpticMagnificationHelper')"; + discreteFov[] = {}; + modelOptics[] = {"\x\cba\addons\optics\cba_optic_big_90.p3d"}; useModelOptics = 1; - opticsZoomInit = 0.0116; - opticsZoomMax = 0.0464; - opticsZoomMin = 0.0116; - discreteFOV[] = {0.0464, 0.0116}; - opticsPPEffects[] = {"OpticsCHAbera1", "OpticsBlur1", "ACE_OpticsRadBlur1"}; - opticsDisablePeripherialVision = 0; }; class Iron: Iron {}; }; }; }; - class ACE_optic_SOS_PIP: ACE_optic_SOS_2D { author = ECSTRING(common,ACETeam); - _generalMacro = "ACE_optic_SOS_PIP"; - //scopeArsenal = 1; + scope = 1; displayName = CSTRING(sos_pip); class ItemInfo: ItemInfo { class OpticsModes: OpticsModes { class Snip: Snip { - modelOptics[] = {QPATHTOF(models\ace_optics_pip.p3d), QPATHTOF(models\ace_optics_pip.p3d)}; + modelOptics[] = {"\x\cba\addons\optics\cba_optic_big_pip.p3d"}; }; class Iron: Iron {}; }; }; }; + // LRPS class optic_LRPS: ItemCore { class ItemInfo: InventoryOpticsItem_Base_F { class OpticsModes { @@ -266,44 +231,64 @@ class CfgWeapons { }; class ACE_optic_LRPS_2D: optic_LRPS { - GVAR(BodyDay) = QPATHTOF(reticles\sos-body_ca.paa); - GVAR(BodyNight) = QPATHTOF(reticles\sos-bodyNight_ca.paa); - GVAR(ReticleDay) = QPATHTOF(reticles\sos-reticleMLR_ca.paa); - GVAR(ReticleNight) = QPATHTOF(reticles\sos-reticleMLRIllum_ca.paa); - author = ECSTRING(common,ACETeam); - _generalMacro = "ACE_optic_LRPS_2D"; + scope = 2; displayName = CSTRING(lrps); - weaponInfoType = "ACE_RscWeapon_SOS"; + + class CBA_ScriptedOptic { + opticsPPEffects[] = {"CBA_OpticsRadBlur3"}; + + reticleTexture = QPATHTOF(reticles\sos-reticleMLR_ca.paa); + reticleTextureNight = QPATHTOF(reticles\sos-reticleMLRIllum_ca.paa); + reticleTextureSize = 0.76; // At 22x using https://github.com/CBATeam/CBA_A3/wiki/Scripted-Optics#debug-reticle, the best choice is 0.76 + + bodyTexture = QPATHTOF(reticles\sos-body_ca.paa); + bodyTextureNight = QPATHTOF(reticles\sos-bodyNight_ca.paa); + bodyTextureSize = 1.55; + }; + weaponInfoType = "CBA_ScriptedOptic"; class ItemInfo: ItemInfo { class OpticsModes: OpticsModes { class Snip: Snip { - modelOptics[] = {QPATHTOF(models\ace_optics_reticle90.p3d), QPATHTOF(models\ace_optics_reticle90.p3d)}; + opticsZoomMin = "22 call (uiNamespace getVariable 'cba_optics_fnc_setOpticMagnificationHelper')"; + opticsZoomMax = "5.5 call (uiNamespace getVariable 'cba_optics_fnc_setOpticMagnificationHelper')"; + opticsZoomInit = "5.5 call (uiNamespace getVariable 'cba_optics_fnc_setOpticMagnificationHelper')"; + discreteFov[] = {}; + modelOptics[] = {"\x\cba\addons\optics\cba_optic_big_90.p3d"}; useModelOptics = 1; - opticsZoomInit = 0.0116; - opticsZoomMax = 0.0464; - opticsZoomMin = 0.0116; - discreteFOV[] = {}; - opticsPPEffects[] = {"OpticsCHAbera1", "OpticsBlur1", "ACE_OpticsRadBlur1"}; - opticsDisablePeripherialVision = 0; }; }; }; }; - class ACE_optic_LRPS_PIP: ACE_optic_LRPS_2D { author = ECSTRING(common,ACETeam); - _generalMacro = "ACE_optic_LRPS_PIP"; - //scopeArsenal = 1; + scope = 1; displayName = CSTRING(lrps_pip); class ItemInfo: ItemInfo { class OpticsModes: OpticsModes { class Snip: Snip { - modelOptics[] = {QPATHTOF(models\ace_optics_pip.p3d), QPATHTOF(models\ace_optics_pip.p3d)}; + modelOptics[] = {"\x\cba\addons\optics\cba_optic_big_pip.p3d"}; }; }; }; }; + + // Binocular + class Default; + class Binocular: Default { + opticsZoomInit = 0.056889; // 7x power IRL + opticsZoomMin = 0.056889; // but in order to make the stadiametric rangefinder useful, ~4.4x magnification has been set + opticsZoomMax = 0.056889; // 9 px/mil + modelOptics = "\z\ace\addons\optics\models\NWD_M22_5x"; // 7 degrees horizontal field of view (Steiner M22) + // Fix AI using Binocs on short range - #18737 + // minRange = 300; // 300 = uses Rangefinder often (runs a few meters, stops, uses RF, repeats) + minRange = 500; // 500 = seem almost never use it..? + minRangeProbab = 0.001; + midRange = 1000; + midRangeProbab = 0.01; + maxRange = 5000; + maxRangeProbab = 0.01; + }; }; diff --git a/addons/optics/XEH_PREP.hpp b/addons/optics/XEH_PREP.hpp deleted file mode 100644 index 8eb8eb1eb56..00000000000 --- a/addons/optics/XEH_PREP.hpp +++ /dev/null @@ -1,3 +0,0 @@ -PREP(handleFired); -PREP(onDrawScope); -PREP(onDrawScope2D); diff --git a/addons/optics/XEH_postInit.sqf b/addons/optics/XEH_postInit.sqf deleted file mode 100644 index abb97e5b5d0..00000000000 --- a/addons/optics/XEH_postInit.sqf +++ /dev/null @@ -1,31 +0,0 @@ -// by commy2 -#include "script_component.hpp" - -if (!hasInterface) exitWith {}; - -GVAR(camera) = objNull; - -// save control for fired EH -["ace_infoDisplayChanged", { - TRACE_1("ace_infoDisplayChanged",_this); - if (!isNull ((_this select 0) displayCtrl 1713001)) then { - uiNamespace setVariable [QGVAR(RscWeaponInfo2D), _this select 0]; - }; -}] call CBA_fnc_addEventHandler; - -// camera has to be re-created every time another camera is created. Otherwise r2t is either black or transparent.. -["featureCamera", { - params ["_player", "_featureCamera"]; - TRACE_1("featureCamera",_featureCamera); - if (_featureCamera isEqualTo "") then { - // Destroy the camera, and it will be re-created in the onDrawScope2d helper - if (!isNull GVAR(camera)) then { - GVAR(camera) cameraEffect ["TERMINATE", "BACK"]; - camDestroy GVAR(camera); - TRACE_1("destroying pip camera for restart",GVAR(camera)); - }; - }; -}] call CBA_fnc_addPlayerEventHandler; - -// Register fire event handler -["ace_firedPlayer", DFUNC(handleFired)] call CBA_fnc_addEventHandler; diff --git a/addons/optics/XEH_preInit.sqf b/addons/optics/XEH_preInit.sqf deleted file mode 100644 index b47cf6628db..00000000000 --- a/addons/optics/XEH_preInit.sqf +++ /dev/null @@ -1,9 +0,0 @@ -#include "script_component.hpp" - -ADDON = false; - -PREP_RECOMPILE_START; -#include "XEH_PREP.hpp" -PREP_RECOMPILE_END; - -ADDON = true; diff --git a/addons/optics/XEH_preStart.sqf b/addons/optics/XEH_preStart.sqf deleted file mode 100644 index 022888575ed..00000000000 --- a/addons/optics/XEH_preStart.sqf +++ /dev/null @@ -1,3 +0,0 @@ -#include "script_component.hpp" - -#include "XEH_PREP.hpp" diff --git a/addons/optics/config.cpp b/addons/optics/config.cpp index c1524320c73..8b61425c67b 100644 --- a/addons/optics/config.cpp +++ b/addons/optics/config.cpp @@ -10,12 +10,11 @@ class CfgPatches { "ACE_optic_Arco_2D", "ACE_optic_Arco_PIP", "ACE_optic_MRCO_2D", - //"ACE_optic_MRCO_PIP", + "ACE_optic_MRCO_PIP", "ACE_optic_SOS_2D", "ACE_optic_SOS_PIP", "ACE_optic_LRPS_2D", "ACE_optic_LRPS_PIP" - //"ACE_optic_DMS" }; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; @@ -26,12 +25,15 @@ class CfgPatches { }; }; -#include "CfgEventHandlers.hpp" - -#include "CfgOpticsEffect.hpp" -#include "CfgRscTitles.hpp" -#include "CfgVehicles.hpp" -#include "CfgWeapons.hpp" +#include "CfgPreloadTextures.hpp" #include "CfgJointRails.hpp" +#include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" -#include "CfgPreloadTextures.hpp" +class CBA_PIPItems { + 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"; +}; diff --git a/addons/optics/functions/fnc_handleFired.sqf b/addons/optics/functions/fnc_handleFired.sqf deleted file mode 100644 index f36f04d8817..00000000000 --- a/addons/optics/functions/fnc_handleFired.sqf +++ /dev/null @@ -1,104 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Taosenai - * Adapted By: KoffeinFlummi, commy2 - * - * Animates the scope when firing. Called from the unified fired EH only for the local player. - * - * Arguments: - * None. Parameters inherited from EFUNC(common,firedEH) - * - * Return Value: - * None - * - * Example: - * call ace_optics_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); - -disableSerialization; - -// Check if compatible scope is used -private _display = uiNamespace getVariable [QGVAR(RscWeaponInfo2D), displayNull]; - -if (isNull _display) exitWith {}; - -// Reduce the reticle movement as the player drops into lower, supported stances. -private _recoilCoef = switch (true) do { - case (isWeaponDeployed _unit): {0.1}; - case (isWeaponRested _unit): {0.4}; - default {1}; -}; - -// Constants which determine how the scope recoils - -private _recoilScope = _recoilCoef * linearConversion [0, 1, random 1, SCOPE_RECOIL_MIN, SCOPE_RECOIL_MAX, false]; - -private _reticleShiftX = _recoilCoef * linearConversion [0, 1, random 1, RETICLE_SHIFT_X_MIN, RETICLE_SHIFT_X_MAX, false]; -private _reticleShiftY = _recoilCoef * linearConversion [0, 1, random 1, RETICLE_SHIFT_Y_MIN, RETICLE_SHIFT_Y_MAX, false]; - -private _scopeShiftX = _recoilCoef * linearConversion [0, 1, random 1, SCOPE_SHIFT_X_MIN, SCOPE_SHIFT_X_MAX, false]; -private _scopeShiftY = _recoilCoef * linearConversion [0, 1, random 1, SCOPE_SHIFT_Y_MIN, SCOPE_SHIFT_Y_MAX, false]; - -// Create and commit recoil effect - -private _sizeX = (0.75 + _recoilScope) / (getResolution select 5); -private _sizeY = _sizeX * (4 / 3); - -private _positionReticle = [ - safezoneX + 0.5 * safezoneW - 0.5 * (_sizeX + _reticleShiftX), - safezoneY + 0.5 * safezoneH - 0.5 * (_sizeY + _reticleShiftY), - _sizeX, - _sizeY -]; - -(_display displayCtrl 1713001) ctrlSetPosition _positionReticle; -(_display displayCtrl 1713002) ctrlSetPosition _positionReticle; - -private _positionBody = [ - safezoneX + 0.5 * safezoneW - 0.5 * (2 * _sizeX + _scopeShiftX), - safezoneY + 0.5 * safezoneH - 0.5 * (2 * _sizeY + _scopeShiftY), - 2 * _sizeX, - 2 * _sizeY -]; - -(_display displayCtrl 1713005) ctrlSetPosition _positionBody; -(_display displayCtrl 1713006) ctrlSetPosition _positionBody; - -(_display displayCtrl 1713001) ctrlCommit 0; -(_display displayCtrl 1713002) ctrlCommit 0; -(_display displayCtrl 1713005) ctrlCommit 0; -(_display displayCtrl 1713006) ctrlCommit 0; - -// Bring them all back -_sizeX = 0.75 / (getResolution select 5); -_sizeY = _sizeX * (4 / 3); - -_positionReticle = [ - safezoneX + 0.5 * safezoneW - 0.5 * _sizeX, - safezoneY + 0.5 * safezoneH - 0.5 * _sizeY, - _sizeX, - _sizeY -]; - -(_display displayCtrl 1713001) ctrlSetPosition _positionReticle; -(_display displayCtrl 1713002) ctrlSetPosition _positionReticle; - -_positionBody = [ - safezoneX + 0.5 * safezoneW - 0.5 * 2 * _sizeX, - safezoneY + 0.5 * safezoneH - 0.5 * 2 * _sizeY, - 2 * _sizeX, - 2 * _sizeY -]; - -(_display displayCtrl 1713005) ctrlSetPosition _positionBody; -(_display displayCtrl 1713006) ctrlSetPosition _positionBody; - -(_display displayCtrl 1713001) ctrlCommit RECENTER_TIME; -(_display displayCtrl 1713002) ctrlCommit RECENTER_TIME; -(_display displayCtrl 1713005) ctrlCommit RECENTER_TIME; -(_display displayCtrl 1713006) ctrlCommit RECENTER_TIME; diff --git a/addons/optics/functions/fnc_onDrawScope.sqf b/addons/optics/functions/fnc_onDrawScope.sqf deleted file mode 100644 index 4b1b9e321df..00000000000 --- a/addons/optics/functions/fnc_onDrawScope.sqf +++ /dev/null @@ -1,39 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * - * - * Arguments: - * 0: Display - * - * Return Value: - * None - * - * Example: - * [DISPLAY] call ace_optics_fnc_onDrawScope - * - * Public: No - */ - -disableSerialization; - -params ["_display"]; - -private _control = _display displayCtrl 1713154; - -if (!ctrlShown (_display displayCtrl 154)) exitWith { - _control ctrlShow false; -}; - -private _sizeX = (call EFUNC(common,getZoom)) / 4; -private _sizeY = _sizeX * safezoneW / safezoneH; - -_control ctrlSetPosition [ - safezoneX + 0.5 * safezoneW - 0.5 * _sizeX, - safezoneY + 0.5 * safezoneH - 0.5 * _sizeY, - _sizeX, - _sizeY -]; - -_control ctrlCommit 0; -_control ctrlShow true; diff --git a/addons/optics/functions/fnc_onDrawScope2D.sqf b/addons/optics/functions/fnc_onDrawScope2D.sqf deleted file mode 100644 index c7fb19c9c13..00000000000 --- a/addons/optics/functions/fnc_onDrawScope2D.sqf +++ /dev/null @@ -1,103 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Helper function for updating the 2d and 3d scope controls - * Called from a dummy map controls onDraw. - * - * Arguments: - * 0: Display (RscInGameUI for a weapon) - * - * Return Value: - * None - * - * Example: - * [ACE_RscWeapon_Arco's Display] call ace_optics_fnc_onDrawScope2D - * - * Public: No - */ - -disableSerialization; - -params ["_display"]; - -// @todo, all weapon types -private _optic = (primaryWeaponItems ACE_player) select 2; -private _isPIP = (getText (configFile >> "CfgWeapons" >> _optic >> "ItemInfo" >> "modelOptics")) == QPATHTOF(models\ace_optics_pip.p3d); - -if (_isPIP) then { - GVAR(pipLastFrame) = diag_frameno; - if (isNull GVAR(camera)) then { - if ((({_x != GVAR(camera)} count allMissionObjects "camera") > 0) || {!isNull curatorCamera}) exitWith { - TRACE_1("waiting for feature camera to end",GVAR(camera)); - }; - - // PiP technique by BadBenson - GVAR(camera) = "camera" camCreate positionCameraToWorld [0, 0, 0]; - GVAR(camera) camSetFov 0.7; - GVAR(camera) camSetTarget ACE_player; - GVAR(camera) camCommit 1; - - QGVAR(rendertarget0) setPiPEffect [0]; - GVAR(camera) cameraEffect ["INTERNAL", "BACK", QGVAR(rendertarget0)]; - - TRACE_2("created new pip camera",GVAR(camera),isNull GVAR(camera)); - - // Start a waitUntil to handle destruction after GVAR(pipLastFrame) is no longer updated - [{ - (abs (diag_frameno - GVAR(pipLastFrame))) > 1 - }, { - GVAR(camera) cameraEffect ["TERMINATE", "BACK"]; - camDestroy GVAR(camera); - TRACE_2("destroyed pip camera",GVAR(camera),isNull GVAR(camera)); - }, []] call CBA_fnc_waitUntilAndExecute; - }; -}; - -//If we are not zoomed into the actual scope (not collimator) -if (!ctrlShown (_display displayCtrl 154)) exitWith { - (_display displayCtrl 1713001) ctrlShow false; - (_display displayCtrl 1713002) ctrlShow false; - (_display displayCtrl 1713005) ctrlShow false; - (_display displayCtrl 1713006) ctrlShow false; - (_display displayCtrl 1713010) ctrlShow false; - (_display displayCtrl 1713011) ctrlShow false; -}; - -if (_isPIP) then { - GVAR(camera) setPosATL positionCameraToWorld [0, 0, 0.4]; - GVAR(camera) camPrepareTarget positionCameraToWorld [0, 0, 50]; - GVAR(camera) camCommitPrepared 0; - - // @todo, check if that needs to be done at all - if (cameraView == "GUNNER") then { - GVAR(camera) camsetFOV 0.7; - GVAR(camera) camcommit 0; - } else { - GVAR(camera) camsetFOV 0.01; - GVAR(camera) camcommit 0; - }; -}; - -// Calculate lighting -private _dayOpacity = call EFUNC(common,ambientBrightness); -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, parseNumber (_dayOpacity < 0.5)]; -(_display displayCtrl 1713005) ctrlSetTextColor [1, 1, 1, _dayOpacity]; -(_display displayCtrl 1713006) ctrlSetTextColor [1, 1, 1, _nightOpacity]; - -/* -(_display displayCtrl 1713001) ctrlCommit 0; -(_display displayCtrl 1713002) ctrlCommit 0; -(_display displayCtrl 1713005) ctrlCommit 0; -(_display displayCtrl 1713006) ctrlCommit 0; - */ - -(_display displayCtrl 1713001) ctrlShow true; -(_display displayCtrl 1713002) ctrlShow true; -(_display displayCtrl 1713005) ctrlShow true; -(_display displayCtrl 1713006) ctrlShow true; -(_display displayCtrl 1713010) ctrlShow _isPIP; -(_display displayCtrl 1713011) ctrlShow _isPIP; diff --git a/addons/optics/models/ace_optics_empty.p3d b/addons/optics/models/ace_optics_empty.p3d deleted file mode 100644 index 89a29d7d8ce..00000000000 Binary files a/addons/optics/models/ace_optics_empty.p3d and /dev/null differ diff --git a/addons/optics/models/ace_optics_pip.p3d b/addons/optics/models/ace_optics_pip.p3d deleted file mode 100644 index 9ec67652942..00000000000 Binary files a/addons/optics/models/ace_optics_pip.p3d and /dev/null differ diff --git a/addons/optics/models/ace_optics_reticle100.p3d b/addons/optics/models/ace_optics_reticle100.p3d deleted file mode 100644 index b5f58cfd1c8..00000000000 Binary files a/addons/optics/models/ace_optics_reticle100.p3d and /dev/null differ diff --git a/addons/optics/models/ace_optics_reticle70.p3d b/addons/optics/models/ace_optics_reticle70.p3d deleted file mode 100644 index 5aa9e8613a8..00000000000 Binary files a/addons/optics/models/ace_optics_reticle70.p3d and /dev/null differ diff --git a/addons/optics/models/ace_optics_reticle80.p3d b/addons/optics/models/ace_optics_reticle80.p3d deleted file mode 100644 index 55cf2330321..00000000000 Binary files a/addons/optics/models/ace_optics_reticle80.p3d and /dev/null differ diff --git a/addons/optics/models/ace_optics_reticle90.p3d b/addons/optics/models/ace_optics_reticle90.p3d deleted file mode 100644 index 30dc511df99..00000000000 Binary files a/addons/optics/models/ace_optics_reticle90.p3d and /dev/null differ diff --git a/addons/optics/models/ace_shortdot_optics.p3d b/addons/optics/models/ace_shortdot_optics.p3d deleted file mode 100644 index 47b82be4b71..00000000000 Binary files a/addons/optics/models/ace_shortdot_optics.p3d and /dev/null differ diff --git a/addons/optics/reticles/ace_shortdot_reticle_1.paa b/addons/optics/reticles/ace_shortdot_reticle_1.paa deleted file mode 100644 index 6c3d23668ae..00000000000 Binary files a/addons/optics/reticles/ace_shortdot_reticle_1.paa and /dev/null differ diff --git a/addons/optics/reticles/ace_shortdot_reticle_2.paa b/addons/optics/reticles/ace_shortdot_reticle_2.paa deleted file mode 100644 index beb7a651c93..00000000000 Binary files a/addons/optics/reticles/ace_shortdot_reticle_2.paa and /dev/null differ diff --git a/addons/optics/reticles/black.rvmat b/addons/optics/reticles/black.rvmat deleted file mode 100644 index 431d76689f5..00000000000 --- a/addons/optics/reticles/black.rvmat +++ /dev/null @@ -1,8 +0,0 @@ -ambient[]={0,0,0,0.89999998}; -diffuse[]={0,0,0,0.89999998}; -forcedDiffuse[]={0,0,0,1}; -emmisive[]={0,0,0,1}; -specular[]={0,0,0,0}; -specularPower=1; -PixelShaderID="Normal"; -VertexShaderID="Basic"; diff --git a/addons/optics/reticles/em.rvmat b/addons/optics/reticles/em.rvmat deleted file mode 100644 index a491df4b9a7..00000000000 --- a/addons/optics/reticles/em.rvmat +++ /dev/null @@ -1,20 +0,0 @@ -ambient[]={1,1,1,1}; -diffuse[]={1,1,1,1}; -forcedDiffuse[]={0,0,0,0}; -emmisive[]={1,1,1,1}; -specular[]={1,0.99956858,1,1}; -specularPower=1; -PixelShaderID="Normal"; -VertexShaderID="Basic"; -class Stage1 -{ - 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}; - }; -}; diff --git a/addons/optics/reticles/scopeblack-100_ca.paa b/addons/optics/reticles/scopeblack-100_ca.paa deleted file mode 100644 index d0232dc0ccd..00000000000 Binary files a/addons/optics/reticles/scopeblack-100_ca.paa and /dev/null differ diff --git a/addons/optics/reticles/scopeblack-70_ca.paa b/addons/optics/reticles/scopeblack-70_ca.paa deleted file mode 100644 index 62b06d7f844..00000000000 Binary files a/addons/optics/reticles/scopeblack-70_ca.paa and /dev/null differ diff --git a/addons/optics/reticles/scopeblack-80_ca.paa b/addons/optics/reticles/scopeblack-80_ca.paa deleted file mode 100644 index f74e3e41f1b..00000000000 Binary files a/addons/optics/reticles/scopeblack-80_ca.paa and /dev/null differ diff --git a/addons/optics/reticles/scopeblack-90_ca.paa b/addons/optics/reticles/scopeblack-90_ca.paa deleted file mode 100644 index 2240dcc5fe0..00000000000 Binary files a/addons/optics/reticles/scopeblack-90_ca.paa and /dev/null differ diff --git a/addons/optics/script_component.hpp b/addons/optics/script_component.hpp index 6cc168aea0c..e57cd984b0b 100644 --- a/addons/optics/script_component.hpp +++ b/addons/optics/script_component.hpp @@ -16,17 +16,10 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define SCOPE_RECOIL_MIN 0.03 -#define SCOPE_RECOIL_MAX 0.032 - -#define SCOPE_SHIFT_X_MIN 0.04 -#define SCOPE_SHIFT_X_MAX 0.05 -#define SCOPE_SHIFT_Y_MIN -0.02 -#define SCOPE_SHIFT_Y_MAX -0.03 - -#define RETICLE_SHIFT_X_MIN 0.006 -#define RETICLE_SHIFT_X_MAX 0.011 -#define RETICLE_SHIFT_Y_MIN -0.009 -#define RETICLE_SHIFT_Y_MAX -0.014 - -#define RECENTER_TIME 0.09 +#define PRELOAD \ +class CBA_ScriptedOptic {\ + reticleTexture = "*";\ + reticleTextureNight = "*";\ + bodyTexture = "*";\ + bodyTextureNight = "*";\ +} diff --git a/addons/optics/stringtable.xml b/addons/optics/stringtable.xml index 85620ac37c7..5433f805092 100644 --- a/addons/optics/stringtable.xml +++ b/addons/optics/stringtable.xml @@ -69,7 +69,7 @@ 先進步槍戰鬥光學瞄準鏡(擬真版) ARCO (PIP) - + MRCO (2D) MRCO (2D) MRCO (2D) @@ -86,7 +86,7 @@ 多距離戰鬥瞄準鏡(2D) MRCO (2D) - + MRCO (PIP) MRCO (PIP) MRCO (PIP) diff --git a/addons/optionsmenu/config.cpp b/addons/optionsmenu/config.cpp index 811b1eecece..0d9977be7a5 100644 --- a/addons/optionsmenu/config.cpp +++ b/addons/optionsmenu/config.cpp @@ -29,13 +29,6 @@ class CfgAddons { #include "gui\mainMenu.hpp" #include "gui\pauseMenu.hpp" -class ACE_Extensions { - class ace_clipboard { - windows = 1; - client = 1; - }; -}; - class CfgCommands { allowedHTMLLoadURIs[] += { "https://ace3.acemod.org/version.html" diff --git a/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf b/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf index 07205dc1952..00d97d20082 100644 --- a/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf +++ b/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf @@ -19,8 +19,7 @@ private _outputText = { diag_log text (_this select 0); - "ace_clipboard" callExtension ((_this select 0) + " -"); + "ace" callExtension ["clipboard:append", [(_this select 0) + endl]]; }; private _text = format ["~~~~~~~~~ACE Debug~~~~~~~~~ @@ -76,8 +75,8 @@ _text = format [" { - _var = missionNamespace getVariable [_x, nil]; - if(!isnil "_var" && {_var isEqualType []} && {(count _var) > MIN_ARRAY_SIZE}) then { + private _var = missionNamespace getVariable [_x, nil]; + if(!isNil "_var" && {_var isEqualType []} && {(count _var) > MIN_ARRAY_SIZE}) then { _text = format ["%1 - ARRAY SIZE: %2", _x, (count _var)]; [_text] call _outputText; }; @@ -87,11 +86,11 @@ _text = format [" private _unit = _x; { private _var = _unit getVariable [_x, nil]; - if(!isnil "_var" && {_var isEqualType []} && {(count _var) > MIN_ARRAY_SIZE}) then { + if(!isNil "_var" && {_var isEqualType []} && {(count _var) > MIN_ARRAY_SIZE}) then { _text = format ["%1 on [%2] - ARRAY SIZE: %3", _x, _unit, (count _var)]; [_text] call _outputText; }; } forEach (allVariables _unit); } forEach allUnits; -"ace_clipboard" callExtension "--COMPLETE--"; +"ace" callExtension ["clipboard:complete", []]; diff --git a/addons/optionsmenu/gui/mainMenu.hpp b/addons/optionsmenu/gui/mainMenu.hpp index 0b26df7017a..9df21dbeb5f 100644 --- a/addons/optionsmenu/gui/mainMenu.hpp +++ b/addons/optionsmenu/gui/mainMenu.hpp @@ -22,7 +22,7 @@ class RscDisplayMain: RscStandardDisplay { class ACE_news_apex: InfoNews { idc = IDC_MAIN_INFO; - y = "safezoneY + safezoneH - (3 * 2 + 1) * (pixelH * pixelGrid * 2) - 4 * (4 * pixelH)"; + y = "safeZoneY + safeZoneH - (3 * 2 + 1) * (pixelH * pixelGrid * 2) - 4 * (4 * pixelH)"; class Controls: Controls { class Background: Background {}; diff --git a/addons/optionsmenu/initSettings.inc.sqf b/addons/optionsmenu/initSettings.inc.sqf index bf77a84fcc0..e5bb44e512e 100644 --- a/addons/optionsmenu/initSettings.inc.sqf +++ b/addons/optionsmenu/initSettings.inc.sqf @@ -5,5 +5,9 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(aceNews)] LSTRING(showNewsOnMainMenu_name), _category, true, - 0 + 0, + { + if (!hasInterface) exitWith {}; + profileNamespace setVariable [QGVAR(showNewsOnMainMenu), _this]; + } ] call CBA_fnc_addSetting; diff --git a/addons/optionsmenu/stringtable.xml b/addons/optionsmenu/stringtable.xml index 4cd7f7d2f75..674ea3eb490 100644 --- a/addons/optionsmenu/stringtable.xml +++ b/addons/optionsmenu/stringtable.xml @@ -12,7 +12,7 @@ Debug a vágólapra Отладка в буфер обмена Debug negli Appunti - クリップボードにデバッグ + デバッグ情報をコピー 클립보드를 디버그하기 复制调试信息至剪贴板 複製除錯訊息至剪貼簿 diff --git a/addons/overheating/CfgWeapons.hpp b/addons/overheating/CfgWeapons.hpp index 9232fa32492..0b8087cc139 100644 --- a/addons/overheating/CfgWeapons.hpp +++ b/addons/overheating/CfgWeapons.hpp @@ -97,17 +97,19 @@ class CfgWeapons { 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 + // Deprecated, 3.16.0 Arsenal supports showing magazines as misc. items + // However, since base game doesn't support misc. items, it's still needed to filling inventories in the editor class ACE_SpareBarrel_Item: ACE_ItemCore { displayName = CSTRING(SpareBarrelName); author = ECSTRING(common,ACETeam); - scope = 1; + scope = 2; scopeArsenal = 0; - descriptionshort = CSTRING(SpareBarrelDescription); - picture = QUOTE(PATHTOF(UI\spare_barrel_ca.paa)); + descriptionShort = CSTRING(SpareBarrelDescription); + picture = QPATHTOF(UI\spare_barrel_ca.paa); class ItemInfo: CBA_MiscItem_ItemInfo { mass = 25; }; diff --git a/addons/overheating/XEH_postInit.sqf b/addons/overheating/XEH_postInit.sqf index 8f02d734e5b..223581adb2c 100644 --- a/addons/overheating/XEH_postInit.sqf +++ b/addons/overheating/XEH_postInit.sqf @@ -35,8 +35,8 @@ if (hasInterface) then { GVAR(storedSpareBarrels) = createHashMap; // Install event handlers for spare barrels - [QGVAR(sendSpareBarrelTemperatureHint), FUNC(sendSpareBarrelsTemperaturesHint)] call CBA_fnc_addEventHandler; - [QGVAR(loadCoolestSpareBarrel), FUNC(loadCoolestSpareBarrel)] call CBA_fnc_addEventHandler; + [QGVAR(sendSpareBarrelTemperatureHint), LINKFUNC(sendSpareBarrelsTemperaturesHint)] call CBA_fnc_addEventHandler; + [QGVAR(loadCoolestSpareBarrel), LINKFUNC(loadCoolestSpareBarrel)] call CBA_fnc_addEventHandler; // Schedule cool down calculation of stored spare barrels [] call FUNC(updateSpareBarrelsTemperaturesThread); @@ -50,14 +50,14 @@ if (hasInterface) then { //Add Take EH if required if (GVAR(unJamOnReload) || {GVAR(cookoffCoef) > 0}) then { - ["CAManBase", "Take", {_this call FUNC(handleTakeEH);}] call CBA_fnc_addClassEventHandler; + ["CAManBase", "Take", LINKFUNC(handleTakeEH)] call CBA_fnc_addClassEventHandler; }; // Register fire event handler - ["ace_firedPlayer", DFUNC(firedEH)] call CBA_fnc_addEventHandler; + ["ace_firedPlayer", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; // Only add eh to non local players if dispersion is enabled if (GVAR(overheatingDispersion) || {GVAR(showParticleEffectsForEveryone)}) then { - ["ace_firedPlayerNonLocal", DFUNC(firedEH)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerNonLocal", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; }; // Schedule cool down calculation of player weapons at (infrequent) regular intervals @@ -71,7 +71,7 @@ if (hasInterface) then { ["CAManBase", "Reloaded", { params ["_unit", "_weapon", "_muzzle"]; if (_muzzle == _weapon) then { - _unit setVariable [format [QGVAR(%1_ammoTemp), _weapon], 0]; + _unit setVariable [format [QGVAR(%1_ammoTemp), _weapon], ambientTemperature select 0]; }; }] call CBA_fnc_addClassEventHandler; }; @@ -86,10 +86,10 @@ if (hasInterface) then { }] call CBA_fnc_addClassEventHandler; // Install event handler to display temp when a barrel was swapped - [QGVAR(showWeaponTemperature), DFUNC(displayTemperature)] call CBA_fnc_addEventHandler; + [QGVAR(showWeaponTemperature), LINKFUNC(displayTemperature)] call CBA_fnc_addEventHandler; // Install event handler to initiate an assisted barrel swap - [QGVAR(initiateSwapBarrelAssisted), DFUNC(swapBarrel)] call CBA_fnc_addEventHandler; + [QGVAR(initiateSwapBarrelAssisted), LINKFUNC(swapBarrel)] call CBA_fnc_addEventHandler; // Add an action to allow hot weapons to be cooled off in AceX Field Rations water sources if (["acex_field_rations"] call EFUNC(common,isModLoaded)) then { @@ -103,6 +103,7 @@ if (hasInterface) then { LLSTRING(CoolWeaponWithWaterSource), QPATHTOEF(field_rations,ui\icon_water_tap.paa), { + //IGNORE_PRIVATE_WARNING ["_player", "_target"]; private _waterSource = _target getVariable [QEGVAR(field_rations,waterSource), objNull]; [_player, _waterSource] call FUNC(coolWeaponWithWaterSource); }, diff --git a/addons/overheating/functions/fnc_calculateCooling.sqf b/addons/overheating/functions/fnc_calculateCooling.sqf index f01f3950e7b..e7ac83f2367 100644 --- a/addons/overheating/functions/fnc_calculateCooling.sqf +++ b/addons/overheating/functions/fnc_calculateCooling.sqf @@ -7,6 +7,7 @@ * 0: Initial temperature * 1: Barrel mass * 2: Time interval + * 3: Bolt type * * Return Value: * Final temperature @@ -17,7 +18,7 @@ * Public: No */ -params ["_temperature", "_barrelMass", "_totalTime"]; +params ["_temperature", "_barrelMass", "_totalTime", "_boltType"]; // The lowest temperature a weapon can reach is the ambient air temperature. private _ambientTemperature = ambientTemperature select 0; @@ -43,6 +44,9 @@ if (ACE_player call EFUNC(common,isSwimming)) then { _convectionRate = _convectionRate * ((linearConversion [0,1,rain,1,5,true] + (5 min (vectorMagnitude wind / 10))) / 2); }; +//Increase convection cooling for open bolt type guns +if (_boltType == 0) then {_convectionRate = _convectionRate * OPEN_BOLT_ADDITIONAL_CONVECTION}; + TRACE_4("cooling",_temperature,_totalTime,_barrelMass,_barrelSurface); private _time = 0; diff --git a/addons/overheating/functions/fnc_coolWeaponWithItem.sqf b/addons/overheating/functions/fnc_coolWeaponWithItem.sqf index bc21963fb61..e5e79aaf626 100644 --- a/addons/overheating/functions/fnc_coolWeaponWithItem.sqf +++ b/addons/overheating/functions/fnc_coolWeaponWithItem.sqf @@ -61,8 +61,8 @@ private _fnc_onSuccess = { }; // cool the weapon - private _barrelMass = ([_weapon] call FUNC(getWeaponData)) select 7; - _temperature = [_temperature, _barrelMass, _liquidAmount * 10] call FUNC(calculateCooling); + private _weaponData = [_weapon] call FUNC(getWeaponData); + _temperature = [_temperature, _weaponData select 7, _liquidAmount * 10, _weaponData select 6] call FUNC(calculateCooling); [_target, _tempVarName, _temperature, TEMP_TOLERANCE] call EFUNC(common,setApproximateVariablePublic); }; diff --git a/addons/overheating/functions/fnc_coolWeaponWithWaterSource.sqf b/addons/overheating/functions/fnc_coolWeaponWithWaterSource.sqf index acf3286c4af..18f8b0f31a3 100644 --- a/addons/overheating/functions/fnc_coolWeaponWithWaterSource.sqf +++ b/addons/overheating/functions/fnc_coolWeaponWithWaterSource.sqf @@ -37,7 +37,7 @@ private _fnc_onFinish = { ] call CBA_fnc_notify; }; - [_player, _player, currentWeapon _player] call ace_overheating_fnc_checkTemperature; + [_player, _player, currentWeapon _player] call FUNC(checkTemperature); GVAR(coolingWeaponWithWaterSource) = false; }; @@ -59,8 +59,8 @@ private _fnc_condition = { }; //Cool the weapon down - private _barrelMass = ([_weapon] call FUNC(getWeaponData)) select 7; - _temperature = [_temperature, _barrelMass, 20] call FUNC(calculateCooling); + private _weaponData = [_weapon] call FUNC(getWeaponData); + _temperature = [_temperature, _weaponData select 7, 20, _weaponData select 6] call FUNC(calculateCooling); [_player, _tempVarName, _temperature, TEMP_TOLERANCE] call EFUNC(common,setApproximateVariablePublic); /* // to be added when licence compatible audio can be found or recorded diff --git a/addons/overheating/functions/fnc_getConsumableChildren.sqf b/addons/overheating/functions/fnc_getConsumableChildren.sqf index 025e9a69397..fea6f897f07 100644 --- a/addons/overheating/functions/fnc_getConsumableChildren.sqf +++ b/addons/overheating/functions/fnc_getConsumableChildren.sqf @@ -19,6 +19,7 @@ params ["_unit"]; private _fnc_getActions = { TRACE_1("Creating overheating consumable item actions",_unit); + //IGNORE_PRIVATE_WARNING ["_unit"]; private _actions = []; private _cfgWeapons = configFile >> "CfgWeapons"; diff --git a/addons/overheating/functions/fnc_getWeaponData.sqf b/addons/overheating/functions/fnc_getWeaponData.sqf index 8edd86bb1aa..ec68cf67b9d 100644 --- a/addons/overheating/functions/fnc_getWeaponData.sqf +++ b/addons/overheating/functions/fnc_getWeaponData.sqf @@ -77,7 +77,7 @@ if (_muzzle == "this") then { _muzzle = _weapon; }; -private _reloadTime = getNumber (configfile >> "CfgWeapons" >> _weapon >> (_modes select 0) >> "reloadTime"); +private _reloadTime = getNumber (configFile >> "CfgWeapons" >> _weapon >> (_modes select 0) >> "reloadTime"); private _closedBolt = getNumber (configFile >> "CfgWeapons" >> _weapon >> QGVAR(closedBolt)); diff --git a/addons/overheating/functions/fnc_jamWeapon.sqf b/addons/overheating/functions/fnc_jamWeapon.sqf index 9a5b8b10491..afe6d15e975 100644 --- a/addons/overheating/functions/fnc_jamWeapon.sqf +++ b/addons/overheating/functions/fnc_jamWeapon.sqf @@ -80,9 +80,11 @@ if (_unit getVariable [QGVAR(JammingActionID), -1] == -1) then { private _condition = { 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), []]))} + (weaponState _unit) params ["_currentWeapon", "_currentMuzzle"]; + + _unit call CBA_fnc_canUseWeapon + && {_currentMuzzle in (_unit getVariable [QGVAR(jammedWeapons), []])} + && {!(["ace_safemode"] call EFUNC(common,isModLoaded)) || {!([_unit, _currentWeapon, _currentMuzzle] call EFUNC(safemode,getWeaponSafety))}} }; private _statement = { diff --git a/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf b/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf index 29b7191471e..a5fb95cf316 100644 --- a/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf +++ b/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf @@ -31,7 +31,7 @@ if (_weaponBarrelClass == "") then { // Find all spare barrel the player has private _allBarrels = [_assistant, _weaponBarrelClass] call CBA_fnc_getMagazineIndex; TRACE_1("_allBarrels",_allBarrels); -if ((count _allBarrels) < 1) exitWith {}; +if (_allBarrels isEqualTo []) exitWith {}; // Determine which on is coolest private _coolestTemp = 10000; diff --git a/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf b/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf index 9204b58124b..5f75423f2e0 100644 --- a/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf +++ b/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf @@ -32,7 +32,7 @@ if (_weaponBarrelClass == "") then { }; private _allBarrels = [_unit, _weaponBarrelClass] call CBA_fnc_getMagazineIndex; TRACE_1("_allBarrels",_allBarrels); -if ((count _allBarrels) < 1) exitWith {}; +if (_allBarrels isEqualTo []) exitWith {}; // Determine the temp of each barrel private _temps = []; diff --git a/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf b/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf index 64110b2c763..da87c5fdbaa 100644 --- a/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf +++ b/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf @@ -20,10 +20,10 @@ TRACE_1("updateSpareBarrelsTemperaturesThread1",GVAR(storedSpareBarrels)); _y params ["_initialTemp","_initialTime", "_barrelMass"]; // Calculate cooling - private _finalTemp = [_initialTemp, _barrelMass, CBA_missionTime - _initialTime] call FUNC(calculateCooling); + private _finalTemp = [_initialTemp, _barrelMass, CBA_missionTime - _initialTime, 0] call FUNC(calculateCooling); //the zero is to indicate an open bolt gun. Barrel is outside of a gun here, so always open. TRACE_4("updateSpareBarrelsTemperaturesThread2",_barrelMagazineID,_initialTemp,_finalTemp,_barrelMass); - if (_finalTemp < 5) then { - // The barrel is cool enough to keep calculating. Remove it from the hash + if (_finalTemp <= (ambientTemperature select 0)) then { + // The barrel is cool enough to finish calculating. Remove it from the hash GVAR(storedSpareBarrels) deleteAt _x; } else { // Store the new temp diff --git a/addons/overheating/functions/fnc_updateTemperature.sqf b/addons/overheating/functions/fnc_updateTemperature.sqf index 8d5ca5d4124..db7f48be83e 100644 --- a/addons/overheating/functions/fnc_updateTemperature.sqf +++ b/addons/overheating/functions/fnc_updateTemperature.sqf @@ -33,8 +33,9 @@ _trackedWeapons pushBackUnique _tempVarName; _unit setVariable [QGVAR(trackedWeapons), _trackedWeapons]; // Calculate cooling -private _barrelMass = ([_weapon] call FUNC(getWeaponData)) select 7; -_temperature = [_temperature, _barrelMass, CBA_missionTime - _lastTime] call FUNC(calculateCooling); +private _weaponData = [_weapon] call FUNC(getWeaponData); +private _barrelMass = _weaponData select 7; +_temperature = [_temperature, _barrelMass, CBA_missionTime - _lastTime, _weaponData select 6] call FUNC(calculateCooling); TRACE_1("cooledTo",_temperature); // Calculate heating diff --git a/addons/overheating/script_component.hpp b/addons/overheating/script_component.hpp index 0837733cd30..dd1b18806f8 100644 --- a/addons/overheating/script_component.hpp +++ b/addons/overheating/script_component.hpp @@ -19,6 +19,7 @@ #define TEMP_TOLERANCE 50 #define METAL_MASS_RATIO 0.55 #define GUNPOWDER_IGNITION_TEMP 180 +#define OPEN_BOLT_ADDITIONAL_CONVECTION 1.1 #ifdef DEBUG_MODE_FULL #define TRACE_PROJECTILE_INFO(BULLET) _vdir = vectorNormalized velocity BULLET; _dir = (_vdir select 0) atan2 (_vdir select 1); _up = asin (_vdir select 2); _mv = vectorMagnitude velocity BULLET; TRACE_3("adjusted projectile",_dir,_up,_mv); diff --git a/addons/overheating/stringtable.xml b/addons/overheating/stringtable.xml index 8ec603a7ed8..0d3f0dd96eb 100644 --- a/addons/overheating/stringtable.xml +++ b/addons/overheating/stringtable.xml @@ -58,6 +58,7 @@ 过热系数 과열 계수 Coeficiente de calentamiento + Coeficiente de aquecimento Coefficient for the amount of heat a weapon generates per shot.\nHigher value increases heat. @@ -70,6 +71,7 @@ 武器每次射击产生的热量系数。\n数值越高,热量越高。 매 발사마다 만들어지는 열에 계수를 적용합니다.\n높은 계수는 더 많은 열을 발생시킵니다. Coeficiente para la cantidad de calor que genera un arma por disparo.\nValores más altos incrementan el calor + Coeficiente da quantidade de calor que um armamento gera por disparo.\nValores mais altos potencializam o aquecimento. Cooling Coefficient @@ -82,6 +84,7 @@ Коэф. остывания Coeficiente de enfriado Coefficient de refroidissement + Coeficiente de resfriamento Coefficient for how quickly a weapon cools down.\nHigher value increases cooling speed. @@ -94,6 +97,7 @@ Коэффициент скорости остывания орудия.\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. + Coeficiente que determina o quão rápido a arma resfria.\nValores mais altos potencializam o resfriamento. Suppressor Coefficient @@ -106,6 +110,7 @@ Коэф. глушителя Coeficiente del silenciador Coefficient de suppresion + Coeficiente de supressão 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. @@ -714,7 +719,7 @@ Cool weapon with... - 武器を・・・で冷却 + 武器をアイテムで冷却 Refroidir l'arme avec... Охладить оружие с... Waffe mit... kühlen @@ -877,39 +882,63 @@ Bolt Type + Tipo di otturatore 遊底(ボルト)形式 노리쇠 방식 Тип болта + Type d'obturateur + Art des Verschlusses + Tipo de Cerrojo Open Bolt + Otturatore Aperto オープンボルト 오픈 볼트 Открыть болт + Obturateur ouvert + Offener Verschluss + Cerrojo Abierto Closed Bolt + Otturatore Chiuso クローズドボルト 클로즈드 볼트 Закрыть болт + Obturateur fermé + Geschlossener Verschluss + Cerrojo Cerrado Barrel Type + Tipo di Canna 銃身形式 총열 방식 Тип ствола + Type de canon + Lauftyp + Tipo de Cañón Non-Removeable + Non-Rimovibile 取り外し不可 제거 불가 Несъемный + Inamovible + Nicht entfernbar + No-Desmontable Quick Change + Cambio Rapido 即時交換可 신속 교체 Быстросъемный + Changement rapide + Schnellwechsel + Cambiado Rápido diff --git a/addons/overpressure/ACE_Settings.hpp b/addons/overpressure/ACE_Settings.hpp deleted file mode 100644 index d46cae7498b..00000000000 --- a/addons/overpressure/ACE_Settings.hpp +++ /dev/null @@ -1,5 +0,0 @@ -class ACE_Settings { - class GVAR(distanceCoefficient) { - movedToSQF = 1; - }; -}; diff --git a/addons/overpressure/XEH_postInit.sqf b/addons/overpressure/XEH_postInit.sqf index 46fe4602682..4b014e89e24 100644 --- a/addons/overpressure/XEH_postInit.sqf +++ b/addons/overpressure/XEH_postInit.sqf @@ -1,14 +1,17 @@ #include "script_component.hpp" ["CBA_settingsInitialized", { - TRACE_1("settingsInit eh",GVAR(distanceCoefficient)); - if (GVAR(distanceCoefficient) <= 0) exitWith {}; + TRACE_2("settingsInit eh",GVAR(backblastDistanceCoefficient),GVAR(overpressureDistanceCoefficient)); ["ace_overpressure", LINKFUNC(overpressureDamage)] call CBA_fnc_addEventHandler; - // Register fire event handler - ["ace_firedPlayer", LINKFUNC(firedEHBB)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicle", LINKFUNC(firedEHOP)] call CBA_fnc_addEventHandler; + // Register fire event handlers + if (GVAR(backblastDistanceCoefficient) > 0) then { + ["ace_firedPlayer", LINKFUNC(firedEHBB)] call CBA_fnc_addEventHandler; + }; + if (GVAR(overpressureDistanceCoefficient) > 0) then { + ["ace_firedPlayerVehicle", LINKFUNC(firedEHOP)] call CBA_fnc_addEventHandler; + }; GVAR(cacheHash) = createHashMap; }] call CBA_fnc_addEventHandler; diff --git a/addons/overpressure/config.cpp b/addons/overpressure/config.cpp index 3815cc831fa..7274cd50593 100644 --- a/addons/overpressure/config.cpp +++ b/addons/overpressure/config.cpp @@ -14,7 +14,6 @@ class CfgPatches { }; }; -#include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" #include "CfgWeapons.hpp" #include "ACE_Arsenal_Stats.hpp" diff --git a/addons/overpressure/functions/fnc_firedEHBB.sqf b/addons/overpressure/functions/fnc_firedEHBB.sqf index 2ef48bf4d99..59b51f28629 100644 --- a/addons/overpressure/functions/fnc_firedEHBB.sqf +++ b/addons/overpressure/functions/fnc_firedEHBB.sqf @@ -15,22 +15,24 @@ * 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); +//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"]; +TRACE_8("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_gunner); // 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 _direction = [0, 0, 0] vectorDiff (vectorDir _projectile); -private _position = ((getPosASL _projectile) vectorAdd (_direction vectorMultiply _offset)); +private _direction = (vectorDir _projectile) vectorMultiply -1; +private _position = (getPosASL _projectile) vectorAdd (_direction vectorMultiply _offset); // Damage to others -private _affected = (ASLtoAGL _position) nearEntities ["CAManBase", _backblastRange]; +private _affected = (ASLToAGL _position) nearEntities ["CAManBase", _backblastRange]; // Let each client handle their own affected units ["ace_overpressure", [_unit, _position, _direction, _weapon, _magazine, _ammo], _affected] call CBA_fnc_targetEvent; @@ -53,7 +55,7 @@ if (_distance < _backblastRange) then { [_damage * 100] call BIS_fnc_bloodEffect; - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [_unit, _damage, "body", "backblast", _unit] call EFUNC(medical,addDamageToUnit); } else { _unit setDamage (damage _unit + _damage); diff --git a/addons/overpressure/functions/fnc_firedEHOP.sqf b/addons/overpressure/functions/fnc_firedEHOP.sqf index 2345d093273..eb51a055076 100644 --- a/addons/overpressure/functions/fnc_firedEHOP.sqf +++ b/addons/overpressure/functions/fnc_firedEHOP.sqf @@ -15,13 +15,15 @@ * 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); +//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"]; +TRACE_8("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_gunner); // Retrieve overpressure values private _opValues = [_weapon, _ammo, _magazine] call FUNC(getOverPressureValues); _opValues params ["_dangerZoneAngle", "_dangerZoneRange", "_dangerZoneDamage"]; +_dangerZoneRange = _dangerZoneRange * GVAR(overpressureDistanceCoefficient); + TRACE_3("cache",_dangerZoneAngle,_dangerZoneRange,_dangerZoneDamage); if (_dangerZoneDamage <= 0) exitWith {}; @@ -31,7 +33,7 @@ private _position = getPosASL _projectile; private _direction = vectorDir _projectile; // Damage to others -private _affected = (ASLtoAGL _position) nearEntities ["CAManBase", _dangerZoneRange]; +private _affected = (ASLToAGL _position) nearEntities ["CAManBase", _dangerZoneRange]; // Let each client handle their own affected units ["ace_overpressure", [_unit, _position, _direction, _weapon, _magazine, _ammo], _affected] call CBA_fnc_targetEvent; diff --git a/addons/overpressure/functions/fnc_getOverPressureValues.sqf b/addons/overpressure/functions/fnc_getOverPressureValues.sqf index 4372d4c8e6d..374e9de9d66 100644 --- a/addons/overpressure/functions/fnc_getOverPressureValues.sqf +++ b/addons/overpressure/functions/fnc_getOverPressureValues.sqf @@ -54,7 +54,7 @@ TRACE_1("ConfigPath",_config); // get the Variables out of the Configs and populate return array with them _return = [ (getNumber (_config >> QGVAR(angle))), - (getNumber (_config >> QGVAR(range))) * GVAR(distanceCoefficient), + (getNumber (_config >> QGVAR(range))), (getNumber (_config >> QGVAR(damage))), (getNumber (_config >> QGVAR(offset))) ]; diff --git a/addons/overpressure/functions/fnc_overpressureDamage.sqf b/addons/overpressure/functions/fnc_overpressureDamage.sqf index 812a2ab7ea2..f727413d4a5 100644 --- a/addons/overpressure/functions/fnc_overpressureDamage.sqf +++ b/addons/overpressure/functions/fnc_overpressureDamage.sqf @@ -57,7 +57,7 @@ TRACE_3("cache",_overpressureAngle,_overpressureRange,_overpressureDamage); [_damage * 100] call BIS_fnc_bloodEffect; }; - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [_x, _damage, "body", "backblast", _firer] call EFUNC(medical,addDamageToUnit); } else { _x setDamage (damage _x + _damage); @@ -73,4 +73,4 @@ TRACE_3("cache",_overpressureAngle,_overpressureRange,_overpressureDamage); #endif }; }; -} forEach ((ASLtoAGL _posASL) nearEntities ["CAManBase", _overpressureRange]); +} forEach ((ASLToAGL _posASL) nearEntities ["CAManBase", _overpressureRange]); diff --git a/addons/overpressure/initSettings.inc.sqf b/addons/overpressure/initSettings.inc.sqf index 7fe64011313..ece1230dcce 100644 --- a/addons/overpressure/initSettings.inc.sqf +++ b/addons/overpressure/initSettings.inc.sqf @@ -1,9 +1,23 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(DisplayName)]; [ - QGVAR(distanceCoefficient), "SLIDER", + QGVAR(overpressureDistanceCoefficient), + "SLIDER", [LSTRING(distanceCoefficient_displayName), LSTRING(distanceCoefficient_toolTip)], _category, - [-1, 10, 1, 1], - 1 + [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 caade38c3d3..2199a4d63ba 100644 --- a/addons/overpressure/stringtable.xml +++ b/addons/overpressure/stringtable.xml @@ -8,7 +8,7 @@ Sovrapressione 과중압력 Nadciśnienie - 過圧 + 超過圧力 Перегрузка Sobrepresiòn Surpression @@ -16,11 +16,11 @@ Overpressure Distance Coefficient Überdruckentfernungskoeffizient - 過圧の距離係数 + 超過圧力の距離係数 과중압력 거리 계수 Mnożnik dystansu nadciśnienia Coefficient de distance pour la surpression - Coefficente Distanza Sovrapressione + Coefficiente Distanza Sovrapressione 超压影响距离系数 高壓影響距離係數 Коэф. избыточного давления @@ -30,25 +30,45 @@ Coeficiente de distancia de sobrepresión - Scales the overpressure effect [Default: 1] - Stellt den Koeffizient für die Überdruckentfernung ein [Standard: 1] - 過圧効果の範囲 [デフォルト: 1] - 과중압력의 효과 크기 [기본설정: 1] - Skaluje efekt nadciśnienia [Domyślne: 1] - Ajuste l'effet de surpression. Valeur par défaut : 1. - Scala l'effetto di sovrapressione [Predefinito: 1] - 超压影响的范围 [预设:1] - 高壓影響的範圍 [預設: 1] - Степень зависимости избыточного давления от расстояния [По умолчанию: 1] - Escala o efeito de sobrepressão [Padrão: 1] - Állítja a túlnyomás hatását [Alapértelmezett: 1] - Nastavuje jak velký je efekt přetlaku [Standard: 1] - Escala el efecto de sobrepresión [Predeterminado: 1] + Scales the overpressure effect + Stellt den Koeffizient für die Überdruckentfernung ein + 火砲による超過圧力の影響範囲の大きさ + 과중압력의 효과 크기 + Skaluje efekt nadciśnienia + Ajuste l'effet de surpression + Scala l'effetto di sovrapressione + 超压影响的范围 + 高壓影響的範圍 + Степень зависимости избыточного давления от расстояния + Escala o efeito de sobrepressão + Állítja a túlnyomás hatását + Nastavuje jak velký je efekt přetlaku + Escala el efecto de sobrepresión + + + Backblast Distance Coefficient + Коэффициент расстояния рекативной струи + Rückstrahl-Entfernung Multiplikator + Coefficiente distanza di svampata + 後方噴射の距離係数 + 후폭풍 거리 계수 + Multiplicateur de distance de réflexion + Coeficiente de Distancia de Fogonazo + + + Scales the backblast effect + Масштабирует эффект реактивной струи + Skaliert den Rückstrahl-Effekt + Scala l'effetto delle svampate dei lanciarazzi + 無反動砲による後方噴射の影響範囲の大きさ + 후폭풍 효과의 스케일을 조정합니다 + Multiplicateur de distance de réflexion + Escala el efecto del fogonazo Backblast range Rückstrahlzone - 後方噴射の範囲 + 後方噴射範囲 向后喷射的范围 後方尾焰的範圍 Raggio della fiammata [lanciarazzi] @@ -56,7 +76,7 @@ Дальность реактивной струи Alcance do Sopro de Disparo Utóhatás távolsága - Portée du backblast + Portée du souffle Dosah zpětné tlakové vlny (backblast) Alcance del cono de fuego 후폭풍 거리 @@ -64,7 +84,7 @@ Backblast angle Rückstrahlwinkel - 後方噴射の角度 + 後方噴射角度 向后喷射的角度 後方尾焰的角度 Angolo della fiammata [lanciarazzi] @@ -72,7 +92,7 @@ Угол реактивной струи Ângulo do Sopro de Disparo Utóhatás aránya - Angle du backblast + Angle du souffle Úhel zpětné tlakové vlny (backblast) Ángulo del cono de fuego 후폭풍 각도 diff --git a/addons/parachute/CfgVehicles.hpp b/addons/parachute/CfgVehicles.hpp index f764494224d..545d9a37053 100644 --- a/addons/parachute/CfgVehicles.hpp +++ b/addons/parachute/CfgVehicles.hpp @@ -101,4 +101,36 @@ class CfgVehicles { class B_Soldier_05_f; class B_Pilot_F: B_Soldier_05_f {backpack = "ACE_NonSteerableParachute";}; class I_Soldier_04_F; class I_pilot_F: I_Soldier_04_F {backpack = "ACE_NonSteerableParachute";}; class O_helipilot_F; class O_Pilot_F: O_helipilot_F {backpack = "ACE_NonSteerableParachute";}; + + class Plane_Base_F; + class Plane_CAS_01_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_CAS_02_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_01_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_02_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_03_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_04_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; }; diff --git a/addons/parachute/RscTitles.hpp b/addons/parachute/RscTitles.hpp index 9e0a1699371..388115a2a88 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_postInit.sqf b/addons/parachute/XEH_postInit.sqf index 1217fa3cabc..f10748b0cff 100644 --- a/addons/parachute/XEH_postInit.sqf +++ b/addons/parachute/XEH_postInit.sqf @@ -34,9 +34,9 @@ if (!hasInterface) exitWith {}; }, {false}, [24, [false, false, false]], false] call CBA_fnc_addKeybind; // Handle reserve chute based on current backpack (fires when parachute opens too) -["loadout", FUNC(handleReserve), true] call CBA_fnc_addPlayerEventHandler; +["loadout", LINKFUNC(handleReserve), true] call CBA_fnc_addPlayerEventHandler; // Don't show vanilla speed and height when in expert mode -["ace_infoDisplayChanged", {_this call FUNC(handleInfoDisplayChanged)}] call CBA_fnc_addEventHandler; +["ace_infoDisplayChanged", LINKFUNC(handleInfoDisplayChanged)] call CBA_fnc_addEventHandler; -["vehicle", {_this call FUNC(handleFailureChance)}] call CBA_fnc_addPlayerEventHandler; +["vehicle", LINKFUNC(handleFailureChance)] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/parachute/functions/fnc_cutParachute.sqf b/addons/parachute/functions/fnc_cutParachute.sqf index c66d9ff0504..604fb201076 100644 --- a/addons/parachute/functions/fnc_cutParachute.sqf +++ b/addons/parachute/functions/fnc_cutParachute.sqf @@ -18,6 +18,6 @@ params ["_unit", "_parachute"]; TRACE_2("cutParachute",_unit,_parachute); -playSound3d ["A3\Sounds_F\characters\parachute\parachute_landing.wss", _unit]; +playSound3D ["A3\Sounds_F\characters\parachute\parachute_landing.wss", _unit]; _unit action ["GetOut", _parachute]; deleteVehicle _parachute; diff --git a/addons/parachute/functions/fnc_showAltimeter.sqf b/addons/parachute/functions/fnc_showAltimeter.sqf index d4533a7a6ba..f86f785cc6e 100644 --- a/addons/parachute/functions/fnc_showAltimeter.sqf +++ b/addons/parachute/functions/fnc_showAltimeter.sqf @@ -40,8 +40,10 @@ private _TimeText = _display displayCtrl 1001; _pfhID call CBA_fnc_removePerFrameHandler; }; - private _hour = floor daytime; - private _minute = floor ((daytime - _hour) * 60); + private _daytime = dayTime; + private _hour = floor _daytime; + private _minute = floor ((_daytime - _hour) * 60); + private _seconds = floor ((((_daytime - _hour) * 60) - _minute) * 60); private _curTime = CBA_missionTime; private _timeDiff = _curTime - _prevTime; @@ -52,7 +54,7 @@ private _TimeText = _display displayCtrl 1001; 0 }; - _TimeText ctrlSetText (format ["%1:%2", [_hour, 2] call CBA_fnc_formatNumber, [_minute, 2] call CBA_fnc_formatNumber]); + _TimeText ctrlSetText (format ["%1:%2:%3", [_hour, 2] call CBA_fnc_formatNumber, [_minute, 2] call CBA_fnc_formatNumber, [_seconds, 2] call CBA_fnc_formatNumber]); _HeightText ctrlSetText str floor _height; _DecendRate ctrlSetText str (_descentRate max 0); diff --git a/addons/parachute/initSettings.inc.sqf b/addons/parachute/initSettings.inc.sqf index 0cfc3f8ca05..0c6804cff79 100644 --- a/addons/parachute/initSettings.inc.sqf +++ b/addons/parachute/initSettings.inc.sqf @@ -5,9 +5,7 @@ private _category = [LELSTRING(common,categoryUncategorized), localize "str_dn_p "CHECKBOX", [LSTRING(HideAltimeter), LSTRING(HideAltimeter_tooltip)], _category, - true, - false, - {[QGVAR(hideAltimeter), _this, false] call EFUNC(common,cbaSettings_settingChanged)} + true ] call CBA_fnc_addSetting; [ diff --git a/addons/parachute/stringtable.xml b/addons/parachute/stringtable.xml index db48a6109cb..b13483dca5e 100644 --- a/addons/parachute/stringtable.xml +++ b/addons/parachute/stringtable.xml @@ -146,6 +146,7 @@ 开伞失败率 낙하산 펼치기 실패 확률 Probabilidad de fallo de paracaidas + Probabilidade de falha do paraquedas diff --git a/addons/pylons/XEH_postInit.sqf b/addons/pylons/XEH_postInit.sqf index 3167c0a838a..e1bd05cb53c 100644 --- a/addons/pylons/XEH_postInit.sqf +++ b/addons/pylons/XEH_postInit.sqf @@ -2,6 +2,7 @@ GVAR(aircraftWithPylons) = []; +//IGNORE_PRIVATE_WARNING ["_player", "_target"]; GVAR(loadoutAction) = [ // create action QGVAR(loadoutAction), localize LSTRING(ConfigurePylons), @@ -36,7 +37,7 @@ GVAR(loadoutAction) = [ // create action [QGVAR(setPylonLoadOutEvent), { params ["_aircraft", "_pylonIndex", "_pylon", "_turret", "_weaponToRemove"]; TRACE_5("setPylonLoadOutEvent",_aircraft,_pylonIndex,_pylon,_turret,_weaponToRemove); - _aircraft setPylonLoadOut [_pylonIndex, _pylon, false, _turret]; + _aircraft setPylonLoadout [_pylonIndex, _pylon, false, _turret]; if (_weaponToRemove != "") then { { if (_aircraft turretLocal _x) then { diff --git a/addons/pylons/functions/fnc_showDialog.sqf b/addons/pylons/functions/fnc_showDialog.sqf index a06cb6f1142..7df50c6b2aa 100644 --- a/addons/pylons/functions/fnc_showDialog.sqf +++ b/addons/pylons/functions/fnc_showDialog.sqf @@ -73,8 +73,8 @@ GVAR(comboBoxes) = []; _combo ctrlSetPosition [ (_picturePos select 0) + (_uiPos select 0), (_picturePos select 1) + (_uiPos select 1), - 0.1 * safezoneW, - 0.028 * safezoneH + 0.1 * safeZoneW, + 0.028 * safeZoneH ]; _combo ctrlCommit 0; @@ -107,16 +107,16 @@ 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); _button ctrlAddEventHandler ["ButtonClick", {[_this select 0, true, []] call FUNC(onButtonTurret)}]; _button ctrlSetPosition [ - (_picturePos select 0) + (_uiPos select 0) - (0.0165 * safezoneW), + (_picturePos select 0) + (_uiPos select 0) - (0.0165 * safeZoneW), (_picturePos select 1) + (_uiPos select 1), - 0.0165 * safezoneW, - 0.028 * safezoneH + 0.0165 * safeZoneW, + 0.028 * safeZoneH ]; _button ctrlCommit 0; }; diff --git a/addons/pylons/menu.hpp b/addons/pylons/menu.hpp index 143792e566e..3f238a9da1c 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 d431910d346..1021a2fc153 100644 --- a/addons/pylons/stringtable.xml +++ b/addons/pylons/stringtable.xml @@ -289,7 +289,7 @@ The time it takes to replace each pylon (in seconds). - 各パイロンの置き換えに掛かる時間を設定します。(秒) + 各パイロンの置き換えに掛かる時間。 (秒単位) Il tempo che impiega ogni pilone ad essere sostituito (in secondi). 每個派龍架需花多久時間進行整補(單位為秒) 每个挂架需花多久时间进行整装(单位为秒)。 diff --git a/addons/quickmount/XEH_postInitClient.sqf b/addons/quickmount/XEH_postInitClient.sqf index 23c225f5839..30f655edd82 100644 --- a/addons/quickmount/XEH_postInitClient.sqf +++ b/addons/quickmount/XEH_postInitClient.sqf @@ -2,9 +2,8 @@ if (!hasInterface) exitWith {}; -["ACE3 Movement", QGVAR(mount), [localize LSTRING(KeybindName), localize LSTRING(KeybindDescription)], "", { +["ACE3 Movement", QGVAR(mount), [LLSTRING(KeybindName), LLSTRING(KeybindDescription)], "", { if (!dialog) then { [] call FUNC(getInNearest); }; - false }] call CBA_fnc_addKeybind; diff --git a/addons/quickmount/config.cpp b/addons/quickmount/config.cpp index d74d99c0503..846e5f05430 100644 --- a/addons/quickmount/config.cpp +++ b/addons/quickmount/config.cpp @@ -2,6 +2,7 @@ class CfgPatches { class ADDON { + name = COMPONENT_NAME; units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; diff --git a/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf b/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf index 4cc3a2d7577..af698510648 100644 --- a/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf +++ b/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf @@ -34,14 +34,14 @@ [ARR_5( \ {!isNull objectParent (_this select 0)}, \ { \ - LOG_1("moved in after %1 frames",diag_frameno-GVAR(frame)); \ + LOG_1("moved in after %1 frames",diag_frameNo-GVAR(frame)); \ (_this select 0) enableSimulation true; \ }, \ [ARR_3(_player,_moveBackCode,_moveBackParams)], \ TAKEN_SEAT_TIMEOUT, \ { \ params [ARR_3("_player","_moveBackCode","_moveBackParams")]; \ - WARNING_1("failed move in after %1 frames",diag_frameno-GVAR(frame)); \ + WARNING_1("failed move in after %1 frames",diag_frameNo-GVAR(frame)); \ [ARR_2(_player,_moveBackParams)] call _moveBackCode; \ localize "str_mis_state_failed" call EFUNC(common,displayTextStructured); \ _player enableSimulation true; \ @@ -58,10 +58,11 @@ ) #define MOVE_IN_CODE(command) (_this select 0) command (_this select 1) +//IGNORE_PRIVATE_WARNING ["_player", "_target"]; private _fnc_move = { (_this select 2) params ["_moveInCode", "_moveInParams", "_currentTurret", "_moveBackCode", "_moveBackParams"]; - TRACE_6("fnc_move params",_moveInCode,_moveInParams,_currentTurret,_moveBackCode,_moveBackParams,call {GVAR(frame)=diag_frameno}); + TRACE_6("fnc_move params",_moveInCode,_moveInParams,_currentTurret,_moveBackCode,_moveBackParams,call {GVAR(frame)=diag_frameNo}); // workaround getting damage when moveOut while vehicle is moving // also this helps with arma bug when unit is stuck in wrong anim when move in turret with configured enabledByAnimationSource @@ -83,7 +84,7 @@ private _fnc_move = { {params ["_target", "_player", "_currentTurret"]; IS_MOVED_OUT}, { params ["", "_player", "", "_moveInCode", "_moveInParams", "_moveBackCode", "_moveBackParams"]; - LOG_2("moved out after %1 frames",diag_frameno-GVAR(frame),call {GVAR(frame)=diag_frameno; 0}); + 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; }, @@ -159,7 +160,7 @@ private _cargoNumber = -1; }; } else { private ["_name", "_icon", "_statement", "_params"]; - switch (toLower _role) do { + switch (toLowerANSI _role) do { case "driver": { if ( lockedDriver _vehicle @@ -202,15 +203,15 @@ private _cargoNumber = -1; if (_vehicle lockedTurret _turretPath) then {breakTo "crewLoop"}; if (_role == "gunner" && {unitIsUAV _vehicle}) then {breakTo "crewLoop"}; private _turretConfig = [_vehicleConfig, _turretPath] call CBA_fnc_getTurret; - if (!_isInVehicle) then { - _params = ["GetInTurret", _vehicle, _turretPath]; - _statement = {_player action (_this select 2)}; - } else { + if (_isInVehicle) then { private _gunnerCompartments = (_turretConfig >> "gunnerCompartments") call BIS_fnc_getCfgData; TO_COMPARTMENT_STRING(_gunnerCompartments); if (_compartment != _gunnerCompartments) then {breakTo "crewLoop"}; _params = [{MOVE_IN_CODE(moveInTurret)}, [_vehicle, _turretPath], _currentTurret, _moveBackCode, _moveBackParams]; _statement = _fnc_move; + } else { + _params = ["GetInTurret", _vehicle, _turretPath]; + _statement = {_player action (_this select 2)}; }; _name = getText (_turretConfig >> "gunnerName"); _icon = switch true do { diff --git a/addons/quickmount/functions/fnc_getInNearest.sqf b/addons/quickmount/functions/fnc_getInNearest.sqf index c618681f7ee..52bc8cd220f 100644 --- a/addons/quickmount/functions/fnc_getInNearest.sqf +++ b/addons/quickmount/functions/fnc_getInNearest.sqf @@ -1,131 +1,125 @@ #include "..\script_component.hpp" /* * Author: Kingsley - * Mount the player in the vehicle they are directly looking at based on their distance. + * Mounts the player in the vehicle they are directly looking at based on their distance. * * Arguments: - * 0: Target (Optional) + * 0: Target (default: objNull) * * Return Value: * None * * Example: - * [] call ace_quickmount_fnc_getInNearest; + * call ace_quickmount_fnc_getInNearest * * Public: No */ -if (!GVAR(enabled) || +if ( + !GVAR(enabled) || {isNull ACE_player} || - {vehicle ACE_player != ACE_player} || - {!alive ACE_player} || - {ACE_player getVariable ["ace_unconscious", false]} + {!isNull objectParent ACE_player} || + {!(ACE_player call EFUNC(common,isAwake))} ) exitWith {}; -params [["_interactionTarget", objNull, [objNull]]]; -TRACE_1("getInNearest",_interactionTarget); +params [["_target", objNull, [objNull]]]; +TRACE_1("getInNearest",_target); -private _start = ACE_player modelToWorldVisualWorld (ACE_player selectionPosition "pilot"); -private _end = (_start vectorAdd (getCameraViewDirection ACE_player vectorMultiply GVAR(distance))); -private _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; -private _target = (_objects param [0, []]) param [2, objNull]; - -if ((isNull _target) && {alive _interactionTarget}) then { - _end = _start vectorAdd ((_start vectorFromTo (aimPos _interactionTarget)) vectorMultiply GVAR(distance)); - _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; - TRACE_1("2nd ray attempt at interaction target aim pos",_objects); +// If target is not defined (e.g. keybind was used), search for valid target +if (isNull _target) then { + private _start = ACE_player modelToWorldVisualWorld (ACE_player selectionPosition "pilot"); + private _end = (_start vectorAdd (getCameraViewDirection ACE_player vectorMultiply GVAR(distance))); + private _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; _target = (_objects param [0, []]) param [2, objNull]; }; -if (locked _target in [2,3] || {!simulationEnabled _target}) exitWith { - [localize LSTRING(VehicleLocked)] call EFUNC(common,displayTextStructured); - true +if (!alive _target) exitWith {}; + +if (locked _target >= 2 || {!simulationEnabled _target}) exitWith { + [LLSTRING(VehicleLocked)] call EFUNC(common,displayTextStructured); }; TRACE_2("",_target,typeOf _target); -if (!isNull _target && - {alive _target} && - {{_target isKindOf _x} count ["Air","LandVehicle","Ship","StaticMortar"] > 0} && - {([ACE_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith))} && - {speed _target <= GVAR(speed)} - ) then { +if ( + (speed _target > GVAR(speed)) || + {["Air", "LandVehicle", "Ship", "StaticMortar"] findIf {_target isKindOf _x} == -1} || + {!([ACE_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith))} +) exitWith {}; +private _seats = ["driver", "gunner", "commander", "cargo"]; +private _sortedSeats = [_seats select GVAR(priority)]; +_seats deleteAt GVAR(priority); +_sortedSeats append _seats; - if (GVAR(priority) > 3 || GVAR(priority) < 0) then { - GVAR(priority) = 0; - }; +private _fullCrew = fullCrew [_target, "", true]; - private _seats = ["Driver", "Gunner", "Commander", "Cargo"]; - private _sortedSeats = [_seats select GVAR(priority)]; - _seats deleteAt GVAR(priority); - _sortedSeats append _seats; +private _hasAction = false; +scopeName "SearchForSeat"; +{ + private _desiredRole = _x; - private _hasAction = false; - scopeName "SearchForSeat"; { - private _desiredRole = _x; - { - _x params ["_unit", "_role", "_cargoIndex", "_turretPath"]; - if ((isNull _unit) || {!alive _unit}) then { - private _effectiveRole = toLower _role; - - if ((_effectiveRole in ["driver", "gunner"]) && {unitIsUAV _target}) exitWith {}; // Ignoring UAV Driver/Gunner - if ((_effectiveRole == "driver") && {(getNumber (configOf _target >> "hasDriver")) == 0}) exitWith {}; // Ignoring Non Driver (static weapons) - - // Seats can be locked independently of the main vehicle - if ((_role == "driver") && {lockedDriver _target}) exitWith {TRACE_1("lockedDriver",_x);}; - if ((_cargoIndex >= 0) && {_target lockedCargo _cargoIndex}) exitWith {TRACE_1("lockedCargo",_x);}; - if ((_turretPath isNotEqualTo []) && {_target lockedTurret _turretPath}) exitWith {TRACE_1("lockedTurret",_x);}; - - if (_effectiveRole == "turret") then { - private _turretConfig = [_target, _turretPath] call CBA_fnc_getTurret; - if (getNumber (_turretConfig >> "isCopilot") == 1) exitWith { - _effectiveRole = "driver"; - }; - if ( - _cargoIndex >= 0 // FFV - || {"" isEqualTo getText (_turretConfig >> "gun")} // turret without weapon - ) exitWith { - _effectiveRole = "cargo"; - }; - _effectiveRole = "gunner"; // door gunners / 2nd turret + _x params ["_unit", "_role", "_cargoIndex", "_turretPath"]; + + if (!alive _unit) then { + private _effectiveRole = _role; + + if ((_effectiveRole in ["driver", "gunner"]) && {unitIsUAV _target}) exitWith {}; // Ignoring UAV Driver/Gunner + if ((_effectiveRole == "driver") && {(getNumber (configOf _target >> "hasDriver")) == 0}) exitWith {}; // Ignoring Non Driver (static weapons) + + // Seats can be locked independently of the main vehicle + if ((_effectiveRole == "driver") && {lockedDriver _target}) exitWith {TRACE_1("lockedDriver",_x);}; + if ((_cargoIndex >= 0) && {_target lockedCargo _cargoIndex}) exitWith {TRACE_1("lockedCargo",_x);}; + if ((_turretPath isNotEqualTo []) && {_target lockedTurret _turretPath}) exitWith {TRACE_1("lockedTurret",_x);}; + + if (_effectiveRole == "turret") then { + private _turretConfig = [_target, _turretPath] call CBA_fnc_getTurret; + + if (getNumber (_turretConfig >> "isCopilot") == 1) exitWith { + _effectiveRole = "driver"; }; - TRACE_2("",_effectiveRole,_x); - if (_effectiveRole != _desiredRole) exitWith {}; - if (_turretPath isNotEqualTo []) then { - // Using GetInTurret seems to solve problems with incorrect GetInEH params when gunner/commander - ACE_player action ["GetInTurret", _target, _turretPath]; - TRACE_3("Geting In Turret",_x,_role,_turretPath); - } else { - if (_cargoIndex > -1) then { - // GetInCargo expects the index of the seat in the "cargo" array from fullCrew - // See description: https://community.bistudio.com/wiki/fullCrew - private _cargoActionIndex = -1; - { - if ((_x select 2) == _cargoIndex) exitWith {_cargoActionIndex = _forEachIndex}; - } forEach (fullCrew [_target, "cargo", true]); - - ACE_player action ["GetInCargo", _target, _cargoActionIndex]; - TRACE_4("Geting In Cargo",_x,_role,_cargoActionIndex,_cargoIndex); - } else { - ACE_player action ["GetIn" + _role, _target]; - TRACE_2("Geting In",_x,_role); - }; + if ( + _cargoIndex >= 0 || // FFV + {getText (_turretConfig >> "gun") == ""} // Turret without weapon + ) exitWith { + _effectiveRole = "cargo"; }; - _hasAction = true; - breakTo "SearchForSeat"; + _effectiveRole = "gunner"; // Door gunners / 2nd turret }; - } forEach (fullCrew [_target, "", true]); - } forEach _sortedSeats; - if (!_hasAction) then { - TRACE_1("no empty seats",_hasAction); - [localize LSTRING(VehicleFull)] call EFUNC(common,displayTextStructured); - }; -}; + TRACE_2("",_effectiveRole,_x); + + if (_effectiveRole != _desiredRole) exitWith {}; + + if (_turretPath isNotEqualTo []) then { + // Using GetInTurret seems to solve problems with incorrect GetInEH params when gunner/commander + ACE_player action ["GetInTurret", _target, _turretPath]; + TRACE_3("Getting In Turret",_x,_role,_turretPath); + } else { + if (_cargoIndex > -1) then { + // GetInCargo expects the index of the seat in the "cargo" array from fullCrew + // See description: https://community.bistudio.com/wiki/fullCrew + private _cargoActionIndex = (fullCrew [_target, "cargo", true]) findIf {(_x select 2) == _cargoIndex}; -true + ACE_player action ["GetInCargo", _target, _cargoActionIndex]; + TRACE_4("Getting In Cargo",_x,_role,_cargoActionIndex,_cargoIndex); + } else { + ACE_player action ["GetIn" + _role, _target]; + TRACE_2("Getting In",_x,_role); + }; + }; + + _hasAction = true; + breakTo "SearchForSeat"; + }; + } forEach _fullCrew; +} forEach _sortedSeats; + +if (!_hasAction) then { + TRACE_1("no empty seats",_hasAction); + [LLSTRING(VehicleFull)] call EFUNC(common,displayTextStructured); +}; diff --git a/addons/rangecard/RscTitles.hpp b/addons/rangecard/RscTitles.hpp index 720f724be4d..6b8af599752 100644 --- a/addons/rangecard/RscTitles.hpp +++ b/addons/rangecard/RscTitles.hpp @@ -73,8 +73,8 @@ class ACE_RangeCard_Dialog { SizeEX=0.025; idc=-1; style=48; - x="safezoneX"; - y="safezoneY+0.181889"; + x="safeZoneX"; + y="safeZoneY+0.181889"; w="1.62727*3/4"; h="1.62727"; colorBackground[]={1,1,1,1}; @@ -84,67 +84,67 @@ class ACE_RangeCard_Dialog { class CAPTION_TEXT_1: RangeCard_RscText { idc=770000; style=ST_LEFT; - x="safezoneX+0.18"; - y="safezoneY+0.181889+0.0"; + x="safeZoneX+0.18"; + y="safeZoneY+0.181889+0.0"; w="0.56*1.62727*3/4"; text=".408 CheyTac - 410 gr Predator Projectiles"; }; class CAPTION_TEXT_2: CAPTION_TEXT_1 { idc=770001; SizeEx=0.022; - y="safezoneY+0.181889+0.03"; + y="safeZoneY+0.181889+0.03"; text="Drop Tables for B.P.: 1013.25mb; Corrected for MVV at Air/Ammo Temperatures -15-35 °C"; }; class CAPTION_TEXT_3: CAPTION_TEXT_2 { idc=770002; - y="safezoneY+0.181889+0.06"; + y="safeZoneY+0.181889+0.06"; text="CheyTac Intervention - 29'' 1:13'' twist (M-200)"; }; class ZERO_RANGE_TEXT: RangeCard_RscText { idc=77003; style=ST_LEFT; SizeEx=0.028; - x="safezoneX+0.885"; - y="safezoneY+0.181889+0.01"; + x="safeZoneX+0.885"; + y="safeZoneY+0.181889+0.01"; w="0.125*1.62727*3/4"; text="100m ZERO"; }; class BAROMETRIC_PRESSURE_TEXT: ZERO_RANGE_TEXT { idc=77004; colorText[]={1,0,0,0.8}; - y="safezoneY+0.181889+0.05"; + y="safeZoneY+0.181889+0.05"; text="B.P.: 1013.25mb"; }; class TARGET_RANGE_TEXT_1: RangeCard_RscText { idc=770010; colorText[]={1,1,1,1}; - x="safezoneX+0.185"; - y="safezoneY+0.181889+0.098"; + x="safeZoneX+0.185"; + y="safeZoneY+0.181889+0.098"; text="Target"; }; class TARGET_RANGE_TEXT_2: TARGET_RANGE_TEXT_1 { idc=770011; SizeEx=0.03; - y="safezoneY+0.181889+0.125"; + y="safeZoneY+0.181889+0.125"; text="Range"; }; class TARGET_RANGE_TEXT_3: TARGET_RANGE_TEXT_1 { idc=770012; - y="safezoneY+0.181889+0.152"; + y="safeZoneY+0.181889+0.152"; text="(m)"; }; class BULLET_DROP_TEXT_1: RangeCard_RscText { idc=770013; - x="safezoneX+0.25"; - y="safezoneY+0.181889+0.095"; + x="safeZoneX+0.25"; + y="safeZoneY+0.181889+0.095"; w="0.405*1.62727*3/4"; text="Bullet Drop (MRADs)"; }; class WIND_LEAD_CAPTION_LIST: RangeCard_RscListNBox { idc=770100; sizeEx=0.021; - x="safezoneX+0.728"; - y="safezoneY+0.181889+0.091"; + x="safeZoneX+0.728"; + y="safeZoneY+0.181889+0.091"; w="0.25*1.62727*3/4"; h="0.0909445"; columns[]={"0.03/2", "0.985/2"}; @@ -153,8 +153,8 @@ class ACE_RangeCard_Dialog { }; class TEMPERATURE_CAPTION_LIST_1: RangeCard_RscListNBox { idc=770200; - x="safezoneX+0.24"; - y="safezoneY+0.181889+0.125"; + x="safeZoneX+0.24"; + 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"}; @@ -163,8 +163,8 @@ class ACE_RangeCard_Dialog { }; class TEMPERATURE_CAPTION_LIST_2: RangeCard_RscListNBox { idc=770300; - x="safezoneX+0.728"; - y="safezoneY+0.181889+0.15"; + x="safeZoneX+0.728"; + 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"}; @@ -173,8 +173,8 @@ class ACE_RangeCard_Dialog { }; class RANGE_CARD_DATA: RangeCard_RscListNBox { idc=770400; - x="safezoneX+0.182"; - y="safezoneY+0.181889+0.194"; + x="safeZoneX+0.182"; + 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", @@ -185,13 +185,13 @@ class ACE_RangeCard_Dialog { class FOOTNOTE_TEXT_1: CAPTION_TEXT_1 { idc=770020; SizeEx=0.022; - y="safezoneY+1.72431"; + y="safeZoneY+1.72431"; w="0.705*1.62727*3/4"; text="For best results keep ammunition at ambient air temperature. Tables calculated for the above listed barrel"; }; class FOOTNOTE_TEXT_2: FOOTNOTE_TEXT_1 { idc=770021; - y="safezoneY+1.72431+0.024"; + y="safeZoneY+1.72431+0.024"; text="and load with optic mounted 1.5'' above line of bore."; }; }; diff --git a/addons/rangecard/XEH_postInit.sqf b/addons/rangecard/XEH_postInit.sqf index 6adc4cf2a1c..af4dfa923ce 100644 --- a/addons/rangecard/XEH_postInit.sqf +++ b/addons/rangecard/XEH_postInit.sqf @@ -1,7 +1,5 @@ #include "script_component.hpp" -#include "initKeybinds.inc.sqf" - GVAR(RangeCardOpened) = false; GVAR(controls) = []; @@ -17,3 +15,7 @@ GVAR(boreHeightCopy) = 3.81; GVAR(ammoClassCopy) = "";//"ACE_762x51_Ball_M118LR"; GVAR(magazineClassCopy) = "";//"ACE_20Rnd_762x51_M118LR_Mag"; GVAR(weaponClassCopy) = "";//srifle_DMR_06_olive_F"; + +if (!hasInterface) exitWith {}; + +#include "initKeybinds.inc.sqf" diff --git a/addons/rangecard/config.cpp b/addons/rangecard/config.cpp index f300fb1a308..56ebec629da 100644 --- a/addons/rangecard/config.cpp +++ b/addons/rangecard/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {"ACE_Item_RangeCard"}; weapons[] = {"ACE_RangeCard"}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ACE_Advanced_Ballistics","ace_scopes"}; + requiredAddons[] = {"ace_advanced_ballistics", "ace_scopes"}; author = ECSTRING(common,ACETeam); authors[] = {"Ruthberg"}; url = ECSTRING(main,URL); diff --git a/addons/rangecard/functions/fnc_calculateRangeCard.sqf b/addons/rangecard/functions/fnc_calculateRangeCard.sqf index d2347b84944..c16b202539e 100644 --- a/addons/rangecard/functions/fnc_calculateRangeCard.sqf +++ b/addons/rangecard/functions/fnc_calculateRangeCard.sqf @@ -65,7 +65,7 @@ private _n = 0; private _range = 0; if (_useABConfig) then { - _bc = parseNumber(("ace_advanced_ballistics" callExtension format["atmosphericCorrection:%1:%2:%3:%4:%5", _bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel])); + _bc = parseNumber (("ace" callExtension ["ballistics:atmospheric_correction", [_bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel]]) select 0); }; private _airFrictionCoef = 1; @@ -83,8 +83,8 @@ _bulletPos set [1, 0]; _bulletPos set [2, -(_boreHeight / 100)]; _bulletVelocity set [0, 0]; -_bulletVelocity set [1, Cos(_scopeBaseAngle) * _muzzleVelocity]; -_bulletVelocity set [2, Sin(_scopeBaseAngle) * _muzzleVelocity]; +_bulletVelocity set [1, cos(_scopeBaseAngle) * _muzzleVelocity]; +_bulletVelocity set [2, sin(_scopeBaseAngle) * _muzzleVelocity]; while {_TOF < 6 && (_bulletPos select 1) < _targetRange} do { _bulletSpeed = vectorMagnitude _bulletVelocity; @@ -99,7 +99,7 @@ while {_TOF < 6 && (_bulletPos select 1) < _targetRange} do { _trueSpeed = vectorMagnitude _trueVelocity; if (_useABConfig) then { - private _drag = parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3:%4", _dragModel, _bc, _trueSpeed, _temperature])); + private _drag = parseNumber (("ace" callExtension ["ballistics:retard", [_dragModel, _bc, _trueSpeed, _temperature]]) select 0); _bulletAccel = (vectorNormalized _trueVelocity) vectorMultiply (-1 * _drag); } else { _bulletAccel = _trueVelocity vectorMultiply (_trueSpeed * _airFriction * _airFrictionCoef); @@ -123,21 +123,21 @@ while {_TOF < 6 && (_bulletPos select 1) < _targetRange} do { _tz = (_lastBulletPos select 2) + (_range - (_lastBulletPos select 1)) * ((_bulletPos select 2) - (_lastBulletPos select 2)) / ((_bulletPos select 1) - (_lastBulletPos select 1)); _elevation = - atan(_tz / _range); _windage = - atan(_tx / _range); - _lead = (_targetSpeed * _TOF) / (Tan(MRAD_TO_DEG(1)) * _range); + _lead = (_targetSpeed * _TOF) / (tan(MRAD_TO_DEG(1)) * _range); }; - private _elevationString = Str(round(-DEG_TO_MRAD(_elevation) * 10) / 10); + private _elevationString = str(round(-DEG_TO_MRAD(_elevation) * 10) / 10); if (_elevationString == "0") then { _elevationString = "-0.0"; }; if (_elevationString find "." == -1) then { _elevationString = _elevationString + ".0"; }; - private _windageString = Str(round(DEG_TO_MRAD(_windage) * 10) / 10); + private _windageString = str(round(DEG_TO_MRAD(_windage) * 10) / 10); if (_windageString find "." == -1) then { _windageString = _windageString + ".0"; }; - private _leadString = Str(round(_lead * 10) / 10); + private _leadString = str(round(_lead * 10) / 10); if (_leadString find "." == -1) then { _leadString = _leadString + ".0"; }; diff --git a/addons/rangecard/functions/fnc_updateRangeCard.sqf b/addons/rangecard/functions/fnc_updateRangeCard.sqf index 999dfc5a2e3..76b679accf5 100644 --- a/addons/rangecard/functions/fnc_updateRangeCard.sqf +++ b/addons/rangecard/functions/fnc_updateRangeCard.sqf @@ -42,7 +42,7 @@ for "_row" from 0 to 49 do { _control ctrlSetTextColor [0, 0, 0, 1]; }; _control ctrlCommit 0; - _control ctrlSetText Str(100 + _row * 50); + _control ctrlSetText str(100 + _row * 50); GVAR(controls) pushBack _control; }; for "_column" from 0 to 8 do { @@ -100,7 +100,7 @@ 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; @@ -161,11 +161,9 @@ if (_isABenabled) 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) + parseNumber (("ace" callExtension ["ballistics:zero_vanilla", [_zeroRange, _muzzleVelocity, _airFriction, _boreHeight]]) select 0) } 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) + parseNumber (("ace" callExtension ["ballistics:zero_advanced", [_zeroRange, _muzzleVelocity, _boreHeight, EGVAR(scopes,zeroReferenceTemperature), EGVAR(scopes,zeroReferenceBarometricPressure), EGVAR(scopes,zeroReferenceHumidity), _bc, _dragModel, _atmosphereModel]]) select 0) }; if (_useAmmoTemperatureInfluence) then { { diff --git a/addons/rangecard/stringtable.xml b/addons/rangecard/stringtable.xml index 859bb2e0484..3e79eac9853 100644 --- a/addons/rangecard/stringtable.xml +++ b/addons/rangecard/stringtable.xml @@ -12,7 +12,7 @@ Távolsági kártya Таблица поправок Tavola Balistica - レンジカード (射表) + レンジカード (弾道射表) 사거리표 射表 彈道射表 diff --git a/addons/realisticnames/CfgMagazines.hpp b/addons/realisticnames/CfgMagazines.hpp index be7ce2b2a51..dc5beec603c 100644 --- a/addons/realisticnames/CfgMagazines.hpp +++ b/addons/realisticnames/CfgMagazines.hpp @@ -390,12 +390,6 @@ 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 { diff --git a/addons/realisticnames/CfgVehicles.hpp b/addons/realisticnames/CfgVehicles.hpp index 8d4d0c2f4a1..ba95cf147d5 100644 --- a/addons/realisticnames/CfgVehicles.hpp +++ b/addons/realisticnames/CfgVehicles.hpp @@ -1,6 +1,5 @@ - class CfgVehicles { - // static weapons + // Static weapons class StaticMGWeapon; class HMG_01_base_F: StaticMGWeapon { displayName = CSTRING(HMG_01_Name); @@ -61,7 +60,7 @@ class CfgVehicles { displayName = CSTRING(MRAP_01_hmg_Name); }; - // punisher + // Punisher class MRAP_02_base_F; class O_MRAP_02_F: MRAP_02_base_F { displayName = CSTRING(MRAP_02_Name); @@ -86,7 +85,7 @@ class CfgVehicles { displayName = CSTRING(MRAP_02_gmg_Name); }; - // strider + // Strider class MRAP_03_base_F; class I_MRAP_03_F: MRAP_03_base_F { displayName = CSTRING(MRAP_03_Name); @@ -102,7 +101,7 @@ class CfgVehicles { displayName = CSTRING(MRAP_03_gmg_Name); }; - // merkava derivates + // Merkava derivates class MBT_01_base_F; class B_MBT_01_base_F: MBT_01_base_F {}; @@ -124,7 +123,7 @@ class CfgVehicles { class B_MBT_01_mlrs_base_F: MBT_01_mlrs_base_F {}; class B_MBT_01_mlrs_F: B_MBT_01_mlrs_base_F { - displayName = CSTRING(MBT_01_mlrs_Name); // Fictional name, (probably wrong) hebrew translation of storm. + displayName = CSTRING(MBT_01_mlrs_Name); // Fictional name, (probably wrong) hebrew translation of storm }; // T100 derivates @@ -142,20 +141,20 @@ class CfgVehicles { displayName = CSTRING(MBT_02_arty_Name); }; - // leopard sg + // Leopard 2 SG class I_MBT_03_base_F; class I_MBT_03_cannon_F: I_MBT_03_base_F { displayName = CSTRING(MBT_03_cannon_Name); }; - // tracked apcs + // Tracked apcs class B_APC_Tracked_01_base_F; class B_APC_Tracked_01_rcws_F: B_APC_Tracked_01_base_F { displayName = CSTRING(APC_Tracked_01_rcws_Name); }; class B_APC_Tracked_01_AA_F: B_APC_Tracked_01_base_F { - displayName = CSTRING(APC_Tracked_01_AA_Name); // Fictional name, (probably wrong) hebrew translation of cheetah. + displayName = CSTRING(APC_Tracked_01_AA_Name); // Fictional name, (probably wrong) hebrew translation of cheetah }; class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { @@ -176,7 +175,7 @@ class CfgVehicles { displayName = CSTRING(APC_tracked_03_cannon_Name); }; - // wheeled apcs + // Wheeled apcs class B_APC_Wheeled_01_base_F; class B_APC_Wheeled_01_cannon_F: B_APC_Wheeled_01_base_F { displayName = CSTRING(APC_Wheeled_01_cannon_Name); @@ -199,7 +198,7 @@ class CfgVehicles { displayName = CSTRING(APC_Wheeled_03_cannon_Name); }; - // trucks + // Trucks class Truck_01_base_F; class B_Truck_01_transport_F: Truck_01_base_F { displayName = CSTRING(Truck_01_transport_Name); @@ -249,6 +248,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 +286,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 { @@ -307,7 +316,7 @@ class CfgVehicles { displayName = CSTRING(Truck_03_medical_Name); }; - // helicopters + // Helicopters class Heli_Attack_01_base_F; class B_Heli_Attack_01_F: Heli_Attack_01_base_F { displayName = CSTRING(Heli_Attack_01_Name); @@ -384,8 +393,11 @@ 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 + // Planes class Plane_CAS_01_base_F; class B_Plane_CAS_01_F: Plane_CAS_01_base_F { displayName = CSTRING(Plane_CAS_01_Name); @@ -425,7 +437,7 @@ class CfgVehicles { displayName = CSTRING(Plane_Fighter_04_Name); }; - // uavs + // UAVs class UAV_02_base_F; class B_UAV_02_F: UAV_02_base_F { displayName = CSTRING(UAV_02_Name); @@ -459,104 +471,93 @@ class CfgVehicles { displayName = CSTRING(UAV_02_Name); }; - // pistols - class Pistol_Base_F; - class Weapon_hgun_P07_F: Pistol_Base_F { - displayName = CSTRING(hgun_P07_Name); - }; - - class Weapon_hgun_Rook40_F: Pistol_Base_F { - displayName = CSTRING(hgun_Rook40_Name); - }; - - class Weapon_hgun_ACPC2_F: Pistol_Base_F { - displayName = CSTRING(hgun_ACPC2_Name); - }; - - class Weapon_hgun_Pistol_heavy_01_F: Pistol_Base_F { - displayName = CSTRING(hgun_Pistol_heavy_01_Name); - }; - - class Weapon_hgun_Pistol_heavy_02_F: Pistol_Base_F { - displayName = CSTRING(hgun_Pistol_heavy_02_Name); - }; - - class Weapon_hgun_Pistol_Signal_F: Pistol_Base_F { - displayName = CSTRING(hgun_Pistol_Signal_Name); - }; - - // rocket launchers - class Launcher_Base_F; - class Weapon_launch_NLAW_F: Launcher_Base_F { - displayName = CSTRING(launch_NLAW_Name); - }; - - class Weapon_launch_RPG32_F: Launcher_Base_F { - displayName = CSTRING(launch_RPG32_Name); - }; - - /*class Weapon_launch_Titan_F: Launcher_Base_F { - displayName = CSTRING(launch_Titan_Name); - }; - - class Weapon_launch_Titan_short_F: Launcher_Base_F { - displayName = CSTRING(launch_Titan_short_Name); - }; + #include "CfgVehiclesAttachments.hpp" - class Weapon_launch_B_Titan_F: Launcher_Base_F { - displayName = CSTRING(launch_Titan_Name); - };*/ - //class Weapon_launch_I_Titan_F: Weapon_launch_B_Titan_F {}; - //class Weapon_launch_O_Titan_F: Weapon_launch_B_Titan_F {}; - - /*class Weapon_launch_launch_B_Titan_short_F: Launcher_Base_F { - displayName = CSTRING(launch_Titan_short_Name); - };*/ - //class Weapon_launch_I_Titan_short_F: Weapon_launch_launch_B_Titan_short_F {}; - //class Weapon_launch_O_Titan_short_F: Weapon_launch_launch_B_Titan_short_F {}; - - // rifles + // Assault rifles // MX class Weapon_Base_F; class Weapon_arifle_MX_F: Weapon_Base_F { displayName = CSTRING(arifle_MX_Name); }; + class Weapon_arifle_MX_Black_F: Weapon_Base_F { + displayName = CSTRING(arifle_MX_Black_Name); + }; + class Weapon_arifle_MX_khk_F: Weapon_Base_F { + displayName = CSTRING(arifle_MX_Khaki_Name); + }; class Weapon_arifle_MXC_F: Weapon_Base_F { displayName = CSTRING(arifle_MXC_Name); }; + class Weapon_arifle_MXC_Black_F: Weapon_Base_F { + displayName = CSTRING(arifle_MXC_Black_Name); + }; + class Weapon_arifle_MXC_khk_F: Weapon_Base_F { + displayName = CSTRING(arifle_MXC_Khaki_Name); + }; class Weapon_arifle_MX_GL_F: Weapon_Base_F { displayName = CSTRING(arifle_MX_GL_Name); }; + class Weapon_arifle_MX_GL_Black_F: Weapon_Base_F { + displayName = CSTRING(arifle_MX_GL_Black_Name); + }; + class Weapon_arifle_MX_GL_khk_F: Weapon_Base_F { + displayName = CSTRING(arifle_MX_GL_Khaki_Name); + }; class Weapon_arifle_MX_SW_F: Weapon_Base_F { displayName = CSTRING(arifle_MX_SW_Name); }; + class Weapon_arifle_MX_SW_Black_F: Weapon_Base_F { + displayName = CSTRING(arifle_MX_SW_Black_Name); + }; + class Weapon_arifle_MX_SW_khk_F: Weapon_Base_F { + displayName = CSTRING(arifle_MX_SW_Khaki_Name); + }; class Weapon_arifle_MXM_F: Weapon_Base_F { displayName = CSTRING(arifle_MXM_Name); }; + class Weapon_arifle_MXM_Black_F: Weapon_Base_F { + displayName = CSTRING(arifle_MXM_Black_Name); + }; + class Weapon_arifle_MXM_khk_F: Weapon_Base_F { + displayName = CSTRING(arifle_MXM_Khaki_Name); + }; // Katiba class Weapon_arifle_Katiba_F: Weapon_Base_F { displayName = CSTRING(arifle_Katiba_Name); }; - class Weapon_arifle_Katiba_C_F: Weapon_Base_F { displayName = CSTRING(arifle_Katiba_C_Name); }; - class Weapon_arifle_Katiba_GL_F: Weapon_Base_F { displayName = CSTRING(arifle_Katiba_GL_Name); }; + // SDAR + class Weapon_arifle_SDAR_F: Weapon_Base_F { + displayName = CSTRING(arifle_SDAR_Name); + }; + + // TAR-21 + class Weapon_arifle_TRG21_F: Weapon_Base_F { + displayName = CSTRING(arifle_TRG21_Name); + }; + class Weapon_arifle_TRG20_F: Weapon_Base_F { + displayName = CSTRING(arifle_TRG20_Name); + }; + class Weapon_arifle_TRG21_GL_F: Weapon_Base_F { + displayName = CSTRING(arifle_TRG21_GL_Name); + }; + // F2000 class Weapon_arifle_Mk20_F: Weapon_Base_F { displayName = CSTRING(arifle_Mk20_Name); }; - class Weapon_arifle_Mk20_plain_F: Weapon_Base_F { displayName = CSTRING(arifle_Mk20_plain_Name); }; @@ -564,7 +565,6 @@ class CfgVehicles { class Weapon_arifle_Mk20C_F: Weapon_Base_F { displayName = CSTRING(arifle_Mk20C_Name); }; - class Weapon_arifle_Mk20C_plain_F: Weapon_Base_F { displayName = CSTRING(arifle_Mk20C_plain_Name); }; @@ -572,46 +572,102 @@ class CfgVehicles { class Weapon_arifle_Mk20_GL_F: Weapon_Base_F { displayName = CSTRING(arifle_Mk20_GL_Name); }; - class Weapon_arifle_Mk20_GL_plain_F: Weapon_Base_F { displayName = CSTRING(arifle_Mk20_GL_plain_Name); }; - // TAR-21 - class Weapon_arifle_TRG21_F: Weapon_Base_F { - displayName = CSTRING(arifle_TRG21_Name); + // P90 (1.86) + class Weapon_SMG_03_TR_black: Weapon_Base_F { + displayName = CSTRING(PS90_TR_Black_Name); }; - - class Weapon_arifle_TRG20_F: Weapon_Base_F { - displayName = CSTRING(arifle_TRG20_Name); + class Weapon_SMG_03_TR_khaki: Weapon_Base_F { + displayName = CSTRING(PS90_TR_Khaki_Name); }; - - class Weapon_arifle_TRG21_GL_F: Weapon_Base_F { - displayName = CSTRING(arifle_TRG21_GL_Name); + class Weapon_SMG_03_TR_camo: Weapon_Base_F { + displayName = CSTRING(PS90_TR_Camo_Name); + }; + class Weapon_SMG_03_TR_hex: Weapon_Base_F { + displayName = CSTRING(PS90_TR_Hex_Name); + }; + class Weapon_SMG_03_black: Weapon_Base_F { + displayName = CSTRING(PS90_Black_Name); + }; + class Weapon_SMG_03_khaki: Weapon_Base_F { + displayName = CSTRING(PS90_Khaki_Name); + }; + class Weapon_SMG_03_camo: Weapon_Base_F { + displayName = CSTRING(PS90_Camo_Name); + }; + class Weapon_SMG_03_hex: Weapon_Base_F { + displayName = CSTRING(PS90_Hex_Name); + }; + class Weapon_SMG_03C_TR_black: Weapon_Base_F { + displayName = CSTRING(P90_TR_Black_Name); + }; + class Weapon_SMG_03C_TR_khaki: Weapon_Base_F { + displayName = CSTRING(P90_TR_Khaki_Name); + }; + class Weapon_SMG_03C_TR_camo: Weapon_Base_F { + displayName = CSTRING(P90_TR_Camo_Name); + }; + class Weapon_SMG_03C_TR_hex: Weapon_Base_F { + displayName = CSTRING(P90_TR_Hex_Name); + }; + class Weapon_SMG_03C_black: Weapon_Base_F { + displayName = CSTRING(P90_Black_Name); + }; + class Weapon_SMG_03C_khaki: Weapon_Base_F { + displayName = CSTRING(P90_Khaki_Name); + }; + class Weapon_SMG_03C_camo: Weapon_Base_F { + displayName = CSTRING(P90_Camo_Name); + }; + class Weapon_SMG_03C_hex: Weapon_Base_F { + displayName = CSTRING(P90_Hex_Name); }; - // sub machine guns + // Vector class Weapon_SMG_01_F: Weapon_Base_F { displayName = CSTRING(SMG_01_Name); }; + // Scorpion class Weapon_SMG_02_F: Weapon_Base_F { displayName = CSTRING(SMG_02_Name); }; - class Weapon_SMG_05_F: Weapon_Base_F { - displayName = CSTRING(SMG_05); - }; - + // CPW class Weapon_hgun_PDW2000_F: Weapon_Base_F { displayName = CSTRING(hgun_PDW2000_Name); }; - class Weapon_arifle_SDAR_F: Weapon_Base_F { - displayName = CSTRING(arifle_SDAR_Name); + // Pistols + class Pistol_Base_F; + class Weapon_hgun_P07_F: Pistol_Base_F { + displayName = CSTRING(hgun_P07_Name); + }; + + class Weapon_hgun_Rook40_F: Pistol_Base_F { + displayName = CSTRING(hgun_Rook40_Name); + }; + + class Weapon_hgun_ACPC2_F: Pistol_Base_F { + displayName = CSTRING(hgun_ACPC2_Name); + }; + + class Weapon_hgun_Pistol_heavy_01_F: Pistol_Base_F { + displayName = CSTRING(hgun_Pistol_heavy_01_Name); + }; + + class Weapon_hgun_Pistol_heavy_02_F: Pistol_Base_F { + displayName = CSTRING(hgun_Pistol_heavy_02_Name); }; - // machine guns + class Weapon_hgun_Pistol_Signal_F: Pistol_Base_F { + displayName = CSTRING(hgun_Pistol_Signal_Name); + }; + + // Machine guns class Weapon_LMG_Mk200_F: Weapon_Base_F { displayName = CSTRING(LMG_Mk200_Name); }; @@ -620,40 +676,73 @@ class CfgVehicles { displayName = CSTRING(LMG_Zafir_Name); }; - // sniper rifles + // Sniper rifles class Weapon_srifle_EBR_F: Weapon_Base_F { displayName = CSTRING(srifle_EBR_Name); }; + class Weapon_srifle_LRR_F: Weapon_Base_F { + displayName = CSTRING(srifle_LRR_Name); + }; + class Weapon_srifle_LRR_camo_F: Weapon_Base_F { + displayName = CSTRING(srifle_LRR_camo_Name); + }; + class Weapon_srifle_GM6_F: Weapon_Base_F { displayName = CSTRING(srifle_GM6_Name); }; - class Weapon_srifle_GM6_camo_F: Weapon_Base_F { displayName = CSTRING(srifle_GM6_camo_Name); }; - class Weapon_srifle_LRR_F: Weapon_Base_F { - displayName = CSTRING(srifle_LRR_Name); + class Weapon_srifle_DMR_01_F: Weapon_Base_F { + displayName = CSTRING(srifle_DMR_01_Name); }; - class Weapon_srifle_LRR_camo_F: Weapon_Base_F { - displayName = CSTRING(srifle_LRR_camo_Name); + // Rocket launchers + class Launcher_Base_F; + class Weapon_launch_RPG32_F: Launcher_Base_F { + displayName = CSTRING(launch_RPG32_Name); }; - class Weapon_srifle_DMR_01_F: Weapon_Base_F { - displayName = CSTRING(srifle_DMR_01_Name); + class Weapon_launch_NLAW_F: Launcher_Base_F { + displayName = CSTRING(launch_NLAW_Name); }; - // marksmen - /*class Weapon_srifle_DMR_02_F: Weapon_Base_F { - displayName = CSTRING(srifle_DMR_02); + /*class Weapon_launch_Titan_F: Launcher_Base_F { + displayName = CSTRING(launch_Titan_Name); + }; + + class Weapon_launch_Titan_short_F: Launcher_Base_F { + displayName = CSTRING(launch_Titan_short_Name); + }; + + class Weapon_launch_B_Titan_F: Launcher_Base_F { + displayName = CSTRING(launch_Titan_Name); + };*/ + //class Weapon_launch_I_Titan_F: Weapon_launch_B_Titan_F {}; + //class Weapon_launch_O_Titan_F: Weapon_launch_B_Titan_F {}; + + /*class Weapon_launch_launch_B_Titan_short_F: Launcher_Base_F { + displayName = CSTRING(launch_Titan_short_Name); + };*/ + //class Weapon_launch_I_Titan_short_F: Weapon_launch_launch_B_Titan_short_F {}; + //class Weapon_launch_O_Titan_short_F: Weapon_launch_launch_B_Titan_short_F {}; + + class Weapon_launch_O_Vorona_brown_F: Launcher_Base_F { + displayName = CSTRING(launch_Vorona_brown); + }; + class Weapon_launch_O_Vorona_green_F: Launcher_Base_F { + displayName = CSTRING(launch_Vorona_green); }; + // Marksmen marksman + class Weapon_srifle_DMR_02_F: Weapon_Base_F { + displayName = CSTRING(srifle_DMR_02); + }; class Weapon_srifle_DMR_02_camo_F: Weapon_Base_F { displayName = CSTRING(srifle_DMR_02_camo); }; - class Weapon_srifle_DMR_02_sniper_F: Weapon_Base_F { displayName = CSTRING(srifle_DMR_02_sniper); }; @@ -661,19 +750,15 @@ class CfgVehicles { class Weapon_srifle_DMR_03_F: Weapon_Base_F { displayName = CSTRING(srifle_DMR_03); }; - class Weapon_srifle_DMR_03_khaki_F: Weapon_Base_F { displayName = CSTRING(srifle_DMR_03_khaki); }; - class Weapon_srifle_DMR_03_tan_F: Weapon_Base_F { displayName = CSTRING(srifle_DMR_03_tan); }; - class Weapon_srifle_DMR_03_multicam_F: Weapon_Base_F { displayName = CSTRING(srifle_DMR_03_multicam); }; - class Weapon_srifle_DMR_03_woodland_F: Weapon_Base_F { displayName = CSTRING(srifle_DMR_03_woodland); }; @@ -681,7 +766,6 @@ class CfgVehicles { class Weapon_srifle_DMR_04_F: Weapon_Base_F { displayName = CSTRING(srifle_DMR_04); }; - class Weapon_srifle_DMR_04_Tan_F: Weapon_Base_F { displayName = CSTRING(srifle_DMR_04_Tan); }; @@ -689,11 +773,9 @@ class CfgVehicles { class Weapon_srifle_DMR_05_blk_F: Weapon_Base_F { displayName = CSTRING(srifle_DMR_05_blk); }; - class Weapon_srifle_DMR_05_hex_F: Weapon_Base_F { displayName = CSTRING(srifle_DMR_05_hex); }; - class Weapon_srifle_DMR_05_tan_f: Weapon_Base_F { displayName = CSTRING(srifle_DMR_05_tan); }; @@ -701,11 +783,11 @@ class CfgVehicles { class Weapon_srifle_DMR_06_camo_F: Weapon_Base_F { displayName = CSTRING(srifle_DMR_06_camo); }; - class Weapon_srifle_DMR_06_olive_F: Weapon_Base_F { displayName = CSTRING(srifle_DMR_06_olive); }; + // Marksmen MGs class Weapon_MMG_01_hex_F: Weapon_Base_F { displayName = CSTRING(MMG_01_hex); }; @@ -724,14 +806,58 @@ class CfgVehicles { class Weapon_MMG_02_sand_F: Weapon_Base_F { displayName = CSTRING(MMG_02_sand); - };*/ + }; - //attachments + // Tanks DLC + + // Rooikat 120 (Rhino MGS) + class 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 { + 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 { + displayName = CSTRING(afv_wheeled_01_up); + }; + class B_T_AFV_Wheeled_01_up_cannon_F: AFV_Wheeled_01_up_base_F { + displayName = CSTRING(afv_wheeled_01_up); + }; - class Item_Base_F; + // T-14 Armata (T-140 Angara) + class 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 { + 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 { + displayName = CSTRING(MBT_04_command); + }; + class O_T_MBT_04_command_F: MBT_04_command_base_F { + displayName = CSTRING(MBT_04_command); + }; - class Item_acc_flashlight: Item_Base_F { - displayName="UTG Defender 126"; + // Wiesel 2 (AWC 302 Nyx) + class 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 { + displayName = CSTRING(LT_01_AT); + }; + class 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 { + displayName = CSTRING(LT_01_scout); }; // APEX/Tanoa @@ -802,54 +928,266 @@ class CfgVehicles { 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 { - displayName = CSTRING(afv_wheeled_01); + // Type 115 + class Weapon_arifle_ARX_blk_F: Weapon_Base_F { + displayName = CSTRING(arifle_arx_blk_Name); }; - class B_T_AFV_Wheeled_01_cannon_F: AFV_Wheeled_01_base_F { - displayName = CSTRING(afv_wheeled_01); + class Weapon_arifle_ARX_ghex_F: Weapon_Base_F { + displayName = CSTRING(arifle_arx_ghex_Name); }; - class 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 Weapon_arifle_ARX_hex_F: Weapon_Base_F { + displayName = CSTRING(arifle_arx_hex_Name); }; - class B_T_AFV_Wheeled_01_up_cannon_F: AFV_Wheeled_01_up_base_F { - displayName = CSTRING(afv_wheeled_01_up); + + // QBZ-95 and variants + class Weapon_arifle_CTAR_blk_F: Weapon_Base_F { + displayName = CSTRING(arifle_CTAR_blk); + }; + class Weapon_arifle_CTAR_ghex_F: Weapon_Base_F { + displayName = CSTRING(arifle_CTAR_ghex); + }; + class Weapon_arifle_CTAR_hex_F: Weapon_Base_F { + displayName = CSTRING(arifle_CTAR_hex); }; - // T-14 Armata (T-140 Angara) - class MBT_04_cannon_base_F; - class O_MBT_04_cannon_F: MBT_04_cannon_base_F { - displayName = CSTRING(MBT_04_cannon); + class Weapon_arifle_CTAR_GL_blk_F: Weapon_Base_F { + displayName = CSTRING(arifle_CTAR_GL_blk); }; - class O_T_MBT_04_cannon_F: MBT_04_cannon_base_F { - displayName = CSTRING(MBT_04_cannon); + class Weapon_arifle_CTAR_GL_ghex_F: Weapon_Base_F { + displayName = CSTRING(arifle_CTAR_GL_ghex); }; - class MBT_04_command_base_F; // Keep "K" designation for command variant. - class O_MBT_04_command_F: MBT_04_command_base_F { - displayName = CSTRING(MBT_04_command); + class Weapon_arifle_CTAR_GL_hex_F: Weapon_Base_F { + displayName = CSTRING(arifle_CTAR_GL_hex); }; - class O_T_MBT_04_command_F: MBT_04_command_base_F { - displayName = CSTRING(MBT_04_command); + + class Weapon_arifle_CTARS_blk_F: Weapon_Base_F { + displayName = CSTRING(arifle_CTARS_blk); + }; + class Weapon_arifle_CTARS_ghex_F: Weapon_Base_F { + displayName = CSTRING(arifle_CTARS_ghex); + }; + class Weapon_arifle_CTARS_hex_F: Weapon_Base_F { + displayName = CSTRING(arifle_CTARS_hex); }; - // Wiesel 2 (AWC 302 Nyx) - class LT_01_AA_base_F; - class I_LT_01_AA_F: LT_01_AA_base_F { - displayName = CSTRING(LT_01_AA); + // QBU-88 + class Weapon_srifle_DMR_07_blk_F: Weapon_Base_F { + displayName = CSTRING(srifle_DMR_07_blk); }; - class LT_01_AT_base_F; - class I_LT_01_AT_F: LT_01_AT_base_F { - displayName = CSTRING(LT_01_AT); + class Weapon_srifle_DMR_07_ghex_F: Weapon_Base_F { + displayName = CSTRING(srifle_DMR_07_ghex); }; - class LT_01_cannon_base_F; - class I_LT_01_cannon_F: LT_01_cannon_base_F { - displayName = CSTRING(LT_01_cannon); + class Weapon_srifle_DMR_07_hex_F: Weapon_Base_F { + displayName = CSTRING(srifle_DMR_07_hex); }; - class LT_01_scout_base_F; - class I_LT_01_scout_F: LT_01_scout_base_F { - displayName = CSTRING(LT_01_scout); + + // GM6 + class Weapon_srifle_GM6_ghex_F: Weapon_Base_F { + displayName = CSTRING(srifle_GM6_ghex); + }; + + // M249 + class Weapon_LMG_03_F: Weapon_Base_F { + displayName = CSTRING(LMG_03); + }; + + // Intervention + class Weapon_srifle_LRR_tna_F: Weapon_Base_F { + displayName = CSTRING(srifle_LRR_tna); + }; + + // MP5 + class Weapon_SMG_05_F: Weapon_Base_F { + displayName = CSTRING(SMG_05); + }; + + // HK416 and variants + class Weapon_arifle_SPAR_01_blk_F: Weapon_Base_F { + displayName = CSTRING(arifle_SPAR_01_blk); + }; + class Weapon_arifle_SPAR_01_khk_F: Weapon_Base_F { + displayName = CSTRING(arifle_SPAR_01_khk); + }; + class Weapon_arifle_SPAR_01_snd_F: Weapon_Base_F { + displayName = CSTRING(arifle_SPAR_01_snd); + }; + + class Weapon_arifle_SPAR_01_GL_blk_F: Weapon_Base_F { + displayName = CSTRING(arifle_SPAR_01_GL_blk); + }; + class Weapon_arifle_SPAR_01_GL_khk_F: Weapon_Base_F { + displayName = CSTRING(arifle_SPAR_01_GL_khk); + }; + class Weapon_arifle_SPAR_01_GL_snd_F: Weapon_Base_F { + displayName = CSTRING(arifle_SPAR_01_GL_snd); + }; + + class Weapon_arifle_SPAR_02_blk_F: Weapon_Base_F { + displayName = CSTRING(arifle_SPAR_02_blk); + }; + class Weapon_arifle_SPAR_02_khk_F: Weapon_Base_F { + displayName = CSTRING(arifle_SPAR_02_khk); + }; + class Weapon_arifle_SPAR_02_snd_F: Weapon_Base_F { + displayName = CSTRING(arifle_SPAR_02_snd); }; + class Weapon_arifle_SPAR_03_blk_F: Weapon_Base_F { + displayName = CSTRING(arifle_SPAR_03_blk); + }; + class Weapon_arifle_SPAR_03_khk_F: Weapon_Base_F { + displayName = CSTRING(arifle_SPAR_03_khk); + }; + class Weapon_arifle_SPAR_03_snd_F: Weapon_Base_F { + displayName = CSTRING(arifle_SPAR_03_snd); + }; + + // RPG-32 + class Weapon_launch_RPG32_ghex_F: Launcher_Base_F { + displayName = CSTRING(launch_RPG32_ghex); + }; + + // P99 + class Weapon_hgun_P07_khk_F: Pistol_Base_F { + displayName = CSTRING(hgun_P07_khk); + }; + class Weapon_hgun_P07_blk_F: Pistol_Base_F { + displayName = CSTRING(hgun_P07_blk); + }; + + // Makarov + class Weapon_hgun_Pistol_01_F: Pistol_Base_F { + displayName = CSTRING(hgun_Pistol_01); + }; + + // AKM + class Weapon_arifle_AKM_F: Weapon_Base_F { + displayName = CSTRING(arifle_AKM); + }; + + // AKSU + class Weapon_arifle_AKS_F: Weapon_Base_F { + displayName = CSTRING(arifle_AKS); + }; + + // Contact/Livonia + + // CZ 581 Shotgun + class Weapon_sgun_HunterShotgun_01_F: Weapon_Base_F { + displayName = CSTRING(sgun_huntershotgun_01_Name); + }; + class Weapon_sgun_HunterShotgun_01_sawedoff_F: Weapon_Base_F { + displayName = CSTRING(sgun_huntershotgun_sawedoff_01_Name); + }; + + // FNX-45 (Green) + class Weapon_hgun_Pistol_heavy_01_green_F: Pistol_Base_F { + displayName = CSTRING(hgun_Pistol_heavy_01_green_Name); + }; + + // RPG-32 (Green) + class Weapon_launch_RPG32_green_F: Launcher_Base_F { + displayName = CSTRING(launch_RPG32_green_Name); + }; + + // AK15 variants + class Weapon_arifle_AK12_F: Weapon_Base_F { + displayName = CSTRING(arifle_AK12); + }; + class Weapon_arifle_AK12_lush_F: Weapon_Base_F { + displayName = CSTRING(arifle_AK12_lush); + }; + class Weapon_arifle_AK12_arid_F: Weapon_Base_F { + displayName = CSTRING(arifle_AK12_arid); + }; + + class Weapon_arifle_AK12_GL_F: Weapon_Base_F { + displayName = CSTRING(arifle_AK12_GL); + }; + class Weapon_arifle_AK12_GL_lush_F: Weapon_Base_F { + displayName = CSTRING(arifle_AK12_GL_lush); + }; + class Weapon_arifle_AK12_GL_arid_F: Weapon_Base_F { + displayName = CSTRING(arifle_AK12_GL_arid); + }; + + class Weapon_arifle_AK12U_F: Weapon_Base_F { + displayName = CSTRING(arifle_AK12U); + }; + class Weapon_arifle_AK12U_lush_F: Weapon_Base_F { + displayName = CSTRING(arifle_AK12U_lush); + }; + class Weapon_arifle_AK12U_arid_F: Weapon_Base_F { + displayName = CSTRING(arifle_AK12U_arid); + }; + + class Weapon_arifle_RPK12_F: Weapon_Base_F { + displayName = CSTRING(arifle_RPK12); + }; + class Weapon_arifle_RPK12_lush_F: Weapon_Base_F { + displayName = CSTRING(arifle_RPK12_lush); + }; + class Weapon_arifle_RPK12_arid_F: Weapon_Base_F { + displayName = CSTRING(arifle_RPK12_arid); + }; + + // M14 (Classic) + class Weapon_srifle_DMR_06_hunter_F: Weapon_Base_F { + displayName = CSTRING(srifle_DMR_06_hunter); + }; + + // Stoner 99 LMG (Black) + class Weapon_LMG_Mk200_black_F: Weapon_Base_F { + displayName = CSTRING(LMG_Mk200_black); + }; + + // MSBS Grot variants + class Weapon_arifle_MSBS65_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65); + }; + class Weapon_arifle_MSBS65_black_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_black); + }; + class Weapon_arifle_MSBS65_camo_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_camo); + }; + class Weapon_arifle_MSBS65_sand_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_sand); + }; + class Weapon_arifle_MSBS65_GL_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_GL); + }; + class Weapon_arifle_MSBS65_GL_black_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_GL_black); + }; + class Weapon_arifle_MSBS65_GL_camo_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_GL_camo); + }; + class Weapon_arifle_MSBS65_GL_sand_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_GL_sand); + }; + class Weapon_arifle_MSBS65_Mark_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_Mark); + }; + class Weapon_arifle_MSBS65_Mark_black_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_Mark_black); + }; + class Weapon_arifle_MSBS65_Mark_camo_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_Mark_camo); + }; + class Weapon_arifle_MSBS65_Mark_sand_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_Mark_sand); + }; + class Weapon_arifle_MSBS65_UBS_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_UBS); + }; + class Weapon_arifle_MSBS65_UBS_black_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_UBS_black); + }; + class Weapon_arifle_MSBS65_UBS_camo_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_UBS_camo); + }; + class Weapon_arifle_MSBS65_UBS_sand_F: Weapon_Base_F { + displayName = CSTRING(arifle_MSBS65_UBS_sand); + }; }; diff --git a/addons/realisticnames/CfgVehiclesAttachments.hpp b/addons/realisticnames/CfgVehiclesAttachments.hpp new file mode 100644 index 00000000000..54e6206fe3a --- /dev/null +++ b/addons/realisticnames/CfgVehiclesAttachments.hpp @@ -0,0 +1,146 @@ +// Attachments +class Item_Base_F; +class Item_acc_flashlight: Item_Base_F { + displayName = CSTRING(flashlight_Name); +}; + +class Item_optic_MRD: Item_Base_F { + displayName = CSTRING(optic_mrd_Name); +}; +class Item_optic_MRD_black: Item_Base_F { + displayName = CSTRING(optic_mrd_black_Name); +}; + +class Item_optic_Hamr: Item_Base_F { + displayName = CSTRING(optic_hamr); +}; +class Item_optic_Hamr_khk_F: Item_Base_F { + displayName = CSTRING(optic_hamr_khk); +}; + +class Item_optic_Arco: Item_Base_F { + displayName = CSTRING(optic_arco); +}; +class Item_optic_Arco_blk_F: Item_Base_F { + displayName = CSTRING(optic_arco_blk); +}; +class Item_optic_Arco_ghex_F: Item_Base_F { + displayName = CSTRING(optic_arco_ghex); +}; +class Item_optic_Arco_lush_F: Item_Base_F { + displayName = CSTRING(optic_arco_lush); +}; +class Item_optic_Arco_arid_F: Item_Base_F { + displayName = CSTRING(optic_arco_arid); +}; +class Item_optic_Arco_AK_blk_F: Item_Base_F { + displayName = CSTRING(optic_arco_ak_blk); +}; +class Item_optic_Arco_AK_lush_F: Item_Base_F { + displayName = CSTRING(optic_arco_ak_lush); +}; +class Item_optic_Arco_AK_arid_F: Item_Base_F { + displayName = CSTRING(optic_arco_ak_arid); +}; + +class Item_optic_ERCO_blk_f: Item_Base_F { + displayName = CSTRING(optic_erco_blk); +}; +class Item_optic_ERCO_khk_f: Item_Base_F { + displayName = CSTRING(optic_erco_khk); +}; +class Item_optic_ERCO_snd_f: Item_Base_F { + displayName = CSTRING(optic_erco_snd); +}; + +class Item_optic_LRPS: Item_Base_F { + displayName = CSTRING(optic_lrps); +}; +class Item_optic_LRPS_ghex_F: Item_Base_F { + displayName = CSTRING(optic_lrps_ghex); +}; +class Item_optic_LRPS_tna_F: Item_Base_F { + displayName = CSTRING(optic_lrps_tna); +}; + +class Item_optic_AMS: Item_Base_F { + displayName = CSTRING(optic_ams); +}; +class Item_optic_AMS_khk: Item_Base_F { + displayName = CSTRING(optic_ams_khk); +}; +class Item_optic_AMS_snd: Item_Base_F { + displayName = CSTRING(optic_ams_snd); +}; + +class Item_optic_KHS_blk: Item_Base_F { + displayName = CSTRING(optic_khs_blk); +}; +class Item_optic_KHS_hex: Item_Base_F { + displayName = CSTRING(optic_khs_hex); +}; +class Item_optic_KHS_old: Item_Base_F { + displayName = CSTRING(optic_khs_old); +}; +class Item_optic_KHS_tan: Item_Base_F { + displayName = CSTRING(optic_khs_tan); +}; + +class Item_optic_DMS: Item_Base_F { + displayName = CSTRING(optic_dms); +}; +class Item_optic_DMS_ghex_F: Item_Base_F { + displayName = CSTRING(optic_dms_ghex); +}; +class Item_optic_DMS_weathered_F: Item_Base_F { + displayName = CSTRING(optic_dms_weathered); +}; +class Item_optic_DMS_weathered_Kir_F: Item_Base_F { + displayName = CSTRING(optic_dms_weathered_kir); +}; + +class Item_optic_holosight: Item_Base_F { + displayName = CSTRING(optic_holosight); +}; +class Item_optic_Holosight_blk_F: Item_Base_F { + displayName = CSTRING(optic_holosight_blk); +}; +class Item_optic_Holosight_khk_F: Item_Base_F { + displayName = CSTRING(optic_holosight_khk); +}; +class Item_optic_Holosight_lush_F: Item_Base_F { + displayName = CSTRING(optic_holosight_lush); +}; +class Item_optic_Holosight_arid_F: Item_Base_F { + displayName = CSTRING(optic_holosight_arid); +}; +class Item_optic_Holosight_smg: Item_Base_F { + displayName = CSTRING(optic_holosight_smg); +}; +class Item_optic_Holosight_smg_blk_F: Item_Base_F { + displayName = CSTRING(optic_holosight_smg_blk); +}; +class Item_optic_Holosight_smg_khk_F: Item_Base_F { + displayName = CSTRING(optic_holosight_smg_khk); +}; + +class Item_optic_MRCO: Item_Base_F { + displayName = CSTRING(optic_MRCO); +}; + +class Item_optic_Yorris: Item_Base_F { + displayName = CSTRING(optic_Yorris); +}; + +class Item_optic_ACO: Item_Base_F { + displayName = CSTRING(optic_ACO); +}; +class Item_optic_ACO_grn: Item_Base_F { + displayName = CSTRING(optic_ACO_grn); +}; +class Item_optic_ACO_smg: Item_Base_F { + displayName = CSTRING(optic_ACO_smg); +}; +class Item_optic_ACO_grn_smg: Item_Base_F { + displayName = CSTRING(optic_ACO_grn_smg); +}; diff --git a/addons/realisticnames/CfgWeapons.hpp b/addons/realisticnames/CfgWeapons.hpp index 953f981051e..c515cf08fc7 100644 --- a/addons/realisticnames/CfgWeapons.hpp +++ b/addons/realisticnames/CfgWeapons.hpp @@ -2,7 +2,9 @@ class Mode_SemiAuto; class Mode_FullAuto; class CfgWeapons { - // assault rifles + #include "CfgWeaponsAttachments.hpp" + + // Assault rifles // MX class arifle_MX_Base_F; @@ -175,13 +177,13 @@ class CfgWeapons { displayName = CSTRING(SMG_02_Name); }; - // PDW 2000 + // CPW class pdw2000_base_F; class hgun_pdw2000_F: pdw2000_base_F { displayName = CSTRING(hgun_PDW2000_Name); }; - // pistols + // Pistols class Pistol_Base_F; class hgun_P07_F: Pistol_Base_F { displayName = CSTRING(hgun_P07_Name); @@ -207,7 +209,7 @@ class CfgWeapons { displayName = CSTRING(hgun_Pistol_Signal_Name); }; - // machine guns + // Machine guns class Rifle_Long_Base_F; class LMG_Mk200_F: Rifle_Long_Base_F { displayName = CSTRING(LMG_Mk200_Name); @@ -217,7 +219,7 @@ class CfgWeapons { displayName = CSTRING(LMG_Zafir_Name); }; - // sniper rifles + // Sniper rifles class EBR_base_F; class srifle_EBR_F: EBR_base_F { displayName = CSTRING(srifle_EBR_Name); @@ -244,7 +246,7 @@ class CfgWeapons { displayName = CSTRING(srifle_DMR_01_Name); }; - // launchers + // Launchers class Launcher_Base_F; class launch_RPG32_F: Launcher_Base_F { displayName = CSTRING(launch_RPG32_Name); @@ -269,42 +271,35 @@ class CfgWeapons { displayName = CSTRING(launch_Vorona_green); }; - // marksmen marksman + // Marksmen marksman class DMR_02_base_F: Rifle_Long_Base_F { displayName = CSTRING(DMR_02); //MAR-10 .338; }; - class srifle_DMR_02_F: DMR_02_base_F { displayName = CSTRING(srifle_DMR_02); //MAR-10 .338 (Black); }; - class srifle_DMR_02_camo_F: srifle_DMR_02_F { displayName = CSTRING(srifle_DMR_02_camo); //MAR-10 .338 (Camo); }; - class srifle_DMR_02_sniper_F: srifle_DMR_02_F { displayName = CSTRING(srifle_DMR_02_sniper); //MAR-10 .338 (Sand); }; + class DMR_03_base_F: Rifle_Long_Base_F { displayName = CSTRING(DMR_03); //Mk-I EMR 7.62 mm; }; - class srifle_DMR_03_F: DMR_03_base_F { displayName = CSTRING(srifle_DMR_03); //Mk-I EMR 7.62 mm (Black); }; - class srifle_DMR_03_khaki_F: srifle_DMR_03_F { displayName = CSTRING(srifle_DMR_03_khaki); //Mk-I EMR 7.62 mm (Khaki); }; - class srifle_DMR_03_tan_F: srifle_DMR_03_F { displayName = CSTRING(srifle_DMR_03_tan); //Mk-I EMR 7.62 mm (Sand); }; - class srifle_DMR_03_multicam_F: srifle_DMR_03_F { displayName = CSTRING(srifle_DMR_03_multicam); //Mk-I EMR 7.62 mm (Camo); }; - class srifle_DMR_03_woodland_F: srifle_DMR_03_F { displayName = CSTRING(srifle_DMR_03_woodland); //Mk-I EMR 7.62 mm (Woodland); }; @@ -312,11 +307,9 @@ class CfgWeapons { class DMR_04_base_F: Rifle_Long_Base_F { displayName = CSTRING(DMR_04); //ASP-1 Kir 12.7 mm; }; - class srifle_DMR_04_F: DMR_04_base_F { displayName = CSTRING(srifle_DMR_04); //ASP-1 Kir 12.7 mm (Black); }; - class srifle_DMR_04_Tan_F: srifle_DMR_04_F { displayName = CSTRING(srifle_DMR_04_Tan); //ASP-1 Kir 12.7 mm (Tan); }; @@ -324,31 +317,27 @@ class CfgWeapons { class DMR_05_base_F: Rifle_Long_Base_F { displayName = CSTRING(DMR_05); //Cyrus 9.3 mm; }; - class srifle_DMR_05_blk_F: DMR_05_base_F { displayName = CSTRING(srifle_DMR_05_blk); //Cyrus 9.3 mm (Black) }; - class srifle_DMR_05_hex_F: srifle_DMR_05_blk_F { displayName = CSTRING(srifle_DMR_05_hex); //Cyrus 9.3 mm (Hex); }; - class srifle_DMR_05_tan_f: srifle_DMR_05_blk_F { displayName = CSTRING(srifle_DMR_05_tan); //Cyrus 9.3 mm (Tan); }; + class DMR_06_base_F: Rifle_Long_Base_F { displayName = CSTRING(DMR_06); //Mk14 7.62 mm; }; - class srifle_DMR_06_camo_F: DMR_06_base_F { displayName = CSTRING(srifle_DMR_06_camo); //Mk14 7.62 mm (Camo) }; - class srifle_DMR_06_olive_F: srifle_DMR_06_camo_F { displayName = CSTRING(srifle_DMR_06_olive); //Mk14 7.62 mm (Olive); }; - // marksmen mgs + // Marksmen MGs class MMG_01_base_F: Rifle_Long_Base_F { displayName = CSTRING(MMG_01); //Navid 9.3 mm; }; @@ -376,15 +365,12 @@ class CfgWeapons { displayName = CSTRING(MMG_02_sand); //SPMG .338 (Sand); }; - // vehicle weapons + // Vehicle weapons - // gatlings + // Gatlings class CannonCore; class gatling_20mm: CannonCore { - //displayName = ""; - class manual: CannonCore { - //displayName = ""; - }; + class manual; }; class Twin_Cannon_20mm: gatling_20mm { displayName = "Plamen PL-20"; @@ -414,7 +400,7 @@ class CfgWeapons { }; }; - // missiles + // Missiles class RocketPods; class Missile_AA_04_Plane_CAS_01_F: RocketPods { displayName = "AIM-9 Sidewinder"; @@ -437,7 +423,7 @@ class CfgWeapons { displayName = CSTRING(missiles_vorona); }; - // rockets + // Rockets class Rocket_04_HE_Plane_CAS_01_F: RocketPods { displayName = "Hydra 70"; class Burst: RocketPods { @@ -468,7 +454,7 @@ class CfgWeapons { }; }; - // more missiles + // More missiles class missiles_DAR: RocketPods { displayName = "Hydra 70"; class Burst: RocketPods { @@ -491,17 +477,17 @@ class CfgWeapons { displayName = "AIM-120A AMRAAM"; }; - class missiles_SCALPEL: RocketPods { // according to zGuba, this is what it's based on + class missiles_SCALPEL: RocketPods { // According to zGuba, this is what it's based on displayName = "9K121 Vikhr"; }; - // bomb + // Bomb class Bomb_04_Plane_CAS_01_F; class Bomb_03_Plane_CAS_02_F: Bomb_04_Plane_CAS_01_F { displayName = "FAB-250M-54"; }; - // machine guns + // Machine guns class MGunCore; class M134_minigun: MGunCore { displayName = "2x M134 Minigun"; @@ -531,11 +517,6 @@ class CfgWeapons { }; }; - class HMG_127_APC: HMG_127 {}; - class ACE_HMG_127_KORD: HMG_127_APC { - displayName = "6P49 Kord"; - }; - class HMG_01: HMG_127 { displayName = "XM312"; }; @@ -550,7 +531,7 @@ class CfgWeapons { }; }; - // grenade launchers + // Grenade launchers class GMG_F; class GMG_20mm: GMG_F { displayName = "XM307"; @@ -566,7 +547,7 @@ class CfgWeapons { }; }; - // autocannons + // Autocannons class autocannon_35mm: CannonCore { displayName = "GDF-001"; class manual: CannonCore { @@ -574,7 +555,7 @@ class CfgWeapons { }; }; - // aa missiles + // AA missiles class missiles_titan: MissileLauncher { displayName = "Mini-Spike"; }; @@ -583,17 +564,17 @@ class CfgWeapons { displayName = "FIM-92F"; }; - // mortar + // Nortar class mortar_155mm_AMOS: CannonCore { displayName = "L/52"; }; - // artillery rockets + // Artillery rockets class rockets_230mm_GAT: RocketPods { displayName = "M269"; }; - // tank guns + // Tank guns class cannon_120mm: CannonCore { class player; displayName = "MG251"; @@ -604,10 +585,6 @@ class CfgWeapons { class player: player {}; }; - class ACE_cannon_120mm_GT12: cannon_120mm { - displayName = "GT12"; - }; - class cannon_105mm: CannonCore { displayName = "M68"; class player: Mode_SemiAuto { @@ -623,28 +600,12 @@ class CfgWeapons { displayName = "2A82-1M"; }; - // coax machine guns + // Coax machine guns class LMG_coax: LMG_RCWS { displayName = "PKT"; }; - class LMG_coax_ext: LMG_coax {}; - class ACE_LMG_coax_ext_MAG58: LMG_coax_ext { - displayName = "MAG 58M"; - }; - class ACE_LMG_coax_MAG58_mem3: LMG_coax { - displayName = "MAG 58M"; - }; - class ACE_LMG_coax_L94A1_mem3: LMG_coax { - displayName = "L94A1"; - }; - class ACE_LMG_coax_ext_MG3: LMG_coax_ext { - displayName = "Rheinmetall MG3"; - }; - class ACE_LMG_coax_DenelMG4: LMG_coax { - displayName = "Denel MG4"; - }; - // more autocannons + // More autocannons class autocannon_Base_F; class autocannon_40mm_CTWS: autocannon_Base_F { displayName = "Mk44 Bushmaster II"; @@ -693,189 +654,19 @@ class CfgWeapons { displayName = "2A42"; }; - class cannon_20mm: autocannon_Base_F { - class AP: autocannon_Base_F {}; - class HE: autocannon_Base_F {}; - }; - class ACE_cannon_20mm_Rh202: cannon_20mm { - displayName = "MK20 Rh 202"; - class AP: AP { - displayName = "MK20 Rh 202"; - }; - class HE: HE { - displayName = "MK20 Rh 202"; - }; - }; - - //attachments - - class ItemCore; - - class acc_flashlight: ItemCore { - displayName = "UTG Defender 126"; - }; - - class optic_Hamr: ItemCore { - displayName = CSTRING(optic_hamr); - }; - class optic_Hamr_khk_F: optic_Hamr { - displayName = CSTRING(optic_hamr_khk); - }; - class ACE_optic_Hamr_2D: optic_Hamr { - displayName = CSTRING(optic_hamr_2d); - }; - class ACE_optic_Hamr_PIP: ACE_optic_Hamr_2D { - displayName = CSTRING(optic_hamr_pip); - }; - - class optic_Arco: ItemCore { - displayName = CSTRING(optic_arco); - }; - class optic_Arco_blk_F: optic_Arco { - displayName = CSTRING(optic_arco_blk); - }; - class optic_Arco_ghex_F: optic_Arco { - displayName = CSTRING(optic_arco_ghex); - }; - class ACE_optic_Arco_2D: optic_Arco { - displayName = CSTRING(optic_arco_2d); - }; - class ACE_optic_Arco_PIP: ACE_optic_Arco_2D { - displayName = CSTRING(optic_arco_pip); - }; - class optic_Arco_lush_F: optic_Arco { - displayName = CSTRING(optic_arco_lush); - }; - class optic_Arco_arid_F: optic_Arco { - displayName = CSTRING(optic_arco_arid); - }; - class optic_Arco_AK_blk_F: optic_Arco_blk_F { - displayName = CSTRING(optic_arco_ak_blk); - }; - class optic_Arco_AK_lush_F: optic_Arco_lush_F { - displayName = CSTRING(optic_arco_ak_lush); - }; - class optic_Arco_AK_arid_F: optic_Arco_arid_F { - displayName = CSTRING(optic_arco_ak_arid); - }; - - class optic_ERCO_blk_f: optic_Arco { - displayName = CSTRING(optic_erco_blk); - }; - class optic_ERCO_khk_f: optic_ERCO_blk_f { - displayName = CSTRING(optic_erco_khk); - }; - class optic_ERCO_snd_f: optic_ERCO_blk_f { - displayName = CSTRING(optic_erco_snd); - }; - - class optic_LRPS: ItemCore { - displayName = CSTRING(optic_lrps); - }; - class optic_LRPS_ghex_F: optic_LRPS { - displayName = CSTRING(optic_lrps_ghex); - }; - class optic_LRPS_tna_F: optic_LRPS { - displayName = CSTRING(optic_lrps_tna); - }; - class ACE_optic_LRPS_2D: optic_LRPS { - displayName = CSTRING(optic_lrps_2d); - }; - class ACE_optic_LRPS_PIP: ACE_optic_LRPS_2D { - displayName = CSTRING(optic_lrps_pip); - }; - - class optic_AMS_base; - class optic_AMS: optic_AMS_base { - displayName = CSTRING(optic_ams); - }; - class optic_AMS_khk: optic_AMS { - displayName = CSTRING(optic_ams_khk); - }; - class optic_AMS_snd: optic_AMS { - displayName = CSTRING(optic_ams_snd); - }; - - class optic_KHS_base; - class optic_KHS_blk: optic_KHS_base { - displayName = CSTRING(optic_khs_blk); - }; - class optic_KHS_hex: optic_KHS_blk { - displayName = CSTRING(optic_khs_hex); - }; - class optic_KHS_old: ItemCore { - displayName = CSTRING(optic_khs_old); - }; - class optic_KHS_tan: optic_KHS_blk { - displayName = CSTRING(optic_khs_tan); - }; - - class optic_DMS: ItemCore { - displayName = CSTRING(optic_dms); - }; - class optic_DMS_ghex_F: optic_DMS { - displayName = CSTRING(optic_dms_ghex); - }; - class optic_DMS_weathered_F: optic_DMS { - displayName = CSTRING(optic_dms_weathered); - }; - class optic_DMS_weathered_Kir_F: optic_DMS_weathered_F { - displayName = CSTRING(optic_dms_weathered_kir); - }; - - class optic_holosight: ItemCore { - displayName = CSTRING(optic_holosight); - }; - class optic_Holosight_blk_F: optic_holosight { - displayName = CSTRING(optic_holosight_blk); - }; - class optic_Holosight_khk_F: optic_holosight { - displayName = CSTRING(optic_holosight_khk); - }; - class optic_Holosight_lush_F: optic_holosight { - displayName = CSTRING(optic_holosight_lush); - }; - class optic_Holosight_arid_F: optic_holosight { - displayName = CSTRING(optic_holosight_arid); - }; - class optic_Holosight_smg: ItemCore { - displayName = CSTRING(optic_holosight_smg); - }; - class optic_Holosight_smg_blk_F: optic_Holosight_smg { - displayName = CSTRING(optic_holosight_smg_blk); - }; - class optic_Holosight_smg_khk_F: optic_Holosight_smg { - displayName = CSTRING(optic_holosight_smg_khk); - }; - - class optic_MRCO: ItemCore { - displayName = CSTRING(optic_MRCO); - }; - class ACE_optic_MRCO_2D: optic_MRCO { - displayName = CSTRING(optic_MRCO_2d); - }; - class ACE_optic_MRCO_PIP: ACE_optic_MRCO_2D { - displayName = CSTRING(optic_MRCO_pip); - }; - - class optic_Yorris: ItemCore { - displayName = CSTRING(optic_Yorris); - }; + // APEX/Tanoa - class optic_ACO: ItemCore { - displayName = CSTRING(optic_ACO); + // Type 115 + class arifle_ARX_base_F; + class arifle_ARX_blk_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_blk_Name); }; - class optic_ACO_grn: ItemCore { - displayName = CSTRING(optic_ACO_grn); + class arifle_ARX_ghex_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_ghex_Name); }; - class optic_ACO_smg: ItemCore { - displayName = CSTRING(optic_ACO_smg); + class arifle_ARX_hex_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_hex_Name); }; - class optic_ACO_grn_smg: ItemCore { - displayName = CSTRING(optic_ACO_grn_smg); - }; - - // APEX/Tanoa // QBZ-95 and variants class arifle_CTAR_base_F; @@ -1018,6 +809,16 @@ class CfgWeapons { // Contact/Livonia + // CZ 581 Shotgun + class sgun_HunterShotgun_01_base_F; + class sgun_HunterShotgun_01_F: sgun_HunterShotgun_01_base_F { + displayName = CSTRING(sgun_huntershotgun_01_Name); + }; + class sgun_HunterShotgun_01_sawedoff_base_F; + class sgun_HunterShotgun_01_sawedoff_F: sgun_HunterShotgun_01_sawedoff_base_F { + displayName = CSTRING(sgun_huntershotgun_sawedoff_01_Name); + }; + // FNX-45 (Green) class hgun_Pistol_heavy_01_green_F: hgun_Pistol_heavy_01_F { displayName = CSTRING(hgun_Pistol_heavy_01_green_Name); diff --git a/addons/realisticnames/CfgWeaponsAttachments.hpp b/addons/realisticnames/CfgWeaponsAttachments.hpp new file mode 100644 index 00000000000..c23559b7028 --- /dev/null +++ b/addons/realisticnames/CfgWeaponsAttachments.hpp @@ -0,0 +1,148 @@ +// 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 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_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 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 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/compat_explosives/CfgMagazines.hpp b/addons/realisticnames/compat_explosives/CfgMagazines.hpp new file mode 100644 index 00000000000..41a19345dbe --- /dev/null +++ b/addons/realisticnames/compat_explosives/CfgMagazines.hpp @@ -0,0 +1,9 @@ +class CfgMagazines { + class CA_Magazine; + 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); + }; +}; diff --git a/addons/realisticnames/compat_explosives/CfgVehicles.hpp b/addons/realisticnames/compat_explosives/CfgVehicles.hpp new file mode 100644 index 00000000000..e22068161a8 --- /dev/null +++ b/addons/realisticnames/compat_explosives/CfgVehicles.hpp @@ -0,0 +1,29 @@ +class CfgVehicles { + class ACE_Explosives_Place; + class ACE_Explosives_Place_DemoCharge: ACE_Explosives_Place { + displayName = CSTRING(DemoCharge_Name); + }; + class ACE_Explosives_Place_APERSBoundingMine: ACE_Explosives_Place { + displayName = CSTRING(APERSBoundingMine_Name); + }; + class ACE_Explosives_Place_APERSMine: ACE_Explosives_Place { + displayName = CSTRING(APERSMine_Name); + }; + class ACE_Explosives_Place_APERSTripwireMine: ACE_Explosives_Place { + displayName = CSTRING(APERSTripwireMine_Name); + }; + class ACE_Explosives_Place_ATMine: ACE_Explosives_Place { + displayName = CSTRING(ATMine_Name); + }; + class ACE_Explosives_Place_Claymore: ACE_Explosives_Place { + displayName = CSTRING(Claymore_Name); + }; + class ACE_Explosives_Place_SatchelCharge: ACE_Explosives_Place { + displayName = CSTRING(SatchelCharge_Name); + }; + + // Orange DLC + class ACE_Explosives_Place_SLAM: ACE_Explosives_Place { + displayName = CSTRING(SLAM_Name); + }; +}; diff --git a/addons/realisticnames/compat_explosives/config.cpp b/addons/realisticnames/compat_explosives/config.cpp new file mode 100644 index 00000000000..208bc7e791f --- /dev/null +++ b/addons/realisticnames/compat_explosives/config.cpp @@ -0,0 +1,22 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {QUOTE(ADDON), "ace_explosives"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + // this prevents any patched class from requiring this addon + addonRootClass = "A3_Characters_F"; + }; +}; + +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/realisticnames/compat_explosives/script_component.hpp b/addons/realisticnames/compat_explosives/script_component.hpp new file mode 100644 index 00000000000..a697aad7f3b --- /dev/null +++ b/addons/realisticnames/compat_explosives/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT explosives +#define SUBCOMPONENT_BEAUTIFIED Explosives +#include "..\script_component.hpp" diff --git a/addons/realisticnames/compat_optics/CfgWeapons.hpp b/addons/realisticnames/compat_optics/CfgWeapons.hpp new file mode 100644 index 00000000000..6ffd6484b2c --- /dev/null +++ b/addons/realisticnames/compat_optics/CfgWeapons.hpp @@ -0,0 +1,33 @@ +class CfgWeapons { + class optic_Hamr; + 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; + 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_LRPS; + 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_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); + }; +}; diff --git a/addons/realisticnames/compat_optics/config.cpp b/addons/realisticnames/compat_optics/config.cpp new file mode 100644 index 00000000000..32d2795dd96 --- /dev/null +++ b/addons/realisticnames/compat_optics/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {QUOTE(ADDON), "ace_optics"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + // this prevents any patched class from requiring this addon + addonRootClass = "A3_Characters_F"; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/realisticnames/compat_optics/script_component.hpp b/addons/realisticnames/compat_optics/script_component.hpp new file mode 100644 index 00000000000..b90538fc4e2 --- /dev/null +++ b/addons/realisticnames/compat_optics/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT optics +#define SUBCOMPONENT_BEAUTIFIED Optics +#include "..\script_component.hpp" diff --git a/addons/realisticnames/compat_vehicles/CfgWeapons.hpp b/addons/realisticnames/compat_vehicles/CfgWeapons.hpp new file mode 100644 index 00000000000..c49ae26bcb4 --- /dev/null +++ b/addons/realisticnames/compat_vehicles/CfgWeapons.hpp @@ -0,0 +1,45 @@ +class CfgWeapons { + class HMG_127_APC; + class ACE_HMG_127_KORD: HMG_127_APC { + displayName = "6P49 Kord"; + }; + + class cannon_120mm; + class ACE_cannon_120mm_GT12: cannon_120mm { + displayName = "GT12"; + }; + + class LMG_coax_ext; + class ACE_LMG_coax_ext_MG3: LMG_coax_ext { + displayName = "Rheinmetall MG3"; + }; + class ACE_LMG_coax_ext_MAG58: LMG_coax_ext { + displayName = "MAG 58M"; + }; + + class LMG_coax; + class ACE_LMG_coax_MAG58_mem3: LMG_coax { + displayName = "MAG 58M"; + }; + class ACE_LMG_coax_L94A1_mem3: LMG_coax { + displayName = "L94A1"; + }; + class ACE_LMG_coax_DenelMG4: LMG_coax { + displayName = "Denel MG4"; + }; + + class 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 { + displayName = "MK20 Rh 202"; + class AP: AP { + displayName = "MK20 Rh 202"; + }; + class HE: HE { + displayName = "MK20 Rh 202"; + }; + }; +}; diff --git a/addons/realisticnames/compat_vehicles/config.cpp b/addons/realisticnames/compat_vehicles/config.cpp new file mode 100644 index 00000000000..846c92a0eec --- /dev/null +++ b/addons/realisticnames/compat_vehicles/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {QUOTE(ADDON), "ace_vehicles"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + // this prevents any patched class from requiring this addon + addonRootClass = "A3_Characters_F"; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/realisticnames/compat_vehicles/script_component.hpp b/addons/realisticnames/compat_vehicles/script_component.hpp new file mode 100644 index 00000000000..17370c415fd --- /dev/null +++ b/addons/realisticnames/compat_vehicles/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT vehicles +#define SUBCOMPONENT_BEAUTIFIED Vehicles +#include "..\script_component.hpp" diff --git a/addons/realisticnames/dev_dumpPylon.sqf b/addons/realisticnames/dev_dumpPylon.sqf index df0d7ea4a56..4bb10a84fb6 100644 --- a/addons/realisticnames/dev_dumpPylon.sqf +++ b/addons/realisticnames/dev_dumpPylon.sqf @@ -22,7 +22,7 @@ private _magazines = configProperties [configFile >> "CfgMagazines", "isClass _x diag_log text format ['class %1;', configName inheritsFrom _x]; diag_log text format ['class %1: %2 {', configName _x, configName inheritsFrom _x]; diag_log text format ['displayName = "%1"; [vanilla: %2 - %3]', _weaponName, _pylonMagName, _pylonWeapon]; - diag_log text format ['};', configName _x, configName inheritsFrom _x, _weaponName, _pylonMagName]; + diag_log text format ['};']; }; }; }; diff --git a/addons/realisticnames/stringtable.xml b/addons/realisticnames/stringtable.xml index c67d3f70adc..6ce1f7ec098 100644 --- a/addons/realisticnames/stringtable.xml +++ b/addons/realisticnames/stringtable.xml @@ -13,7 +13,7 @@ XM312 XM312 XM312 - XM312 + XM312 중기관총 XM312重機槍 XM312 XM312 @@ -30,7 +30,7 @@ XM312A XM312A XM312A - XM312A + XM312A 무인 중기관총 XM312A重機槍 XM312A XM312A @@ -46,8 +46,8 @@ XM312 (Alta) XM312 (Magasított) XM312 (Alto) - XM312 (高) - XM312 (높음) + XM312 (ハイマウント) + XM312 중기관총 (높음) XM312重機槍 (高射腳架) XM312(高) XM312 (Yüksek) @@ -64,7 +64,7 @@ XM307 XM307 XM307 - XM307 + XM307 유탄기관총 XM307榴彈機槍 XM307 XM307 @@ -81,7 +81,7 @@ XM307A XM307A XM307A - XM307A + XM307A 무인유탄기관총 XM307A榴彈機槍 XM307A XM307A @@ -97,8 +97,8 @@ XM307 (Alta) XM307 (Magasított) XM307 (Alto) - XM307 (高) - XM307 (높음) + XM307 (ハイマウント) + XM307 유탄기관총 (높음) XM307榴彈機槍 (高射腳架) XM307(高) XM307 (Yüksek) @@ -149,7 +149,7 @@ YABHON-R3 YABHON-R3 YABHON-R3 - YABHON-R3 + YABHON-R3 무인기 "亞伯罕-R3型"空中無人載具 "联合"-R3 YABHON-R3 @@ -166,7 +166,7 @@ YABHON-R3 (CAS) YABHON-R3 (CAS) YABHON-R3 (CAS) - YABHON-R3 (근접지원) + YABHON-R3 무인기 (근접항공지원) "亞伯罕-R3型"空中無人載具 (近空支援) "联合"-R3(近空支援) YABHON-R3 (CAS) @@ -361,7 +361,7 @@ HEMTT Transport HEMTT Transport - HEMTT de transporte + HEMTT de Transporte HEMTT Transportowy HEMTT (valník) HEMTT Transport @@ -378,7 +378,7 @@ HEMTT Transport (covered) HEMTT Transport (bedeckt) - HEMTT de transporte (cubierto) + HEMTT de Transporte (cubierto) HEMTT Transportowy (zakryty) HEMTT (valník-krytý) HEMTT Transport (bâché) @@ -412,7 +412,7 @@ HEMTT Container HEMTT Container - HEMTT con contenedor + HEMTT con Contenedor HEMTT Kontener HEMTT (skříňový) HEMTT Conteneur @@ -429,7 +429,7 @@ HEMTT Medical HEMTT Sanitäter - HEMTT médico + HEMTT Médico HEMTT Medyczny HEMTT (zdravotnický) HEMTT Médical @@ -446,7 +446,7 @@ HEMTT Ammo HEMTT Munition - HEMTT de munición + HEMTT de Munición HEMTT Amunicyjny HEMTT (muniční) HEMTT Munitions @@ -463,7 +463,7 @@ HEMTT Fuel HEMTT Treibstoff - HEMTT de combustible + HEMTT de Combustible HEMTT Cysterna HEMTT (cisterna) HEMTT Citerne @@ -480,7 +480,7 @@ HEMTT Repair HEMTT Instandsetzung - HEMTT de reparación + HEMTT de Reparación HEMTT Naprawczy HEMTT (opravárenský) HEMTT Réparation @@ -556,7 +556,7 @@ Leopard 2SG Leopard 2SG Leopard 2SG - レオパルト 2SG + レオパルト2SG 레오파르트 2SG "豹2型新加坡版"主戰坦克 "豹"2 新加坡版 @@ -599,7 +599,7 @@ KamAZ Transport KamAS Transport - KamAZ de transporte + KamAZ de Transporte KamAZ transportowy KamAZ (valník) KamAZ Transport @@ -616,7 +616,7 @@ KamAZ Transport (covered) KamAS Transport (bedeckt) - KamAZ de transporte (cubierto) + KamAZ de Transporte (cubierto) KamAZ Transportowy (zakryty) KamAZ (valník-krytý) KamAZ Transport (bâché) @@ -633,7 +633,7 @@ KamAZ Ammo KamAS Munition - KamAZ de munición + KamAZ de Munición KamAZ Amunicyjny KamAZ (muniční) KamAZ Munitions @@ -650,7 +650,7 @@ KamAZ Fuel KamAS Treibstoff - KamAZ de combustible + KamAZ de Combustible KamAZ cysterna KamAZ (cisterna) KamAZ Citerne @@ -667,7 +667,7 @@ KamAZ Repair KamAS Instandsetzung - KamAZ de reparación + KamAZ de Reparación KamAZ Naprawczy KamAZ (opravárenský) KamAZ Réparation @@ -684,7 +684,7 @@ KamAZ Medical KamAS Sanitäter - KamAZ médico + KamAZ Médico KamAZ Medyczny KamAZ (zdravotnický) KamAZ Médical @@ -698,6 +698,17 @@ "卡玛兹"(医疗) KamAZ Medikal + + KamAZ Water + KamAZ Água + KamAZ 給水 + КамАЗ (водоноситель) + 카마즈 급수 + KamAS Wasser + KamAZ Acqua + KamAZ Eau + KamAZ de Agua + KamAZ MRL KamAS MRL @@ -845,7 +856,7 @@ Otokar ARMA Otokar ARMA オトカ アルマ - 오토카르 아르마 APC + 오토카 아르마 APC "奧托卡—阿爾默"裝甲運兵車 奥托卡尔 "阿玛" Otokar ARMA @@ -1151,7 +1162,7 @@ L-159 ALCA (Légitámogató) L-159 ALCA (CAS) L-159 ALCA (CAS) - L-159 ALCA (근접지원) + L-159 ALCA (근접항공지원) L-159先進輕型戰鬥機 (近空支援) L-159 ALCA(近空支援) L-159 ALCA (CAS) @@ -1315,7 +1326,7 @@ Demoliční nálož M183 M183 Charge de démolition M183 комплектный подрывной заряд - M183 Sacola de Demolição + M183 Conjunto de Carga de Demolição M183 romboló töltet M183 Carica da Demolizioni M183 梱包爆薬 @@ -1336,6 +1347,7 @@ M183 Geballte Sprengladung (Werfbar) M183 炸药包(可投掷) M183 폭파 장약 (투척) + M183 Carga de Demolição (Arremessável) M112 Demolition Block @@ -1366,6 +1378,7 @@ M112 Sprengladung (Werfbar) M112 塑性炸药(可投掷) M112 폭파 장약 (투척) + M112 Carga de Demolição (Arremessável) M67 Fragmentation Grenade @@ -1655,6 +1668,28 @@ FNX-45戰術型手槍 FNX-45 战术型 + + CZ 581 + CZ 581 + 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) + CZ 581 (canon scié) + CZ 581 (Recortada) + FNX-45 Tactical (Green) FNX-45 Tactical (Grün) @@ -1662,7 +1697,7 @@ FNX-45 Tactical (Zielony) FNX-45 Tactical (Vert) FNX-45 Tactical (Zöld) - FNX-45 Tactical (Verde) + HEMTT de transporte (cubierto) FNX-45 Tactical (зелёный) FNX-45 Tactical (Verde) FNX-45 Tactical (Verde) @@ -2321,7 +2356,7 @@ Scorpion Evo 3 A1 Scorpion Evo 3 A1 Scorpion Evo 3 A1 - スコーピオン エボ 3 A1 + スコーピオン Evo 3 A1 스콜피온 에보 3 A1 "蠍式"Evo 3 A1衝鋒槍 Evo 3 A1 "蝎" @@ -2372,7 +2407,7 @@ Stoner 99 LMG Stoner 99 LMG Stoner 99 LMG - ストーナー 99 LMG + ストーナー99 LMG 스토너 99 LMG 斯通納99輕機槍 斯通纳 99 @@ -2704,7 +2739,7 @@ ASP-1 Kir (Tan) ASP-1 Kir (Žlutohnědá) - ASP-1 Kir (Tan) + ASP-1 Kir (Marron) ASP-1 Kir (Tan) ASP-1 Kir (пустынный) ASP-1 Kir (Hellbraun) @@ -3056,6 +3091,39 @@ "柏拉格" 战斗无人机 Burraq UCAV + + Type 115 (Black) + Type 115 (Preto) + Type 115 (ブラック) + Type 115 (чёрный) + 115식 보총 (검정) + Type 115 (Schwarz) + Type 115 (Nero) + Type 115 (Noir) + Type 115 (Negro) + + + Type 115 (Green Hex) + Type 115 (Verde Hex) + Type 115 (緑六角形迷彩) + Type 115 (зелёный гекс) + 115식 보총 (초록육각) + Type 115 (Hex Grün) + Type 115 (Hex Verde) + Type 115 (Hew Vert) + Type 115 (Verde Hex) + + + Type 115 (Hex) + Type 115 (Hex) + Type 115 (六角形迷彩) + Type 115 (гекс) + 115식 보총 (육각) + Type 115 (Hex) + Type 115 (Hex) + Type 115 (Hex) + Type 115 (Hex) + QBZ-95-1 (Black) QBZ-95-1 (Černá) @@ -3077,7 +3145,7 @@ QBZ-95-1 (Green Hex) QBZ-95-1 (Hex Grün) QBZ-95-1 (Hex Verde) - QBZ-95-1 (zielony hex) + QBZ-95-1 (Zielony hex) QBZ-95-1 (Zelený Hex) QBZ-95-1 (Hex Vert) QBZ-95-1 (зелёный гекс) @@ -3128,7 +3196,7 @@ QBZ-95-1 GL (Green Hex) QBZ-95-1 GL (Hex Grün) QBZ-95-1 GL (Hex Verde) - QBZ-95-1 GL (zielony hex) + QBZ-95-1 GL (Zielony hex) QBZ-95-1 GL (Zelený Hex) QBZ-95-1 GL (Hex Vert) QBZ-95-1 GL (зелёный гекс) @@ -3179,7 +3247,7 @@ QBZ-95-1 LSW (Green Hex) QBZ-95-1 LSW (Hex Grün) QBZ-95-1 LSW (Hex Verde) - QBZ-95-1 LSW (zielony hex) + QBZ-95-1 LSW (Zielony hex) QBZ-95-1 LSW (Zelený Hex) QBZ-95-1 LSW (Hex Vert) QBZ-95-1 LSW (зелёный гекс) @@ -3230,7 +3298,7 @@ QBU-88 (Green Hex) QBU-88 (Hex Grün) QBU-88 (Hex Verde) - QBU-88 (zielony hex) + QBU-88 (Zielony hex) QBU-88 (Zelený Hex) QBU-88 (Hex Vert) QBU-88 (зелёный гекс) @@ -3536,7 +3604,7 @@ RPG-32 (Green Hex) RPG-32 (Hex Grün) RPG-32 (Hex Verde) - RPG-32 (zielony hex) + RPG-32 (Zielony hex) RPG-32 (Zelený Hex) RPG-32 (Hex Vert) RPG-32 (зелёный гекс) @@ -3614,7 +3682,7 @@ Polaris DAGOR (XM312) Polaris DAGOR (XM312) Polaris DAGOR (XM312) - 폴라리스 DAGOR (XM312) + 폴라리스 DAGOR (XM312 중기관총) Polaris DAGOR (Mini-Spike AT) @@ -3630,7 +3698,7 @@ Polaris DAGOR (Mini-Spike AT) Polaris DAGOR (Mini-Spike AT) Polaris DAGOR (Mini-Spike AT) - 폴라리스 DAGOR (스파이크 미사일 대전차) + 폴라리스 DAGOR (스파이크 대전차미사일) Polaris DAGOR @@ -3651,7 +3719,7 @@ Polaris DAGOR (light) Polaris DAGOR (leicht) - ポラリス DAGOR (軽) + ポラリス DAGOR (軽装) "北極星"先進佈署越野車 (輕型) "北极星"(轻型) Polaris DAGOR (leggero) @@ -3678,7 +3746,7 @@ LSV Mk. II (M134) LSV Mk. II (M134) LSV Mk. II (M134) - LSV Mk.II (M134) + LSV Mk.II (M134 미니건) LSV Mk. II (Metis-M) @@ -3790,7 +3858,7 @@ Wiesel 2 Ozelot (AA) Wiesel 2 Ozelot (AA) Wiesel 2 Ozelot (AA) - 비젤 2 오셀롯 (대공) + 비젤 2 오젤롯 (대공) Wiesel 2 (ATGM) @@ -3806,7 +3874,7 @@ Wiesel 2 (ATGM) Wiesel 2 (ATGM) Wiesel 2 (ATGM) - 비젤 2 (대전차유도) + 비젤 2 (대전차미사일) Wiesel 2 (MK20) @@ -3840,6 +3908,39 @@ 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 + UTG Defender 126 + UTG Defender 126 + + + EOTech MRDS + EOTech MRDS + EOTech MRDS + EOTech MRDS + 이오텍 MRDS + EOTech MRDS + EOTech MRDS + EOTech MRDS + EOTech MRDS + + + EOTech MRDS (Black) + EOTech MRDS (Preto) + EOTech MRDS (ブラック) + EOTech MRDS (чёрный) + 이오텍 MRDS (검정) + EOTech MRDS (Schwarz) + EOTech MRDS (Nero) + EOTech MRDS (Noir) + EOTech MRDS (Negro) + Leupold Mark 4 HAMR Leupold Mark 4 HAMR @@ -3995,6 +4096,7 @@ 엘칸 스펙터OS (초목) ELCAN SpecterOS (обильная растительность) ELCAN SpecterOS (Exuberante) + ELCAN SpecterOS (Exuberante) ELCAN SpecterOS (Arid) @@ -4007,6 +4109,7 @@ 엘칸 스펙터OS (건조) ELCAN SpecterOS (сухая местность) ELCAN SpecterOS (Árido) + ELCAN SpecterOS (Árido) ELCAN SpecterOS 7.62 (Black) @@ -4019,6 +4122,7 @@ 엘칸 스펙터OS 7.62 (검정) ELCAN SpecterOS 7.62 (чёрный) ELCAN SpecterOS 7.62 (Negro) + ELCAN SpecterOS 7.62 (Preto) ELCAN SpecterOS 7.62 (Lush) @@ -4031,6 +4135,7 @@ 엘칸 스펙터OS 7.62 (초목) ELCAN SpecterOS 7.62 (обильная растительность) ELCAN SpecterOS 7.62 (Exuberante) + ELCAN SpecterOS 7.62 (Exuberante) ELCAN SpecterOS 7.62 (Arid) @@ -4043,6 +4148,7 @@ 엘칸 스펙터OS 7.62 (건조) ELCAN SpecterOS 7.62 (сухая местность) ELCAN SpecterOS 7.62 (Árido) + ELCAN SpecterOS 7.62 (Árido) SIG BRAVO4 / ROMEO3 (Black) @@ -4272,7 +4378,7 @@ KAHLES Helia (Tan) KAHLES Helia (Tan) KAHLES Helia(沙色) - KAHLES Helia (タン) + KAHLES ヘリア (タン) KAHLES Helia (Tan) KAHLES Helia (Marroncino) KAHLES Helia (пустынный) @@ -4327,6 +4433,7 @@ 버리스 XTR II (낡음) Burris XTR II (старый) Burris XTR II (Viejo) + Burris XTR II (Velho) Burris XTR II (ASP-1 Kir) @@ -4339,6 +4446,7 @@ 버리스 XTR II (ASP-1 키르용) Burris XTR II (ASP-1 Kir) Burris XTR II (ASP-1 Kir) + Burris XTR II (ASP-1 Kir) EOTech XPS3 (Tan) @@ -4399,6 +4507,7 @@ 이오텍 XPS3 (초목) EOTech XPS3 (обильная растительность) EOTech XPS3 (Exuberante) + EOTech XPS3 (Exuberante) EOTech XPS3 (Arid) @@ -4411,6 +4520,7 @@ 이오텍 XPS3 (건조) EOTech XPS3 (сухая местность) EOTech XPS3 (Árido) + EOTech XPS3 (Árido) EOTech XPS3 SMG (Tan) diff --git a/addons/realisticweights/config.cpp b/addons/realisticweights/config.cpp index 91c1ea00aa9..ebd919fc49b 100644 --- a/addons/realisticweights/config.cpp +++ b/addons/realisticweights/config.cpp @@ -2,6 +2,7 @@ class CfgPatches { class ADDON { + name = COMPONENT_NAME; units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; diff --git a/addons/realisticweights/script_component.hpp b/addons/realisticweights/script_component.hpp index fcdb3450689..bf7173a3e70 100644 --- a/addons/realisticweights/script_component.hpp +++ b/addons/realisticweights/script_component.hpp @@ -1,4 +1,5 @@ #define COMPONENT realisticweights +#define COMPONENT_BEAUTIFIED Realistic Weights #include "\z\ace\addons\main\script_mod.hpp" // #define DEBUG_MODE_FULL diff --git a/addons/rearm/XEH_postInit.sqf b/addons/rearm/XEH_postInit.sqf index f156fb71d64..61ec35b8dec 100644 --- a/addons/rearm/XEH_postInit.sqf +++ b/addons/rearm/XEH_postInit.sqf @@ -1,9 +1,8 @@ #include "script_component.hpp" -GVAR(hardpointGroupsCache) = [] call CBA_fnc_createNamespace; GVAR(configTypesAdded) = []; -GVAR(magazineNameCache) = [] call CBA_fnc_createNamespace; -GVAR(originalMagazineNames) = []; +GVAR(magazineNameCache) = createHashMap; +GVAR(usedMagazineNames) = createHashMap; [QGVAR(initSupplyVehicle), { TRACE_1("initSupplyVehicle EH",_this); // Warning: this can run before settings are init diff --git a/addons/rearm/XEH_preStart.sqf b/addons/rearm/XEH_preStart.sqf index b092699f9b9..b013b04b860 100644 --- a/addons/rearm/XEH_preStart.sqf +++ b/addons/rearm/XEH_preStart.sqf @@ -4,6 +4,6 @@ // Test binarization one time at startup - ref https://github.com/acemod/ACE3/pull/8093 private _test = getText (configFile >> "Cfg3DEN" >> "Object" >> "AttributeCategories" >> "ace_attributes" >> "Attributes" >> "ace_rearm_rearmCargo" >> "defaultValue"); -if (!("else {" in _test)) then { +if !("else {" in _test) then { ERROR("3den attribute has ERROR [check binarization]"); }; diff --git a/addons/rearm/functions/fnc_addRearmActions.sqf b/addons/rearm/functions/fnc_addRearmActions.sqf index e71cab8f0ca..200dd2f2b44 100644 --- a/addons/rearm/functions/fnc_addRearmActions.sqf +++ b/addons/rearm/functions/fnc_addRearmActions.sqf @@ -30,7 +30,9 @@ private _cswCarryMagazines = []; private _vehicleActions = []; { private _vehicle = _x; - + private _displayName = getText (configOf _vehicle >> "displayName"); + private _distanceStr = (ACE_player distance _vehicle) toFixed 1; + private _actionName = format ["%1 (%2m)", _displayName, _distanceStr]; // Array of magazines that can be rearmed in the vehicle private _needRearmMags = ([_vehicle] call FUNC(getNeedRearmMagazines)) apply {_x select 0}; @@ -57,7 +59,7 @@ private _vehicleActions = []; // [Level 0] adds a single action to rearm the entire vic private _action = [ _vehicle, - getText(configOf _vehicle >> "displayName"), + _actionName, _icon, {_this call FUNC(rearmEntireVehicle)}, {true}, @@ -84,7 +86,7 @@ private _vehicleActions = []; private _action = [ _vehicle, - getText(configOf _vehicle >> "displayName"), + _actionName, _icon, {}, {true}, diff --git a/addons/rearm/functions/fnc_canRearm.sqf b/addons/rearm/functions/fnc_canRearm.sqf index 8d2b0b58e50..34bb3727536 100644 --- a/addons/rearm/functions/fnc_canRearm.sqf +++ b/addons/rearm/functions/fnc_canRearm.sqf @@ -22,7 +22,7 @@ if (!alive _vehicle) exitWith {false}; if (GVAR(level) == 0 || {isNull _unit} || {!(_unit isKindOf "CAManBase")} || {!local _unit} || {_vehicle distance _unit > REARM_ACTION_DISTANCE} || {_vehicle getVariable [QGVAR(disabled), false]}) exitWith {false}; private _dummy = _unit getVariable [QGVAR(dummy), objNull]; -if (isNull _dummy) exitwith {false}; +if (isNull _dummy) exitWith {false}; private _magazineClass = _dummy getVariable QGVAR(magazineClass); if (isNil "_magazineClass") exitWith {false}; diff --git a/addons/rearm/functions/fnc_dropAmmo.sqf b/addons/rearm/functions/fnc_dropAmmo.sqf index af4b74ee775..ba89c9cd917 100644 --- a/addons/rearm/functions/fnc_dropAmmo.sqf +++ b/addons/rearm/functions/fnc_dropAmmo.sqf @@ -38,8 +38,8 @@ if (_actionID != -1) then { _unit removeAction _actionID; _unit setVariable [QGVAR(ReleaseActionID), nil]; }; -[_unit, "forceWalk", "ACE_rearm", false] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", "ACE_rearm", false] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); if (_unholster) then { REARM_UNHOLSTER_WEAPON diff --git a/addons/rearm/functions/fnc_getMagazineName.sqf b/addons/rearm/functions/fnc_getMagazineName.sqf index 2ee4a988ed9..e961831c8c4 100644 --- a/addons/rearm/functions/fnc_getMagazineName.sqf +++ b/addons/rearm/functions/fnc_getMagazineName.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Author: PabstMirror - * Gets a non-ambigious display name for a magazine using displayNameShort (AP/HE) + * Author: PabstMirror, johnb43 + * Gets a non-ambigious display name for a magazine using displayNameShort (AP/HE). * * Arguments: * 0: Magazine Classname @@ -10,7 +10,7 @@ * Display Name * * Example: - * ["B_20mm_AP"] call ace_rearm_fnc_getMagazineName + * "60Rnd_20mm_AP_shells" call ace_rearm_fnc_getMagazineName * * Public: No */ @@ -18,31 +18,31 @@ params ["_className"]; TRACE_1("getMagazineName",_className); -private _magName = GVAR(magazineNameCache) getVariable _className; -if (isNil "_magName") then { - private _displayName = getText(configFile >> "CfgMagazines" >> _className >> "displayName"); +GVAR(magazineNameCache) getOrDefaultCall [_className, { + private _cfgMagazines = configFile >> "CfgMagazines"; + private _displayName = getText (_cfgMagazines >> _className >> "displayName"); + if (_displayName == "") then { _displayName = _className; WARNING_1("Magazine is missing display name [%1]",_className); }; - if ((_displayName select [0,6]) == "[CSW] ") then { _displayName = _displayName select [6]; }; + // [CSW] prefix is localised + if (["ace_csw"] call EFUNC(common,isModLoaded)) then { + _displayName = trim (_displayName regexReplace [LELSTRING(csw,regex), ""]); + }; - GVAR(magazineNameCache) setVariable [_className, _displayName]; - GVAR(originalMagazineNames) pushBack _displayName; - TRACE_2("Adding to cache",_className,_displayName); + // If the display name exists already, add displayNameShort to the existing entry + private _existingClassname = GVAR(usedMagazineNames) get _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)); + if (!isNil "_existingClassname") then { + GVAR(magazineNameCache) set [_existingClassname, format ["%1: %2", _displayName, getText (_cfgMagazines >> _existingClassname >> "displayNameShort")]]; - _magName = GVAR(magazineNameCache) getVariable _className; -}; + _displayName = format ["%1: %2", _displayName, getText (_cfgMagazines >> _className >> "displayNameShort")]; + }; + + GVAR(usedMagazineNames) set [_displayName, _className]; + TRACE_2("Adding to cache",_className,_displayName); -_magName + _displayName +}, true] // return diff --git a/addons/rearm/functions/fnc_grabAmmo.sqf b/addons/rearm/functions/fnc_grabAmmo.sqf index d3554853092..b7f87a69ba4 100644 --- a/addons/rearm/functions/fnc_grabAmmo.sqf +++ b/addons/rearm/functions/fnc_grabAmmo.sqf @@ -19,8 +19,8 @@ params ["_dummy", "_unit"]; REARM_HOLSTER_WEAPON; -[_unit, "forceWalk", "ACE_rearm", true] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", "ACE_rearm", true] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); [ TIME_PROGRESSBAR(5), @@ -35,7 +35,7 @@ REARM_HOLSTER_WEAPON; _unit removeAction _actionID; }; _actionID = _unit addAction [ - format ["%1", localize ELSTRING(dragging,Drop)], + format ["%1", LELSTRING(common,Drop)], '(_this select 0) call FUNC(dropAmmo)', nil, 20, diff --git a/addons/rearm/functions/fnc_hasEnoughSupply.sqf b/addons/rearm/functions/fnc_hasEnoughSupply.sqf index c7efb7eca63..8b606bdf6f7 100644 --- a/addons/rearm/functions/fnc_hasEnoughSupply.sqf +++ b/addons/rearm/functions/fnc_hasEnoughSupply.sqf @@ -44,7 +44,6 @@ if (GVAR(supply) == 2) exitWith { { _x params ["_magazine", "_rounds"]; if ((_magazine isEqualTo _magazineClass) && (_rounds > 0)) exitWith {_magazinePresent = true; }; - false - } count _magazineSupply; + } forEach _magazineSupply; _magazinePresent }; diff --git a/addons/rearm/functions/fnc_initSupplyVehicle.sqf b/addons/rearm/functions/fnc_initSupplyVehicle.sqf index 7749f0b609a..4ab04fcaf61 100644 --- a/addons/rearm/functions/fnc_initSupplyVehicle.sqf +++ b/addons/rearm/functions/fnc_initSupplyVehicle.sqf @@ -33,7 +33,7 @@ if (!alive _vehicle) exitWith {}; private _configSupply = getNumber (_configOf >> QGVAR(defaultSupply)); if (_configSupply == 0) then { - _configSupply = getNumber (_config >> "transportAmmo"); + _configSupply = getNumber (_configOf >> "transportAmmo"); }; private _isSupplyVehicle = _vehicle getVariable [QGVAR(isSupplyVehicle), false]; private _oldRearmConfig = isClass (_configOf >> "ACE_Actions" >> "ACE_MainActions" >> QGVAR(takeAmmo)); diff --git a/addons/rearm/functions/fnc_readSupplyCounter.sqf b/addons/rearm/functions/fnc_readSupplyCounter.sqf index 7526fd013a9..f298579705e 100644 --- a/addons/rearm/functions/fnc_readSupplyCounter.sqf +++ b/addons/rearm/functions/fnc_readSupplyCounter.sqf @@ -58,8 +58,7 @@ if (GVAR(supply) == 1) then { _numChars = _numChars max (count _line); _text = format ["%1
%2", _text, _line]; _supply = _supply + 0.5; - false - } count _magazines; + } forEach _magazines; }; if (_supply > 1.5) then { [[LSTRING(Hint_RemainingAmmo), _text], _supply, _unit, (_numChars/2.9)] call EFUNC(common,displayTextStructured); diff --git a/addons/rearm/functions/fnc_rearm.sqf b/addons/rearm/functions/fnc_rearm.sqf index 81f467a5ca8..52c00a54c0e 100644 --- a/addons/rearm/functions/fnc_rearm.sqf +++ b/addons/rearm/functions/fnc_rearm.sqf @@ -20,9 +20,9 @@ params ["_target", "_unit"]; TRACE_2("rearm",_target,_unit); private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull]; -if (isNull _attachedDummy) exitwith {ERROR_1("attachedDummy null",_attachedDummy);}; +if (isNull _attachedDummy) exitWith {ERROR_1("attachedDummy null %1",_attachedDummy);}; private _magazineClass = _attachedDummy getVariable QGVAR(magazineClass); -if (isNil "_magazineClass") exitWith {ERROR_1("magazineClass nil",_attachedDummy);}; +if (isNil "_magazineClass") exitWith {ERROR_1("magazineClass nil %1",_attachedDummy);}; ([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"]; @@ -45,6 +45,7 @@ private _magazineDisplayName = _magazineClass call FUNC(getMagazineName); "", format [localize LSTRING(RearmAction), getText(configOf _target >> "displayName"), _magazineDisplayName], { + //IGNORE_PRIVATE_WARNING ["_player"]; param [0] params ["_target", "_unit"]; _player distance _target <= GVAR(distance); }, diff --git a/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf b/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf index d014e9d58d1..396b501dabd 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf @@ -28,8 +28,7 @@ if (isServer) then { } else { [QGVAR(rearmEntireVehicleSuccessLocalEH), [_truck, _vehicle, _x], _turretOwnerID] call CBA_fnc_ownerEvent; }; - false - } count _turrets; + } forEach _turrets; } else { [QGVAR(rearmEntireVehicleSuccessEH), _this] call CBA_fnc_serverEvent; }; diff --git a/addons/rearm/functions/fnc_rearmSuccessLocal.sqf b/addons/rearm/functions/fnc_rearmSuccessLocal.sqf index f41dff6ea9c..ace43baf8f9 100644 --- a/addons/rearm/functions/fnc_rearmSuccessLocal.sqf +++ b/addons/rearm/functions/fnc_rearmSuccessLocal.sqf @@ -31,7 +31,7 @@ if (_pylon > 0) exitWith { // Fill magazine completely if (_turretPath isEqualTo [-1]) then {_turretPath = [];}; // Convert back to pylon turret format TRACE_3("",_pylon,_magazineClass,_rounds); - _vehicle setPylonLoadOut [_pylon, _magazineClass, true, _turretPath]; + _vehicle setPylonLoadout [_pylon, _magazineClass, true, _turretPath]; [QEGVAR(common,displayTextStructured), [[LSTRING(Hint_RearmedTriple), _rounds, getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), getText(configOf _vehicle >> "displayName")], 3, _unit], [_unit]] call CBA_fnc_targetEvent; @@ -41,7 +41,7 @@ if (_pylon > 0) exitWith { private _currentCount = _vehicle ammoOnPylon _pylon; private _newCount = ((_currentCount max 0) + _numRounds) min _rounds; TRACE_3("",_pylon,_magazineClass,_newCount); - _vehicle setPylonLoadOut [_pylon, _magazineClass, true, _turretPath]; + _vehicle setPylonLoadout [_pylon, _magazineClass, true, _turretPath]; _vehicle setAmmoOnPylon [_pylon, _newCount]; [QEGVAR(common,displayTextStructured), [[LSTRING(Hint_RearmedTriple), _numRounds, getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), diff --git a/addons/rearm/functions/fnc_storeAmmo.sqf b/addons/rearm/functions/fnc_storeAmmo.sqf index e9f57369f3d..1d08d289be4 100644 --- a/addons/rearm/functions/fnc_storeAmmo.sqf +++ b/addons/rearm/functions/fnc_storeAmmo.sqf @@ -19,7 +19,7 @@ params ["_truck", "_unit"]; private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull]; -if (isNull _attachedDummy) exitwith {}; +if (isNull _attachedDummy) exitWith {}; private _magazineClass = _attachedDummy getVariable [QGVAR(magazineClass), "#noVar"]; diff --git a/addons/rearm/functions/fnc_takeSuccess.sqf b/addons/rearm/functions/fnc_takeSuccess.sqf index 717d549b86c..214713c80d6 100644 --- a/addons/rearm/functions/fnc_takeSuccess.sqf +++ b/addons/rearm/functions/fnc_takeSuccess.sqf @@ -36,13 +36,13 @@ if (_vehicle == _unit) exitWith { [_unit, _magazineClass, _rounds] call EFUNC(csw,reload_handleReturnAmmo); }; -[_unit, "forceWalk", "ACE_rearm", true] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", "ACE_rearm", true] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); private _dummy = [_unit, _magazineClass] call FUNC(createDummy); [_dummy, _unit] call FUNC(pickUpAmmo); private _actionID = _unit addAction [ - format ["%1", localize ELSTRING(dragging,Drop)], + format ["%1", LELSTRING(common,Drop)], '(_this select 0) call FUNC(dropAmmo)', nil, 20, diff --git a/addons/rearm/initSettings.inc.sqf b/addons/rearm/initSettings.inc.sqf index 37535d8d90e..6489bd9326c 100644 --- a/addons/rearm/initSettings.inc.sqf +++ b/addons/rearm/initSettings.inc.sqf @@ -7,7 +7,7 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)]; true, true, {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -15,8 +15,7 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)]; [LSTRING(RearmSettings_level_DisplayName), LSTRING(RearmSettings_level_Description)], _category, [[0,1,2],[LSTRING(RearmSettings_vehicle), LSTRING(RearmSettings_magazine), LSTRING(RearmSettings_caliber)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(level), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -24,8 +23,7 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)]; [LSTRING(RearmSettings_supply_DisplayName), LSTRING(RearmSettings_supply_Description)], _category, [[0,1,2],[LSTRING(RearmSettings_unlimited), LSTRING(RearmSettings_limited), LSTRING(RearmSettings_magazineSupply)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(supply), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -33,6 +31,5 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)]; [LLSTRING(RearmSettings_distance_DisplayName), LLSTRING(RearmSettings_distance_Description)], _category, [10, 50, 20, 0], - true, // isGlobal - {[QGVAR(supply), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/rearm/script_component.hpp b/addons/rearm/script_component.hpp index 83d495bc38a..4bcff331d68 100644 --- a/addons/rearm/script_component.hpp +++ b/addons/rearm/script_component.hpp @@ -28,12 +28,14 @@ #define REARM_HOLSTER_WEAPON \ - _unit setVariable [QGVAR(selectedWeaponOnRearm), currentWeapon _unit]; \ + if (currentWeapon _unit != "") then { \ + _unit setVariable [QGVAR(selectedWeaponOnRearm), (weaponState _unit) select [0, 3]]; \ + }; \ TRACE_2("REARM_HOLSTER_WEAPON",_unit,currentWeapon _unit); \ _unit action ["SwitchWeapon", _unit, _unit, 299]; #define REARM_UNHOLSTER_WEAPON \ - _weaponSelect = _unit getVariable QGVAR(selectedWeaponOnRearm); \ + private _weaponSelect = _unit getVariable QGVAR(selectedWeaponOnRearm); \ if (!isNil "_weaponSelect") then { \ TRACE_2("REARM_UNHOLSTER_WEAPON",_unit,_weaponSelect); \ _unit selectWeapon _weaponSelect; \ diff --git a/addons/rearm/stringtable.xml b/addons/rearm/stringtable.xml index 157be6eec29..b8dfd37f774 100644 --- a/addons/rearm/stringtable.xml +++ b/addons/rearm/stringtable.xml @@ -698,7 +698,7 @@ 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 diff --git a/addons/recoil/$PBOPREFIX$ b/addons/recoil/$PBOPREFIX$ index 1ab9ffa5e1f..efd38b75edf 100644 --- a/addons/recoil/$PBOPREFIX$ +++ b/addons/recoil/$PBOPREFIX$ @@ -1 +1 @@ -z\ace\addons\recoil \ No newline at end of file +z\ace\addons\recoil diff --git a/addons/recoil/CfgEventHandlers.hpp b/addons/recoil/CfgEventHandlers.hpp index 6c29240403a..f6503c2479b 100644 --- a/addons/recoil/CfgEventHandlers.hpp +++ b/addons/recoil/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); diff --git a/addons/recoil/CfgMoves.hpp b/addons/recoil/CfgMoves.hpp index 29bca9c81ab..aca9d93f3cd 100644 --- a/addons/recoil/CfgMoves.hpp +++ b/addons/recoil/CfgMoves.hpp @@ -1,4 +1,3 @@ - // Completely disable BI's camshake on fire. #define ACE_CAMSHAKEFIRE_BASE 0 #define ACE_CAMSHAKEFIRE_LESS 0 diff --git a/addons/recoil/CfgRecoils.hpp b/addons/recoil/CfgRecoils.hpp index c6482937ae2..b8d181e5664 100644 --- a/addons/recoil/CfgRecoils.hpp +++ b/addons/recoil/CfgRecoils.hpp @@ -1,4 +1,3 @@ - #define KICKBACK 1.4 #define MUZZLETEMP 1.2 @@ -15,28 +14,28 @@ class CfgRecoils { // 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[] = { - QUOTE(0*MUZZLERIGHT_POS), - QUOTE(0.4*MUZZLECLIMB_POS), - QUOTE(0.5*MUZZLERIGHT_MAG), - QUOTE(0.6*MUZZLECLIMB_MAG) + 0*MUZZLERIGHT_POS, + 0.4*MUZZLECLIMB_POS, + 0.5*MUZZLERIGHT_MAG, + 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[] = { - QUOTE(0.05*KICKBACK), - QUOTE(0.1*KICKBACK) + 0.05*KICKBACK, + 0.1*KICKBACK }; - permanent = QUOTE(0.1*MUZZLEPERM); - temporary = QUOTE(0.01*MUZZLETEMP); + permanent = 0.1*MUZZLEPERM; + temporary = 0.01*MUZZLETEMP; }; class recoil_default: Default { muzzleOuter[] = { - QUOTE(0.3*MUZZLERIGHT_POS), - QUOTE(1*MUZZLECLIMB_POS), - QUOTE(0.3*MUZZLERIGHT_MAG), - QUOTE(0.2*MUZZLECLIMB_MAG) + 0.3*MUZZLERIGHT_POS, + 1*MUZZLECLIMB_POS, + 0.3*MUZZLERIGHT_MAG, + 0.2*MUZZLECLIMB_MAG }; muzzleInner[] = {0, 0, @@ -44,528 +43,529 @@ class CfgRecoils { 0.1 }; kickBack[] = { - QUOTE(0.03*KICKBACK), - QUOTE(0.06*KICKBACK) + 0.03*KICKBACK, + 0.06*KICKBACK }; - permanent = QUOTE(0.1*MUZZLEPERM); - temporary = QUOTE(0.01*MUZZLETEMP); + permanent = 0.1*MUZZLEPERM; + temporary = 0.01*MUZZLETEMP; }; class recoil_mk20: recoil_default { muzzleOuter[] = { - QUOTE(0.2*MUZZLERIGHT_POS), - QUOTE(0.6*MUZZLECLIMB_POS), - QUOTE(0.2*MUZZLERIGHT_MAG), - QUOTE(0.2*MUZZLECLIMB_MAG) + 0.2*MUZZLERIGHT_POS, + 0.6*MUZZLECLIMB_POS, + 0.2*MUZZLERIGHT_MAG, + 0.2*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.01*KICKBACK), - QUOTE(0.03*KICKBACK) + 0.01*KICKBACK, + 0.03*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); + temporary = 0.01*MUZZLETEMP; }; class recoil_mk20c: recoil_default { muzzleOuter[] = { - QUOTE(0.2*MUZZLERIGHT_POS), - QUOTE(0.8*MUZZLECLIMB_POS), - QUOTE(0.3*MUZZLERIGHT_MAG), - QUOTE(0.2*MUZZLECLIMB_MAG) + 0.2*MUZZLERIGHT_POS, + 0.8*MUZZLECLIMB_POS, + 0.3*MUZZLERIGHT_MAG, + 0.2*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.02*KICKBACK), - QUOTE(0.04*KICKBACK) + 0.02*KICKBACK, + 0.04*KICKBACK }; - temporary = QUOTE(0.015*MUZZLETEMP); + temporary = 0.015*MUZZLETEMP; }; class recoil_trg20: recoil_default { muzzleOuter[] = { - QUOTE(0.2*MUZZLERIGHT_POS), - QUOTE(1*MUZZLECLIMB_POS), - QUOTE(0.3*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.2*MUZZLERIGHT_POS, + 1*MUZZLECLIMB_POS, + 0.3*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.02*KICKBACK), - QUOTE(0.04*KICKBACK) + 0.02*KICKBACK, + 0.04*KICKBACK }; - temporary = QUOTE(0.015*MUZZLETEMP); + temporary = 0.015*MUZZLETEMP; }; class recoil_trg21: recoil_default { muzzleOuter[] = { - QUOTE(0.2*MUZZLERIGHT_POS), - QUOTE(0.8*MUZZLECLIMB_POS), - QUOTE(0.3*MUZZLERIGHT_MAG), - QUOTE(0.2*MUZZLECLIMB_MAG) + 0.2*MUZZLERIGHT_POS, + 0.8*MUZZLECLIMB_POS, + 0.3*MUZZLERIGHT_MAG, + 0.2*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.01*KICKBACK), - QUOTE(0.03*KICKBACK) + 0.01*KICKBACK, + 0.03*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); + temporary = 0.01*MUZZLETEMP; }; class recoil_mx: recoil_default { muzzleOuter[] = { - QUOTE(0.3*MUZZLERIGHT_POS), - QUOTE(1*MUZZLECLIMB_POS), - QUOTE(0.4*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.3*MUZZLERIGHT_POS, + 1*MUZZLECLIMB_POS, + 0.4*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.02*KICKBACK), - QUOTE(0.04*KICKBACK) + 0.02*KICKBACK, + 0.04*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); + temporary = 0.01*MUZZLETEMP; }; class recoil_mxc: recoil_default { muzzleOuter[] = { - QUOTE(0.3*MUZZLERIGHT_POS), - QUOTE(1.2*MUZZLECLIMB_POS), - QUOTE(0.4*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.3*MUZZLERIGHT_POS, + 1.2*MUZZLECLIMB_POS, + 0.4*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.03*KICKBACK), - QUOTE(0.06*KICKBACK) + 0.03*KICKBACK, + 0.06*KICKBACK }; - temporary = QUOTE(0.015*MUZZLETEMP); + temporary = 0.015*MUZZLETEMP; }; class recoil_sw: recoil_default { muzzleOuter[] = { - QUOTE(0.3*MUZZLERIGHT_POS), - QUOTE(0.8*MUZZLECLIMB_POS), - QUOTE(0.5*MUZZLERIGHT_MAG), - QUOTE(0.2*MUZZLECLIMB_MAG) + 0.3*MUZZLERIGHT_POS, + 0.8*MUZZLECLIMB_POS, + 0.5*MUZZLERIGHT_MAG, + 0.2*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.02*KICKBACK), - QUOTE(0.04*KICKBACK) + 0.02*KICKBACK, + 0.04*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); //0.005*MUZZLETEMP; + temporary = 0.01*MUZZLETEMP; //0.005*MUZZLETEMP; }; class recoil_mxm: recoil_default { muzzleOuter[] = { - QUOTE(0.3*MUZZLERIGHT_POS), - QUOTE(0.8*MUZZLECLIMB_POS), - QUOTE(0.4*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.3*MUZZLERIGHT_POS, + 0.8*MUZZLECLIMB_POS, + 0.4*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.02*KICKBACK), - QUOTE(0.04*KICKBACK) + 0.02*KICKBACK, + 0.04*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); + temporary = 0.01*MUZZLETEMP; }; class recoil_ktb: recoil_default { muzzleOuter[] = { - QUOTE(0.3*MUZZLERIGHT_POS), - QUOTE(1*MUZZLECLIMB_POS), - QUOTE(0.3*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.3*MUZZLERIGHT_POS, + 1*MUZZLECLIMB_POS, + 0.3*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.02*KICKBACK), - QUOTE(0.04*KICKBACK) + 0.02*KICKBACK, + 0.04*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); + temporary = 0.01*MUZZLETEMP; }; class recoil_ktbc: recoil_default { muzzleOuter[] = { - QUOTE(0.3*MUZZLERIGHT_POS), - QUOTE(1.2*MUZZLECLIMB_POS), - QUOTE(0.3*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.3*MUZZLERIGHT_POS, + 1.2*MUZZLECLIMB_POS, + 0.3*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.03*KICKBACK), - QUOTE(0.06*KICKBACK) + 0.03*KICKBACK, + 0.06*KICKBACK }; - temporary = QUOTE(0.015*MUZZLETEMP); + temporary = 0.015*MUZZLETEMP; }; class recoil_smg_01: recoil_default { muzzleOuter[] = { - QUOTE(0.1*MUZZLERIGHT_POS), - QUOTE(0.8*MUZZLECLIMB_POS), - QUOTE(0.3*MUZZLERIGHT_MAG), - QUOTE(0.2*MUZZLECLIMB_MAG) + 0.1*MUZZLERIGHT_POS, + 0.8*MUZZLECLIMB_POS, + 0.3*MUZZLERIGHT_MAG, + 0.2*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.01*KICKBACK), - QUOTE(0.03*KICKBACK) + 0.01*KICKBACK, + 0.03*KICKBACK }; - temporary = QUOTE(0.015*MUZZLETEMP); + temporary = 0.015*MUZZLETEMP; }; class recoil_smg_02: recoil_default { muzzleOuter[] = { - QUOTE(0.1*MUZZLERIGHT_POS), - QUOTE(0.6*MUZZLECLIMB_POS), - QUOTE(0.2*MUZZLERIGHT_MAG), - QUOTE(0.2*MUZZLECLIMB_MAG) + 0.1*MUZZLERIGHT_POS, + 0.6*MUZZLECLIMB_POS, + 0.2*MUZZLERIGHT_MAG, + 0.2*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.01*KICKBACK), - QUOTE(0.02*KICKBACK) + 0.01*KICKBACK, + 0.02*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); + temporary = 0.01*MUZZLETEMP; }; class recoil_pdw: recoil_default { muzzleOuter[] = { - QUOTE(0.2*MUZZLERIGHT_POS), - QUOTE(1*MUZZLECLIMB_POS), - QUOTE(0.3*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.2*MUZZLERIGHT_POS, + 1*MUZZLECLIMB_POS, + 0.3*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.02*KICKBACK), - QUOTE(0.04*KICKBACK) + 0.02*KICKBACK, + 0.04*KICKBACK }; - temporary = QUOTE(0.02*MUZZLETEMP); + temporary = 0.02*MUZZLETEMP; }; class recoil_sdar: recoil_default { muzzleOuter[] = { - QUOTE(0.2*MUZZLERIGHT_POS), - QUOTE(1*MUZZLECLIMB_POS), - QUOTE(0.3*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.2*MUZZLERIGHT_POS, + 1*MUZZLECLIMB_POS, + 0.3*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.02*KICKBACK), - QUOTE(0.04*KICKBACK) + 0.02*KICKBACK, + 0.04*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); + temporary = 0.01*MUZZLETEMP; }; class recoil_pistol_p07: recoil_default { muzzleOuter[] = { - QUOTE(0.2*MUZZLERIGHT_POS), - QUOTE(1*MUZZLECLIMB_POS), - QUOTE(0.2*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.2*MUZZLERIGHT_POS, + 1*MUZZLECLIMB_POS, + 0.2*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.03*KICKBACK), - QUOTE(0.06*KICKBACK) + 0.03*KICKBACK, + 0.06*KICKBACK }; - temporary = QUOTE(0.03*MUZZLETEMP); + temporary = 0.03*MUZZLETEMP; }; class recoil_pistol_rook40: recoil_default { muzzleOuter[] = { - QUOTE(0.2*MUZZLERIGHT_POS), - QUOTE(1*MUZZLECLIMB_POS), - QUOTE(0.2*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.2*MUZZLERIGHT_POS, + 1*MUZZLECLIMB_POS, + 0.2*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.03*KICKBACK), - QUOTE(0.06*KICKBACK) + 0.03*KICKBACK, + 0.06*KICKBACK }; - temporary = QUOTE(0.02*MUZZLETEMP); + temporary = 0.02*MUZZLETEMP; }; class recoil_pistol_acpc2: recoil_default { muzzleOuter[] = { - QUOTE(0.2*MUZZLERIGHT_POS), - QUOTE(1.5*MUZZLECLIMB_POS), - QUOTE(0.2*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.2*MUZZLERIGHT_POS, + 1.5*MUZZLECLIMB_POS, + 0.2*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.04*KICKBACK), - QUOTE(0.08*KICKBACK) + 0.04*KICKBACK, + 0.08*KICKBACK }; - temporary = QUOTE(0.04*MUZZLETEMP); + temporary = 0.04*MUZZLETEMP; }; class recoil_pistol_4five: recoil_default { muzzleOuter[] = { - QUOTE(0.2*MUZZLERIGHT_POS), - QUOTE(1.5*MUZZLECLIMB_POS), - QUOTE(0.2*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.2*MUZZLERIGHT_POS, + 1.5*MUZZLECLIMB_POS, + 0.2*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.04*KICKBACK), - QUOTE(0.08*KICKBACK) + 0.04*KICKBACK, + 0.08*KICKBACK }; - temporary = QUOTE(0.06*MUZZLETEMP); + temporary = 0.06*MUZZLETEMP; }; class recoil_pistol_zubr: recoil_default { muzzleOuter[] = { - QUOTE(0.2*MUZZLERIGHT_POS), - QUOTE(1.5*MUZZLECLIMB_POS), - QUOTE(0.2*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.2*MUZZLERIGHT_POS, + 1.5*MUZZLECLIMB_POS, + 0.2*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.04*KICKBACK), - QUOTE(0.08*KICKBACK) + 0.04*KICKBACK, + 0.08*KICKBACK }; - temporary = QUOTE(0.08*MUZZLETEMP); + temporary = 0.08*MUZZLETEMP; }; class recoil_pistol_signal: recoil_default { muzzleOuter[] = { - QUOTE(0.2*MUZZLERIGHT_POS), - QUOTE(1.5*MUZZLECLIMB_POS), - QUOTE(0.2*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.2*MUZZLERIGHT_POS, + 1.5*MUZZLECLIMB_POS, + 0.2*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.02*KICKBACK), - QUOTE(0.04*KICKBACK) + 0.02*KICKBACK, + 0.04*KICKBACK }; - temporary = QUOTE(0.02*MUZZLETEMP); + temporary = 0.02*MUZZLETEMP; }; class recoil_rpg: recoil_default { muzzleOuter[] = { - QUOTE(2*MUZZLERIGHT_POS), - QUOTE(3*MUZZLECLIMB_POS), - QUOTE(1*MUZZLERIGHT_MAG), - QUOTE(0.5*MUZZLECLIMB_MAG) + 0.0*MUZZLERIGHT_POS, + 0.1*MUZZLECLIMB_POS, + 0.3*MUZZLERIGHT_MAG, + 0.5*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.08*KICKBACK), - QUOTE(0.1*KICKBACK) + 0.0*KICKBACK, + 0.08*KICKBACK }; - temporary = QUOTE(0.1*MUZZLETEMP); + permanent = 1.0*MUZZLEPERM; + temporary = 0.05*MUZZLETEMP; }; class recoil_nlaw: recoil_default { muzzleOuter[] = { - QUOTE(2*MUZZLERIGHT_POS), - QUOTE(3*MUZZLECLIMB_POS), - QUOTE(1*MUZZLERIGHT_MAG), - QUOTE(0.5*MUZZLECLIMB_MAG) + 2*MUZZLERIGHT_POS, + 3*MUZZLECLIMB_POS, + 1*MUZZLERIGHT_MAG, + 0.5*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.06*KICKBACK), - QUOTE(0.08*KICKBACK) + 0.06*KICKBACK, + 0.08*KICKBACK }; - temporary = QUOTE(0.08*MUZZLETEMP); + temporary = 0.08*MUZZLETEMP; }; class recoil_titan_long: recoil_default { muzzleOuter[] = { - QUOTE(2*MUZZLERIGHT_POS), - QUOTE(3*MUZZLECLIMB_POS), - QUOTE(1*MUZZLERIGHT_MAG), - QUOTE(0.5*MUZZLECLIMB_MAG) + 2*MUZZLERIGHT_POS, + 3*MUZZLECLIMB_POS, + 1*MUZZLERIGHT_MAG, + 0.5*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.1*KICKBACK), - QUOTE(0.12*KICKBACK) + 0.1*KICKBACK, + 0.12*KICKBACK }; - temporary = QUOTE(0.15*MUZZLETEMP); + temporary = 0.15*MUZZLETEMP; }; class recoil_titan_short: recoil_default { muzzleOuter[] = { - QUOTE(2*MUZZLERIGHT_POS), - QUOTE(3*MUZZLECLIMB_POS), - QUOTE(1*MUZZLERIGHT_MAG), - QUOTE(0.5*MUZZLECLIMB_MAG) + 2*MUZZLERIGHT_POS, + 3*MUZZLECLIMB_POS, + 1*MUZZLERIGHT_MAG, + 0.5*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.1*KICKBACK), - QUOTE(0.12*KICKBACK) + 0.1*KICKBACK, + 0.12*KICKBACK }; - temporary = QUOTE(0.12*MUZZLETEMP); + temporary = 0.12*MUZZLETEMP; }; class recoil_mk200: recoil_default { muzzleOuter[] = { - QUOTE(0.4*MUZZLERIGHT_POS), - QUOTE(0.6*MUZZLECLIMB_POS), - QUOTE(0.6*MUZZLERIGHT_MAG), - QUOTE(0.2*MUZZLECLIMB_MAG) + 0.4*MUZZLERIGHT_POS, + 0.6*MUZZLECLIMB_POS, + 0.6*MUZZLERIGHT_MAG, + 0.2*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.03*KICKBACK), - QUOTE(0.06*KICKBACK) + 0.03*KICKBACK, + 0.06*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); //0.005*MUZZLETEMP; + temporary = 0.01*MUZZLETEMP; //0.005*MUZZLETEMP; }; class recoil_zafir: recoil_default { muzzleOuter[] = { - QUOTE(0.5*MUZZLERIGHT_POS), - QUOTE(1*MUZZLECLIMB_POS), - QUOTE(0.7*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.5*MUZZLERIGHT_POS, + 1*MUZZLECLIMB_POS, + 0.7*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.02*KICKBACK), - QUOTE(0.08*KICKBACK) + 0.02*KICKBACK, + 0.08*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); //0.005*MUZZLETEMP; + temporary = 0.01*MUZZLETEMP; //0.005*MUZZLETEMP; }; class recoil_m320: recoil_default { muzzleOuter[] = { - QUOTE(1*MUZZLERIGHT_POS), - QUOTE(3*MUZZLECLIMB_POS), - QUOTE(0.5*MUZZLERIGHT_MAG), - QUOTE(0.6*MUZZLECLIMB_MAG) + 1*MUZZLERIGHT_POS, + 3*MUZZLECLIMB_POS, + 0.5*MUZZLERIGHT_MAG, + 0.6*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.08*KICKBACK), - QUOTE(0.1*KICKBACK) + 0.08*KICKBACK, + 0.1*KICKBACK }; - temporary = QUOTE(0.02*MUZZLETEMP); + temporary = 0.02*MUZZLETEMP; }; class recoil_gm6: recoil_default { muzzleOuter[] = { - QUOTE(1.4*MUZZLERIGHT_POS), - QUOTE(3.5*MUZZLECLIMB_POS), - QUOTE(0.7*MUZZLERIGHT_MAG), - QUOTE(0.8*MUZZLECLIMB_MAG) + 1.4*MUZZLERIGHT_POS, + 3.5*MUZZLECLIMB_POS, + 0.7*MUZZLERIGHT_MAG, + 0.8*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.1*KICKBACK), - QUOTE(0.12*KICKBACK) + 0.1*KICKBACK, + 0.12*KICKBACK }; - temporary = QUOTE(0.025*MUZZLETEMP); + temporary = 0.025*MUZZLETEMP; }; class recoil_ebr: recoil_default { muzzleOuter[] = { - QUOTE(0.4*MUZZLERIGHT_POS), - QUOTE(1.5*MUZZLECLIMB_POS), - QUOTE(0.6*MUZZLERIGHT_MAG), - QUOTE(0.4*MUZZLECLIMB_MAG) + 0.4*MUZZLERIGHT_POS, + 1.5*MUZZLECLIMB_POS, + 0.6*MUZZLERIGHT_MAG, + 0.4*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.04*KICKBACK), - QUOTE(0.07*KICKBACK) + 0.04*KICKBACK, + 0.07*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); + temporary = 0.01*MUZZLETEMP; }; class recoil_dmr_01: recoil_default { muzzleOuter[] = { - QUOTE(0.5*MUZZLERIGHT_POS), - QUOTE(2*MUZZLECLIMB_POS), - QUOTE(0.5*MUZZLERIGHT_MAG), - QUOTE(0.5*MUZZLECLIMB_MAG) + 0.5*MUZZLERIGHT_POS, + 2*MUZZLECLIMB_POS, + 0.5*MUZZLERIGHT_MAG, + 0.5*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.03*KICKBACK), - QUOTE(0.08*KICKBACK) + 0.03*KICKBACK, + 0.08*KICKBACK }; - temporary = QUOTE(0.015*MUZZLETEMP); + temporary = 0.015*MUZZLETEMP; }; class recoil_dmr_02: recoil_default { muzzleOuter[] = { - QUOTE(0.5*MUZZLERIGHT_POS), - QUOTE(2.5*MUZZLECLIMB_POS), - QUOTE(0.6*MUZZLERIGHT_MAG), - QUOTE(0.5*MUZZLECLIMB_MAG) + 0.5*MUZZLERIGHT_POS, + 2.5*MUZZLECLIMB_POS, + 0.6*MUZZLERIGHT_MAG, + 0.5*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.06*KICKBACK), - QUOTE(0.08*KICKBACK) + 0.06*KICKBACK, + 0.08*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); + temporary = 0.01*MUZZLETEMP; }; class recoil_dmr_03: recoil_default { muzzleOuter[] = { - QUOTE(0.3*MUZZLERIGHT_POS), - QUOTE(1.5*MUZZLECLIMB_POS), - QUOTE(0.5*MUZZLERIGHT_MAG), - QUOTE(0.4*MUZZLECLIMB_MAG) + 0.3*MUZZLERIGHT_POS, + 1.5*MUZZLECLIMB_POS, + 0.5*MUZZLERIGHT_MAG, + 0.4*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.03*KICKBACK), - QUOTE(0.06*KICKBACK) + 0.03*KICKBACK, + 0.06*KICKBACK }; - temporary = QUOTE(0.005*MUZZLETEMP); + temporary = 0.005*MUZZLETEMP; }; class recoil_dmr_04: recoil_default { muzzleOuter[] = { - QUOTE(0.4*MUZZLERIGHT_POS), - QUOTE(1.5*MUZZLECLIMB_POS), - QUOTE(0.5*MUZZLERIGHT_MAG), - QUOTE(0.4*MUZZLECLIMB_MAG) + 0.4*MUZZLERIGHT_POS, + 1.5*MUZZLECLIMB_POS, + 0.5*MUZZLERIGHT_MAG, + 0.4*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.02*KICKBACK), - QUOTE(0.04*KICKBACK) + 0.02*KICKBACK, + 0.04*KICKBACK }; - temporary = QUOTE(0.015*MUZZLETEMP); + temporary = 0.015*MUZZLETEMP; }; class recoil_dmr_05: recoil_default { muzzleOuter[] = { - QUOTE(0.5*MUZZLERIGHT_POS), - QUOTE(2.5*MUZZLECLIMB_POS), - QUOTE(0.8*MUZZLERIGHT_MAG), - QUOTE(0.6*MUZZLECLIMB_MAG) + 0.5*MUZZLERIGHT_POS, + 2.5*MUZZLECLIMB_POS, + 0.8*MUZZLERIGHT_MAG, + 0.6*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.08*KICKBACK), - QUOTE(0.1*KICKBACK) + 0.08*KICKBACK, + 0.1*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); + temporary = 0.01*MUZZLETEMP; }; class recoil_dmr_06: recoil_default { muzzleOuter[] = { - QUOTE(0.5*MUZZLERIGHT_POS), - QUOTE(2*MUZZLECLIMB_POS), - QUOTE(0.7*MUZZLERIGHT_MAG), - QUOTE(0.5*MUZZLECLIMB_MAG) + 0.5*MUZZLERIGHT_POS, + 2*MUZZLECLIMB_POS, + 0.7*MUZZLERIGHT_MAG, + 0.5*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.05*KICKBACK), - QUOTE(0.1*KICKBACK) + 0.05*KICKBACK, + 0.1*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); + temporary = 0.01*MUZZLETEMP; }; class recoil_mmg_01: recoil_default { muzzleOuter[] = { - QUOTE(0.6*MUZZLERIGHT_POS), - QUOTE(1.5*MUZZLECLIMB_POS), - QUOTE(0.8*MUZZLERIGHT_MAG), - QUOTE(0.3*MUZZLECLIMB_MAG) + 0.6*MUZZLERIGHT_POS, + 1.5*MUZZLECLIMB_POS, + 0.8*MUZZLERIGHT_MAG, + 0.3*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.02*KICKBACK), - QUOTE(0.08*KICKBACK) + 0.02*KICKBACK, + 0.08*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); //0.005*MUZZLETEMP; + temporary = 0.01*MUZZLETEMP; //0.005*MUZZLETEMP; }; class recoil_mmg_02: recoil_default { muzzleOuter[] = { - QUOTE(0.5*MUZZLERIGHT_POS), - QUOTE(1.5*MUZZLECLIMB_POS), - QUOTE(0.6*MUZZLERIGHT_MAG), - QUOTE(0.4*MUZZLECLIMB_MAG) + 0.5*MUZZLERIGHT_POS, + 1.5*MUZZLECLIMB_POS, + 0.6*MUZZLERIGHT_MAG, + 0.4*MUZZLECLIMB_MAG }; kickBack[] = { - QUOTE(0.04*KICKBACK), - QUOTE(0.08*KICKBACK) + 0.04*KICKBACK, + 0.08*KICKBACK }; - temporary = QUOTE(0.01*MUZZLETEMP); //0.005*MUZZLETEMP; + temporary = 0.01*MUZZLETEMP; //0.005*MUZZLETEMP; }; }; diff --git a/addons/recoil/XEH_PREP.hpp b/addons/recoil/XEH_PREP.hpp index 9e34c47492b..90c7c9cccf8 100644 --- a/addons/recoil/XEH_PREP.hpp +++ b/addons/recoil/XEH_PREP.hpp @@ -1,2 +1 @@ - PREP(camshake); diff --git a/addons/recoil/XEH_postInit.sqf b/addons/recoil/XEH_postInit.sqf index 29e54646127..639b22d6f94 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/XEH_preInit.sqf b/addons/recoil/XEH_preInit.sqf index ffd1bfc414d..1566a79fd48 100644 --- a/addons/recoil/XEH_preInit.sqf +++ b/addons/recoil/XEH_preInit.sqf @@ -7,4 +7,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +GVAR(recoilCache) = createHashMap; + ADDON = true; diff --git a/addons/recoil/functions/fnc_camshake.sqf b/addons/recoil/functions/fnc_camshake.sqf index e2a7e3a4a1c..9c6e78608f8 100644 --- a/addons/recoil/functions/fnc_camshake.sqf +++ b/addons/recoil/functions/fnc_camshake.sqf @@ -1,17 +1,17 @@ #include "..\script_component.hpp" /* - * Author: Orginal by Ryan Schultz, edited by KoffeinFlummi, commy2 + * Author: Original by Ryan Schultz, edited by KoffeinFlummi, commy2 * Adds camera shake when firing. Called from the unified fired EH only for the local player. * From TMR: Small Arms * * Arguments: - * None. Parameters inherited from EFUNC(common,firedEH) + * Parameters inherited from EFUNC(common,firedEH) * * Return Value: * None * * Example: - * [player, (currentWeapon player), (currentMuzzle player)] call ace_recoil_fnc_camshake; + * [player, currentWeapon player, currentMuzzle player] call ace_recoil_fnc_camshake * * Public: No */ @@ -24,24 +24,23 @@ TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_veh #define BASE_FREQ 13 #define RECOIL_COEF 40 -if (toLower _weapon in ["throw", "put"]) exitWith {}; +if (toLowerANSI _weapon in ["throw", "put"]) exitWith {}; private _powerMod = ([0, -0.1, -0.1, 0, -0.2] select (["STAND", "CROUCH", "PRONE", "UNDEFINED", ""] find stance _unit)) + ([0, -1, 0, -1] select (["INTERNAL", "EXTERNAL", "GUNNER", "GROUP"] find cameraView)); -// to get camshake read kickback -private _recoil = missionNamespace getVariable format [QGVAR(%1-%2), _weapon, _muzzle]; - -if (isNil "_recoil") then { +// Get camshake read kickback +private _recoil = GVAR(recoilCache) getOrDefaultCall [_weapon + _muzzle, { private _config = configFile >> "CfgWeapons" >> _weapon; - if (_muzzle == _weapon) then { - _recoil = getText (_config >> "recoil") + private _recoil = if (_muzzle == _weapon) then { + getText (_config >> "recoil") } else { - _recoil = getText (_config >> _muzzle >> "recoil") + getText (_config >> _muzzle >> "recoil") }; if (isClass (configFile >> "CfgRecoils" >> _recoil)) then { _recoil = getArray (configFile >> "CfgRecoils" >> _recoil >> "kickBack"); + if (count _recoil < 2) then { _recoil = [0, 0]; }; @@ -51,17 +50,20 @@ if (isNil "_recoil") then { TRACE_3("Caching Recoil config",_weapon,_muzzle,_recoil); - // parse numbers - _recoil set [0, call compile format ["%1", _recoil select 0]]; - _recoil set [1, call compile format ["%1", _recoil select 1]]; + // Ensure format is correct + _recoil resize [2, 0]; - missionNamespace setVariable [format [QGVAR(%1-%2), _weapon, _muzzle], _recoil]; -}; + // Parse numbers + _recoil apply { if (_x isEqualType 0) then { _x } else { call compile format ["%1", _x] } } // return +}, true]; private _powerCoef = RECOIL_COEF * linearConversion [0, 1, random 1, _recoil select 0, _recoil select 1, false]; if (isWeaponRested _unit) then {_powerMod = _powerMod - 0.07}; if (isWeaponDeployed _unit) then {_powerMod = _powerMod - 0.11}; +if (_weapon isEqualTo secondaryWeapon _unit) then { + _powerCoef = _powerCoef + 25.0; +}; private _camshake = [ _powerCoef * (BASE_POWER + _powerMod) max 0, diff --git a/addons/refuel/ACE_Refuel_Positions.hpp b/addons/refuel/ACE_Refuel_Positions.hpp new file mode 100644 index 00000000000..0db8667751f --- /dev/null +++ b/addons/refuel/ACE_Refuel_Positions.hpp @@ -0,0 +1,116 @@ +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", {{3920,4105,0},{4788,5525,0}}} + }; + go_map_fjord[] = { /* Fjord */ + {"Land_fs_feed_F", {{26,14296,0},{121,14298,0},{7480,1812,0}}}, + {"Land_FuelStation_01_pump_F", {{66,14293,0}}}, + {"Land_FuelStation_Feed_F", {{37,14301,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}}} + }; + egl_laghisola[] = { /* Laghisola */ + {"Land_fs_feed_F", {{281,595,0},{1926,5751,0},{4904,6278,0}}}, + {"Land_FuelStation_01_pump_F", {{1347,8907,0},{6478,2391,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}}} + }; + mehland[] = { /* Mehland */ + {"Land_fs_feed_F", {{13469,9984,0},{16773,16454,0},{17389,14420,0},{17785,10415,0},{19155,15564,0},{19373,13170,0}}}, + {"Land_FuelStation_01_pump_F", {{2122,15875,0},{2238,8505,0},{15134,19009,0},{17909,9856,1},{18595,8701,0},{18691,8629,1},{18947,15114,0}}}, + {"Land_FuelStation_03_pump_F", {{4136,13875,0},{6356,12183,0},{7677,10989,2},{8880,17775,0},{13881,19437,1}}} + }; + 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}}} + }; + FDF_Isle1_a[] = { /* Podagorsk */ {"Land_A_FuelStation_Feed", {{7980,10293,0},{8356,7555,0},{10930,6878,0},{11999,10476,0},{12692,6317,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}}} + }; + yulakia[] = { /* Yulakia v1.0beta6 */ + {"Land_fs_feed_F", {{10424,6328,0}}}, + {"Land_FuelStation_03_pump_F", {{5964,8016,0}}}, + {"Land_Fuelstation_army", {{410,10339,0},{1892,2501,0},{4157,9653,0},{9629,2467,0},{10018,4642,0},{10696,7289,0},{11325,8200,0},{11647,7639,0}}} + }; +}; diff --git a/addons/refuel/Cfg3DEN.hpp b/addons/refuel/Cfg3DEN.hpp index 33831079955..00d5453d955 100644 --- a/addons/refuel/Cfg3DEN.hpp +++ b/addons/refuel/Cfg3DEN.hpp @@ -1,7 +1,4 @@ -#define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) #define GET_1ST_ARRAY(config) (if (isArray (config)) then {getArray (config) select 0} else {[ARR_3(0,0,0)]}) - -#define DEFAULT_FUELCARGO GET_NUMBER(configOf _this >> QQGVAR(fuelCargo),REFUEL_DISABLED_FUEL) #define DEFAULT_HOOKS GET_1ST_ARRAY(configOf _this >> QQGVAR(hooks)) class Cfg3DEN { @@ -14,8 +11,8 @@ class Cfg3DEN { tooltip = CSTRING(fuelCargo_edenDesc); property = QGVAR(fuelCargo); control = "EditShort"; - expression = QUOTE(if (_value != DEFAULT_FUELCARGO) then {[ARR_2(_this,_value)] call DFUNC(makeSource)}); - defaultValue = QUOTE(DEFAULT_FUELCARGO); + expression = QUOTE(if (_value != (_this call FUNC(getFuelCargo))) then {[ARR_2(_this,_value)] call FUNC(makeSource)}); + defaultValue = QUOTE(_this call FUNC(getFuelCargo)); validate = "number"; condition = "(1-objectBrain)*(1-objectAgent)"; typeName = "NUMBER"; diff --git a/addons/refuel/CfgVehicles.hpp b/addons/refuel/CfgVehicles.hpp index 5fba3369434..dbbcaf04d1c 100644 --- a/addons/refuel/CfgVehicles.hpp +++ b/addons/refuel/CfgVehicles.hpp @@ -1,3 +1,5 @@ +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} + class CBA_Extended_EventHandlers; class CfgNonAIVehicles { @@ -45,9 +47,7 @@ class CfgVehicles { class ThingX; class GVAR(fuelNozzle): ThingX { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; + XEH_INHERITED; displayName = QGVAR(fuelNozzle); scope = 1; @@ -238,6 +238,20 @@ class CfgVehicles { // Patria = LAV GVAR(fuelCapacity) = 269; }; + class APC_Wheeled_02_base_F: Wheeled_APC_F { + class EGVAR(interaction,anims); + }; + class APC_Wheeled_02_base_v2_F: APC_Wheeled_02_base_F { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class showCanisters { + phase = 0; + positions[] = {{-1.188, -3.87, -0.769}, {1.638, -3.87, -0.769}}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = CSTRING(TakeFuelCanister); + text = CSTRING(TakeFuelCanisterAction); + }; + }; + }; class Truck_F: Car_F { GVAR(fuelCapacity) = 400; @@ -275,12 +289,6 @@ class CfgVehicles { GVAR(hooks)[] = {{0.38,-3.17,-0.7},{-0.41,-3.17,-0.7}}; GVAR(fuelCargo) = 2000; }; - class C_Van_01_fuel_F: Van_01_fuel_base_F { - transportFuel = 0; //1k - }; - class I_G_Van_01_fuel_F: Van_01_fuel_base_F { - transportFuel = 0; //1k - }; class Tank_F: Tank { GVAR(fuelCapacity) = 1200; @@ -295,7 +303,6 @@ class CfgVehicles { class B_APC_Tracked_01_base_F: APC_Tracked_01_base_F {}; class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{-1.08,-4.81,-0.8}}; GVAR(fuelCargo) = 1000; }; @@ -315,12 +322,14 @@ class CfgVehicles { class MBT_01_base_F: Tank_F { // Merkava IV GVAR(fuelCapacity) = 1400; + class EGVAR(interaction,anims); }; class MBT_02_base_F: Tank_F { // T100 Black Eagle // Assuming T80 GVAR(fuelCapacity) = 1100; + class EGVAR(interaction,anims); }; class MBT_03_base_F: Tank_F { @@ -331,11 +340,37 @@ class CfgVehicles { class MBT_01_arty_base_F: MBT_01_base_F { // Assuming similar 2S3 GVAR(fuelCapacity) = 830; + + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class showCanisters { + phase = 0; + // Rotate interactions with turret rotation + positions[] = { + "[0, -2.5, 0] vectorAdd ([[1.6, -2.4, -0.3], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)", + "[0, -2.5, 0] vectorAdd ([[1.8, 0.55, -0.7], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)", + "[0, -2.5, 0] vectorAdd ([[-1.8, 0.55, -0.7], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)" + }; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = CSTRING(TakeFuelCanister); + text = CSTRING(TakeFuelCanisterAction); + }; + }; }; class MBT_02_arty_base_F: MBT_02_base_F { // Assuming similar 2S3 GVAR(fuelCapacity) = 830; + + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class showCanisters { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, -2.1, 0] vectorAdd ([[1.6, -2.65, -0.3], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)"}; + items[] = {"Land_CanisterFuel_F"}; + name = CSTRING(TakeFuelCanister); + text = CSTRING(TakeFuelCanisterAction); + }; + }; }; class Heli_Light_02_base_F: Helicopter_Base_H { @@ -407,7 +442,6 @@ class CfgVehicles { // Vanilla fuel vehicles class Truck_02_fuel_base_F: Truck_02_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{0.99,-3.47,-0.67},{-1.04,-3.47,-0.67}}; GVAR(fuelCargo) = 10000; }; @@ -416,13 +450,11 @@ class CfgVehicles { }; class B_Truck_01_fuel_F: B_Truck_01_mover_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{0.28,-4.99,-0.3},{-0.25,-4.99,-0.3}}; GVAR(fuelCargo) = 10000; }; class O_Truck_03_fuel_F: Truck_03_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{1.3,-1.59,-0.62},{-1.16,-1.59,-0.62}}; GVAR(fuelCargo) = 10000; }; @@ -436,20 +468,17 @@ class CfgVehicles { class Pod_Heli_Transport_04_base_F: Slingload_base_F {}; class Land_Pod_Heli_Transport_04_fuel_F: Pod_Heli_Transport_04_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{-1.49,1.41,-0.3}}; GVAR(fuelCargo) = 10000; }; class Slingload_01_Base_F: Slingload_base_F {}; class B_Slingload_01_Fuel_F: Slingload_01_Base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{0.55,3.02,-0.5},{-0.52,3.02,-0.5}}; GVAR(fuelCargo) = 10000; }; class O_Heli_Transport_04_fuel_F: Heli_Transport_04_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{-1.52,1.14,-1.18}}; GVAR(fuelCargo) = 10000; }; @@ -466,11 +495,7 @@ class CfgVehicles { }; }; class Land_StorageBladder_01_F: StorageBladder_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - - transportFuel = 0; //60k + XEH_INHERITED; GVAR(hooks)[] = {{-3.35,2.45,0.17}}; GVAR(fuelCargo) = 60000; }; @@ -486,36 +511,35 @@ class CfgVehicles { }; }; class Land_FlexibleTank_01_F: FlexibleTank_base_F { - transportFuel = 0; //300 GVAR(hooks)[] = {{0, 0, 0.5}}; GVAR(fuelCargo) = 300; }; // Vanilla buildings class Land_Fuelstation_Feed_F: House_Small_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0,0,-0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_fs_feed_F: House_Small_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{-0.4,0.022,-0.23}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_01_pump_F: House_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_01_pump_malevil_F: House_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_03_pump_F: House_F { // Enoch - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; diff --git a/addons/refuel/XEH_PREP.hpp b/addons/refuel/XEH_PREP.hpp index 077c8f1aed7..cb9279500bc 100644 --- a/addons/refuel/XEH_PREP.hpp +++ b/addons/refuel/XEH_PREP.hpp @@ -11,6 +11,7 @@ PREP(disconnect); PREP(dropNozzle); PREP(getCapacity); PREP(getFuel); +PREP(getFuelCargo); PREP(handleDisconnect); PREP(handleRespawn); PREP(initSource); diff --git a/addons/refuel/XEH_postInit.sqf b/addons/refuel/XEH_postInit.sqf index c826efd3d45..4edd18de148 100644 --- a/addons/refuel/XEH_postInit.sqf +++ b/addons/refuel/XEH_postInit.sqf @@ -1,95 +1,151 @@ #include "script_component.hpp" -if (isServer) then { - addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; -}; +["CBA_settingsInitialized", { + if (!GVAR(enabled)) exitWith {}; -[QGVAR(initSource), LINKFUNC(initSource)] call CBA_fnc_addEventHandler; + ["All", "InitPost", { + params ["_vehicle"]; + if (getFuelCargo _vehicle <= 0) exitWith {}; + TRACE_1("initPost",_vehicle); -if (!hasInterface) exitWith {}; + if (local _vehicle) then { + _vehicle setFuelCargo 0; + LOG("initPost setFuelCargo"); + }; + }, true, ["Man"], true] call CBA_fnc_addClassEventHandler; -["isNotRefueling", {!((_this select 0) getVariable [QGVAR(isRefueling), false])}] call EFUNC(common,addCanInteractWithCondition); + if (isServer) then { + addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; + }; -["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler; + private _cfgPositions = configFile >> QGVAR(positions) >> worldName; + if (isArray _cfgPositions) then { + { + _x params ["_class", "_positions"]; + { + private _objects = _x nearObjects [_class, 30]; + if (_objects isEqualTo []) then { + WARNING_3("no pumps %1 found near %2 %3",_class,worldName,_x); + } else { + { + // terrain fuel pumps don't trigger init and must setFuelCargo on each client + _x setFuelCargo 0; + } forEach _objects; + }; + } forEach _positions; + } forEach getArray _cfgPositions; -GVAR(mainAction) = [ - QGVAR(Refuel), - localize LSTRING(Refuel), - QPATHTOF(ui\icon_refuel_interact.paa), - {}, - { - alive _target - && {[_player, _target, [INTERACT_EXCEPTIONS]] call EFUNC(common,canInteractWith)} - && {REFUEL_DISABLED_FUEL != ([_target] call FUNC(getCapacity))} - }, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE -] call EFUNC(interact_menu,createAction); - -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), + // 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)); + + { + { + _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; + + //IGNORE_PRIVATE_WARNING ["_player", "_target"]; + GVAR(mainAction) = [ + QGVAR(Refuel), + localize LSTRING(Refuel), QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(returnNozzle)}, - {[_player, _target] call FUNC(canReturnNozzle)}, + {}, + { + 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) -]; + ] 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); - { - [_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); + 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, true] call EFUNC(interact_menu,addActionToClass); - } forEach GVAR(actions); - TRACE_1("add menu to dynamic",_x); -} forEach _dynamicClasses; - -#ifdef DRAW_HOOKS_POS -addMissionEventHandler ["Draw3D", { - private _source = cursorObject; - private _cfgPos = getArray (configOf _source >> QGVAR(hooks)); - private _dynPos = _source getVariable [QGVAR(hooks), []]; + 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; + { - 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 + private _className = _x; + [_className, 0, ["ACE_MainActions"], GVAR(mainAction), true] call EFUNC(interact_menu,addActionToClass); + { + [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x, true] call EFUNC(interact_menu,addActionToClass); + } forEach GVAR(actions); + TRACE_1("add menu to dynamic",_x); + } forEach _baseDynamicClasses; + + #ifdef DRAW_HOOKS_POS + addMissionEventHandler ["Draw3D", { + private _source = cursorObject; + private _cfgPos = getArray (configOf _source >> QGVAR(hooks)); + private _dynPos = _source getVariable [QGVAR(hooks), _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_preStart.sqf b/addons/refuel/XEH_preStart.sqf index fa5fe4acda1..308ca30a9b9 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 b39b6650594..79b97994f17 100644 --- a/addons/refuel/config.cpp +++ b/addons/refuel/config.cpp @@ -14,6 +14,7 @@ class CfgPatches { }; }; +#include "ACE_Refuel_Positions.hpp" #include "ACE_Settings.hpp" #include "Cfg3DEN.hpp" #include "CfgEventHandlers.hpp" diff --git a/addons/refuel/dev/exportTerrainRefuelPositions.sqf b/addons/refuel/dev/exportTerrainRefuelPositions.sqf new file mode 100644 index 00000000000..e096af47b89 --- /dev/null +++ b/addons/refuel/dev/exportTerrainRefuelPositions.sqf @@ -0,0 +1,116 @@ +#include "\z\ace\addons\refuel\script_component.hpp" + +// call compileScript ["z\ace\addons\refuel\dev\exportTerrainRefuelPositions.sqf"] +// copies to clipboard header and positions +// returns total found feed and position count, messages and output +// can run in Eden Editor console + +// use this command to move player to needed position: +// player setPos [15121,19011]; +// use this command to view fuel feeds around player position +// ["f", {count (getPos player nearObjects ["Land_fs_feed_F", 30])}] call ace_common_fnc_watchVariable; + +{ + 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 SEARCH 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; +}; + +private _cfgPositions = configFile >> QGVAR(positions) >> worldName; +if (isArray _cfgPositions) then { + private _currentPositionsPumps = []; + { + _x params ["_class", "_positions"]; + { + _currentPositionsPumps insert [-1, _x nearObjects [_class, 30], true]; + } forEach _positions; + } forEach getArray _cfgPositions; + if (_checkCount != count _currentPositionsPumps) then { + _message = "WRONG CURRENT " + str count _currentPositionsPumps; + }; +}; + +// 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 f427f07d28c..52ff8a962ae 100644 --- a/addons/refuel/dev/test_debugConfigs.sqf +++ b/addons/refuel/dev/test_debugConfigs.sqf @@ -5,14 +5,14 @@ private _testPass = true; -diag_log text format ["[ACE-refuel] Showing CfgVehicles with vanilla transportFuel"]; -private _fuelTrucks = configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(getNumber (_x >> 'transportFuel')) > 0}", true]; +INFO("Showing CfgVehicles with transportFuel and without XEH"); +private _badCfgVehicles = ' + 2 == getNumber (_x >> "scope") + && {0 < getNumber (_x >> "transportFuel")} + && {!isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init")} +' configClasses (configFile >> "CfgVehicles"); { - if ((configName _x) isKindOf "Car") then { - diag_log text format ["Car [%1] needs config [transportFuel: %2]", configName _x, getNumber (_x >> 'transportFuel')]; - } else { - diag_log text format ["Non-car? [%1] needs config [transportFuel: %2]", configName _x, getNumber (_x >> 'transportFuel')]; - }; -} forEach _fuelTrucks; + diag_log text format ["Class %1: %2 [%3] needs XEH", configName _x, configName inheritsFrom _x, configSourceMod _x]; +} forEach _badCfgVehicles; _testPass diff --git a/addons/refuel/functions/fnc_canTakeNozzle.sqf b/addons/refuel/functions/fnc_canTakeNozzle.sqf index a2dc39b8158..f2fa4a6a9ce 100644 --- a/addons/refuel/functions/fnc_canTakeNozzle.sqf +++ b/addons/refuel/functions/fnc_canTakeNozzle.sqf @@ -24,7 +24,7 @@ if (isNull _unit || {!alive _object} || {!isNull (_unit getVariable [QGVAR(nozzle), objNull])} || // Not already carrying a nozzle {(_object getVariable [QGVAR(jerryCan), false]) && {!isNull (_object getVariable [QGVAR(nozzle), objNull])}} || // Prevent jerry cans from being picked up if they have a nozzle connected - {typeOf _object == QGVAR(fuelNozzle) && {!isNull (attachedTo _object)}} || // Not carried by someone else + {!([_unit, _object, [INTERACT_EXCEPTIONS]] call EFUNC(common,canInteractWith))} || // Not carried by someone else {([_unit, _object] call EFUNC(interaction,getInteractionDistance)) > REFUEL_ACTION_DISTANCE}) exitWith {false}; !(_object getVariable [QGVAR(isConnected), false]) && {!(_unit getVariable [QGVAR(isRefueling), false])} diff --git a/addons/refuel/functions/fnc_connectNozzleAction.sqf b/addons/refuel/functions/fnc_connectNozzleAction.sqf index ad658492fa8..1a022b6e768 100644 --- a/addons/refuel/functions/fnc_connectNozzleAction.sqf +++ b/addons/refuel/functions/fnc_connectNozzleAction.sqf @@ -62,7 +62,7 @@ if (_bestPosASL isEqualTo []) exitWith { //Move it out slightly, for visibility sake (better to look a little funny than be embedded//sunk in the hull and be useless) _bestPosASL = _bestPosASL vectorAdd ((_bestPosASL vectorFromTo _startingPosASL) vectorMultiply 0.05); -private _attachPosModel = _sink worldToModel (ASLtoAGL _bestPosASL); +private _attachPosModel = _sink worldToModel (ASLToAGL _bestPosASL); [ GVAR(progressDuration), @@ -116,6 +116,9 @@ private _attachPosModel = _sink worldToModel (ASLtoAGL _bestPosASL); // Reset fuel counter _source setVariable [QGVAR(fuelCounter), 0, true]; + // Let other players access nozzle + [objNull, _nozzle] call EFUNC(common,claim); + [_unit, _sink, _nozzle, _endPosTestOffset] call FUNC(refuel); private _canReceive = getNumber ((configOf _sink) >> QGVAR(canReceive)) == 1; diff --git a/addons/refuel/functions/fnc_dropNozzle.sqf b/addons/refuel/functions/fnc_dropNozzle.sqf index 5ca375dc29e..ee37a869e10 100644 --- a/addons/refuel/functions/fnc_dropNozzle.sqf +++ b/addons/refuel/functions/fnc_dropNozzle.sqf @@ -24,6 +24,9 @@ TRACE_3("dropNozzle",_unit,_nozzle,_disconnectOnly); detach _nozzle; _nozzle setVariable [QGVAR(isRefueling), false, true]; +// Remove claim on nozzle +[objNull, _nozzle] call EFUNC(common,claim); + if (_disconnectOnly) exitWith {}; _nozzle setVelocity [0, 0, 0]; diff --git a/addons/refuel/functions/fnc_getFuelCargo.sqf b/addons/refuel/functions/fnc_getFuelCargo.sqf new file mode 100644 index 00000000000..360679013e4 --- /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 cf4b37cce9a..3aa1831a186 100644 --- a/addons/refuel/functions/fnc_handleDisconnect.sqf +++ b/addons/refuel/functions/fnc_handleDisconnect.sqf @@ -24,4 +24,4 @@ private _nozzle = _unit getVariable [QGVAR(nozzle), objNull]; if (isNull _nozzle) exitWith {}; [_unit, _nozzle] call FUNC(dropNozzle); -[_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); diff --git a/addons/refuel/functions/fnc_makeJerryCan.sqf b/addons/refuel/functions/fnc_makeJerryCan.sqf index 4b807756c9e..29b5dd98fcd 100644 --- a/addons/refuel/functions/fnc_makeJerryCan.sqf +++ b/addons/refuel/functions/fnc_makeJerryCan.sqf @@ -16,6 +16,13 @@ * Public: Yes */ +// Only run this after the settings are initialized +if !(EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(makeJerryCan), _this]; +}; + +if (!GVAR(enabled)) exitWith {}; + params [["_target", objNull, [objNull]], ["_fuelAmount", 20, [0]]]; if (isNull _target || @@ -31,6 +38,8 @@ if (isServer) then { [QGVAR(jerryCanInitalized), [_target]] call CBA_fnc_globalevent; }; +//IGNORE_PRIVATE_WARNING ["_player", "_target"]; + // Main Action private _action = [QGVAR(Refuel), localize LSTRING(Refuel), diff --git a/addons/refuel/functions/fnc_makeSource.sqf b/addons/refuel/functions/fnc_makeSource.sqf index 38b2d8a2618..9d76635849f 100644 --- a/addons/refuel/functions/fnc_makeSource.sqf +++ b/addons/refuel/functions/fnc_makeSource.sqf @@ -25,21 +25,39 @@ if !(EGVAR(common,settingsInitFinished)) exitWith { EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(makeSource), _this]; }; +if (!GVAR(enabled)) exitWith {}; + params [ ["_source", objNull, [objNull]], ["_fuelCargo", 0, [0]], ["_hooks", nil, [[]]] ]; -TRACE_3("makeSource",_source,_fuelCargo,_hooks); -private _fuelCargoConfig = getNumber (configOf _source >> QGVAR(fuelCargo)); +private _fuelCargoConfig = _source call FUNC(getFuelCargo); + +TRACE_4("makeSource",_source,_fuelCargo,_hooks,_fuelCargoConfig); if ( isNull _source || {_fuelCargo < 0 && {!(_fuelCargo in [REFUEL_INFINITE_FUEL, REFUEL_DISABLED_FUEL])}} - || {_fuelCargo != 0 && {_fuelCargo == _fuelCargoConfig}} ) exitWith {}; +// We might be removing fuel from an object that in config doesn't have fuel, but was given fuel via this function prior +if (_fuelCargo == REFUEL_DISABLED_FUEL && {_fuelCargoConfig == REFUEL_DISABLED_FUEL}) exitWith { + if (isNil {_source getVariable QGVAR(currentFuelCargo)}) exitWith {}; + + _source setVariable [QGVAR(currentFuelCargo), nil, true]; + _source setVariable [QGVAR(capacity), REFUEL_DISABLED_FUEL, true]; + + private _jipID = _source getVariable QGVAR(initSource_jipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _source setVariable [QGVAR(initSource_jipID), nil]; +}; + private _capacity = if (_fuelCargo < 0) then {_fuelCargo} else {_fuelCargoConfig max _fuelCargo}; _source setVariable [QGVAR(capacity), _capacity, true]; @@ -57,10 +75,10 @@ if ( }; // only add if menu doesn't already exist -if (!(_fuelCargoConfig != 0 && {!isNil {_source getVariable QGVAR(initSource_jipID)}})) then { - private _jipID = [QGVAR(initSource), [_source]] call CBA_fnc_globalEventJIP; - [_jipID, _source] call CBA_fnc_removeGlobalEventJIP; - _source setVariable [QGVAR(initSource_jipID), _jipID]; -}; +if (_fuelCargoConfig != REFUEL_DISABLED_FUEL || {!isNil {_source getVariable QGVAR(initSource_jipID)}}) exitWith {}; + +private _jipID = [QGVAR(initSource), [_source]] call CBA_fnc_globalEventJIP; +[_jipID, _source] call CBA_fnc_removeGlobalEventJIP; +_source setVariable [QGVAR(initSource_jipID), _jipID]; [QGVAR(sourceInitialized), [_source]] call CBA_fnc_globalEvent; diff --git a/addons/refuel/functions/fnc_returnNozzle.sqf b/addons/refuel/functions/fnc_returnNozzle.sqf index ea84f6a5180..eba836ed8a1 100644 --- a/addons/refuel/functions/fnc_returnNozzle.sqf +++ b/addons/refuel/functions/fnc_returnNozzle.sqf @@ -43,12 +43,12 @@ 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); + [_source, "blockEngine", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); }, "", localize LSTRING(ReturnAction), diff --git a/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf b/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf index d2f1e2aaa50..da47bc3c725 100644 --- a/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf +++ b/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf @@ -23,8 +23,8 @@ #define END_PFH \ _unit setVariable [QGVAR(hint), nil]; \ call EFUNC(interaction,hideMouseHint); \ - [_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set); \ - [_unit, "blockThrow", "ACE_refuel", false] call EFUNC(common,statusEffect_set); \ + [_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); \ + [_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); \ [_idPFH] call CBA_fnc_removePerFrameHandler; params ["_unit", "_nozzle"]; @@ -35,11 +35,9 @@ TRACE_2("start",_unit,_nozzle); _args params ["_unit", "_nozzle"]; if !( - alive _unit + _unit call EFUNC(common,isAwake) && {"" isEqualTo currentWeapon _unit || {_unit call EFUNC(common,isSwimming)}} && {[_unit, objNull, [INTERACT_EXCEPTIONS, "notOnMap"]] call EFUNC(common,canInteractWith)} - && {"unconscious" isNotEqualTo toLower animationState _unit} - && {!(_unit getVariable ["ACE_isUnconscious", false])} ) exitWith { TRACE_3("stop dead/weapon/interact/uncon",_unit,alive _unit,currentWeapon _unit); DROP_NOZZLE @@ -91,7 +89,7 @@ TRACE_2("start",_unit,_nozzle); }; private _hintLMB = ""; - private _hintRMB = localize ELSTRING(dragging,Drop); + private _hintRMB = LELSTRING(common,Drop); getCursorObjectParams params ["_cursorObject", "", "_distance"]; if (!isNull _cursorObject && {_distance < REFUEL_NOZZLE_ACTION_DISTANCE}) then { diff --git a/addons/refuel/functions/fnc_takeNozzle.sqf b/addons/refuel/functions/fnc_takeNozzle.sqf index 8eb0a16f1f9..51db8789e5d 100644 --- a/addons/refuel/functions/fnc_takeNozzle.sqf +++ b/addons/refuel/functions/fnc_takeNozzle.sqf @@ -32,17 +32,23 @@ params [ private _source = _object; private _nozzle = _object; - if (typeOf _object isEqualTo QGVAR(fuelNozzle) || {_object getVariable [QGVAR(jerryCan), false]}) then { // func is called on muzzle either connected or on ground + if (typeOf _object isEqualTo QGVAR(fuelNozzle) || {_object getVariable [QGVAR(jerryCan), false]}) then { // func is called on nozzle either connected or on ground _source = _nozzle getVariable QGVAR(source); if (_nozzle getVariable [QGVAR(jerryCan), false]) then { _nozzle attachTo [_unit, [0,1,0], "pelvis"]; } else { _nozzle attachTo [_unit, [-0.02,0.05,-0.12], "righthandmiddle1"]; }; + + // Don't allow other players to take nozzle + [_unit, _nozzle] call EFUNC(common,claim); } else { // func is called on fuel truck _nozzle = QGVAR(fuelNozzle) createVehicle [0,0,0]; _nozzle attachTo [_unit, [-0.02,0.05,-0.12], "righthandmiddle1"]; + // Don't allow other players to take nozzle + [_unit, _nozzle] call EFUNC(common,claim); + private _ropeTarget = _source; if !(_source isKindOf "AllVehicles") then { private _helper = QGVAR(helper) createVehicle [0,0,0]; @@ -74,7 +80,7 @@ params [ _nozzle setVariable [QGVAR(attachPos), _attachPos, true]; _nozzle setVariable [QGVAR(source), _source, true]; - [_source, "blockEngine", "ACE_Refuel", true] call EFUNC(common,statusEffect_set); + [_source, "blockEngine", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); _source setVariable [QGVAR(isConnected), true, true]; _source setVariable [QGVAR(ownedNozzle), _nozzle, true]; @@ -94,8 +100,8 @@ params [ _unit call EFUNC(common,fixLoweredRifleAnimation); _unit action ["SwitchWeapon", _unit, _unit, 299]; - [_unit, "forceWalk", "ACE_refuel", true] call EFUNC(common,statusEffect_set); - [_unit, "blockThrow", "ACE_refuel", true] call EFUNC(common,statusEffect_set); + [_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + [_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); [_unit, _nozzle] call FUNC(startNozzleInHandsPFH); }, diff --git a/addons/refuel/initSettings.inc.sqf b/addons/refuel/initSettings.inc.sqf index f3744697a44..2888ad190ce 100644 --- a/addons/refuel/initSettings.inc.sqf +++ b/addons/refuel/initSettings.inc.sqf @@ -1,12 +1,21 @@ 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 - {[QGVAR(rate), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -14,8 +23,7 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"]; [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 - {[QGVAR(cargoRate), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -23,8 +31,7 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"]; [LSTRING(RefuelSettings_hoseLength_DisplayName)], _category, [0,50,12,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(hoseLength), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -32,6 +39,5 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"]; [LSTRING(RefuelSettings_progressDuration_DisplayName), LSTRING(RefuelSettings_progressDuration_Description)], _category, [0, 10, 2], // [min, max, default value] - true, // isGlobal - {[QGVAR(progressDuration), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/refuel/stringtable.xml b/addons/refuel/stringtable.xml index dc61a2c168a..648ee38c6da 100644 --- a/addons/refuel/stringtable.xml +++ b/addons/refuel/stringtable.xml @@ -505,6 +505,8 @@ 燃料キャニスターを持つ 연료통 집어들기 Взять канистру с топливом + Ramasser le réservoir de carburant + Coger garrafa de combustible Picking fuel canister up... @@ -513,6 +515,8 @@ 燃料キャニスターを持ち上げています・・・ 연료통 집어드는 중... Поднимаю канистру с топливом... + Ramasser les bidons de carburant... + Cogiendo garrafa de combustible... Connect fuel canister @@ -521,6 +525,8 @@ 燃料キャニスターを接続する 연료통 꽂기 Подсоединить канистру с топливом + Raccorder le réservoir de carburant + Conectar garrafa de combustible Connecting fuel canister... @@ -529,6 +535,8 @@ 燃料キャニスターを接続しています・・・ 연료통 꽂는 중... Подсоединение топливной канистры... + Raccorder le réservoir de carburant... + Conectando garrafa de combustible... Disconnect fuel canister @@ -537,6 +545,8 @@ 燃料キャニスターを外します 연료통 빼기 Отсоединить канистру с топливом + Débrancher le réservoir de carburant + Desconectar garrafa de combustible Refuel hose length @@ -573,7 +583,7 @@ Время в секундах, которое занимает взаимодействие со шлангом. 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. diff --git a/addons/reload/functions/fnc_canCheckAmmo.sqf b/addons/reload/functions/fnc_canCheckAmmo.sqf index 96b9f88d501..829e57e2569 100644 --- a/addons/reload/functions/fnc_canCheckAmmo.sqf +++ b/addons/reload/functions/fnc_canCheckAmmo.sqf @@ -4,23 +4,24 @@ * Check if a unit can check the ammo of the target. * * Arguments: - * 0: Unit equipped with the weapon + * 0: Unit equipped with the weapon/CSW to check + * 1: Unit checking ammo * * Return Value: * Can check ammo * * Example: - * [cursorObject] call ace_reload_fnc_canCheckAmmo + * [cursorObject, player] call ace_reload_fnc_canCheckAmmo * * Public: No */ -params ["_target"]; +params ["_target", "_player"]; // Static weapons if (_target isKindOf "StaticWeapon") exitWith { // No check ammo action on destroyed static weapons - if (!alive _target) exitWith {false}; + if (!alive _target || {!([_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew))}) exitWith {false}; if (currentMagazine _target != "") exitWith {true}; diff --git a/addons/reload/functions/fnc_checkAmmo.sqf b/addons/reload/functions/fnc_checkAmmo.sqf index f558d917699..8039c9527ca 100644 --- a/addons/reload/functions/fnc_checkAmmo.sqf +++ b/addons/reload/functions/fnc_checkAmmo.sqf @@ -23,7 +23,7 @@ if (_unit == _target) then { _target = vehicle _target; }; - [_unit, "Gear", 1] call EFUNC(common,doGesture); + [_unit, "reloadMagazine", 0] call EFUNC(common,doGesture); }; [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 68e176587ad..7e38ee65f87 100644 --- a/addons/reload/functions/fnc_displayAmmo.sqf +++ b/addons/reload/functions/fnc_displayAmmo.sqf @@ -122,7 +122,7 @@ if (_isStaticWeapon) then { _loadedName = parseText format ["%1", _loadedName]; - private _text = composeText [_loadedName, linebreak, _ammoBarsStructuredText]; + private _text = composeText [_loadedName, lineBreak, _ammoBarsStructuredText]; [_text] call EFUNC(common,displayTextStructured); } else { if (_magazine != "") then { diff --git a/addons/reload/stringtable.xml b/addons/reload/stringtable.xml index e081834e29b..ec860ff46a1 100644 --- a/addons/reload/stringtable.xml +++ b/addons/reload/stringtable.xml @@ -38,7 +38,7 @@ 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 @@ -53,7 +53,7 @@ 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. @@ -107,7 +107,7 @@ Gurt anhängen Töltényheveder összekötése Combina nastro - Ligar cintos de munição + Conectar cintos de munição ベルトを繋げる 탄띠 연결 连接弹链 @@ -123,7 +123,7 @@ Gurt anhängen... Töltényheveder összekötése folyamatban... Combinando nastro... - Ligando cintos... + Conectando cintos... ベルトを繋げています・・・ 탄띠 연결 중... 正在连接弹链... @@ -138,6 +138,8 @@ Taśma została połączona 탄띠가 연결되었습니다 Ремень был пристегнут + Cinta enganchada + Cinto conectado Belt could not be linked @@ -148,6 +150,8 @@ Taśma nie mogła być połączona 탄띠를 연결할 수 없습니다 Ремень не удалось пристегнуть + La cinta no ha podido ser enganchada + Cinto não pôde ser conectado diff --git a/addons/reloadlaunchers/stringtable.xml b/addons/reloadlaunchers/stringtable.xml index ac42ef4d99e..6324a97b552 100644 --- a/addons/reloadlaunchers/stringtable.xml +++ b/addons/reloadlaunchers/stringtable.xml @@ -10,6 +10,8 @@ 동료의 장전에 대한 알림 표시 Affichage de notifications lors d'une rechargement par un ami Отображает уведомления о загрузке помощника + Mostrar notificaciones para recarga de compañero + Mostrar notificações para Carregamento de Companheiro Displays notifications when an assistant loads a gunner's launcher. @@ -20,6 +22,8 @@ 부사수가 사수의 발사기를 장전할 때 알림을 표시합니다. Affiche une notofication lorsqu'un assistant recharge l'arme du tireur. Отображает уведомления, когда помощник загружает пусковую установку стрелка. + Mostrar notificaciones cuando un asistente recarga el lanzador del tirador. + Notifica quando um assistente carrega o lançador do atirador Load launcher @@ -47,6 +51,8 @@ %1 ładuje twoją wyrzutnię %1이(가) 당신의 발사기를 장전했습니다. %1 загружает Вашу установку + %1 está cargando tu lanzador + %1 está carregando seu lançador %1 stopped loading your launcher @@ -57,6 +63,8 @@ %1 przestał ładować twoją wyrzutnię %1이(가) 당신의 발사기 장전을 멈췄습니다. %1 прекратил загружать Вашу установку + %1 paró de cargar tu lanzador + %1 parou de carregar seu lançador Loading launcher... @@ -118,6 +126,8 @@ Wyrzutnia nie mogła być załadowana 발사기를 장전할 수 없습니다. Не удалось загрузить пусковую установку + El lanzador no ha podido ser cargado + O lançador não pôde ser carregado Buddy Loading @@ -128,6 +138,8 @@ Nachladen durch Kamerad バディローディング Перезарядка помощником + Cargado de Compañero + Carregamento de Companheiro diff --git a/addons/repair/CfgVehicles.hpp b/addons/repair/CfgVehicles.hpp index ce74737b766..89d3cd83133 100644 --- a/addons/repair/CfgVehicles.hpp +++ b/addons/repair/CfgVehicles.hpp @@ -429,9 +429,34 @@ class CfgVehicles { GVAR(hitpointPositions)[] = {{"HitTurret", {0,-2,0}}}; }; + class Tank_F; + class APC_Tracked_02_base_F: Tank_F { + class EGVAR(interaction,anims) { + class showTracks { + phase = 0; + selections[] = {"vhc_tracks"}; + positions[] = {"private _pos = _target selectionPosition 'vhc_tracks'; _pos set [0, -(_pos select 0)]; _pos"}; // Mirror position to other side of vehicle + items[] = {"ACE_Track", "ACE_Track", "ACE_Track"}; + name = CSTRING(RemoveTrack); + text = CSTRING(RemovingTrack); + }; + }; + }; + class Car_F: Car { class HitPoints; }; + class Offroad_02_base_F: Car_F { + class EGVAR(interaction,anims) { + class hideSpareWheel { + positions[] = {"_target selectionPosition ['spare_wheel', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = CSTRING(RemoveWheel); + text = CSTRING(RemovingWheel); + }; + }; + }; + class Truck_F: Car_F { class HitPoints: HitPoints { class HitLBWheel; @@ -449,10 +474,45 @@ class CfgVehicles { }; }; + class Truck_01_viv_base_F; + class Truck_01_cargo_base_F: Truck_01_viv_base_F { + class EGVAR(interaction,anims) { + class Tyre1_hide { + positions[] = {"_target selectionPosition ['tyre1_hide', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = CSTRING(RemoveWheel); + text = CSTRING(RemovingWheel); + distance = 2.5; + }; + }; + }; + class Truck_01_flatbed_base_F: Truck_01_viv_base_F { + class EGVAR(interaction,anims) { + class Tyre1_hide { + positions[] = {"_target selectionPosition ['tyre1_hide', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = CSTRING(RemoveWheel); + text = CSTRING(RemovingWheel); + distance = 2.5; + }; + }; + }; + class Quadbike_01_base_F: Car_F { GVAR(hitpointPositions)[] = { {"HitEngine", {0, 0.5, -0.7}}, {"HitFuel", {0, 0, -0.5}} }; }; class Hatchback_01_base_F: Car_F { GVAR(hitpointPositions)[] = {{"HitBody", {0, 0.7, -0.5}}, {"HitFuel", {0, -1.75, -0.75}}}; }; + + class Van_02_base_F: Truck_F { + class EGVAR(interaction,anims) { + class spare_tyre_hide { + positions[] = {"_target selectionPosition ['spare_tyre', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = CSTRING(RemoveWheel); + text = CSTRING(RemovingWheel); + }; + }; + }; }; diff --git a/addons/repair/XEH_PREP.hpp b/addons/repair/XEH_PREP.hpp index 186ec0b310f..16e11b7476e 100644 --- a/addons/repair/XEH_PREP.hpp +++ b/addons/repair/XEH_PREP.hpp @@ -25,7 +25,6 @@ PREP(getSelectionsToIgnore); PREP(getPatchWheelTime); PREP(getPostRepairDamage); PREP(getRepairItems); -PREP(getWheelHitPointsWithSelections); PREP(hasItems); PREP(isEngineer); PREP(isInRepairFacility); diff --git a/addons/repair/XEH_postInit.sqf b/addons/repair/XEH_postInit.sqf index 58bb1be6e5a..012ddb9f09a 100644 --- a/addons/repair/XEH_postInit.sqf +++ b/addons/repair/XEH_postInit.sqf @@ -2,10 +2,10 @@ ["CBA_settingsInitialized", { - if !GVAR(enabled) exitWith {}; + if (!GVAR(enabled)) exitWith {}; - [QGVAR(setVehicleDamage), {_this call FUNC(setDamage)}] call CBA_fnc_addEventHandler; - [QGVAR(setVehicleHitPointDamage), {_this call FUNC(setHitPointDamage)}] call CBA_fnc_addEventHandler; + [QGVAR(setVehicleDamage), LINKFUNC(setDamage)] call CBA_fnc_addEventHandler; + [QGVAR(setVehicleHitPointDamage), LINKFUNC(setHitPointDamage)] call CBA_fnc_addEventHandler; [QGVAR(setWheelHitPointDamage), { params ["_object", "_hitPoint", "_damage"]; private _damageDisabled = !isDamageAllowed _object; @@ -39,12 +39,27 @@ ["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]; + private _isEngineer = _unit getUnitTrait "engineer"; + if (isNil "_isEngineer" || {_isEngineer isNotEqualTo true}) exitWith {}; + TRACE_4("setUnitTrait 1",_unit,typeOf _unit,local _unit,ACE_player); + + if (local _unit) 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"); + + // Handle player locality delay, can be anywhere from instant to 10+ seconds (#10337) + if (_unit isNotEqualTo ACE_player) exitWith {}; + _unit addEventHandler ["Local", { + params ["_unit", "_isLocal"]; + if (!_isLocal) exitWith {}; + TRACE_3("setUnitTrait 2",_unit,typeOf _unit,_unit getUnitTrait "engineer"); + _unit setUnitTrait ["engineer", false]; + _unit removeEventHandler ["Local", _thisEventHandler]; + }]; }, true, [], true] call CBA_fnc_addClassEventHandler; diff --git a/addons/repair/dev/draw_showRepairInfo.sqf b/addons/repair/dev/draw_showRepairInfo.sqf index f516e14ef9b..182b2f7a088 100644 --- a/addons/repair/dev/draw_showRepairInfo.sqf +++ b/addons/repair/dev/draw_showRepairInfo.sqf @@ -4,6 +4,7 @@ #include "..\script_component.hpp" addMissionEventHandler ["Draw3D", { + if (isGamePaused) exitWith {}; if !((cursorObject isKindOf "Car") || (cursorObject isKindOf "Tank") || (cursorObject isKindOf "Air")) exitWith {}; private _config = configOf cursorObject; @@ -11,7 +12,7 @@ addMissionEventHandler ["Draw3D", { private _hitpointGroups = getArray (_config >> QGVAR(hitpointGroups)); (getAllHitPointsDamage cursorObject) params [["_hitPoints", []], ["_hitSelections", []]]; - ([cursorObject] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; + ([cursorObject] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; private _output = []; @@ -20,7 +21,7 @@ addMissionEventHandler ["Draw3D", { private _hitpoint = _hitPoints select _forEachIndex; if ((_selection != "") && {_hitPoint != ""}) then { - if (((toLower _hitPoint) find "glass") != -1) exitWith {}; + if ("glass" in (toLowerANSI _hitPoint)) exitWith {}; private _info = ""; private _color = [1,0,0,1]; @@ -28,7 +29,7 @@ addMissionEventHandler ["Draw3D", { _info = _info + "[Wheel]"; _color = [0,1,0,1]; }; - if (!((getText (_config>> "HitPoints" >> _hitpoint >> "depends")) in ["", "0"])) then { + if !((getText (_config>> "HitPoints" >> _hitpoint >> "depends")) in ["", "0"]) then { _info = _info + format ["[depends: %1]", getText (_config>> "HitPoints" >> _hitpoint >> "depends")]; _color = [0,0,1,1] }; diff --git a/addons/repair/functions/fnc_addRepairActions.sqf b/addons/repair/functions/fnc_addRepairActions.sqf index 1e0147d7e2b..095df261aaa 100644 --- a/addons/repair/functions/fnc_addRepairActions.sqf +++ b/addons/repair/functions/fnc_addRepairActions.sqf @@ -37,7 +37,7 @@ private _selectionsToIgnore = _vehicle call FUNC(getSelectionsToIgnore); (getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; // Since 1.82 these are all lower case // get hitpoints of wheels with their selections -([_vehicle] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; +([_vehicle] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; private _hitPointsAddedNames = []; private _hitPointsAddedStrings = []; @@ -52,7 +52,7 @@ private _turretPaths = ((fullCrew [_vehicle, "gunner", true]) + (fullCrew [_vehi { private _selection = _x; - private _hitpoint = toLower (_hitPoints select _forEachIndex); + private _hitpoint = toLowerANSI (_hitPoints select _forEachIndex); // Skip ignored selections if (_forEachIndex in _selectionsToIgnore) then { @@ -66,11 +66,11 @@ private _turretPaths = ((fullCrew [_vehicle, "gunner", true]) + (fullCrew [_vehi TRACE_3("Adding Wheel Actions",_hitpoint,_forEachIndex,_selection); // An action to replace the wheel is required - _name = format ["Replace_%1_%2", _forEachIndex, _hitpoint]; - _text = localize LSTRING(ReplaceWheel); - _condition = {[_this select 1, _this select 0, _this select 2 select 0, "ReplaceWheel"] call DFUNC(canRepair)}; - _statement = {[_this select 1, _this select 0, _this select 2 select 0, "ReplaceWheel"] call DFUNC(repair)}; - _action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 2] call EFUNC(interact_menu,createAction); + private _name = format ["Replace_%1_%2", _forEachIndex, _hitpoint]; + private _text = localize LSTRING(ReplaceWheel); + private _condition = {[_this select 1, _this select 0, _this select 2 select 0, "ReplaceWheel"] call DFUNC(canRepair)}; + private _statement = {[_this select 1, _this select 0, _this select 2 select 0, "ReplaceWheel"] call DFUNC(repair)}; + private _action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 2] call EFUNC(interact_menu,createAction); [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass); // Create a wheel interaction @@ -118,6 +118,7 @@ private _turretPaths = ((fullCrew [_vehicle, "gunner", true]) + (fullCrew [_vehi }; // Find the action position + //IGNORE_PRIVATE_WARNING ["_target"]; private _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _selection]; { _x params ["_hit", "_pos"]; diff --git a/addons/repair/functions/fnc_canRepair.sqf b/addons/repair/functions/fnc_canRepair.sqf index 264baf9ef0a..4a77383c288 100644 --- a/addons/repair/functions/fnc_canRepair.sqf +++ b/addons/repair/functions/fnc_canRepair.sqf @@ -21,7 +21,7 @@ params ["_caller", "_target", "_hitPoint", "_className"]; TRACE_4("params",_caller,_target,_hitPoint,_className); -private _config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); +private _config = (configFile >> "ACE_Repair" >> "Actions" >> _className); if !(isClass _config) exitWith {false}; // or go for a default? // if(isEngineOn _target) exitWith {false}; // Ignore here so action shows, then exit and show warning when selected #3348 @@ -38,7 +38,7 @@ private _engineerRequired = if (isNumber (_config >> "requiredEngineer")) then { if !([_caller, _engineerRequired] call FUNC(isEngineer)) exitWith {false}; private _items = _config call FUNC(getRepairItems); -if (count _items > 0 && {!([_caller, _items] call FUNC(hasItems))}) exitWith {false}; +if (_items isNotEqualTo [] && {!([_caller, _items] call FUNC(hasItems))}) exitWith {false}; private _return = true; if (getText (_config >> "condition") != "") then { @@ -65,7 +65,7 @@ if (!_return) exitWith {false}; // if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitWith {false}; private _repairLocations = getArray (_config >> "repairLocations"); -if (!("All" in _repairLocations)) then { +if !("All" in _repairLocations) then { private _repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))}; private _repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))}; { diff --git a/addons/repair/functions/fnc_doRepairTrack.sqf b/addons/repair/functions/fnc_doRepairTrack.sqf index 519a3f78d68..fcd71b59c9a 100644 --- a/addons/repair/functions/fnc_doRepairTrack.sqf +++ b/addons/repair/functions/fnc_doRepairTrack.sqf @@ -26,7 +26,7 @@ TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); _claimedObjects params [["_track", objNull]]; if ((isNull _track) || {!([_unit, _track, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { - ERROR_1("Bad Track",_claimedObjects); + ERROR_1("Bad Track %1",_claimedObjects); }; // can't use a destroyed track diff --git a/addons/repair/functions/fnc_doReplaceTrack.sqf b/addons/repair/functions/fnc_doReplaceTrack.sqf index a512089c891..899532d96a8 100644 --- a/addons/repair/functions/fnc_doReplaceTrack.sqf +++ b/addons/repair/functions/fnc_doReplaceTrack.sqf @@ -26,7 +26,7 @@ TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); _claimedObjects params [["_track", objNull]]; if ((isNull _track) || {!([_unit, _track, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { - ERROR_1("Bad Track",_claimedObjects); + ERROR_1("Bad Track %1",_claimedObjects); }; // get current hitpoint damage diff --git a/addons/repair/functions/fnc_doReplaceWheel.sqf b/addons/repair/functions/fnc_doReplaceWheel.sqf index 7ec617127cf..368fe049702 100644 --- a/addons/repair/functions/fnc_doReplaceWheel.sqf +++ b/addons/repair/functions/fnc_doReplaceWheel.sqf @@ -26,7 +26,7 @@ TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); _claimedObjects params [["_wheel", objNull]]; if ((isNull _wheel) || {!([_unit, _wheel, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { - WARNING_1("Bad Claimed Wheel",_claimedObjects); + WARNING_1("Bad Claimed Wheel %1",_claimedObjects); }; // get current hitpoint damage diff --git a/addons/repair/functions/fnc_getHitPointString.sqf b/addons/repair/functions/fnc_getHitPointString.sqf index 93a4c153b20..23a57f8895d 100644 --- a/addons/repair/functions/fnc_getHitPointString.sqf +++ b/addons/repair/functions/fnc_getHitPointString.sqf @@ -20,17 +20,9 @@ */ params ["_hitPoint", "_textLocalized", "_textDefault", ["_trackArray", []]]; +_trackArray params [["_trackNames", []], ["_trackStrings", []], ["_trackAmount", []]]; -private _track = (count _trackArray > 0); -private _trackNames = []; -private _trackStrings = []; -private _trackAmount = []; - -if (_track) then { - _trackNames = _trackArray select 0; - _trackStrings = _trackArray select 1; - _trackAmount = _trackArray select 2; -}; +private _track = _trackArray isNotEqualTo []; // Prepare first part of the string from stringtable //IGNORE_STRING_WARNING(str_ace_repair_hit); @@ -40,7 +32,7 @@ private _text = LSTRING(Hit); if ((_hitpoint select [0, 1]) == "#") then { _hitPoint = _hitPoint select [1] }; // Remove "Hit" from hitpoint name if one exists -private _toFind = if ((toLower _hitPoint) find "hit" == 0) then { +private _toFind = if ((toLowerANSI _hitPoint) find "hit" == 0) then { [_hitPoint, 3] call CBA_fnc_substr } else { _hitPoint diff --git a/addons/repair/functions/fnc_getSelectionsToIgnore.sqf b/addons/repair/functions/fnc_getSelectionsToIgnore.sqf index b90e44e8e65..455b58c0405 100644 --- a/addons/repair/functions/fnc_getSelectionsToIgnore.sqf +++ b/addons/repair/functions/fnc_getSelectionsToIgnore.sqf @@ -28,14 +28,14 @@ private _turretPaths = ((fullCrew [_vehicle, "gunner", true]) + (fullCrew [_vehi (getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; // get hitpoints of wheels with their selections -([_vehicle] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; +([_vehicle] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; private _indexesToIgnore = []; private _processedSelections = []; { private _selection = _x; - private _hitpoint = toLower (_hitPoints select _forEachIndex); + private _hitpoint = toLowerANSI (_hitPoints select _forEachIndex); private _isWheelOrTrack = _selection in _wheelHitSelections || {_hitpoint in _wheelHitPoints} || {_hitpoint in TRACK_HITPOINTS}; if (_hitpoint isEqualTo "") then { // skip empty hitpoint @@ -117,7 +117,7 @@ private _processedSelections = []; continue }; - if (!(getText (_vehCfg >> "HitPoints" >> _hitpoint >> "depends") in ["", "0"])) then { // skip depends hitpoints, should be normalized by engine + 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]; diff --git a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf deleted file mode 100644 index 347c3878d74..00000000000 --- a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf +++ /dev/null @@ -1,97 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Returns the wheel hitpoints and their selections. - * - * Arguments: - * 0: Vehicle - * - * Return Value: - * 0: Wheel hitpoints - * 1: Wheel hitpoint selections in model coordinates - * - * Example: - * [car1] call ace_repair_fnc_getWheelHitPointsWithSelections - * - * Public: No - */ - -params ["_vehicle"]; -TRACE_1("params",_vehicle); - -// get the vehicles wheel config -private _wheels = configOf _vehicle >> "Wheels"; - -// exit with nothing if the vehicle has no wheels class -if !(isClass _wheels) exitWith {TRACE_1("No Wheels",_wheels); [[],[]]}; - -// get all hitpoints and selections -(getAllHitPointsDamage _vehicle) params ["_hitPoints", "_hitPointSelections"]; - -// get all wheels and read selections from config -_wheels = "true" configClasses _wheels; - -private _wheelHitPoints = []; -private _wheelHitPointSelections = []; - -{ - private _wheelName = configName _x; - private _wheelCenter = getText (_x >> "center"); - private _wheelBone = getText (_x >> "boneName"); - private _wheelBoneNameResized = _wheelBone select [0, 9]; //ount "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles. - - TRACE_4("",_wheelName,_wheelCenter,_wheelBone,_wheelBoneNameResized); - - private _wheelHitPoint = ""; - private _wheelHitPointSelection = ""; - - //Commy's orginal method - { - if ((_wheelBoneNameResized != "") && {_x find _wheelBoneNameResized == 0}) exitWith { // same as above. Requirement for physx. - _wheelHitPoint = _hitPoints select _forEachIndex; - _wheelHitPointSelection = _hitPointSelections select _forEachIndex; - TRACE_2("wheel found [Orginal]",_wheelName,_wheelHitPoint); - }; - } forEach _hitPointSelections; - - - if (_vehicle isKindOf "Car") then { - //Backup method, search for the closest hitpoint to the wheel's center selection pos. - //Ref #2742 - RHS's HMMWV - if (_wheelHitPoint == "") then { - private _wheelCenterPos = _vehicle selectionPosition _wheelCenter; - if (_wheelCenterPos isEqualTo [0,0,0]) exitWith {TRACE_1("no center?",_wheelCenter);}; - - - private _bestDist = 99; - private _bestIndex = -1; - { - if (_x != "") then { - //Filter out things that definitly aren't wheeels (#3759) - if ((toLower (_hitPoints select _forEachIndex)) in ["hitengine", "hitfuel", "hitbody"]) exitWith {TRACE_1("filter",_x)}; - private _xPos = _vehicle selectionPosition _x; - if (_xPos isEqualTo [0,0,0]) exitWith {}; - private _xDist = _wheelCenterPos distance _xPos; - if (_xDist < _bestDist) then { - _bestIndex = _forEachIndex; - _bestDist = _xDist; - }; - }; - } forEach _hitPointSelections; - - TRACE_2("closestPoint",_bestDist,_bestIndex); - if (_bestIndex != -1) then { - _wheelHitPoint = _hitPoints select _bestIndex; - _wheelHitPointSelection = _hitPointSelections select _bestIndex; - TRACE_2("wheel found [Backup]",_wheelName,_wheelHitPoint); - }; - }; - }; - - if ((_wheelHitPoint != "") && {_wheelHitPointSelection != ""}) then { - _wheelHitPoints pushBack _wheelHitPoint; - _wheelHitPointSelections pushBack _wheelHitPointSelection; - }; -} forEach _wheels; - -[_wheelHitPoints, _wheelHitPointSelections] diff --git a/addons/repair/functions/fnc_isInRepairFacility.sqf b/addons/repair/functions/fnc_isInRepairFacility.sqf index 51cc5424bbd..74d94c5e75a 100644 --- a/addons/repair/functions/fnc_isInRepairFacility.sqf +++ b/addons/repair/functions/fnc_isInRepairFacility.sqf @@ -33,6 +33,7 @@ private _checkObject = { }; private _fnc_check = { + //IGNORE_PRIVATE_WARNING ["_unit", "_checkObject", "_x"]; 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)} diff --git a/addons/repair/functions/fnc_isNearRepairVehicle.sqf b/addons/repair/functions/fnc_isNearRepairVehicle.sqf index d319273e641..13b089bdd90 100644 --- a/addons/repair/functions/fnc_isNearRepairVehicle.sqf +++ b/addons/repair/functions/fnc_isNearRepairVehicle.sqf @@ -19,6 +19,7 @@ params ["_unit"]; TRACE_1("params",_unit); +//IGNORE_PRIVATE_WARNING ["_unit"]; private _fnc_check = { private _nearObjects = nearestObjects [_unit, ["Air", "LandVehicle", "Slingload_base_F"], 20]; diff --git a/addons/repair/functions/fnc_moduleAddSpareParts.sqf b/addons/repair/functions/fnc_moduleAddSpareParts.sqf index bccccdcc22a..cb6da371d76 100644 --- a/addons/repair/functions/fnc_moduleAddSpareParts.sqf +++ b/addons/repair/functions/fnc_moduleAddSpareParts.sqf @@ -30,8 +30,7 @@ if (!isNull _logic) then { // Add synchronized objects to list { _list pushBack _x; - nil - } count (synchronizedObjects _logic); + } forEach (synchronizedObjects _logic); if (_list isEqualTo []) exitWith {}; @@ -40,6 +39,5 @@ if (!isNull _logic) then { // Add spare parts { [_x, _amount, _part, true] call FUNC(addSpareParts); - false - } count _list; + } forEach _list; }; diff --git a/addons/repair/functions/fnc_normalizeHitPoints.sqf b/addons/repair/functions/fnc_normalizeHitPoints.sqf index 5e61ef8c88a..97f34c22db6 100644 --- a/addons/repair/functions/fnc_normalizeHitPoints.sqf +++ b/addons/repair/functions/fnc_normalizeHitPoints.sqf @@ -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"); }; diff --git a/addons/repair/functions/fnc_patchRemovedWheel.sqf b/addons/repair/functions/fnc_patchRemovedWheel.sqf index b0978013d55..1f1d8e32c68 100644 --- a/addons/repair/functions/fnc_patchRemovedWheel.sqf +++ b/addons/repair/functions/fnc_patchRemovedWheel.sqf @@ -23,7 +23,7 @@ params ["_unit", "_target"]; private _wheelDamage = (damage _target) - GVAR(patchWheelMaximumRepair); [ceil (_wheelDamage / 0.05) * GVAR(patchWheelTime), [_target], {}, {}, LLSTRING(PatchingWheel), { - params ["_args"]; + params ["_args", "_elapsedTime", "_totalTime"]; _args params ["_target"]; private _damage = damage _target; @@ -35,5 +35,4 @@ private _wheelDamage = (damage _target) - GVAR(patchWheelMaximumRepair); _target setDamage _damage; _damage > GVAR(patchWheelMaximumRepair) -}] call ace_common_fnc_progressBar; - +}] call EFUNC(common,progressBar); diff --git a/addons/repair/functions/fnc_repair.sqf b/addons/repair/functions/fnc_repair.sqf index b537963e0ff..ae4038daf0a 100644 --- a/addons/repair/functions/fnc_repair.sqf +++ b/addons/repair/functions/fnc_repair.sqf @@ -21,7 +21,7 @@ params ["_caller", "_target", "_hitPoint", "_className"]; TRACE_4("params",_caller,_target,_hitPoint,_className); -private _config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); +private _config = (configFile >> "ACE_Repair" >> "Actions" >> _className); if !(isClass _config) exitWith {false}; // or go for a default? private _engineerRequired = if (isNumber (_config >> "requiredEngineer")) then { @@ -44,7 +44,7 @@ if ((isEngineOn _target) && {!GVAR(autoShutOffEngineWhenStartingRepair)}) exitWi }; private _items = _config call FUNC(getRepairItems); -if (count _items > 0 && {!([_caller, _items] call FUNC(hasItems))}) exitWith {false}; +if (_items isNotEqualTo [] && {!([_caller, _items] call FUNC(hasItems))}) exitWith {false}; private _return = true; if (getText (_config >> "condition") != "") then { @@ -70,7 +70,7 @@ if (!_return) exitWith {false}; // if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitWith {false}; private _repairLocations = getArray (_config >> "repairLocations"); -if (!("All" in _repairLocations)) then { +if !("All" in _repairLocations) then { private _repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))}; private _repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))}; { @@ -149,10 +149,15 @@ if (_callbackProgress == "") then { // Player Animation private _callerAnim = [getText (_config >> "animationCaller"), getText (_config >> "animationCallerProne")] select (stance _caller == "PRONE"); private _loopAnim = (getNumber (_config >> "loopAnimation")) isEqualTo 1; -_caller setVariable [QGVAR(selectedWeaponOnrepair), currentWeapon _caller]; + +private _currentWeapon = currentWeapon _caller; + +if (_currentWeapon != "") then { + _caller setVariable [QGVAR(selectedWeaponOnrepair), (weaponState _caller) select [0, 3]]; +}; // Cannot use secondairy weapon for animation -if (currentWeapon _caller == secondaryWeapon _caller) then { +if (_currentWeapon == secondaryWeapon _caller) then { _caller selectWeapon (primaryWeapon _caller); }; @@ -172,7 +177,7 @@ if (vehicle _caller == _caller && {_callerAnim != ""}) then { } else { _caller setVariable [QGVAR(repairPrevAnimCaller), animationState _caller]; }; - _caller setVariable [QGVAR(repairCurrentAnimCaller), toLower _callerAnim]; + _caller setVariable [QGVAR(repairCurrentAnimCaller), toLowerANSI _callerAnim]; [_caller, _callerAnim] call EFUNC(common,doAnimation); }; }; diff --git a/addons/repair/functions/fnc_repair_failure.sqf b/addons/repair/functions/fnc_repair_failure.sqf index c305c90b6bf..0c7fcbf9af3 100644 --- a/addons/repair/functions/fnc_repair_failure.sqf +++ b/addons/repair/functions/fnc_repair_failure.sqf @@ -38,9 +38,11 @@ if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) th _caller setVariable [QGVAR(repairCurrentAnimCaller), nil]; _caller setVariable [QGVAR(repairPrevAnimCaller), nil]; -private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]); -if (_weaponSelect != "") then { +private _weaponSelect = _caller getVariable QGVAR(selectedWeaponOnrepair); + +if (!isNil "_weaponSelect") then { _caller selectWeapon _weaponSelect; + _caller setVariable [QGVAR(selectedWeaponOnrepair), nil]; } else { _caller action ["SwitchWeapon", _caller, _caller, 299]; }; @@ -57,7 +59,7 @@ if (_weaponSelect != "") then { // Record specific callback -private _config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); +private _config = (configFile >> "ACE_Repair" >> "Actions" >> _className); private _callback = getText (_config >> "callbackFailure"); if (isNil _callback) then { @@ -65,7 +67,7 @@ if (isNil _callback) then { } else { _callback = missionNamespace getVariable _callback; }; -if (!(_callback isEqualType {})) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; +if !(_callback isEqualType {}) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; _args call _callback; diff --git a/addons/repair/functions/fnc_repair_success.sqf b/addons/repair/functions/fnc_repair_success.sqf index 271d662cd49..94ffd819e31 100644 --- a/addons/repair/functions/fnc_repair_success.sqf +++ b/addons/repair/functions/fnc_repair_success.sqf @@ -38,9 +38,11 @@ if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) th _caller setVariable [QGVAR(repairCurrentAnimCaller), nil]; _caller setVariable [QGVAR(repairPrevAnimCaller), nil]; -private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]); -if (_weaponSelect != "") then { +private _weaponSelect = _caller getVariable QGVAR(selectedWeaponOnrepair); + +if (!isNil "_weaponSelect") then { _caller selectWeapon _weaponSelect; + _caller setVariable [QGVAR(selectedWeaponOnrepair), nil]; } else { _caller action ["SwitchWeapon", _caller, _caller, 299]; }; @@ -52,7 +54,7 @@ if (_weaponSelect != "") then { } forEach _claimedObjects; // Record specific callback -private _config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); +private _config = (configFile >> "ACE_Repair" >> "Actions" >> _className); private _callback = getText (_config >> "callbackSuccess"); if (isNil _callback) then { @@ -60,7 +62,7 @@ if (isNil _callback) then { } else { _callback = missionNamespace getVariable _callback; }; -if (!(_callback isEqualType {})) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; +if !(_callback isEqualType {}) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; _args call _callback; diff --git a/addons/repair/functions/fnc_setHitPointDamage.sqf b/addons/repair/functions/fnc_setHitPointDamage.sqf index bfce0e3f5ef..0a6051e0843 100644 --- a/addons/repair/functions/fnc_setHitPointDamage.sqf +++ b/addons/repair/functions/fnc_setHitPointDamage.sqf @@ -44,7 +44,7 @@ private _hitPointDamageRepaired = 0; //positive for repairs : newSum = (oldSum - if ((!isNil {_vehicle getHit _selectionName}) && {_x != ""}) then { _realHitpointCount = _realHitpointCount + 1; - if ((((toLower _x) find "glass") == -1) && {(getText (configOf _vehicle >> "HitPoints" >> _x >> "depends")) in ["", "0"]}) then { + if (!("glass" in (toLowerANSI _x)) && {(getText (configOf _vehicle >> "HitPoints" >> _x >> "depends")) in ["", "0"]}) then { _hitPointDamageSumOld = _hitPointDamageSumOld + (_allHitPointDamages select _forEachIndex); if (_forEachIndex == _hitPointIndex) then { _hitPointDamageRepaired = (_allHitPointDamages select _forEachIndex) - _hitPointDamage; diff --git a/addons/repair/functions/fnc_useItems.sqf b/addons/repair/functions/fnc_useItems.sqf index edc18bcb16f..784c4a5da2a 100644 --- a/addons/repair/functions/fnc_useItems.sqf +++ b/addons/repair/functions/fnc_useItems.sqf @@ -25,14 +25,14 @@ private _itemsUsedBy = []; if (_x isEqualType []) then { { private _itemUsedInfo = [_unit, _x] call FUNC(useItem); - if (_itemUsedInfo select 0) exitWith { _itemsUsedBy pushback [(_itemUsedInfo select 1), _x]}; + if (_itemUsedInfo select 0) exitWith { _itemsUsedBy pushBack [(_itemUsedInfo select 1), _x]}; } forEach _x; }; // handle required item if (_x isEqualType "") then { private _itemUsedInfo = [_unit, _x] call FUNC(useItem); - if (_itemUsedInfo select 0) exitWith { _itemsUsedBy pushback [(_itemUsedInfo select 1), _x]}; + if (_itemUsedInfo select 0) exitWith { _itemsUsedBy pushBack [(_itemUsedInfo select 1), _x]}; }; } forEach _items; diff --git a/addons/repair/initSettings.inc.sqf b/addons/repair/initSettings.inc.sqf index 26d502e757a..e39bb93a764 100644 --- a/addons/repair/initSettings.inc.sqf +++ b/addons/repair/initSettings.inc.sqf @@ -8,16 +8,14 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; true, true, {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ QGVAR(displayTextOnRepair), "CHECKBOX", [LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], _category, - true, // default value - false, // isGlobal - {[QGVAR(displayTextOnRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // default value ] call CBA_fnc_addSetting; [ @@ -25,8 +23,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(engineerSetting_Repair_name), LSTRING(engineerSetting_Repair_description)], _category, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],1], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_repair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -34,8 +31,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(engineerSetting_Wheel_name), LSTRING(engineerSetting_Wheel_description)], _category, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_wheel), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -69,8 +65,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(repairDamageThreshold_name), LSTRING(repairDamageThreshold_description)], _category, [0, 1, 0.6, 1, true], - true, // isGlobal - {[QGVAR(repairDamageThreshold), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -78,8 +73,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(repairDamageThreshold_Engineer_name), LSTRING(repairDamageThreshold_Engineer_description)], _category, [0, 1, 0.4, 1, true], - true, // isGlobal - {[QGVAR(repairDamageThreshold_engineer), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -87,8 +81,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(consumeItem_ToolKit_name), LSTRING(consumeItem_ToolKit_description)], _category, [[0,1],[ELSTRING(common,No), ELSTRING(common,Yes)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(consumeItem_toolKit), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -105,8 +98,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(fullRepairLocation), LSTRING(fullRepairLocation_description)], _catFullRepair, [[0,1,2,3,4],[LSTRING(useAnywhere), LSTRING(repairVehicleOnly), LSTRING(repairFacilityOnly), LSTRING(vehicleAndFacility), ELSTRING(common,Disabled)],2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(fullRepairLocation), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -114,8 +106,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(engineerSetting_fullRepair_name), LSTRING(engineerSetting_fullRepair_description)], _catFullRepair, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_fullRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -168,8 +159,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(autoShutOffEngineWhenStartingRepair_name), LSTRING(autoShutOffEngineWhenStartingRepair_description)], _category, false, // default value - true, // isGlobal - {[QGVAR(autoShutOffEngineWhenStartingRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ diff --git a/addons/repair/stringtable.xml b/addons/repair/stringtable.xml index 016f2fc78d8..eae73fa671c 100644 --- a/addons/repair/stringtable.xml +++ b/addons/repair/stringtable.xml @@ -280,7 +280,8 @@ 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. @@ -291,6 +292,7 @@ 전체적인 수리를 수행하는 데 걸리는 시간을 수정합니다.\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. @@ -314,7 +316,7 @@ Lugares de reparación completa Luoghi Riparazione Completa Endroits pour réparation complète - 完全修理できる場所 + 完全修理可能な場所 완전수리 구역 完整维修地点 完整維修地點 @@ -1007,7 +1009,7 @@ Jobb középső kerék Правое среднее колесо 右中央輪 - 오른족 가운데 바퀴 + 오른쪽 가운데 바퀴 右中轮 右中輪 @@ -1262,6 +1264,7 @@ タイヤ交換の許可 바퀴 교체 허용 Autoriser le remplacement des roues + Permitir Recambio de Rueda Who can remove and replace wheels? @@ -1287,6 +1290,7 @@ 바퀴 수리 허용 Autoriser le rafistolage des roues Разрешить починить колесо + Permitir Parcheo de Rueda Who can patch wheels? @@ -1297,6 +1301,7 @@ 누가 바퀴를 수리할 수 있습니까? Qui peut rafistoler les roues ? Кто может починить колеса? + Quién puede parchear ruedas? Allow Repair @@ -1957,6 +1962,7 @@ 바퀴 수리 아이템 필요 Exigences pour rafistoler une roue Требования для починки колеса + Requerimientos de Parcheo de Ruedas Items required to patch a wheel. @@ -1967,6 +1973,7 @@ 바퀴를 수리하기 위해 아이템이 필요합니다. Equipements requis pour rafistoler une roue. Предметы, необходимые для починки колеса. + Objetos requeridos para parchear una rueda. Misc Repair Requirements @@ -2142,16 +2149,18 @@ 부품 수리 시간 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 @@ -2162,16 +2171,18 @@ 바퀴 교체 시간 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 @@ -2182,6 +2193,7 @@ 바퀴 수리 Rafistoler la roue Чинить колесо + Parchear Rueda Patching Wheel... @@ -2192,6 +2204,7 @@ 바퀴 수리 중... Rafistolage de la roue... Починка колеса... + Parcheando Rueda... Wheel Patch Time @@ -2202,6 +2215,7 @@ 바퀴 수리 시간 Temps de rafistolage d'une roue Время починки полеса + Tiempo de Parcheo de Rueda Time it takes to patch a wheel by 5%. @@ -2212,6 +2226,7 @@ 바퀴를 5% 수리하는 데 걸리는 시간(초 단위) Durée pour rafistoler une roue de 5%. Время, необходимое для починки колеса, сокращается на 5%. + Tiempo que lleva parchear una rueda por cada 5%. Patch Wheel Threshold @@ -2222,36 +2237,40 @@ 바퀴 수리 한계점 Seuil de rafistolage d'une roue Порог починки колеса + Umbral de Parcheo de Rueda - Maximum level to which a wheel can be patched. - タイヤを補修できる最大の度合い。 - Maksymalny poziom, do którego koło może zostać załatane. + Maximum damage to which a wheel can be patched.\n0% means all damage can be repaired. + タイヤをのダメージ補修できる最大の度合い。/n 0%は、すべてのダメージが修復可能であることを意味します。 + Maksymalny poziom, do którego koło może zostać załatane.\n0% oznacza że każde uszkodzenia mogą być naprawione. Livello di integrità massimo di una ruota rattoppata. - Maximales Level, bis zu dem ein Rad geflickt werden kann. + Maximales Level, bis zu dem ein Rad geflickt werden kann.\n0% bedeutet, dass das Rad vollständig repariert werden kann. 바퀴를 수리할 수 있는 최대 레벨입니다. - Niveau maximum de rafistolage d'une roue. + Niveau maximum de dégâts jusqu'à laquelle une roue peut être réparée.\n0% signifie que la roue peut être reparée entièrement. Максимальный уровень, до которого колесо может быть починено. + 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 @@ -2262,6 +2281,7 @@ 지면 위 Sur le terrain На земле + En el suelo On a vehicle @@ -2272,6 +2292,7 @@ 차량 Sur un véhicule На транспорте + En un vehículo diff --git a/addons/respawn/XEH_postInit.sqf b/addons/respawn/XEH_postInit.sqf index 6c1b1e99611..502f5f729ff 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/functions/fnc_handleKilled.sqf b/addons/respawn/functions/fnc_handleKilled.sqf index 1383561f2ce..eeca8f96e57 100644 --- a/addons/respawn/functions/fnc_handleKilled.sqf +++ b/addons/respawn/functions/fnc_handleKilled.sqf @@ -21,7 +21,7 @@ params ["_unit"]; // Saves the gear when the player! (and only him) is killed if (ACE_player == _unit && {GVAR(SavePreDeathGear)}) then { _unit setVariable [QGVAR(unitGear), [_unit] call CBA_fnc_getLoadout]; - _unit setVariable [QGVAR(activeWeaponAndMuzzle), [currentWeapon _unit, currentMuzzle _unit, currentWeaponMode _unit]]; + _unit setVariable [QGVAR(activeWeaponAndMuzzle), (weaponState _unit) select [0, 3]]; [QGVAR(saveGear), _unit] call CBA_fnc_localEvent; }; diff --git a/addons/respawn/functions/fnc_moduleRallypoint.sqf b/addons/respawn/functions/fnc_moduleRallypoint.sqf index 0af33572016..31ba68f1d6b 100644 --- a/addons/respawn/functions/fnc_moduleRallypoint.sqf +++ b/addons/respawn/functions/fnc_moduleRallypoint.sqf @@ -23,7 +23,6 @@ if !(_activated) exitWith {}; { _x setVariable ["ACE_canMoveRallypoint", true]; - false -} count _units; +} forEach _units; INFO("Rallypoint Module Initialized."); diff --git a/addons/respawn/functions/fnc_moveRallypoint.sqf b/addons/respawn/functions/fnc_moveRallypoint.sqf index 3c4d8b6441c..03c29624735 100644 --- a/addons/respawn/functions/fnc_moveRallypoint.sqf +++ b/addons/respawn/functions/fnc_moveRallypoint.sqf @@ -39,7 +39,7 @@ _position set [2, 0]; [localize LSTRING(Deploy)] call EFUNC(common,displayTextStructured); [{ - params ["_rallypoint", "_unit", "_position"]; + params ["_rallypoint", "_unit", "_position", "_side"]; _rallypoint setPosATL _position; _unit reveal _rallypoint; @@ -49,4 +49,4 @@ _position set [2, 0]; ["ace_rallypointMoved", [_rallypoint, _side, _position]] call CBA_fnc_globalEvent; [localize LSTRING(Deployed)] call EFUNC(common,displayTextStructured); -}, [_rallypoint, _unit, _position], 5] call CBA_fnc_waitAndExecute; +}, [_rallypoint, _unit, _position, _side], 5] call CBA_fnc_waitAndExecute; diff --git a/addons/respawn/functions/fnc_restoreGear.sqf b/addons/respawn/functions/fnc_restoreGear.sqf index afbc7def866..34c5918383f 100644 --- a/addons/respawn/functions/fnc_restoreGear.sqf +++ b/addons/respawn/functions/fnc_restoreGear.sqf @@ -5,7 +5,8 @@ * * Arguments: * 0: Unit - * 1: All Gear based on return value of ACE_common_fnc_getAllGear + * 1: All Gear based on return value of ace_common_fnc_getAllGear + * 2: All weapon info needed for restoring previous weapon status * * Return Value: * None @@ -19,36 +20,12 @@ params ["_unit", "_allGear", "_activeWeaponAndMuzzle"]; TRACE_3("restoreGear",_unit,count _allGear,_activeWeaponAndMuzzle); -// restore all gear +// Restore all gear if (!isNil "_allGear") then { [_unit, _allGear] call CBA_fnc_setLoadout; }; -// restore the last active weapon, muzzle and weaponMode +// Restore the last active weapon, muzzle and weapon mode if (!isNil "_activeWeaponAndMuzzle") then { - // @todo, replace this with CBA_fnc_selectWeapon after next CBA update - _activeWeaponAndMuzzle params ["_activeWeapon", "_activeMuzzle", "_activeWeaponMode"]; - - if ( - (_activeMuzzle != "") && - {_activeMuzzle != _activeWeapon} && - {_activeMuzzle in getArray (configFile >> "CfgWeapons" >> _activeWeapon >> "muzzles")} - ) then { - _unit selectWeapon _activeMuzzle; - } else { - if (_activeWeapon != "") then { - _unit selectWeapon _activeWeapon; - }; - }; - - if (currentWeapon _unit != "") then { - private _index = 0; - - while { - _index < 299 && {currentWeaponMode _unit != _activeWeaponMode} - } do { - _unit action ["SwitchWeapon", _unit, _unit, _index]; - _index = _index + 1; - }; - }; + _unit selectWeapon _activeWeaponAndMuzzle; }; diff --git a/addons/respawn/functions/fnc_updateRallypoint.sqf b/addons/respawn/functions/fnc_updateRallypoint.sqf index a0e14a4ed29..bedc887b3c2 100644 --- a/addons/respawn/functions/fnc_updateRallypoint.sqf +++ b/addons/respawn/functions/fnc_updateRallypoint.sqf @@ -18,7 +18,7 @@ */ params ["_rallypoint", "_side"]; -private _position = param [2, getpos _rallypoint]; +private _position = param [2, getPos _rallypoint]; if (!hasInterface) exitWith {}; diff --git a/addons/respawn/stringtable.xml b/addons/respawn/stringtable.xml index 8ff5ded8ff5..1de77a45d36 100644 --- a/addons/respawn/stringtable.xml +++ b/addons/respawn/stringtable.xml @@ -28,7 +28,7 @@ Kihelyezés 5 másodperc múlva... Dispiegamento in 5 secondi... Será posicionado em 5 segundos... - 5秒後に設置します・・・ + 5秒後に設置が完了します・・・ 5초 후 재투입... 5秒后完成部署... 5秒後完成佈署... @@ -126,7 +126,7 @@ Gyülekezőpont, Nyugat (Bázis) Bod shromáždění Západ (Základna) Ponto de encontro Oeste (Base) - ラリーポイント 同盟軍 (ベース) + ラリーポイント BLUFOR軍 (ベース) 蓝方集合点(基地) 藍方集合點 (基地) 청군 집결지 (기지) @@ -158,7 +158,7 @@ Gyülekezőpont, Független (Bázis) Bod shromáždění Nezávislý (Základna) Ponto de encontro Independente (Base) - ラリーポイント 独立軍 (ベース) + ラリーポイント INDEPENDENT軍 (ベース) 独立方集合点(基地) 獨立方集合點 (基地) 무소속군 집결지 (기지) @@ -174,7 +174,7 @@ Gyülekezőpont, Nyugat Bod shromáždění Západ Ponto de encontro Oeste - ラリーポイント 同盟軍 + ラリーポイント BLUFOR軍 蓝方集合点 藍方集合點 청군 집결지 @@ -206,7 +206,7 @@ Gyülekezőpont, Független Bod shromáždění Nezávislý Ponto de encontro Independente - ラリーポイント 独立軍 + ラリーポイント INDEPENDENT軍 独立方集合点 獨立方集合點 무소속군 집결지 @@ -319,7 +319,7 @@ Ce module vous permet de configurer les fonctionnalités ACE spécifiques à la réapparition des joueurs. Questo modulo ti permette di configurare le funzionalità ACE specifiche dei respawn. Este módulo permite configurar parámetros relacionados con la reaparición - 有効化するとリスポーンへ ACE 機能を設定できます。 + このモジュールを使用すると、リスポーンに ACE 固有の機能を設定できます。 이 모듈은 ACE 재투입의 자세한 설정을 변경할 수 있게 해줍니다. 该模块使您可以设定 ACE 的重生功能 該模塊使您可以設定ACE的重生功能 @@ -335,7 +335,7 @@ Baráti tűz üzenetek Сообщения об огне по своим Messaggi Fuoco Amico - 友軍誤射の布告 + フレンドリーファイア通知 아군 오인사격 메시지 友军误击信息 友軍誤擊訊息 @@ -350,7 +350,7 @@ L'utilisation de ce module fait en sorte qu'à chaque joueur mort par un tir ami, un rapport sera affiché dans le chat, indiquant qui a tué qui. Usando questo modulo nella tua missione farà in modo che ogni uccisione per fuoco amico venga mostrata in forma di messaggio in chat. El usar este módulo, todas las muertes por fuego amigo serán indicadas en el chat. - もし友軍誤射による死者が出た場合は、チャットにてその旨を表示します。 + ミッションでこのモジュールを使用すると、誤射による友軍キルがチャット上のメッセージとして表示されるようになります。 이 모듈은 미션 중 아군 오인사격으로 인한 사망자 발생 시 채팅창에 메시지를 표시해줍니다. 摆放此模块后,当有发生友军误击致死的事件,会显示提示信息在聊天视窗中。 擺放此模塊後,當有發生友軍誤擊致死的事件,會顯示提示訊息在聊天視窗中 @@ -381,8 +381,8 @@ Questo modulo ti consente di usare Rallypoint in missione, a cui ti puoi teleportare rapidamente dalla bandiera in base. Richiede il piazzamento di oggetti speciali in mappa - base e bandiera. Entrambi disponibili nella categoria Vuoto -> ACE Riapparizione Este módulo permite usar puntos de reunión en la misión, a los que pueden teletransportarse las unidades desde la bandera de base. Requiere colocar objetos especiales en el mapa: las banderas de base y de reunión, ambas disponibles en la categoría Vacio-> Reaparición ACE Ce module vous permet d'utiliser des points de ralliement dans les missions, vers lesquels vous pouvez vous téléporter rapidement depuis le drapeau de la base.\nNécessite de placer des objets spéciaux sur la carte - base et drapeau, tous deux disponibles dans la catégorie "Vide -> ACE Réapparition". - ミッションでベースから素早く移動できるラリーポイントを使えるようにします。ゲーム内に専用オブジェクトとなるベースとフラッグを設置している必要があります。両オブジェクトは Empty 下の ACE リスポーンから設置できます。 - 이 모듈은 미션 중에 기지 깃발에서 집결지로 빠르게 텔레포트 시켜주는 역할을 합니다. 지도 상에 기지 및 깃발이 필요합니다. 두 가지 모두 Empty->ACE Respawn 카테고리에서 찾을 수 있습니다. + このモジュールを使用すると、ミッションでラリーポイントを使用できるようになります。ラリーポイントには、ベース旗からすばやくテレポートできます。マップ上に特別なラリー/ベース旗オブジェクトを配置する必要があります。両オブジェクトは道具カテゴリ下の看板サブカテゴリ内、旗から設置できます。 + 이 모듈은 미션 중에 기지 깃발에서 집결지로 빠르게 텔레포트 시켜주는 역할을 합니다. 지도 상에 기지 및 깃발이 필요합니다. 두 가지 모두 비어 있음->ACE 재투입 카테고리에서 찾을 수 있습니다. 摆放此模块后,你将能在任务中部署集合点,使你可以快速往返基地与前线。要使用本功能,请记得放上空物体->ACE 重生里面的基地与旗帜。 擺放此模塊後,你將能在任務中佈署集合點,使你可以快速往返基地與前線。要使用本功能,請記得放上空物件->ACE 重生裡面的基地與旗幟 diff --git a/addons/safemode/CfgEventHandlers.hpp b/addons/safemode/CfgEventHandlers.hpp index 6c29240403a..f6503c2479b 100644 --- a/addons/safemode/CfgEventHandlers.hpp +++ b/addons/safemode/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); diff --git a/addons/safemode/XEH_PREP.hpp b/addons/safemode/XEH_PREP.hpp index 2f23aa02c9e..499ae808670 100644 --- a/addons/safemode/XEH_PREP.hpp +++ b/addons/safemode/XEH_PREP.hpp @@ -1,6 +1,6 @@ - +PREP(getWeaponSafety); PREP(lockSafety); PREP(playChangeFiremodeSound); PREP(setSafeModeVisual); -PREP(unlockSafety); PREP(setWeaponSafety); +PREP(unlockSafety); diff --git a/addons/safemode/XEH_postInit.sqf b/addons/safemode/XEH_postInit.sqf index db922f9b35d..fa6649aa9f1 100644 --- a/addons/safemode/XEH_postInit.sqf +++ b/addons/safemode/XEH_postInit.sqf @@ -4,18 +4,42 @@ if (!hasInterface) exitWith {}; -["ACE3 Weapons", QGVAR(safeMode), localize LSTRING(SafeMode), { +["ACE3 Weapons", QGVAR(safeMode), LLSTRING(SafeMode), { // Conditions: canInteract if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + + (weaponState ACE_player) params ["_currentWeapon", "_currentMuzzle"]; + // Conditions: specific - if !([ACE_player] call CBA_fnc_canUseWeapon && {currentWeapon ACE_player != binocular ACE_player} && {currentWeapon ACE_player != ""}) exitWith {false}; + if !(ACE_player call CBA_fnc_canUseWeapon && {_currentWeapon != ""} && {_currentWeapon != binocular ACE_player}) exitWith {false}; + + // Statement: Toggle weapon safety + [ACE_player, _currentWeapon, _currentMuzzle] call FUNC(lockSafety); - // Statement - [ACE_player, currentWeapon ACE_player, currentMuzzle ACE_player] call FUNC(lockSafety); true }, {false}, [DIK_GRAVE, [false, true, false]], false] call CBA_fnc_addKeybind; ["unit", { - private _weaponSafe = currentWeapon ACE_player in (ACE_player getVariable [QGVAR(safedWeapons), []]); - [!_weaponSafe] call FUNC(setSafeModeVisual); + (weaponState ACE_player) params ["_currentWeapon", "_currentMuzzle"]; + + private _weaponSafe = [ACE_player, _currentWeapon, _currentMuzzle] call FUNC(getWeaponSafety); + + // Player HUD + !_weaponSafe call FUNC(setSafeModeVisual); }] call CBA_fnc_addPlayerEventHandler; + +// Variables are transferred from corpse to new body and EH above triggers on respawn, which desyncs safeties +// Therefore, clear variables and remove mouse button input blocking upon respawn +[QUOTE(ADDON), "Respawn", { + params ["_unit"]; + + _unit setVariable [QGVAR(safedWeapons), nil]; + + private _ehID = _unit getVariable QGVAR(actionID); + + if (isNil "_ehID") exitWith {}; + + [_unit, "DefaultAction", _ehID] call EFUNC(common,removeActionEventHandler); + + _unit setVariable [QGVAR(actionID), nil]; +}] call EFUNC(common,addPlayerEH); diff --git a/addons/safemode/functions/fnc_getWeaponSafety.sqf b/addons/safemode/functions/fnc_getWeaponSafety.sqf new file mode 100644 index 00000000000..b171d974e4d --- /dev/null +++ b/addons/safemode/functions/fnc_getWeaponSafety.sqf @@ -0,0 +1,45 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Getter for weapon safety state. + * + * Arguments: + * 0: Unit + * 1: Weapon + * 2: Muzzle (default: current muzzle of weapon) + * + * Return Value: + * Safety status + * + * Example: + * [ACE_player, currentWeapon ACE_player] call ace_safemode_fnc_getWeaponSafety + * + * Public: Yes + */ + +params [ + ["_unit", objNull, [objNull]], + ["_weapon", "", [""]], + ["_muzzle", nil, [""]] +]; + +if (_weapon == "" || {!(_unit hasWeapon _weapon)}) exitWith {false}; + +// Check if weapon is a binocular +if ((_weapon call EFUNC(common,getItemType)) select 1 == "binocular") exitWith {false}; + +// Check for invalid muzzles +_muzzle = if (isNil "_muzzle") then { + // Get current weapon muzzle if not defined + (_unit weaponState _weapon) select 1 +} else { + // Get config case muzzle names + private _muzzles = _weapon call EFUNC(common,getWeaponMuzzles); + + _muzzles param [_muzzles findIf {_x == _muzzle}, ""] +}; + +// Weapon is not available +if (_muzzle == "") exitWith {false}; + +_muzzle in ((_unit getVariable [QGVAR(safedWeapons), createHashMap]) getOrDefault [_weapon, createHashMap]) // return diff --git a/addons/safemode/functions/fnc_lockSafety.sqf b/addons/safemode/functions/fnc_lockSafety.sqf index 6c617c18989..28adb42df91 100644 --- a/addons/safemode/functions/fnc_lockSafety.sqf +++ b/addons/safemode/functions/fnc_lockSafety.sqf @@ -1,13 +1,13 @@ #include "..\script_component.hpp" /* - * Author: commy2 - * Put weapon on safety, or take it off safety if safety is already put on. + * Author: commy2, johnb43 + * Puts weapon on safety, or take it off safety if safety is already put on. * * Arguments: * 0: Unit * 1: Weapon * 2: Muzzle - * 3: Show hint + * 3: Show hint (default: true) * * Return Value: * None @@ -18,67 +18,74 @@ * Public: No */ -params ["_unit", "_weapon", "_muzzle", ["_hint", true, [true]]]; +params ["_unit", "_weapon", "_muzzle", ["_hint", true]]; -private _safedWeapons = _unit getVariable [QGVAR(safedWeapons), []]; +private _safedWeapons = _unit getVariable QGVAR(safedWeapons); -if (_weapon in _safedWeapons) exitWith { - _this call FUNC(unlockSafety); +if (isNil "_safedWeapons") then { + _safedWeapons = createHashMap; + + _unit setVariable [QGVAR(safedWeapons), _safedWeapons]; +}; + +// See if the current weapon has locked muzzles +private _safedWeaponMuzzles = _safedWeapons getOrDefault [_weapon, createHashMap, true]; + +// If muzzle is locked, unlock it (toggle) +if (_muzzle in _safedWeaponMuzzles) exitWith { + [_unit, _weapon, _muzzle, _hint] call FUNC(unlockSafety); }; -_safedWeapons pushBack _weapon; +private _firemode = (_unit weaponState _muzzle) select 2; -_unit setVariable [QGVAR(safedWeapons), _safedWeapons]; +// This syntax of selectWeapon doesn't mess with gun lights and lasers +_unit selectWeapon [_weapon, _muzzle, _firemode]; -if (_unit getVariable [QGVAR(actionID), -1] == -1) then { +// Store new muzzle & firemode +_safedWeaponMuzzles set [_muzzle, _firemode]; + +// Lock muzzle +if (isNil {_unit getVariable QGVAR(actionID)}) then { _unit setVariable [QGVAR(actionID), [ _unit, "DefaultAction", { + params ["", "_unit"]; + if ( - [_this select 1] call CBA_fnc_canUseWeapon - && { - if (currentMuzzle (_this select 1) in ((_this select 1) getVariable [QGVAR(safedWeapons), []])) then { - if (inputAction "nextWeapon" > 0) exitWith { - [_this select 1, currentWeapon (_this select 1), currentMuzzle (_this select 1)] call FUNC(unlockSafety); + _unit call CBA_fnc_canUseWeapon && { + (weaponState _unit) params ["_currentWeapon", "_currentMuzzle"]; + + // Block firing the muzzle in safe mode + if (_currentMuzzle in ((_unit getVariable [QGVAR(safedWeapons), createHashMap]) getOrDefault [_currentWeapon, createHashMap])) then { + if (inputAction "nextWeapon" > 0 || {inputAction "prevWeapon" > 0}) exitWith { + [_unit, _currentWeapon, _currentMuzzle] call FUNC(unlockSafety); + false }; + true - } else {false} + } else { + false + } } ) then { - // player hud - [false] call FUNC(setSafeModeVisual); + // Player HUD + false call FUNC(setSafeModeVisual); + true } else { - // player hud - [true] call FUNC(setSafeModeVisual); + // Player HUD + true call FUNC(setSafeModeVisual); + false }; }, {} ] call EFUNC(common,addActionEventHandler)]; }; -if (_muzzle isEqualType "") then { - private _laserEnabled = _unit isIRLaserOn _weapon || {_unit isFlashlightOn _weapon}; - - _unit selectWeapon _muzzle; - - if ( - _laserEnabled - && { - _muzzle == primaryWeapon _unit // prevent UGL switch - || {"" == primaryWeapon _unit} // Arma switches to primary weapon if exists - } - ) then { - {_unit action [_x, _unit]} forEach ["GunLightOn", "IRLaserOn"]; - }; -}; - -// play fire mode selector sound +// Play fire mode selector sound [_unit, _weapon, _muzzle] call FUNC(playChangeFiremodeSound); -// show info box unless disabled +// Show info box unless disabled if (_hint) then { - private _picture = getText (configFile >> "CfgWeapons" >> _weapon >> "picture"); - [localize LSTRING(PutOnSafety), _picture] call EFUNC(common,displayTextPicture); + [LLSTRING(PutOnSafety), getText (configFile >> "CfgWeapons" >> _weapon >> "picture")] call EFUNC(common,displayTextPicture); }; - diff --git a/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf b/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf index 30c4dfd59cc..1edc2363340 100644 --- a/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf +++ b/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: commy2 - * Play weapon firemode change sound. + * Plays weapon firemode change sound. * * Arguments: * 0: Unit @@ -21,21 +21,23 @@ params ["_unit", "_weapon"]; private _sound = getArray (configFile >> "CfgWeapons" >> _weapon >> "changeFiremodeSound"); if (_sound isEqualTo []) exitWith { - playSound "ACE_Sound_Click"; + playSoundUI ["ACE_Sound_Click"]; }; -// get position where to play the sound (position of the weapon) -private _position = _unit modelToWorldVisualWorld (_unit selectionPosition "RightHand"); - -_sound params ["_filename", ["_volume", 1], ["_soundPitch", 1], ["_distance", 0]]; +_sound params [["_filename", ""], ["_volume", 1], ["_soundPitch", 1], ["_distance", 0]]; if (_filename == "") exitWith { - playSound "ACE_Sound_Click"; + playSoundUI ["ACE_Sound_Click"]; }; -// add file extension .wss as default -if !(toLower (_filename select [count _filename - 4]) in [".wav", ".ogg", ".wss"]) then { +// Add file extension .wss as default +if !(toLowerANSI (_filename select [count _filename - 4]) in [".wav", ".ogg", ".wss"]) then { _filename = format ["%1.wss", _filename]; }; -playSound3D [_filename, objNull, false, _position, _volume, _soundPitch, _distance]; +// Get position where to play the sound (position of the weapon) +private _position = _unit modelToWorldVisualWorld (_unit selectionPosition "RightHand"); + +playSound3D [_filename, objNull, insideBuilding _unit >= 0.5, _position, _volume, _soundPitch, _distance]; + +nil // return diff --git a/addons/safemode/functions/fnc_setSafeModeVisual.sqf b/addons/safemode/functions/fnc_setSafeModeVisual.sqf index d62a542b9d7..12b7f864ef3 100644 --- a/addons/safemode/functions/fnc_setSafeModeVisual.sqf +++ b/addons/safemode/functions/fnc_setSafeModeVisual.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: commy2 - * Show firemode indicator, representing safety lock + * Shows firemode indicator, representing safety lock. * * Arguments: * 0: Show firemode @@ -10,7 +10,7 @@ * None * * Example: - * [true] call ace_safemode_fnc_setSafeModeVisual + * true call ace_safemode_fnc_setSafeModeVisual * * Public: No */ @@ -27,8 +27,8 @@ if (_show) then { private _config = configFile >> "RscInGameUI" >> "RscUnitInfoSoldier" >> "WeaponInfoControlsGroupLeft" >> "controls" >> "CA_ModeTexture"; _control ctrlSetPosition [getNumber (_config >> "x"), getNumber (_config >> "y"), getNumber (_config >> "w"), getNumber (_config >> "h")]; - _control ctrlCommit 0; } else { _control ctrlSetPosition [0, 0, 0, 0]; - _control ctrlCommit 0; }; + +_control ctrlCommit 0; diff --git a/addons/safemode/functions/fnc_setWeaponSafety.sqf b/addons/safemode/functions/fnc_setWeaponSafety.sqf index d80e1d8c38f..3db0033bf8f 100644 --- a/addons/safemode/functions/fnc_setWeaponSafety.sqf +++ b/addons/safemode/functions/fnc_setWeaponSafety.sqf @@ -1,13 +1,14 @@ #include "..\script_component.hpp" /* - * Author: Brostrom.A - * Safe or unsafe the given weapon based on weapon state; locked or unlocked. + * Author: Brostrom.A, johnb43 + * Lock or unlock the given weapon based on weapon state. * * Arguments: * 0: Unit * 1: Weapon * 2: State * 3: Show hint (default: true) + * 4: Muzzle (default: current muzzle of weapon) * * Return Value: * None @@ -22,17 +23,31 @@ params [ ["_unit", objNull, [objNull]], ["_weapon", "", [""]], ["_state", true, [true]], - ["_hint", true, [true]] + ["_hint", true, [true]], + ["_muzzle", nil, [""]] ]; -if (_weapon == "") exitWith {}; +// Don't allow to set weapon safety if unit doesn't have one (but allow removing safety, in case unit doesn't have weapon anymore) +if (_weapon == "" || {_state && {!(_unit hasWeapon _weapon)}}) exitWith {}; -private _safedWeapons = _unit getVariable [QGVAR(safedWeapons), []]; +// Check if weapon is a binocular +if ((_weapon call EFUNC(common,getItemType)) select 1 == "binocular") exitWith {}; -_weapon = configName (configFile >> "CfgWeapons" >> _weapon); +// Check for invalid muzzles +_muzzle = if (isNil "_muzzle") then { + // Get current weapon muzzle if not defined + (_unit weaponState _weapon) select 1 +} else { + // Get config case muzzle names + private _muzzles = _weapon call EFUNC(common,getWeaponMuzzles); -private _muzzle = currentMuzzle _unit; - -if (_state isNotEqualTo (_weapon in _safedWeapons)) then { - [_unit, _weapon, _muzzle, _hint] call FUNC(lockSafety); + _muzzles param [_muzzles findIf {_x == _muzzle}, ""] }; + +// Weapon is not available +if (_muzzle == "") exitWith {}; + +// If the weapon is already in the desired state, don't do anything +if (_state == (_muzzle in ((_unit getVariable [QGVAR(safedWeapons), createHashMap]) getOrDefault [_weapon, createHashMap]))) exitWith {}; + +[_unit, _weapon, _muzzle, _hint] call FUNC(lockSafety); diff --git a/addons/safemode/functions/fnc_unlockSafety.sqf b/addons/safemode/functions/fnc_unlockSafety.sqf index 8afc6802c14..97716025dc6 100644 --- a/addons/safemode/functions/fnc_unlockSafety.sqf +++ b/addons/safemode/functions/fnc_unlockSafety.sqf @@ -1,13 +1,13 @@ #include "..\script_component.hpp" /* - * Author: commy2 - * Take weapon of safety lock. + * Author: commy2, johnb43 + * Takes the weapon safety lock off. * * Arguments: * 0: Unit * 1: Weapon * 2: Muzzle - * 3: Show hint + * 3: Show hint (default: true) * * Return Value: * None @@ -18,68 +18,37 @@ * Public: No */ -params ["_unit", "_weapon", "_muzzle", ["_hint", true, [true]]]; +params ["_unit", "_weapon", "_muzzle", ["_hint", true]]; -private _safedWeapons = _unit getVariable [QGVAR(safedWeapons), []]; -_safedWeapons deleteAt (_safedWeapons find _weapon); +private _safedWeaponMuzzles = (_unit getVariable QGVAR(safedWeapons)) get _weapon; +private _firemode = _safedWeaponMuzzles deleteAt _muzzle; -_unit setVariable [QGVAR(safedWeapons), _safedWeapons]; +// Remove action if all weapons have removed their safeties +if (_safedWeaponMuzzles isEqualTo createHashMap) then { + (_unit getVariable QGVAR(safedWeapons)) deleteAt _weapon; -// remove action if all weapons have put their safety on -if (_safedWeapons isEqualTo []) then { - [_unit, "DefaultAction", _unit getVariable [QGVAR(actionID), -1]] call EFUNC(common,removeActionEventHandler); - _unit setVariable [QGVAR(actionID), -1]; -}; - -private _laserEnabled = _unit isIRLaserOn _weapon || {_unit isFlashlightOn _weapon}; + private _ehID = _unit getVariable QGVAR(actionID); -_unit selectWeapon _muzzle; + if (!isNil "_ehID" && {(_unit getVariable QGVAR(safedWeapons)) isEqualTo createHashMap}) then { + [_unit, "DefaultAction", _ehID] call EFUNC(common,removeActionEventHandler); -if ( - _laserEnabled - && { - _muzzle == primaryWeapon _unit // prevent UGL switch - || {"" == primaryWeapon _unit} // Arma switches to primary weapon if exists - } -) then { - {_unit action [_x, _unit]} forEach ["GunLightOn", "IRLaserOn"]; + _unit setVariable [QGVAR(actionID), nil]; + }; }; -if (inputAction "nextWeapon" > 0) then { - // switch to the last mode to roll over to first after the default nextWeapon action - // get weapon modes - private _modes = []; - { - if (getNumber (configFile >> "CfgWeapons" >> _weapon >> _x >> "showToPlayer") == 1) then { - _modes pushBack _x; - }; - if (_x == "this") then { - _modes pushBack _weapon; - }; - nil - } count getArray (configFile >> "CfgWeapons" >> _weapon >> "modes"); +// Let engine handle switching to next firemode/muzzle +if (inputAction "nextWeapon" == 0 && {inputAction "prevWeapon" == 0}) then { + // This syntax of selectWeapon doesn't mess with gun lights and lasers + _unit selectWeapon [_weapon, _muzzle, _firemode]; - // select last mode - private _mode = _modes select (count _modes - 1); - - // switch to last mode - private _index = 0; - while { - _index < 299 && {currentMuzzle _unit != _weapon || {currentWeaponMode _unit != _mode}} - } do { - _unit action ["SwitchWeapon", _unit, _unit, _index]; - _index = _index + 1; - }; -} else { - // play fire mode selector sound + // Play fire mode selector sound [_unit, _weapon, _muzzle] call FUNC(playChangeFiremodeSound); }; -// player hud -[true] call FUNC(setSafeModeVisual); +// Player HUD +true call FUNC(setSafeModeVisual); -// show info box unless disabled +// Show info box unless disabled if (_hint) then { - private _picture = getText (configFile >> "CfgWeapons" >> _weapon >> "picture"); - [localize LSTRING(TookOffSafety), _picture] call EFUNC(common,displayTextPicture); + [LLSTRING(TookOffSafety), getText (configFile >> "CfgWeapons" >> _weapon >> "picture")] call EFUNC(common,displayTextPicture); }; diff --git a/addons/sandbag/XEH_postInit.sqf b/addons/sandbag/XEH_postInit.sqf index a03f6076a19..24122aed8eb 100644 --- a/addons/sandbag/XEH_postInit.sqf +++ b/addons/sandbag/XEH_postInit.sqf @@ -15,11 +15,11 @@ GVAR(deployDirection) = 0; ["ace_interactMenuOpened", {[ACE_player] call FUNC(handleInteractMenuOpened)}] call CBA_fnc_addEventHandler; // Cancel deploy on player change. This does work when returning to lobby, but not when hard disconnecting. -["unit", {_this call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; -["loadout", {_this call FUNC(handlePlayerInventoryChanged)}] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +["loadout", LINKFUNC(handlePlayerInventoryChanged)] call CBA_fnc_addPlayerEventHandler; ["vehicle", {[ACE_player, objNull] call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; // handle waking up dragged unit and falling unconscious while dragging -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; +["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; //@todo Captivity? diff --git a/addons/sandbag/functions/fnc_deploy.sqf b/addons/sandbag/functions/fnc_deploy.sqf index 1ef84851128..31818907489 100644 --- a/addons/sandbag/functions/fnc_deploy.sqf +++ b/addons/sandbag/functions/fnc_deploy.sqf @@ -18,8 +18,8 @@ params ["_unit"]; // prevent the placing unit from running -[_unit, "forceWalk", "ACE_Sandbag", true] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", "ACE_Sandbag", true] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); // create the sandbag private _sandBag = createVehicle ["ACE_SandbagObject_NoGeo", [0, 0, 0], [], 0, "NONE"]; diff --git a/addons/sandbag/functions/fnc_deployCancel.sqf b/addons/sandbag/functions/fnc_deployCancel.sqf index aa2c2419a39..bccae637e5e 100644 --- a/addons/sandbag/functions/fnc_deployCancel.sqf +++ b/addons/sandbag/functions/fnc_deployCancel.sqf @@ -21,8 +21,8 @@ params ["_unit", "_key"]; if (_key != 1 || {GVAR(deployPFH) == -1}) exitWith {}; // enable running again -[_unit, "forceWalk", "ACE_Sandbag", false] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", "ACE_Sandbag", false] call EFUNC(common,statusEffect_set); +[_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(sandBag); diff --git a/addons/sandbag/functions/fnc_deployConfirm.sqf b/addons/sandbag/functions/fnc_deployConfirm.sqf index 20b821b3b53..ef2aafd97c7 100644 --- a/addons/sandbag/functions/fnc_deployConfirm.sqf +++ b/addons/sandbag/functions/fnc_deployConfirm.sqf @@ -18,8 +18,8 @@ params ["_unit"]; // enable running again -[_unit, "forceWalk", "ACE_Sandbag", false] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", "ACE_Sandbag", false] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); // remove sandbag from inventory _unit removeItem "ACE_Sandbag_empty"; diff --git a/addons/sandbag/functions/fnc_pickup.sqf b/addons/sandbag/functions/fnc_pickup.sqf index 7c21656ca07..07a6285e685 100644 --- a/addons/sandbag/functions/fnc_pickup.sqf +++ b/addons/sandbag/functions/fnc_pickup.sqf @@ -29,12 +29,12 @@ _unit setVariable [QGVAR(isUsingSandbag), true]; if (isNull _sandbag) exitWith {}; - deletevehicle _sandbag; + deleteVehicle _sandbag; // 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/scopes/RscTitles.hpp b/addons/scopes/RscTitles.hpp index c108caaf4d8..5b3002599ea 100644 --- a/addons/scopes/RscTitles.hpp +++ b/addons/scopes/RscTitles.hpp @@ -26,10 +26,10 @@ 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 { idc = 12; @@ -43,10 +43,10 @@ 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 { idc = 13; @@ -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_postInit.sqf b/addons/scopes/XEH_postInit.sqf index 8c221a46514..997fe8d6dd2 100644 --- a/addons/scopes/XEH_postInit.sqf +++ b/addons/scopes/XEH_postInit.sqf @@ -9,6 +9,9 @@ if (!hasInterface) exitWith {}; +// Add keybinds +#include "initKeybinds.inc.sqf" + GVAR(Optics) = ["", "", ""]; GVAR(Guns) = ["", "", ""]; GVAR(canAdjustElevation) = [false, false, false]; @@ -16,15 +19,17 @@ GVAR(canAdjustWindage) = [false, false, false]; GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; ["CBA_settingsInitialized", { - if (!GVAR(enabled)) exitWith {}; - if (GVAR(deduceBarometricPressureFromTerrainAltitude)) then { - GVAR(zeroReferenceBarometricPressure) = 1013.25 * (1 - (0.0065 * EGVAR(common,mapAltitude)) / 288.15) ^ 5.255754495; + // Overwrite setting if automatic pressure deduction is wanted + if (isServer && GVAR(deduceBarometricPressureFromTerrainAltitude)) then { + private _referencePressure = 1013.25 * (1 - (0.0065 * EGVAR(common,mapAltitude)) / 288.15) ^ 5.255754495; + + [QGVAR(zeroReferenceBarometricPressure), _referencePressure, 2, "server"] call CBA_settings_fnc_set; }; // Check inventory when it changes - ["loadout", FUNC(inventoryCheck), true] call CBA_fnc_addPlayerEventHandler; + ["loadout", LINKFUNC(inventoryCheck), true] call CBA_fnc_addPlayerEventHandler; // Instantly hide knobs when scoping in ["cameraView", { @@ -41,106 +46,7 @@ GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; }; }] call CBA_fnc_addPlayerEventHandler; - // Add keybinds - ["ACE3 Scope Adjustment", QGVAR(AdjustUpMinor), localize LSTRING(AdjustUpMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, ELEVATION_UP, MINOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [201, [false, false, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustDownMinor), localize LSTRING(AdjustDownMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, ELEVATION_DOWN, MINOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [209, [false, false, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustLeftMinor), localize LSTRING(AdjustLeftMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, WINDAGE_LEFT, MINOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [209, [false, true, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustRightMinor), localize LSTRING(AdjustRightMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, WINDAGE_RIGHT, MINOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [201, [false, true, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustUpMajor), localize LSTRING(AdjustUpMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, ELEVATION_UP, MAJOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [201, [true, false, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustDownMajor), localize LSTRING(AdjustDownMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, ELEVATION_DOWN, MAJOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [209, [true, false, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustLeftMajor), localize LSTRING(AdjustLeftMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, WINDAGE_LEFT, MAJOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [209, [true, true, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustRightMajor), localize LSTRING(AdjustRightMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, WINDAGE_RIGHT, MAJOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [201, [true, true, false]], true] call CBA_fnc_addKeybind; - - // Register fire event handler - ["ace_firedPlayer", DFUNC(firedEH)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerNonLocal", DFUNC(firedEH)] call CBA_fnc_addEventHandler; - + ["ace_firedPlayer", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerNonLocal", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/scopes/functions/fnc_adjustScope.sqf b/addons/scopes/functions/fnc_adjustScope.sqf index bd2d2d1da67..a760065cdec 100644 --- a/addons/scopes/functions/fnc_adjustScope.sqf +++ b/addons/scopes/functions/fnc_adjustScope.sqf @@ -17,12 +17,13 @@ * Public: No */ +if (!GVAR(enabled)) exitWith {false}; + params ["_unit", "_turretAndDirection", "_majorStep"]; TRACE_3("adjustScope",_unit,_turretAndDirection,_majorStep); -if (!(_unit isKindOf "Man")) exitWith {false}; +if !(_unit isKindOf "Man") exitWith {false}; if (currentMuzzle _unit != currentWeapon _unit) exitWith {false}; -if (!GVAR(enabled)) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; diff --git a/addons/scopes/functions/fnc_adjustZero.sqf b/addons/scopes/functions/fnc_adjustZero.sqf index 1a130840ede..44e64b7674b 100644 --- a/addons/scopes/functions/fnc_adjustZero.sqf +++ b/addons/scopes/functions/fnc_adjustZero.sqf @@ -17,7 +17,7 @@ params ["_unit"]; -if (vehicle _unit != _unit) exitWith {false}; +if (!isNull objectParent _unit) exitWith {false}; private _weaponClass = currentWeapon _unit; private _weaponIndex = [_unit, _weaponClass] call EFUNC(common,getWeaponIndex); diff --git a/addons/scopes/functions/fnc_applyScopeAdjustment.sqf b/addons/scopes/functions/fnc_applyScopeAdjustment.sqf index b813dde9ef8..d356343099d 100644 --- a/addons/scopes/functions/fnc_applyScopeAdjustment.sqf +++ b/addons/scopes/functions/fnc_applyScopeAdjustment.sqf @@ -43,6 +43,10 @@ if (cameraView == "GUNNER") then { _yaw = _yaw + _windageDifference; [_unit, _pitch, _bank, _yaw] call EFUNC(common,setPitchBankYaw); }; + + if (GVAR(inScopeAdjustment)) then { + [] call FUNC(showZeroing); + }; } else { [] call FUNC(showZeroing); }; diff --git a/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf b/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf index 6cb53c3898c..670a119f839 100644 --- a/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf +++ b/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf @@ -4,24 +4,28 @@ * Calculates the zero angle correction for the new zero range based on current zero range and bore height (distance between bore- and sight axis) * * Arguments: - * 0: Zero range - * 1: Bore height - * 2: Weapon - * 3: Ammo - * 4: Magazine - * 5: Advanced Ballistics enabled? + * 0: Old Zero range + * 1: New Zero range + * 2: Bore height + * 3: Weapon + * 4: Ammo + * 5: Magazine + * 6: Advanced Ballistics enabled? * * Return Value: * zeroAngleCorrection * * Example: - * [5, 6, gun, ammo, magazine, true] call ace_scopes_fnc_calculateZeroAngleCorrection + * [5, 6, 7, gun, ammo, magazine, true] call ace_scopes_fnc_calculateZeroAngleCorrection * * Public: No */ params ["_oldZeroRange", "_newZeroRange", "_boreHeight"/*in cm*/, "_weapon", "_ammo", "_magazine", "_advancedBallistics"]; +// When FFV from vehicles currentZeroing will report 0 so just bail +if (_oldZeroRange <= 0) exitWith { 0 }; + private _airFriction = getNumber (configFile >> "CfgAmmo" >> _ammo >> "airFriction"); private _initSpeed = getNumber(configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); private _initSpeedCoef = getNumber(configFile >> "CfgWeapons" >> _weapon >> "initSpeed"); @@ -32,25 +36,21 @@ if (_initSpeedCoef < 0) then { _initSpeed = _initSpeed * (-1 * _initSpeedCoef); }; -private _zeroAngle = "ace_advanced_ballistics" callExtension format ["replicateVanillaZero:%1:%2:%3", _oldZeroRange, _initSpeed, _airFriction]; -private _vanillaZero = parseNumber _zeroAngle; +private _vanillaZero = parseNumber (("ace" callExtension ["ballistics:replicate_vanilla_zero", [_oldZeroRange, _initSpeed, _airFriction]]) select 0); #ifdef DISABLE_DISPERSION _vanillaZero = 0; #endif -private _trueZero = if (!_advancedBallistics) then { - _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _newZeroRange, _initSpeed, _airFriction, _boreHeight]; - (parseNumber _zeroAngle) -} else { +private _trueZero = if (_advancedBallistics) then { // Get Weapon and Ammo Configurations private _AmmoCacheEntry = uiNamespace getVariable format[QEGVAR(advanced_ballistics,%1), _ammo]; if (isNil "_AmmoCacheEntry") then { - _AmmoCacheEntry = _ammo call EFUNC(advanced_ballistics,readAmmoDataFromConfig); + _AmmoCacheEntry = _ammo call EFUNC(advanced_ballistics,readAmmoDataFromConfig); }; private _WeaponCacheEntry = uiNamespace getVariable format[QEGVAR(advanced_ballistics,%1), _weapon]; if (isNil "_WeaponCacheEntry") then { - _WeaponCacheEntry = _weapon call EFUNC(advanced_ballistics,readWeaponDataFromConfig); + _WeaponCacheEntry = _weapon call EFUNC(advanced_ballistics,readWeaponDataFromConfig); }; _AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleVelocityVariationSD"]; @@ -66,8 +66,21 @@ private _trueZero = if (!_advancedBallistics) then { _initSpeed = _initSpeed + _ammoTemperatureVelocityShift; }; - _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _newZeroRange, _initSpeed, _boreHeight, GVAR(zeroReferenceTemperature), GVAR(zeroReferenceBarometricPressure), GVAR(zeroReferenceHumidity), _ballisticCoefficients select 0, _dragModel, _atmosphereModel]; - (parseNumber _zeroAngle) + parseNumber ( + ("ace" callExtension ["ballistics:zero_advanced", [ + _newZeroRange, + _initSpeed, + _boreHeight, + GVAR(zeroReferenceTemperature), + GVAR(zeroReferenceBarometricPressure), + GVAR(zeroReferenceHumidity), + _ballisticCoefficients select 0, + _dragModel, + _atmosphereModel + ]]) select 0 + ) +} else { + parseNumber (("ace" callExtension ["ballistics:zero_vanilla", [_newZeroRange, _initSpeed, _airFriction, _boreHeight]]) select 0) }; private _zeroAngleCorrection = _trueZero - _vanillaZero; diff --git a/addons/scopes/functions/fnc_canAdjustZero.sqf b/addons/scopes/functions/fnc_canAdjustZero.sqf index 58a88074804..1461d91d204 100644 --- a/addons/scopes/functions/fnc_canAdjustZero.sqf +++ b/addons/scopes/functions/fnc_canAdjustZero.sqf @@ -18,9 +18,9 @@ params ["_unit"]; if (cameraView == "GUNNER") exitWith {false}; -if (vehicle _unit != _unit) exitWith {false}; +if (!isNull objectParent _unit) exitWith {false}; if (GVAR(simplifiedZeroing)) exitWith {false}; -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {false}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; diff --git a/addons/scopes/functions/fnc_canResetZero.sqf b/addons/scopes/functions/fnc_canResetZero.sqf index cd3f1fb4ebd..92bbda1a4dd 100644 --- a/addons/scopes/functions/fnc_canResetZero.sqf +++ b/addons/scopes/functions/fnc_canResetZero.sqf @@ -18,8 +18,8 @@ params ["_unit"]; if (cameraView == "GUNNER") exitWith {false}; -if (vehicle _unit != _unit) exitWith {false}; -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {false}; +if (!isNull objectParent _unit) exitWith {false}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; diff --git a/addons/scopes/functions/fnc_firedEH.sqf b/addons/scopes/functions/fnc_firedEH.sqf index f1b8e91bf4e..5ff78a44b70 100644 --- a/addons/scopes/functions/fnc_firedEH.sqf +++ b/addons/scopes/functions/fnc_firedEH.sqf @@ -18,7 +18,7 @@ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); -if (!(_ammo isKindOf "BulletBase")) exitWith {}; +if !(_ammo isKindOf "BulletBase") exitWith {}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {}; diff --git a/addons/scopes/functions/fnc_getCurrentZeroRange.sqf b/addons/scopes/functions/fnc_getCurrentZeroRange.sqf index 001e5e8b79e..d1bc3b7790d 100644 --- a/addons/scopes/functions/fnc_getCurrentZeroRange.sqf +++ b/addons/scopes/functions/fnc_getCurrentZeroRange.sqf @@ -17,12 +17,12 @@ params ["_unit"]; -if (!GVAR(enabled)) exitWith { currentZeroing _unit }; +if (!GVAR(enabled)) exitWith {currentZeroing _unit}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith { currentZeroing _unit }; if (GVAR(simplifiedZeroing)) exitWith { - if (!(GVAR(canAdjustElevation) select _weaponIndex)) exitWith { currentZeroing _unit }; + if !(GVAR(canAdjustElevation) select _weaponIndex) exitWith {currentZeroing _unit}; private _adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; ((_adjustment select _weaponIndex) select 0) }; diff --git a/addons/scopes/functions/fnc_getOptics.sqf b/addons/scopes/functions/fnc_getOptics.sqf index 6be1952b6f8..c52b032008c 100644 --- a/addons/scopes/functions/fnc_getOptics.sqf +++ b/addons/scopes/functions/fnc_getOptics.sqf @@ -19,14 +19,4 @@ params ["_unit"]; -private _optics = ["", "", ""]; - -if (!(_unit isKindOf "CAManBase")) exitWith {_optics}; - -{ - if (count _x >= 2) then { - _optics set [_forEachIndex, _x select 2]; - }; -} forEach [primaryWeaponItems _unit, secondaryWeaponItems _unit, handgunItems _unit]; - -_optics +[primaryWeaponItems _unit, secondaryWeaponItems _unit, handgunItems _unit] apply {_x select 2} // return diff --git a/addons/scopes/functions/fnc_resetZero.sqf b/addons/scopes/functions/fnc_resetZero.sqf index 76ee6355a80..c22df8bb0fe 100644 --- a/addons/scopes/functions/fnc_resetZero.sqf +++ b/addons/scopes/functions/fnc_resetZero.sqf @@ -17,7 +17,7 @@ params ["_unit"]; -if (vehicle _unit != _unit) exitWith {false}; +if (!isNull objectParent _unit) exitWith {false}; private _weaponClass = currentWeapon _unit; private _weaponIndex = [_unit, _weaponClass] call EFUNC(common,getWeaponIndex); diff --git a/addons/scopes/initKeybinds.inc.sqf b/addons/scopes/initKeybinds.inc.sqf new file mode 100644 index 00000000000..0e8db972381 --- /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 index 917587be8e2..e74bcb4c073 100644 --- a/addons/scopes/initSettings.inc.sqf +++ b/addons/scopes/initSettings.inc.sqf @@ -5,7 +5,9 @@ private _category = format ["ACE %1", localize LSTRING(DisplayName)]; [LSTRING(enabled_displayName), LSTRING(enabled_description)], _category, true, - 1 + 1, + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -69,6 +71,16 @@ private _category = format ["ACE %1", localize LSTRING(DisplayName)]; [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(simplifiedZeroing), "CHECKBOX", + [LSTRING(simplifiedZeroing_displayName), LSTRING(simplifiedZeroing_description)], + _category, + false, 1 ] call CBA_fnc_addSetting; @@ -77,13 +89,13 @@ private _category = format ["ACE %1", localize LSTRING(DisplayName)]; [LSTRING(useLegacyUI_displayName), LSTRING(useLegacyUI_description)], _category, false, - 0 + 2 ] call CBA_fnc_addSetting; [ - QGVAR(simplifiedZeroing), "CHECKBOX", - [LSTRING(simplifiedZeroing_displayName), LSTRING(simplifiedZeroing_description)], + QGVAR(inScopeAdjustment), "CHECKBOX", + LSTRING(inScopeAdjustment_displayName), _category, false, - 1 + 0 ] call CBA_fnc_addSetting; diff --git a/addons/scopes/stringtable.xml b/addons/scopes/stringtable.xml index b69d59e3c8e..947447d379c 100644 --- a/addons/scopes/stringtable.xml +++ b/addons/scopes/stringtable.xml @@ -21,7 +21,7 @@ Enable ACE Scope adjustment Aktiviere das Nullen von Zielfernrohren ACE スコープ調節を有効化 - ACE 조준경 영점조작 활성화 + ACE 조준경 영점조절 활성화 Włącz ustawienia celowników optycznych ACE Activer le réglage ACE des lunettes Abilita Regolazione Mirino ACE @@ -35,7 +35,7 @@ Enable adjustment turrets on high powered scopes Aktiviere Absehenverstellungen für Waffen mit Zielfernrohren - 高倍率スコープでACE スコープ調節を有効化 + 高倍率スコープでのタレット調整を有効化します 고성능 조준경 조절 나사 활성화 Włącz pokrętła regulacyjne Active les tourelles de réglage des lunettes de visée à fort grossissement. @@ -50,7 +50,7 @@ Force adjustment turrets Erzwinge Absehenverstellungen - ACE スコープ調節を有効化 + タレット調整を強制 조절 나사 강제 Wymuś użycie pokręteł regulacyjnych Forcer les tourelles de réglage @@ -65,7 +65,7 @@ Force usage of adjustment turrets on high powered scopes Erzwinge Absehenverstellungen für Waffen mit Zielfernrohren - 高倍率スコープで調整の使用を強制させます + 高倍率スコープでタレット調整の使用を強制させます 고성능 조준경의 조절 나사 사용을 강제합니다 Wymuś użycie pokręteł regulacyjnych dla celowników o dużym powiększeniu Force l'utilisation des tourelles de réglage sur les lunettes de visée à fort grossissement. @@ -80,7 +80,7 @@ Correct zeroing Nullungsanpassung - ゼロイン調節 + ゼロイン規整 영점 고치기 Poprawka zerowania Corriger le zérotage @@ -95,7 +95,7 @@ Corrects the zeroing of all small arms sights Korrigiert alle Nullungen von Handfeuerwaffen - 全ての小口径用照準器のゼロインを調節します + 全ての小火器用照準器のゼロインを規整します 모든 소화기의 영점을 고칩니다 Poprawia zerowanie wszystkich celowników broni ręcznej Corrige le zérotage de tous les viseurs d'armes légères. @@ -125,7 +125,7 @@ Uses the 'defaultZeroRange' setting to overwrite the zero range of high power scopes Nutzt die Einstellung 'defaultZeroRange' um Zielfernrohre anzupassen - 'defaultZeroRange'設定を使う高倍率スコープのゼロイン距離を上書きします + '標準のゼロイン距離'設定を使用して、高倍率スコープのゼロイン距離を上書きします。 기존 고성능 조준경의 영점거리에 'defaultZeroRange'를 덮어씌웁니다 Używa 'defaultZeroRange' zamiast ustawionej odległości zerowania dla celowników o duzym przybliżeniu Utilise le paramètre "Distance de zérotage par défaut" pour remplacer la distance de zérotage des lunettes de visée à fort grossissement. @@ -155,7 +155,7 @@ High powered scopes will be zeroed at this distance Zielfernrohre werden auf diese Entfernung genullt - 高倍率スコープのゼロイン距離はこの設定になります + 高倍率スコープのゼロイン位置はこの設定になります 고성능 조준경이 정해진 수만큼 영점거리를 맞추게 됩니다. Celowniki o dużym powiększeniu będą zerowane dla tej odległości Distance de zérotage des lunettes de visée à fort grossissement. @@ -308,7 +308,7 @@ Visualizza Alzo e Deriva con numeri firmati 使用帶著標籤的數字顯示歸零遠近與風偏程度 使用带着标签的数字显示归零远近与风偏程度 - 印付きの数字で仰角と横風を表示 + ウィンデージとエレベーションを符号付き数字で表示します 기존의 부호가 있는 숫자로 표고와 폭을 표시합니다. Wyświetla elewację i tarcie powietrza poprzez podpisane liczby Отображает горизонтальные и вертикальные поправки с подписанными числами @@ -320,7 +320,7 @@ Simplified zeroing Vereinfachte Nullung - 簡略なゼロイン + 簡素化ゼロイン Azzeramento semplificato 단순화된 영점 조정 簡單歸零 @@ -335,9 +335,9 @@ 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 复杂的归零模拟。 Replikuje system zerowania, dla celowników karabinowych, z domyślnej gry. @@ -347,6 +347,15 @@ Replikuje systém naměřování puškohledů ze základní hry. Replica en los visores el sistema de homogeneizado de vanilla + + Show adjustment UI in scope + Zeige Absehenverstellungs-UI im Zielfernrohr + Mostra UI delle manopole nel mirino + 調整UIをスコープ内に表示 + 스코프에 조절 UI 보이기 + Показать интерфейс настройки в области видимости. + Mostrar IU de ajuste en el visor + Minor adjustment up Kleine Korrektur hoch @@ -486,7 +495,7 @@ Állítások nullázása Zerar ajuste Vynulovat korekci - ゼロインを調節 + ゼロイン調節をセット 영점 초기화 设定归零 設定歸零 @@ -496,7 +505,7 @@ Nullung zurücksetzen ゼロイン調節を初期化 Resetta l'azzeramento - 영점 조정 재설정 + 영점 조절 재설정 重設歸零 重设归零 Zresetuj wyzerowanie @@ -509,7 +518,7 @@ This module adds windage and elevation adjustment turrets on high power rifle scopes. Dieses Modul fügt Absehenverstellung (horizontal und vertikal) zu Zielfernrohren hinzu. - このモジュールは高倍率ライフル スコープにおいて横風と仰角の調節ができます。 + このモジュールは高倍率ライフル スコープにおいてウィンデージとエレベーションの調節ができます。 이 모듈은 고성능 조준경에 조준 나사를 이용한 편차 및 고도 조절 기능을 더해줍니다. Ten moduł włącza pokrętła kalibracyjne poprawki na wiatr oraz poprawki wysokości dla celowników o dużym powiększeniu. Ce module ajoute les tourelles de correction de hausse et de dérive sur les lunettes de visée à fort grossissement. diff --git a/addons/sitting/XEH_clientInit.sqf b/addons/sitting/XEH_clientInit.sqf index f0b0b7c2f0b..5495ef0e978 100644 --- a/addons/sitting/XEH_clientInit.sqf +++ b/addons/sitting/XEH_clientInit.sqf @@ -10,7 +10,7 @@ if (!hasInterface) exitWith {}; if (!XGVAR(enable)) exitWith {}; // Initialize classes as they spawn - ["ThingX", "init", FUNC(addSitActions), nil, nil, true] call CBA_fnc_addClassEventHandler; + ["ThingX", "init", LINKFUNC(addSitActions), nil, nil, true] call CBA_fnc_addClassEventHandler; // Initialize statically defined benches (also appear as world objects, no class EH thrown) { @@ -21,6 +21,6 @@ if (!hasInterface) exitWith {}; ["isNotSitting", {isNil {(_this select 0) getVariable QGVAR(sittingStatus)}}] call EFUNC(common,addCanInteractWithCondition); // Handle interruptions - ["ace_unconscious", {_this call DFUNC(handleInterrupt)}] call CBA_fnc_addEventHandler; - ["ace_captives_SetHandcuffed", {_this call DFUNC(handleInterrupt)}] call CBA_fnc_addEventHandler; + ["ace_unconscious", LINKFUNC(handleInterrupt)] call CBA_fnc_addEventHandler; + ["ace_captives_SetHandcuffed", LINKFUNC(handleInterrupt)] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/sitting/functions/fnc_canSit.sqf b/addons/sitting/functions/fnc_canSit.sqf index 4328234bd90..609bcea6828 100644 --- a/addons/sitting/functions/fnc_canSit.sqf +++ b/addons/sitting/functions/fnc_canSit.sqf @@ -21,6 +21,7 @@ params ["_seat", "_player", ["_seatPos", 0]]; // Sitting enabled, not occupied and standing up (or not on a big slope) XGVAR(enable) && +{[_player, _seat] call EFUNC(common,canInteractWith)} && {isNil {_player getVariable QGVAR(sittingStatus)}} && { private _seatsClaimed = _seat getVariable [QGVAR(seatsClaimed), []]; diff --git a/addons/sitting/functions/fnc_getRandomAnimation.sqf b/addons/sitting/functions/fnc_getRandomAnimation.sqf index ac8bd9e68d0..b0aa2ba2700 100644 --- a/addons/sitting/functions/fnc_getRandomAnimation.sqf +++ b/addons/sitting/functions/fnc_getRandomAnimation.sqf @@ -4,7 +4,7 @@ * Gets a random animations from the list. * * Arguments: - * None + * 0: Object to get animation pool from (default: objNull) * * Return Value: * Random Animation @@ -15,30 +15,42 @@ * Public: No */ +params [["_object", objNull, [objNull]]]; + +private _animations = []; + +if (!isNull _object) then { + _animations = getArray (configOf _object >> QGVAR(animations)); +}; + +if (_animations isEqualTo []) then { + _animations = [ + QGVAR(HubSittingChairA_idle1), + QGVAR(HubSittingChairA_idle2), + QGVAR(HubSittingChairA_idle3), + QGVAR(HubSittingChairA_move1), + QGVAR(HubSittingChairB_idle1), + QGVAR(HubSittingChairB_idle2), + QGVAR(HubSittingChairB_idle3), + QGVAR(HubSittingChairB_move1), + QGVAR(HubSittingChairC_idle1), + QGVAR(HubSittingChairC_idle2), + QGVAR(HubSittingChairC_idle3), + QGVAR(HubSittingChairC_move1), + QGVAR(HubSittingChairUA_idle1), + QGVAR(HubSittingChairUA_idle2), + QGVAR(HubSittingChairUA_idle3), + QGVAR(HubSittingChairUA_move1), + QGVAR(HubSittingChairUB_idle1), + QGVAR(HubSittingChairUB_idle2), + QGVAR(HubSittingChairUB_idle3), + QGVAR(HubSittingChairUB_move1), + QGVAR(HubSittingChairUC_idle1), + QGVAR(HubSittingChairUC_idle2), + QGVAR(HubSittingChairUC_idle3), + QGVAR(HubSittingChairUC_move1) + ]; +}; + // Select random animation from Animations Pool -selectRandom [ - QGVAR(HubSittingChairA_idle1), - QGVAR(HubSittingChairA_idle2), - QGVAR(HubSittingChairA_idle3), - QGVAR(HubSittingChairA_move1), - QGVAR(HubSittingChairB_idle1), - QGVAR(HubSittingChairB_idle2), - QGVAR(HubSittingChairB_idle3), - QGVAR(HubSittingChairB_move1), - QGVAR(HubSittingChairC_idle1), - QGVAR(HubSittingChairC_idle2), - QGVAR(HubSittingChairC_idle3), - QGVAR(HubSittingChairC_move1), - QGVAR(HubSittingChairUA_idle1), - QGVAR(HubSittingChairUA_idle2), - QGVAR(HubSittingChairUA_idle3), - QGVAR(HubSittingChairUA_move1), - QGVAR(HubSittingChairUB_idle1), - QGVAR(HubSittingChairUB_idle2), - QGVAR(HubSittingChairUB_idle3), - QGVAR(HubSittingChairUB_move1), - QGVAR(HubSittingChairUC_idle1), - QGVAR(HubSittingChairUC_idle2), - QGVAR(HubSittingChairUC_idle3), - QGVAR(HubSittingChairUC_move1) -] +selectRandom _animations diff --git a/addons/sitting/functions/fnc_sit.sqf b/addons/sitting/functions/fnc_sit.sqf index 2d7cc999daa..d359083c44a 100644 --- a/addons/sitting/functions/fnc_sit.sqf +++ b/addons/sitting/functions/fnc_sit.sqf @@ -48,7 +48,7 @@ if (_multiSitting) then { }; // Get random animation and perform it (before moving player to ensure correct placement) -[_player, call FUNC(getRandomAnimation), 2] call EFUNC(common,doAnimation); // Correctly places when using non-transitional animations +[_player, [_seat] call FUNC(getRandomAnimation), 2] call EFUNC(common,doAnimation); // Correctly places when using non-transitional animations [_player, "", 1] call EFUNC(common,doAnimation); // Correctly applies animation's config values (such as disallow throwing of grenades, intercept keybinds... etc). TRACE_2("Sit pos and dir",_sitPosition,_sitDirection); @@ -56,7 +56,7 @@ TRACE_2("Sit pos and dir",_sitPosition,_sitDirection); // Set direction and position _player setDir _sitDirection; //modelToWorld returns AGL -_player setPosASL (AGLtoASL (_seat modelToWorld _sitPosition)); +_player setPosASL (AGLToASL (_seat modelToWorld _sitPosition)); // Set variables, save seat object on player _player setVariable [QGVAR(sittingStatus), [_seat, _actionID, _seatPos]]; @@ -78,7 +78,7 @@ if (_seatsClaimed isEqualTo []) then { _seat setVariable [QGVAR(seatsClaimed), _seatsClaimed, true]; // Also prevent dragging/carrying -if (!([_seat] call EFUNC(common,owned))) then { +if !([_seat] call EFUNC(common,owned)) then { [_player, _seat] call EFUNC(common,claim); }; diff --git a/addons/sitting/initSettings.inc.sqf b/addons/sitting/initSettings.inc.sqf index 744c188e9fd..ee1af1ec8ef 100644 --- a/addons/sitting/initSettings.inc.sqf +++ b/addons/sitting/initSettings.inc.sqf @@ -6,5 +6,5 @@ true, true, {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; diff --git a/addons/slideshow/functions/fnc_addSlideActions.sqf b/addons/slideshow/functions/fnc_addSlideActions.sqf index 8ec804d577b..409c724943e 100644 --- a/addons/slideshow/functions/fnc_addSlideActions.sqf +++ b/addons/slideshow/functions/fnc_addSlideActions.sqf @@ -34,7 +34,7 @@ private _actions = []; (_this select 2) params ["_objects", "_image", "_currentSlideshow", "_selection"]; { _x setObjectTextureGlobal [_selection, _image] - } count _objects; + } forEach _objects; [QGVAR(slideChanged), [_image, _currentSlideshow]] call CBA_fnc_localEvent; }, {true}, diff --git a/addons/slideshow/functions/fnc_autoTransition.sqf b/addons/slideshow/functions/fnc_autoTransition.sqf index 793b8baf1b1..6a18a041c47 100644 --- a/addons/slideshow/functions/fnc_autoTransition.sqf +++ b/addons/slideshow/functions/fnc_autoTransition.sqf @@ -36,7 +36,7 @@ private _image = _images select _currentSlide; // Set slide { _x setObjectTextureGlobal [_selection, _image]; -} count _objects; +} forEach _objects; [QGVAR(slideChanged), [_image, _currentSlideshow]] call CBA_fnc_localEvent; diff --git a/addons/slideshow/functions/fnc_createSlideshow.sqf b/addons/slideshow/functions/fnc_createSlideshow.sqf index 9021a926136..c24d3023467 100644 --- a/addons/slideshow/functions/fnc_createSlideshow.sqf +++ b/addons/slideshow/functions/fnc_createSlideshow.sqf @@ -50,7 +50,7 @@ if (isServer) then { // Default images on whiteboards (first image) { _x setObjectTextureGlobal [_selection, _images select 0]; - } count _objects; + } forEach _objects; }; // Number of slideshows (multiple modules support) @@ -89,8 +89,7 @@ if (_duration == 0) then { 2 ] call EFUNC(interact_menu,createAction); [_x, 0, ["ACE_MainActions"], _slidesAction] call EFUNC(interact_menu,addActionToObject); - nil - } count _controllers; + } forEach _controllers; } else { if !(isServer) exitWith {}; diff --git a/addons/slideshow/functions/fnc_mapImage_init.sqf b/addons/slideshow/functions/fnc_mapImage_init.sqf index 5235315bd0f..3fb6e4c7f89 100644 --- a/addons/slideshow/functions/fnc_mapImage_init.sqf +++ b/addons/slideshow/functions/fnc_mapImage_init.sqf @@ -50,7 +50,7 @@ ctrlMapAnimCommit _map; // add drawEH to draw markers next update (they will get drawn 3 times total) _map setVariable ["markers", _markers]; -_map ctrlAddEventHandler ["draw", { +_map ctrlAddEventHandler ["Draw", { params ["_map"]; private _markers = _map getVariable ["markers", []]; TRACE_2("drawing markers",_map,count _markers); diff --git a/addons/slideshow/functions/fnc_moduleInit.sqf b/addons/slideshow/functions/fnc_moduleInit.sqf index 896c64eb50c..7e6a78dc95d 100644 --- a/addons/slideshow/functions/fnc_moduleInit.sqf +++ b/addons/slideshow/functions/fnc_moduleInit.sqf @@ -37,8 +37,7 @@ private _selection = _logic getVariable ["Selection", 0]; // Objects synced to the module { _objects pushBack _x; - nil -} count (synchronizedObjects _logic); +} forEach (synchronizedObjects _logic); // Prepare with actions [_objects, _controllers, _images, _names, _duration, _setName, _selection] call FUNC(createSlideshow); diff --git a/addons/smallarms/stringtable.xml b/addons/smallarms/stringtable.xml index c10248ca161..c31dad8f3eb 100644 --- a/addons/smallarms/stringtable.xml +++ b/addons/smallarms/stringtable.xml @@ -12,7 +12,7 @@ 17-Schuss-9mm-Magazin 9 mm, 17ks zásobník Carregador 17Mun. 9 mm - 9mm 17발 탄창 + 9mm 17발 들이 탄창 9 mm 17发 弹匣 9mm 17Rnd マガジン 9 mm 17 Merm. Şarjör @@ -29,21 +29,23 @@ .45 ACP 25 Merm. Şarjör .45 ACP 25Rnd マガジン .45 ACP 25发 弹匣 - .45 ACP 25발 탄창 + .45구경 ACP 25발 들이 탄창 + Carregador 25Mun. .45 ACP .45 ACP 25Rnd Tracers (Green) Mag - 25-nab. mag. .45 ACP (zielony smugacz) + 25-nab. mag. .45 ACP (Zielony smugacz) Магазин, 25 патр. .45 ACP (зелёные трассеры) - Mag. 25 traçantes (vertes) .45 ACP - Cargador de 25 balas trazadoras (verde) de .45 ACP + Mag. 25 traçantes (Vertes) .45 ACP + Cargador de 25 balas trazadoras (Verde) de .45 ACP Caricatore 25cp .45 ACP Traccianti (Verdi) 25-Schuss-.45-ACP-Vermin-Magazin (Leuchtspur Grün) - .45 ACP, 25ks zásobník stopovky (zelené) + .45 ACP, 25ks zásobník stopovky (Zelené) .45 ACP 25 Merm. İzli (Yeşil) Şarjör .45 ACP 25Rnd トレーサー (緑) マガジン .45 ACP 25发 弹匣(曳光,绿) - .45 ACP 25발 예광탄 (초록) 탄창 + .45구경 ACP 25발 들이 탄창 (녹색 예광탄) + Carregador 25Mun. .45 ACP Traçante (Verde) .45 ACP 25Rnd Tracers (Red) Mag @@ -57,7 +59,8 @@ .45 ACP 25 Merm. İzli (Kırmızı) Şarjör .45 ACP 25Rnd トレーサー (赤) マガジン .45 ACP 25发 弹匣(曳光,红) - .45 ACP 25발 예광탄 (빨강) 탄창 + .45구경 ACP 25발 들이 탄창 (적색 예광탄) + Carregador 25Mun. .45 ACP Traçante (Vermelha) .45 ACP 25Rnd Tracers (Yellow) Mag @@ -71,7 +74,8 @@ .45 ACP 25 Merm. İzli (Sarı) Şarjör .45 ACP 25Rnd トレーサー (黄) マガジン .45 ACP 25发 弹匣(曳光,黄) - .45 ACP 25발 예광탄 (노랑) 탄창 + .45구경 ACP 25발 들이 탄창 (황색 예광탄) + Carregador 25Mun. .45 ACP Traçante (Amarela) .45 ACP 8Rnd Mag @@ -85,7 +89,8 @@ .45 ACP 8 Merm. Şarjör .45 ACP 8Rnd マガジン .45 ACP 8发 弹匣 - .45 ACP 8발 탄창 + .45구경 ACP 8발 들이 탄창 + Carregador 8Mun. .45 ACP .45 ACP 15Rnd Mag @@ -99,7 +104,8 @@ .45 ACP 15 Merm. Şarjör .45 ACP 15Rnd マガジン .45 ACP 15发 弹匣 - .45 ACP 15발 탄창 + .45구경 ACP 15발 들이 탄창 + Carregador 15Mun. .45 ACP diff --git a/addons/spectator/functions/fnc_cam.sqf b/addons/spectator/functions/fnc_cam.sqf index d63a3c24a81..a9f8e975225 100644 --- a/addons/spectator/functions/fnc_cam.sqf +++ b/addons/spectator/functions/fnc_cam.sqf @@ -132,6 +132,9 @@ if (_init) then { GVAR(camDummy) = nil; // Stop tracking everything + { deleteVehicle _x; } forEach GVAR(camLights); + GVAR(camLights) = nil; + GVAR(camMode) = nil; GVAR(camVision) = nil; GVAR(camFocus) = nil; @@ -144,6 +147,5 @@ if (_init) then { GVAR(camYaw) = nil; GVAR(camPitch) = nil; GVAR(camSlow) = nil; - GVAR(camLights) = nil; GVAR(camLight) = nil; }; diff --git a/addons/spectator/functions/fnc_cam_setVisionMode.sqf b/addons/spectator/functions/fnc_cam_setVisionMode.sqf index 5bcf8710b6b..eaec12a86d3 100644 --- a/addons/spectator/functions/fnc_cam_setVisionMode.sqf +++ b/addons/spectator/functions/fnc_cam_setVisionMode.sqf @@ -29,10 +29,10 @@ if !(_newVision in _visions) then { if (GVAR(camMode) != MODE_FPS) then { // 0+ are all thermal vision types if (_newVision < 0) then { - false setCamUseTi 0; + false setCamUseTI 0; camUseNVG (_newVision >= VISION_NVG); } else { - true setCamUseTi _newVision; + true setCamUseTI _newVision; }; // Give user feedback that vision mode changed diff --git a/addons/spectator/functions/fnc_cam_tick.sqf b/addons/spectator/functions/fnc_cam_tick.sqf index 1e7e1b99137..11f257b7d5a 100644 --- a/addons/spectator/functions/fnc_cam_tick.sqf +++ b/addons/spectator/functions/fnc_cam_tick.sqf @@ -58,7 +58,9 @@ if (_cameraMode != MODE_FREE) then { _camTarget = GVAR(camFocus); // Focus get in / out of vehicle state -if !(isNull _camTarget) then { +if (isNull _camTarget) then { + GVAR(camTargetInVehicle) = false; +} else { private _targetInVeh = GVAR(camTargetInVehicle); if (GVAR(camHasTarget)) then { @@ -72,8 +74,6 @@ if !(isNull _camTarget) then { GVAR(camTargetInVehicle) = false; }; }; -} else { - GVAR(camTargetInVehicle) = false; }; // Camera lights diff --git a/addons/spectator/functions/fnc_compat_spectatorBI.sqf b/addons/spectator/functions/fnc_compat_spectatorBI.sqf index 3d982830a00..9bf39ec256d 100644 --- a/addons/spectator/functions/fnc_compat_spectatorBI.sqf +++ b/addons/spectator/functions/fnc_compat_spectatorBI.sqf @@ -18,7 +18,7 @@ */ private _respawn = getMissionConfigValue ["respawn",0]; -if (_respawn isEqualType "") then { _respawn = ["","bird","","","group","side"] find (toLower _respawn); }; +if (_respawn isEqualType "") then { _respawn = ["","bird","","","group","side"] find (toLowerANSI _respawn); }; if !(_respawn in [1,4,5]) exitWith {}; // Remember to check for side specific templates diff --git a/addons/spectator/functions/fnc_handleFired.sqf b/addons/spectator/functions/fnc_handleFired.sqf index f8683af947e..9817452386e 100644 --- a/addons/spectator/functions/fnc_handleFired.sqf +++ b/addons/spectator/functions/fnc_handleFired.sqf @@ -27,7 +27,7 @@ params [ // Remove the EH when spectator is no longer active or unit is removed if (isNil QGVAR(entitiesToDraw) || {!(_unit in GVAR(entitiesToDraw))}) exitWith { - //USES_VARIABLES ["_thisEventHandler"] + //IGNORE_PRIVATE_WARNING ["_thisEventHandler"]; _unit removeEventHandler ["Fired", _thisEventHandler]; SETVAR(_unit,GVAR(firedEH),nil); }; diff --git a/addons/spectator/functions/fnc_setCameraAttributes.sqf b/addons/spectator/functions/fnc_setCameraAttributes.sqf index f33f23c09a4..48cc4fb0c58 100644 --- a/addons/spectator/functions/fnc_setCameraAttributes.sqf +++ b/addons/spectator/functions/fnc_setCameraAttributes.sqf @@ -88,7 +88,7 @@ if (!isNil QGVAR(camera)) then { // GVARs exits purely for pre-setting of these attributes if (!isNil "_position") then { - GVAR(camPos) = ATLtoASL _position; + GVAR(camPos) = ATLToASL _position; }; if (!isNil "_direction") then { diff --git a/addons/spectator/functions/fnc_ui_handleKeyDown.sqf b/addons/spectator/functions/fnc_ui_handleKeyDown.sqf index c26a06786d7..59dd418782a 100644 --- a/addons/spectator/functions/fnc_ui_handleKeyDown.sqf +++ b/addons/spectator/functions/fnc_ui_handleKeyDown.sqf @@ -108,13 +108,13 @@ if (_key == DIK_L) exitWith { { deleteVehicle _x; } forEach GVAR(camLights); GVAR(camLights) = []; } else { - private _cameraLight = "#lightpoint" createvehicleLocal getPosASL GVAR(camera); + private _cameraLight = "#lightpoint" createVehicleLocal getPosASL GVAR(camera); _cameraLight setLightBrightness 2; _cameraLight setLightAmbient [1,1,1]; _cameraLight setLightColor [0,0,0]; _cameraLight lightAttachObject [GVAR(camera), [0,0,0]]; - private _pointerLight = "#lightpoint" createvehicleLocal getPosASL GVAR(camera); + private _pointerLight = "#lightpoint" createVehicleLocal getPosASL GVAR(camera); _pointerLight setLightBrightness 1; _pointerLight setLightAmbient [1,1,1]; _pointerLight setLightColor [0,0,0]; diff --git a/addons/spectator/functions/fnc_ui_handleListClick.sqf b/addons/spectator/functions/fnc_ui_handleListClick.sqf index 600b7e711ce..f81a73f4fd1 100644 --- a/addons/spectator/functions/fnc_ui_handleListClick.sqf +++ b/addons/spectator/functions/fnc_ui_handleListClick.sqf @@ -33,7 +33,7 @@ if !(isNull _object) then { if (_dblClick) then { // Place camera within ~10m of the object and above ground level private _pos = getPosASLVisual _object; - GVAR(camera) setPosASL (AGLtoASL (_pos getPos [1 + random 10, random 360]) vectorAdd [0,0,2 + random 10]); + GVAR(camera) setPosASL (AGLToASL (_pos getPos [1 + random 10, random 360]) vectorAdd [0,0,2 + random 10]); // Reset the focus [objNull] call FUNC(setFocus); diff --git a/addons/spectator/functions/fnc_ui_updateHelp.sqf b/addons/spectator/functions/fnc_ui_updateHelp.sqf index 1ddbbacad91..4a226bf3613 100644 --- a/addons/spectator/functions/fnc_ui_updateHelp.sqf +++ b/addons/spectator/functions/fnc_ui_updateHelp.sqf @@ -31,7 +31,7 @@ private _controls = []; // When not in first person, camera rotation applies if (_cameraMode != MODE_FPS) then { - _controls pushback ["[RMB]", localize "STR_A3_Spectator_Helper_CameraRotation"]; + _controls pushBack ["[RMB]", localize "STR_A3_Spectator_Helper_CameraRotation"]; }; // When in free camera, focus/un-focus with LMB @@ -52,31 +52,31 @@ if (_hasTarget && {count _availableModes > 1}) then { }; if (_cameraMode == MODE_FREE) then { - _controls pushback [ + _controls pushBack [ format ["[%1/%2]", [DIK_W] call CBA_fnc_localizeKey, [DIK_S] call CBA_fnc_localizeKey], localize "STR_A3_Spectator_Helper_Movement" ]; - _controls pushback [ + _controls pushBack [ format ["[%1/%2]", [DIK_A] call CBA_fnc_localizeKey, [DIK_D] call CBA_fnc_localizeKey], localize "STR_A3_Spectator_Helper_Strafing" ]; - _controls pushback [ + _controls pushBack [ format ["[%1/%2]", [DIK_Q] call CBA_fnc_localizeKey, [DIK_Z] call CBA_fnc_localizeKey], localize "STR_A3_Spectator_Helper_Height" ]; } else { - _controls pushback [ + _controls pushBack [ format ["[%1]", toUpper ([DIK_RIGHT] call CBA_fnc_localizeKey)], localize LSTRING(nextUnit) ]; - _controls pushback [ + _controls pushBack [ format ["[%1]", toUpper ([DIK_LEFT] call CBA_fnc_localizeKey)], localize LSTRING(prevUnit) ]; }; if (_cameraMode != MODE_FPS) then { - _controls pushback [ + _controls pushBack [ format ["[%1]", ([DIK_N] call CBA_fnc_localizeKey)], localize LSTRING(nextVis) ]; @@ -128,7 +128,7 @@ lnbClear _help; // Set height based on number of rows private _newH = (GVAR(uiHelpH) / MAX_CONTROLS_HELP_ENTRIES) * count _controls; -private _newY = safezoneY + safezoneH - _newH; +private _newY = safeZoneY + safeZoneH - _newH; (ctrlPosition _help) params ["_newX","","_newW"]; diff --git a/addons/spectator/functions/fnc_ui_updateIconsToDraw.sqf b/addons/spectator/functions/fnc_ui_updateIconsToDraw.sqf index 6093467d639..e5a736a7754 100644 --- a/addons/spectator/functions/fnc_ui_updateIconsToDraw.sqf +++ b/addons/spectator/functions/fnc_ui_updateIconsToDraw.sqf @@ -89,7 +89,7 @@ private _camPos = AGLToASL positionCameraToWorld [0,0,0]; 0, _heightByDistance, 0, - groupID _group, + groupId _group, 2, _fontSizeByDistance, "PuristaMedium", diff --git a/addons/spectator/functions/fnc_ui_updateListEntities.sqf b/addons/spectator/functions/fnc_ui_updateListEntities.sqf index 000f9a4b226..969460329c9 100644 --- a/addons/spectator/functions/fnc_ui_updateListEntities.sqf +++ b/addons/spectator/functions/fnc_ui_updateListEntities.sqf @@ -54,7 +54,7 @@ private _entities = [true] call FUNC(getTargetEntities); // Cache the info of the group itself private _groupTexture = [_group] call FUNC(getGroupIcon); - private _groupInfo = [_group, str _group, _groupTexture, groupID _group]; + private _groupInfo = [_group, str _group, _groupTexture, groupId _group]; // Add the group to the correct side private _side = side _group; diff --git a/addons/spectator/script_component.hpp b/addons/spectator/script_component.hpp index b4e7c82ac88..c29c60bdefc 100644 --- a/addons/spectator/script_component.hpp +++ b/addons/spectator/script_component.hpp @@ -17,12 +17,12 @@ #include "\z\ace\addons\main\script_macros.hpp" // UI grid -#define SIZEX ((safezoneW / safezoneH) min 1.2) +#define SIZEX ((safeZoneW / safeZoneH) min 1.2) #define SIZEY (SIZEX / 1.2) #define W_PART(num) (num * (SIZEX / 40)) #define H_PART(num) (num * (SIZEY / 25)) -#define X_PART(num) (W_PART(num) + (safezoneX + (safezoneW - SIZEX)/2)) -#define Y_PART(num) (H_PART(num) + (safezoneY + (safezoneH - SIZEY)/2)) +#define X_PART(num) (W_PART(num) + (safeZoneX + (safeZoneW - SIZEX)/2)) +#define Y_PART(num) (H_PART(num) + (safeZoneY + (safeZoneH - SIZEY)/2)) // UI/Camera related values #define SPEED_SLOW 0.1 diff --git a/addons/spectator/stringtable.xml b/addons/spectator/stringtable.xml index 4bd6817591f..7f55998d9fb 100644 --- a/addons/spectator/stringtable.xml +++ b/addons/spectator/stringtable.xml @@ -224,7 +224,7 @@ 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. 攝影機能追隨目標的最大距離 摄影机能追随目标的最大距离 diff --git a/addons/spectator/ui.hpp b/addons/spectator/ui.hpp index f61e7749eea..d81887db760 100644 --- a/addons/spectator/ui.hpp +++ b/addons/spectator/ui.hpp @@ -82,7 +82,7 @@ class GVAR(display) { onMouseExit = QUOTE([true] call FUNC(ui_fadeList)); x = "safeZoneX"; - y = "safezoneY"; + y = "safeZoneY"; w = QUOTE(W_PART(13.5)); h = QUOTE(H_PART(1.5)); @@ -98,7 +98,7 @@ class GVAR(display) { class CameraTypesGroup: RscControlsGroupNoScrollbars { idc = IDC_CAM_TYPES; x = QUOTE(X_PART(15.5)); - y = QUOTE(safezoneY + safezoneH - H_PART(2.38)); + y = QUOTE(safeZoneY + safeZoneH - H_PART(2.38)); w = QUOTE(W_PART(8.6)); h = 2.6; class controls { @@ -245,8 +245,8 @@ class GVAR(display) { }; class HelpBackground: RscText { idc = IDC_HELP_BACK; - x = QUOTE(safezoneX + safezoneW - W_PART(12)); - y = QUOTE(safezoneY + safezoneH - 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}; @@ -256,8 +256,8 @@ class GVAR(display) { disableOverflow = 0; rowHeight = QUOTE(H_PART(1)); idc = IDC_HELP; - x = QUOTE(safezoneX + safezoneW - W_PART(12)); - y = QUOTE(safezoneY + safezoneH - 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)); }; diff --git a/addons/spottingscope/CfgVehicles.hpp b/addons/spottingscope/CfgVehicles.hpp index 6be6d70d632..93fa00a7bc1 100644 --- a/addons/spottingscope/CfgVehicles.hpp +++ b/addons/spottingscope/CfgVehicles.hpp @@ -48,7 +48,7 @@ class CfgVehicles { selection = ""; displayName = CSTRING(PickUp); distance = 5; - condition = QUOTE((alive _target) && (count (crew _target) == 0)); + condition = QUOTE((alive _target) && {(crew _target) isEqualTo []}); statement = QUOTE([ARR_2(_target,_player)] call FUNC(pickup)); showDisabled = 0; exceptions[] = {}; diff --git a/addons/spottingscope/script_component.hpp b/addons/spottingscope/script_component.hpp index 6b2d95abbd5..cf7b8a835f7 100644 --- a/addons/spottingscope/script_component.hpp +++ b/addons/spottingscope/script_component.hpp @@ -16,8 +16,8 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define POS_X_BASE(size) safezoneX + 0.5 * safezoneW - 0.5 * (size) / (getResolution select 5) -#define POS_Y_BASE(size) safezoneY + 0.5 * safezoneH - 0.5 * (size) / (getResolution select 5) * 4/3 +#define POS_X_BASE(size) safeZoneX + 0.5 * safeZoneW - 0.5 * (size) / (getResolution select 5) +#define POS_Y_BASE(size) safeZoneY + 0.5 * safeZoneH - 0.5 * (size) / (getResolution select 5) * 4/3 #define POS_W_BASE(size) (size) / (getResolution select 5) #define POS_H_BASE(size) (size) / (getResolution select 5) * 4/3 diff --git a/addons/switchunits/functions/fnc_initPlayer.sqf b/addons/switchunits/functions/fnc_initPlayer.sqf index ffc0f7ad630..ba9c3f77b30 100644 --- a/addons/switchunits/functions/fnc_initPlayer.sqf +++ b/addons/switchunits/functions/fnc_initPlayer.sqf @@ -36,7 +36,7 @@ if (vehicle _playerUnit == _playerUnit) then { removeAllContainers _playerUnit; _playerUnit linkItem "ItemMap"; - [_playerUnit, "forceWalk", "ACE_SwitchUnits", true] call EFUNC(common,statusEffect_set); + [_playerUnit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); [] call FUNC(addMapFunction); }; diff --git a/addons/switchunits/functions/fnc_isValidAi.sqf b/addons/switchunits/functions/fnc_isValidAi.sqf index e78e990924a..53ebcdaac25 100644 --- a/addons/switchunits/functions/fnc_isValidAi.sqf +++ b/addons/switchunits/functions/fnc_isValidAi.sqf @@ -19,6 +19,6 @@ params ["_unit"]; !([_unit] call EFUNC(common,isPlayer) || {_unit in playableUnits} -|| {vehicle _unit != _unit} +|| {!isNull objectParent _unit} || {_unit getVariable [QGVAR(IsPlayerUnit), false]} || {_unit getVariable [QGVAR(IsPlayerControlled), false]}) // return diff --git a/addons/switchunits/functions/fnc_markAiOnMap.sqf b/addons/switchunits/functions/fnc_markAiOnMap.sqf index 8c7dc4924c6..203ba426ffe 100644 --- a/addons/switchunits/functions/fnc_markAiOnMap.sqf +++ b/addons/switchunits/functions/fnc_markAiOnMap.sqf @@ -27,7 +27,7 @@ GVAR(AllMarkerNames) = []; // delete markers { deleteMarkerLocal _x; - } count GVAR(AllMarkerNames); + } forEach GVAR(AllMarkerNames); // reset the array GVAR(AllMarkerNames) = []; @@ -58,8 +58,7 @@ GVAR(AllMarkerNames) = []; }; GVAR(AllMarkerNames) pushBack _markerName; - nil }; - } count allUnits; + } forEach allUnits; }; }, 1.5, [_sidesToShow]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/switchunits/functions/fnc_switchUnit.sqf b/addons/switchunits/functions/fnc_switchUnit.sqf index 6fc8fa35c9e..9ce074eecbb 100644 --- a/addons/switchunits/functions/fnc_switchUnit.sqf +++ b/addons/switchunits/functions/fnc_switchUnit.sqf @@ -18,7 +18,7 @@ params ["_unit"]; // don't switch to original player units -if (!([_unit] call FUNC(isValidAi))) exitWith {}; +if !([_unit] call FUNC(isValidAi)) exitWith {}; // exit var private _leave = false; @@ -27,7 +27,7 @@ if (GVAR(EnableSafeZone)) then { private _allNearestPlayers = [position _unit, GVAR(SafeZoneRadius)] call FUNC(nearestPlayers); private _nearestEnemyPlayers = _allNearestPlayers select {((side GVAR(OriginalGroup)) getFriend side _x < 0.6) && !(_x getVariable [QGVAR(IsPlayerControlled), false])}; - if (count _nearestEnemyPlayers > 0) exitWith { + if (_nearestEnemyPlayers isNotEqualTo []) exitWith { _leave = true; }; }; diff --git a/addons/switchunits/stringtable.xml b/addons/switchunits/stringtable.xml index c772b408673..11e54342aa0 100644 --- a/addons/switchunits/stringtable.xml +++ b/addons/switchunits/stringtable.xml @@ -92,7 +92,7 @@ Átváltás BLUFOR-ra? На синих? Cambia per BLUFOR? - 同盟軍へ切り替える? + BLUFOR軍へ切り替える? 切换至蓝方? 切換至藍方? 청군으로 변경합니까? @@ -109,7 +109,7 @@ Nyugat-fakciós egységekre való váltás engedélyezése? Разрешить переключаться на синих юнитов? Consenti passaggio ad unità BLUFOR? - 同盟軍ユニットへの切り替えを許可しますか? + BLUFOR軍ユニットへの切り替えを許可しますか? 允许切换至蓝方? 允許切換至藍方? 청군 인원으로 변경하는 것을 허락합니까? @@ -158,7 +158,7 @@ Átváltás INDFOR-ra? На независимых? Cambia per INDFOR? - 独立軍へ切り替える? + INDEPENDENT軍へ切り替える? 切换至独立方? 切換至獨立方? 무소속군으로 전환합니까? @@ -175,7 +175,7 @@ Független egységekre való váltás engedélyezése? Разрешить переключаться на независимых юнитов? Consenti passaggio ad unità INDFOR? - 独立軍ユニットへの切り替えを許可しますか? + INDEPENDENT軍ユニットへの切り替えを許可しますか? 允许切换至独立方? 允許切換至獨立方? 무소속군 인원으로 변경하는 것을 허락합니까? diff --git a/addons/tacticalladder/XEH_postInit.sqf b/addons/tacticalladder/XEH_postInit.sqf index 1a6f356fb02..c4b25a77ab1 100644 --- a/addons/tacticalladder/XEH_postInit.sqf +++ b/addons/tacticalladder/XEH_postInit.sqf @@ -17,10 +17,10 @@ GVAR(currentAngle) = 0; ["ace_interactMenuOpened", {[ACE_player] call FUNC(handleInteractMenuOpened)}] call CBA_fnc_addEventHandler; // Cancel adjusting on player change. -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; ["vehicle", {[ACE_player, objNull] call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; // handle falling unconscious -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; +["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; // @todo captivity? diff --git a/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf b/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf index 7c05cbbe63b..24013f02d74 100644 --- a/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf +++ b/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf @@ -23,8 +23,8 @@ params ["_unit", "_key"]; if (_key != 1 || {isNull GVAR(ladder)}) exitWith {}; // enable running again -[_unit, "forceWalk", "ACE_Ladder", false] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", "ACE_Ladder", false] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); detach GVAR(ladder); diff --git a/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf b/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf index 9fe13e4e658..8211dc5f9d0 100644 --- a/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf +++ b/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf @@ -19,8 +19,8 @@ params ["_unit", "_ladder"]; // enable running again -[_unit, "forceWalk", "ACE_Ladder", false] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", "ACE_Ladder", false] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); private _pos1 = getPosASL _ladder; private _pos2 = _ladder modelToWorldWorld (_ladder selectionPosition "check2"); diff --git a/addons/tacticalladder/functions/fnc_positionTL.sqf b/addons/tacticalladder/functions/fnc_positionTL.sqf index 1ea19e737be..e9168d75a1a 100644 --- a/addons/tacticalladder/functions/fnc_positionTL.sqf +++ b/addons/tacticalladder/functions/fnc_positionTL.sqf @@ -21,12 +21,12 @@ params ["_unit", "_ladder"]; // prevent the placing unit from running -[_unit, "forceWalk", "ACE_Ladder", true] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", "ACE_Ladder", true] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); { _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/stringtable.xml b/addons/tacticalladder/stringtable.xml index a7d33865f96..298c0e3c442 100644 --- a/addons/tacticalladder/stringtable.xml +++ b/addons/tacticalladder/stringtable.xml @@ -79,7 +79,7 @@ +Ctrl incliner +Ctrl per inclinare +Ctrl で傾ける - +컨트롤 키 기울이기 + +컨트롤 키로 기울이기 +Ctrl 倾斜 +Ctrl 傾斜 diff --git a/addons/tagging/XEH_postInit.sqf b/addons/tagging/XEH_postInit.sqf index 7fefa5757e6..02e082648a7 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_preStart.sqf b/addons/tagging/XEH_preStart.sqf index 9303bdb135c..eb8f7ab767a 100644 --- a/addons/tagging/XEH_preStart.sqf +++ b/addons/tagging/XEH_preStart.sqf @@ -12,7 +12,7 @@ private _vehicleClasses = "(configName _x) isKindOf 'Static'" configClasses (con private _model = getText (_x >> "model"); if (_model != "") then { private _array = _model splitString "\"; - _cacheStaticModels pushBackUnique toLower (_array select ((count _array) - 1)); + _cacheStaticModels pushBackUnique toLowerANSI (_array select -1); }; } forEach _vehicleClasses; @@ -24,11 +24,11 @@ private _cfgBase = configFile >> "CfgNonAIVehicles"; private _model = getText (_x >> "model"); if (_model != "") then { private _array = _model splitString "\"; - _cacheStaticModels pushBackUnique toLower (_array select ((count _array) - 1)); + _cacheStaticModels pushBackUnique toLowerANSI (_array select -1); }; -} forEach (_nonaivehicleClasses select {(configName _x) isKindOf ["Bridge_base_F", _cfgBase]}); +} forEach (_nonAIVehicleClasses select {(configName _x) isKindOf ["Bridge_base_F", _cfgBase]}); -uiNamespace setVariable [QGVAR(cacheStaticModels), compileFinal str _cacheStaticModels]; +uiNamespace setVariable [QGVAR(cacheStaticModels), compileFinal (_cacheStaticModels createHashMapFromArray [])]; TRACE_1("compiled",count _cacheStaticModels); // force preload of stencil texture to avoid error popup diff --git a/addons/tagging/functions/fnc_addTagActions.sqf b/addons/tagging/functions/fnc_addTagActions.sqf index 9c720e1f6c5..79603487408 100644 --- a/addons/tagging/functions/fnc_addTagActions.sqf +++ b/addons/tagging/functions/fnc_addTagActions.sqf @@ -19,6 +19,7 @@ params ["_unit"]; private _actions = []; { + //IGNORE_PRIVATE_WARNING ["_player", "_target"]; _actions pushBack [ [ format ["ACE_TagItem_%1", _x], diff --git a/addons/tagging/functions/fnc_checkTaggable.sqf b/addons/tagging/functions/fnc_checkTaggable.sqf index 7eab60c1ba5..5f9d162694d 100644 --- a/addons/tagging/functions/fnc_checkTaggable.sqf +++ b/addons/tagging/functions/fnc_checkTaggable.sqf @@ -17,6 +17,7 @@ [_this, { params ["_unit"]; + //IGNORE_PRIVATE_WARNING ["_unit"]; // Exit if no required item in inventory if ([_unit, { @@ -43,14 +44,14 @@ if (_object isKindOf "Static") exitWith {false}; // Taggable vehicle, do not exit - if (((_object getVariable [QGVAR(canTag), getNumber (configOf _object >> QGVAR(canTag))]) in [1, true]) + if (((_object getVariable [QGVAR(canTag), getNumber (configOf _object >> QGVAR(canTag))]) in [1, true]) && {getText (configOf _object >> "selectionClan") in selectionNames _object}) exitWith { false }; // If the class is not categorized correctly search the cache - private _modelName = (getModelInfo _object) select 0; - private _isStatic = GVAR(cacheStaticModels) getVariable [_modelName, false]; + private _modelName = toLowerANSI ((getModelInfo _object) select 0); + private _isStatic = _modelName in (uiNamespace getVariable QGVAR(cacheStaticModels)); TRACE_2("Object:",_modelName,_isStatic); // If the class in not on the cache, exit (!_isStatic) diff --git a/addons/tagging/functions/fnc_compileTagAction.sqf b/addons/tagging/functions/fnc_compileTagAction.sqf index a49de10f47d..3b9e060c5c3 100644 --- a/addons/tagging/functions/fnc_compileTagAction.sqf +++ b/addons/tagging/functions/fnc_compileTagAction.sqf @@ -24,6 +24,7 @@ _actions pushBack ([ _displayName, _icon, { + //IGNORE_PRIVATE_WARNING ["_player", "_target"]; (_this select 2) params ["_class", "_textures", "_materials", "_tagModel"]; ( diff --git a/addons/tagging/functions/fnc_createTag.sqf b/addons/tagging/functions/fnc_createTag.sqf index 90923cc8034..134e37bcc0a 100644 --- a/addons/tagging/functions/fnc_createTag.sqf +++ b/addons/tagging/functions/fnc_createTag.sqf @@ -68,7 +68,7 @@ if (_object getVariable [QGVAR(testVar), false]) then { if (_selection == "" && _damage >= 1) then { { deleteVehicle _x; - } foreach (_object getVariable [QGVAR(attachedTags), []]); + } forEach (_object getVariable [QGVAR(attachedTags), []]); _object setVariable [QGVAR(attachedTags), []]; }; }]; diff --git a/addons/tagging/functions/fnc_generateStencilTexture.sqf b/addons/tagging/functions/fnc_generateStencilTexture.sqf index 1870d671141..6d8dffdc551 100644 --- a/addons/tagging/functions/fnc_generateStencilTexture.sqf +++ b/addons/tagging/functions/fnc_generateStencilTexture.sqf @@ -29,10 +29,10 @@ params [ ["_dimension", 512, [0]] ]; -if (_textColor select [0, 1] == "#") then { _textColor = _textColor select [1]; }; -if (_backgroundColor select [0, 1] == "#") then { _backgroundColor = _backgroundColor select [1]; }; -if (!((count _textColor) in [6,8])) exitWith { ERROR_1("bad Tcolor %1",_textColor); "" }; -if (!((count _backgroundColor) in [6,8])) exitWith { ERROR_1("bad Bcolor %1",_textColor); "" }; +if (_textColor select [0, 1] == "#") then {_textColor = _textColor select [1];}; +if (_backgroundColor select [0, 1] == "#") then {_backgroundColor = _backgroundColor select [1];}; +if !((count _textColor) in [6,8]) exitWith {ERROR_1("bad Tcolor %1",_textColor); ""}; +if !((count _backgroundColor) in [6,8]) exitWith {ERROR_1("bad Bcolor %1",_textColor); ""}; if (_autoMultiline) then { private _magicWidth = 0.75; diff --git a/addons/tagging/functions/fnc_stencilVehicle.sqf b/addons/tagging/functions/fnc_stencilVehicle.sqf index b2ee99c2413..1dfd86a2f95 100644 --- a/addons/tagging/functions/fnc_stencilVehicle.sqf +++ b/addons/tagging/functions/fnc_stencilVehicle.sqf @@ -29,7 +29,7 @@ TRACE_2("",_vehicle,_text); if (!isServer) exitWith {}; if (_text == "") exitWith {}; private _clanSel = getText (configOf _vehicle >> "selectionClan"); -if (!(_clanSel in selectionNames _vehicle)) exitWith { TRACE_1("no tag",_clanSel); }; +if !(_clanSel in selectionNames _vehicle) exitWith {TRACE_1("no tag",_clanSel);}; private _texture = [_text, _textSize, _textColor, "00000000", true] call FUNC(generateStencilTexture); TRACE_1("",_texture); diff --git a/addons/tagging/functions/fnc_tag.sqf b/addons/tagging/functions/fnc_tag.sqf index aa0ba9fac97..f130e1322b3 100644 --- a/addons/tagging/functions/fnc_tag.sqf +++ b/addons/tagging/functions/fnc_tag.sqf @@ -60,8 +60,8 @@ if ((!isNull _object) && { }; // If the class is not categorized correctly search the cache - private _modelName = (getModelInfo _object) select 0; - private _isStatic = GVAR(cacheStaticModels) getVariable [_modelName, false]; + private _modelName = toLowerANSI ((getModelInfo _object) select 0); + private _isStatic = _modelName in (uiNamespace getVariable QGVAR(cacheStaticModels)); TRACE_2("Object:",_modelName,_isStatic); // If the class in not on the cache, exit (!_isStatic) diff --git a/addons/tagging/initSettings.inc.sqf b/addons/tagging/initSettings.inc.sqf index 4fc35b83d1b..e05146c0819 100644 --- a/addons/tagging/initSettings.inc.sqf +++ b/addons/tagging/initSettings.inc.sqf @@ -4,8 +4,5 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(Tagging)] QGVAR(quickTag), "LIST", [LLSTRING(QuickTag), LLSTRING(QuickTagDesc)], _category, - [[0,1,2,3], [LELSTRING(Common,Disabled), LLSTRING(LastUsed), LLSTRING(RandomX), LLSTRING(Random)], 1], // [values, titles, defaultIndex] - false, // isGlobal - {[QGVAR(quickTag), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + [[0,1,2,3], [LELSTRING(Common,Disabled), LLSTRING(LastUsed), LLSTRING(RandomX), LLSTRING(Random)], 1] // [values, titles, defaultIndex] ] call CBA_fnc_addSetting; diff --git a/addons/tagging/stringtable.xml b/addons/tagging/stringtable.xml index 4d32fac6d66..fa54b56b542 100644 --- a/addons/tagging/stringtable.xml +++ b/addons/tagging/stringtable.xml @@ -384,6 +384,7 @@ 차량 ID 마킹 Marquage ID des véhicules Идентификационная маркировка транспортного средства + Marcado Identificativo de Vehículo Replaces clan tag with stenciled text @@ -394,6 +395,7 @@ 클랜 태그를 스텐실 텍스트로 바꿉니다. Remplace le tag du clan par un texte au pochoir Заменяет тег клана трафаретным текстом + Reemplaza marca del clan con un texto serigrafiado diff --git a/addons/towing/config.cpp b/addons/towing/config.cpp index d4d1b5e8540..7c98be1756c 100644 --- a/addons/towing/config.cpp +++ b/addons/towing/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_common", "ace_logistics_rope"}; + requiredAddons[] = {"ace_interaction", "ace_logistics_rope"}; author = ECSTRING(common,ACETeam); authors[] = {"tcvm"}; url = ECSTRING(main,URL); @@ -16,4 +16,3 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" - diff --git a/addons/towing/functions/fnc_attachRopePFH.sqf b/addons/towing/functions/fnc_attachRopePFH.sqf index 37f626e0a92..31def8dcb83 100644 --- a/addons/towing/functions/fnc_attachRopePFH.sqf +++ b/addons/towing/functions/fnc_attachRopePFH.sqf @@ -21,7 +21,7 @@ private _viewDirection = getCameraViewDirection _unit; GVAR(attachHelper) setPosASL (_unit modelToWorldVisualWorld [0, 1, 1.5]); private _hintLMB = ""; -private _hintRMB = localize ELSTRING(dragging,Drop); +private _hintRMB = LELSTRING(common,Drop); private _startPos = eyePos _unit; private _endPos = _startPos vectorAdd (_viewDirection vectorMultiply TOW_ACTION_DISTANCE); diff --git a/addons/towing/functions/fnc_isSuitableSimulation.sqf b/addons/towing/functions/fnc_isSuitableSimulation.sqf index 6df9c3d40e3..a4131e6a918 100644 --- a/addons/towing/functions/fnc_isSuitableSimulation.sqf +++ b/addons/towing/functions/fnc_isSuitableSimulation.sqf @@ -22,4 +22,4 @@ private _simulationType = getText ((configOf _target) >> "simulation"); // TRACE_1("sim type",_simulationType); // Biki lies, you can both tow and tow as either TankX or CarX -(toLower _simulationType) in ["tankx", "carx", "shipx"] +(toLowerANSI _simulationType) in ["tankx", "carx", "shipx"] diff --git a/addons/towing/functions/fnc_towStateMachinePFH.sqf b/addons/towing/functions/fnc_towStateMachinePFH.sqf index c3b7e197207..ad516f211b6 100644 --- a/addons/towing/functions/fnc_towStateMachinePFH.sqf +++ b/addons/towing/functions/fnc_towStateMachinePFH.sqf @@ -44,15 +44,14 @@ if (GVAR(isSwimming) && {currentWeapon _unit isNotEqualTo ""}) then { private _exitCondition = !( (alive GVAR(attachHelper)) && { alive _parent } && - { alive _unit } && + { _unit call EFUNC(common,isAwake) } && { currentWeapon _unit isEqualTo "" || {_unit call EFUNC(common,isSwimming)} // swimming in wetsuit forces weapon in hands || {getPosASLW _unit select 2 < -1.5} // walking-to-swimming animation in wetsuit lasts for 3 seconds } && { [_unit, objNull, [INTERACTION_EXCEPTIONS]] call EFUNC(common,canInteractWith) } && - { "unconscious" isNotEqualTo toLower animationState _unit } && - { !(_unit getVariable ["ACE_isUnconscious", false]) } && + { "unconscious" != animationState _unit } && { ACE_player == _unit } ); @@ -71,7 +70,7 @@ switch (_state) do { // 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]; + _rope = ropeCreate [_parent, _parent worldToModelVisual ASLToAGL getPosASLVisual GVAR(attachHelper), GVAR(helper), [0, 0, 0], _length]; _args set [3, _rope]; }; @@ -96,7 +95,7 @@ switch (_state) do { 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); + private _relativeAttachPos = _child worldToModelVisual ASLToAGL getPosASLVisual GVAR(attachHelper); TRACE_3("child&pos",_parent,_child,_relativeAttachPos); @@ -119,7 +118,7 @@ switch (_state) do { }; private _hookParent = createVehicle [QGVAR(hook), [0, 0, 0], [], 0, "CAN_COLLIDE"]; - _hookParent attachTo [_parent, _parent worldToModelVisual ASLtoAGL getPosASLVisual _rope]; + _hookParent attachTo [_parent, _parent worldToModelVisual ASLToAGL getPosASLVisual _rope]; private _hook = createVehicle [QGVAR(hook), [0, 0, 0], [], 0, "CAN_COLLIDE"]; _hook attachTo [_child, _relativeAttachPos]; diff --git a/addons/towing/stringtable.xml b/addons/towing/stringtable.xml index 949d36dd488..7549fb3c8a8 100644 --- a/addons/towing/stringtable.xml +++ b/addons/towing/stringtable.xml @@ -12,6 +12,7 @@ 牵引 견인 Remolcado + Rebocando Attach Tow Rope @@ -24,6 +25,7 @@ 系上牵引绳 견인줄 부착 Sujetar cuerda de remolcado + Fixar corda de reboque Attaching Cancelled @@ -36,6 +38,7 @@ 取消系上绳索 견인 취소됨 Sujección cancelada + Reboque cancelado Attach Tow Rope (3.2m) @@ -48,6 +51,7 @@ 系上牵引绳(3.2米) 견인줄 부착(3.2M) Sujetar cuerda de remolcado (3.2m) + Fixar corda de reboque (3,2m) Attach Tow Rope (6.2m) @@ -60,6 +64,7 @@ 系上牵引绳(6.2米) 견인줄 부착(6.2M) Sujetar cuerda de remolcado (6.2m) + Fixar corda de reboque (6,2m) Attach Tow Rope (12.2m) @@ -72,6 +77,7 @@ 系上牵引绳(12.2米) 견인줄 부착(12.2M) Sujetar cuerda de remolcado (12.2m) + Fixar corda de reboque (12,2m) Attach Tow Rope (15.2m) @@ -84,6 +90,7 @@ 系上牵引绳(15.2米) 견인줄 부착(15.2M) Sujetar cuerda de remolcado (15.2m) + Fixar corda de reboque (15,2m) Attach Tow Rope (18.3m) @@ -96,6 +103,7 @@ 系上牵引绳(18.3米) 견인줄 부착(18.2M) Sujetar cuerda de remolcado (18.3m) + Fixar corda de reboque (18,3m) Attach Tow Rope (27.4m) @@ -108,6 +116,7 @@ 系上牵引绳(27.4米) 견인줄 부착(27.4M) Sujetar cuerda de remolcado (27.4m) + Fixar corda de reboque (27,4m) Attach Tow Rope (36.6m) @@ -120,6 +129,7 @@ 系上牵引绳(36.6米) 견인줄 부착(36.6M) Sujetar cuerda de remolcado (36.6m) + Fixar corda de reboque (36,6m) Detach Tow Rope @@ -132,6 +142,7 @@ 解开牵引绳 견인줄 분리 Desmontar cuerda de remolcado + Soltar corda de reboque Add Tow Rope to Vehicle Inventory @@ -143,6 +154,7 @@ 車両のインベントリに牽引ロープを追加する Abschleppseil zum Fahrzeuginventar hinzufügen Ajouter une corde à l'inventaire des véhicules + Adicionar corda de reboque ao inventário do veículo diff --git a/addons/trenches/CfgVehicles.hpp b/addons/trenches/CfgVehicles.hpp index bec66e2e641..554a75149b8 100644 --- a/addons/trenches/CfgVehicles.hpp +++ b/addons/trenches/CfgVehicles.hpp @@ -106,4 +106,44 @@ class CfgVehicles { MACRO_ADDITEM(ACE_EntrenchingTool,50); }; }; + + class Wheeled_APC_F; + class APC_Wheeled_02_base_F: Wheeled_APC_F { + class EGVAR(interaction,anims); + }; + class APC_Wheeled_02_base_v2_F: APC_Wheeled_02_base_F { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class showTools { + phase = 0; + positions[] = {{-1.108, -1.47, -0.769}}; + items[] = {"ACE_EntrenchingTool"}; + name = CSTRING(EntrenchingToolName); + text = CSTRING(EntrenchingToolName); + }; + }; + }; + class APC_Wheeled_03_base_F: Wheeled_APC_F { + class EGVAR(interaction,anims) { + class showTools { + phase = 0; + positions[] = {{-0.9, -3, -0.5}}; + items[] = {"ACE_EntrenchingTool"}; + name = CSTRING(EntrenchingToolName); + text = CSTRING(EntrenchingToolName); + }; + }; + }; + + class Tank_F; + class LT_01_base_F: Tank_F { + class EGVAR(interaction,anims) { + class showTools { + phase = 0; + positions[] = {{0.6, 0, -0.3}}; + items[] = {"ACE_EntrenchingTool"}; + name = CSTRING(EntrenchingToolName); + text = CSTRING(EntrenchingToolName); + }; + }; + }; }; diff --git a/addons/trenches/XEH_postInit.sqf b/addons/trenches/XEH_postInit.sqf index ea8ff7e24f0..59a6fb8a087 100644 --- a/addons/trenches/XEH_postInit.sqf +++ b/addons/trenches/XEH_postInit.sqf @@ -27,11 +27,11 @@ GVAR(digDirection) = 0; ["ace_interactMenuOpened", {[ACE_player] call FUNC(handleInteractMenuOpened)}] call CBA_fnc_addEventHandler; // Cancel dig on player change. This does work when returning to lobby, but not when hard disconnecting. -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; -["loadout", FUNC(handlePlayerInventoryChanged)] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +["loadout", LINKFUNC(handlePlayerInventoryChanged)] call CBA_fnc_addPlayerEventHandler; ["vehicle", {[ACE_player, objNull] call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; // handle waking up dragged unit and falling unconscious while dragging -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; +["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; //@todo Captivity? diff --git a/addons/trenches/XEH_preInit.sqf b/addons/trenches/XEH_preInit.sqf index 94decd550af..c8c9a3451f9 100644 --- a/addons/trenches/XEH_preInit.sqf +++ b/addons/trenches/XEH_preInit.sqf @@ -8,6 +8,6 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" -GVAR(entrenchingTools) = call (uiNamespace getVariable QGVAR(entrenchingTools)); +GVAR(entrenchingTools) = keys (uiNamespace getVariable QGVAR(entrenchingTools)); ADDON = true; diff --git a/addons/trenches/XEH_preStart.sqf b/addons/trenches/XEH_preStart.sqf index c966b2c9b6d..05065910397 100644 --- a/addons/trenches/XEH_preStart.sqf +++ b/addons/trenches/XEH_preStart.sqf @@ -6,4 +6,4 @@ private _entrenchingTools = (QUOTE(getNumber (_x >> QQGVAR(entrenchingTool)) > 0 _entrenchingTools append (QUOTE(getNumber (_x >> QQGVAR(entrenchingTool)) > 0) configClasses (configFile >> "CfgVehicles") apply {configName _x}); TRACE_1("",_entrenchingTools); -uiNamespace setVariable [QGVAR(entrenchingTools), compileFinal str _entrenchingTools]; +uiNamespace setVariable [QGVAR(entrenchingTools), compileFinal (_entrenchingTools createHashMapFromArray [])]; diff --git a/addons/trenches/functions/fnc_continueDiggingTrench.sqf b/addons/trenches/functions/fnc_continueDiggingTrench.sqf index 78047c189e4..e3aadcfd51c 100644 --- a/addons/trenches/functions/fnc_continueDiggingTrench.sqf +++ b/addons/trenches/functions/fnc_continueDiggingTrench.sqf @@ -81,7 +81,7 @@ if(_actualProgress == 0) then { _cutterPos set [2, getTerrainHeightASL _cutterPos]; _trenchGrassCutter setPosASL _cutterPos; deleteVehicle _trenchGrassCutter; - } foreach getArray (configOf _trench >> QGVAR(grassCuttingPoints)); + } forEach getArray (configOf _trench >> QGVAR(grassCuttingPoints)); }; private _progressLeft = (_actualProgress * 10) + 1; diff --git a/addons/trenches/functions/fnc_hasEntrenchingTool.sqf b/addons/trenches/functions/fnc_hasEntrenchingTool.sqf index 5a1127d0072..1568801fdb8 100644 --- a/addons/trenches/functions/fnc_hasEntrenchingTool.sqf +++ b/addons/trenches/functions/fnc_hasEntrenchingTool.sqf @@ -23,4 +23,4 @@ private _uniqueItems = _unit call EFUNC(common,uniqueItems); _uniqueItems append weapons _unit; _uniqueItems pushBack backpack _unit; -GVAR(entrenchingTools) findIf {_x in _uniqueItems} != -1 // return +GVAR(entrenchingTools) findAny _uniqueItems != -1 // return diff --git a/addons/trenches/functions/fnc_placeCancel.sqf b/addons/trenches/functions/fnc_placeCancel.sqf index a06ecff4590..f3cd20c0beb 100644 --- a/addons/trenches/functions/fnc_placeCancel.sqf +++ b/addons/trenches/functions/fnc_placeCancel.sqf @@ -21,8 +21,8 @@ params ["_unit", "_key"]; if (_key != 1 || {GVAR(digPFH) == -1}) exitWith {}; // enable running again -[_unit, "forceWalk", "ACE_Trenches", false] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", "ACE_Trenches", false] call EFUNC(common,statusEffect_set); +[_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(trench); diff --git a/addons/trenches/functions/fnc_placeConfirm.sqf b/addons/trenches/functions/fnc_placeConfirm.sqf index 03d4791e026..2cfdaf8891e 100644 --- a/addons/trenches/functions/fnc_placeConfirm.sqf +++ b/addons/trenches/functions/fnc_placeConfirm.sqf @@ -18,8 +18,8 @@ params ["_unit"]; // enable running again -[_unit, "forceWalk", "ACE_Trenches", false] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", "ACE_Trenches", false] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); // remove dig pfh [GVAR(digPFH)] call CBA_fnc_removePerFrameHandler; @@ -64,7 +64,7 @@ for [{private _ix = -_dx/2},{_ix <= _dx/2},{_ix = _ix + _dx/3}] do { _pos set [2, getTerrainHeightASL _pos]; _pos2 = +_pos; _pos2 set [2, getTerrainHeightASL _pos + 1]; - drawLine3D [ASLtoAGL _pos, ASLtoAGL _pos2, [1,1,0,1]]; + drawLine3D [ASLToAGL _pos, ASLToAGL _pos2, [1,1,0,1]]; #endif }; }; diff --git a/addons/trenches/functions/fnc_placeTrench.sqf b/addons/trenches/functions/fnc_placeTrench.sqf index f49aef4a385..285fe278e94 100644 --- a/addons/trenches/functions/fnc_placeTrench.sqf +++ b/addons/trenches/functions/fnc_placeTrench.sqf @@ -27,8 +27,8 @@ GVAR(trenchPlacementData) = getArray (configFile >> "CfgVehicles" >> _trenchClas TRACE_1("",GVAR(trenchPlacementData)); // prevent the placing unit from running -[_unit, "forceWalk", "ACE_Trenches", true] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", "ACE_Trenches", true] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); // create the trench private _trench = createVehicle [_noGeoModel, [0, 0, 0], [], 0, "NONE"]; @@ -77,7 +77,7 @@ GVAR(digPFH) = [{ _pos set [2, getTerrainHeightASL _pos]; _pos2 = +_pos; _pos2 set [2, getTerrainHeightASL _pos + 1]; - drawLine3D [ASLtoAGL _pos, ASLtoAGL _pos2, [1,1,0,1]]; + drawLine3D [ASLToAGL _pos, ASLToAGL _pos2, [1,1,0,1]]; #endif }; }; diff --git a/addons/trenches/stringtable.xml b/addons/trenches/stringtable.xml index 6e029cb4c04..5242603bc28 100644 --- a/addons/trenches/stringtable.xml +++ b/addons/trenches/stringtable.xml @@ -237,6 +237,7 @@ Camuffa la trincea 塹壕を偽装 Graben tarnen + Camuflar trincheira Removing Trench @@ -265,6 +266,7 @@ ACE Trincee ACE 战壕 ACE 참호 + ACE Trincheiras Small Trench Dig Duration @@ -277,18 +279,20 @@ Trincea piccola - Durata di scavo 小型战壕挖掘时间 소형참호 건설 시간 + Duração de Escavamento de Trincheira Pequena 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. 挖一条小型战壕所需的时间(秒)。 소형 참호를 팔 때 필요한 시간을 설정합니다. (초 단위) + Tempo, em segundos, necessário para cavar uma trincheira pequena. Small Trench Remove Duration @@ -301,18 +305,20 @@ Trincea piccola - Durata di rimozione 小型战壕回填时间 소형참호 제거 시간 + Duração de Remoção de Trincheira Pequena 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. 回填一条小型战壕所需的时间(秒)。 소형 참호를 제거할때 필요한 시간을 설정합니다. (초 단위) + Tempo, em segundos, necessário para remover uma trincheira pequena. Big Trench Dig Duration @@ -325,18 +331,20 @@ Trincea grande - Durata di scavo 大型战壕挖掘时间 대형참호 건설 시간 + Duração de Escavamento de Trincheira Grande 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. 挖一条大型战壕所需的时间(秒)。 대형 참호를 팔때 필요한 시간을 설정합니다. (초 단위) + Tempo, em segundos, necessário para cavar uma trincheira grande. Big Trench Remove Duration @@ -349,18 +357,20 @@ Trincea grande - Durata di rimozione 大型战壕回填时间 대형참호 제거 시간 + Duração de Remoção de Trincheira Grande 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. 回填一条大型战壕所需的时间(秒)。 대형 참호를 제거할때 필요한 시간을 설정합니다. (초 단위) + Tempo, em segundos, necessário para remover uma trincheira grande. diff --git a/addons/tripod/XEH_postInit.sqf b/addons/tripod/XEH_postInit.sqf index 9fbfaa6c8de..febd71390b5 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 db31a0733fb..b7cdc842e99 100644 --- a/addons/tripod/functions/fnc_adjust.sqf +++ b/addons/tripod/functions/fnc_adjust.sqf @@ -35,8 +35,7 @@ GVAR(adjustPFH) = [{ { _tripod animate [_x, 1 - GVAR(height)]; - } count ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"]; - + } forEach ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"]; }, 0, [_unit, _tripod]] call CBA_fnc_addPerFrameHandler; [_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); diff --git a/addons/tripod/functions/fnc_place.sqf b/addons/tripod/functions/fnc_place.sqf index ecefe127845..0109990ded6 100644 --- a/addons/tripod/functions/fnc_place.sqf +++ b/addons/tripod/functions/fnc_place.sqf @@ -34,7 +34,7 @@ if (stance _unit == "STAND") then { { _tripod animate [_x, 0.5]; - } count ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"]; + } forEach ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"]; [{ (_this select 0) params ["_tripod", "_direction", "_position"]; diff --git a/addons/ui/CfgInGameUI.hpp b/addons/ui/CfgInGameUI.hpp index 8f39984b03c..3e1f28ba204 100644 --- a/addons/ui/CfgInGameUI.hpp +++ b/addons/ui/CfgInGameUI.hpp @@ -1,5 +1,5 @@ class CfgInGameUI { class DefaultAction { - size = QUOTE(profileNamespace getVariable [ARR_2('GVAR(hideDefaultActionIcon)',(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8))]); + size = QUOTE(profileNamespace getVariable [ARR_2('GVAR(hideDefaultActionIcon)',(((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25) * 0.8))]); }; }; diff --git a/addons/ui/XEH_PREP.hpp b/addons/ui/XEH_PREP.hpp index f7edabcc3fa..436e59361c5 100644 --- a/addons/ui/XEH_PREP.hpp +++ b/addons/ui/XEH_PREP.hpp @@ -1,5 +1,4 @@ PREP(compileConfigUI); -PREP(handlePlayerChanged); PREP(handleSpeedIndicator); PREP(moduleInit); PREP(onAnimChanged); diff --git a/addons/ui/XEH_clientInit.sqf b/addons/ui/XEH_clientInit.sqf index 66aa0b3650f..5bf28bc58d4 100644 --- a/addons/ui/XEH_clientInit.sqf +++ b/addons/ui/XEH_clientInit.sqf @@ -1,14 +1,15 @@ #include "script_component.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" // Exit on Headless if (!hasInterface) exitWith {}; // Compile and cache config UI -GVAR(configCache) = call CBA_fnc_createNamespace; +GVAR(configCache) = createHashMap; call FUNC(compileConfigUI); // Scripted API namespace -GVAR(elementsSet) = call CBA_fnc_createNamespace; +GVAR(elementsSet) = createHashMap; // Attach all event handlers where UI has to be updated ["CBA_settingsInitialized", { @@ -19,10 +20,9 @@ GVAR(elementsSet) = call CBA_fnc_createNamespace; ["ace_infoDisplayChanged", { // Selective UI Advanced // Defaults must be set in this EH to make sure controls are activated and advanced settings can be modified - private _force = [true, false] select (GVAR(allowSelectiveUI)); { - [_x, missionNamespace getVariable (format [QGVAR(%1), _x]), false, _force] call FUNC(setAdvancedElement); - } forEach (allVariables GVAR(configCache)); + [_x, missionNamespace getVariable (format [QGVAR(%1), _x]), false, !GVAR(allowSelectiveUI)] call FUNC(setAdvancedElement); + } forEach (keys GVAR(configCache)); // Execute local event for when it's safe to modify UI through this API // infoDisplayChanged can execute multiple times, make sure it only happens once @@ -40,13 +40,33 @@ GVAR(elementsSet) = call CBA_fnc_createNamespace; if (_name in ELEMENTS_BASIC) then { [true] call FUNC(setElements); } else { - private _nameNoPrefix = toLower (_name select [7]); - private _cachedElement = GVAR(configCache) getVariable _nameNoPrefix; - if (!isNil "_cachedElement") then { + private _nameNoPrefix = toLowerANSI (_name select [7]); + if (_nameNoPrefix in GVAR(configCache)) then { [_nameNoPrefix, _value, true] call FUNC(setAdvancedElement); }; }; }] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; -["unit", FUNC(handlePlayerChanged), true] call CBA_fnc_addPlayerEventHandler; +[QUOTE(ADDON), "AnimChanged", LINKFUNC(onAnimChanged), true] call EFUNC(common,addPlayerEH); + + +["ACE3 Common", QGVAR(hideHud), localize LSTRING(hideHud), { + GVAR(hideHud) = !(missionNamespace getVariable [QGVAR(hideHud), false]); + [QGVAR(hideHud), [GVAR(hideHud)]] call CBA_fnc_localEvent; + + private _mask = []; + if (GVAR(hideHud)) then { _mask resize [10, false] }; + [QGVAR(hideHud), _mask] call EFUNC(common,showHud); + + if (missionNamespace getVariable [QGVAR(hideHud_hideChat), true]) then { + showChat !GVAR(hideHud); + }; + + if (!isNil "diwako_dui_main_toggled_off") then { + diwako_dui_main_toggled_off = GVAR(hideHud); // ref https://github.com/diwako/diwako_dui/wiki/Hiding-DUI-for-cutscenes + }; + true +}, +{false}, +[DIK_F12, [false, true, false]], false] call CBA_fnc_addKeybind; // ctrl+f12 diff --git a/addons/ui/functions/fnc_compileConfigUI.sqf b/addons/ui/functions/fnc_compileConfigUI.sqf index 17eaa27308f..960db9aed45 100644 --- a/addons/ui/functions/fnc_compileConfigUI.sqf +++ b/addons/ui/functions/fnc_compileConfigUI.sqf @@ -17,7 +17,7 @@ { private _failure = false; - private _class = toLower (configName _x); + private _class = toLowerANSI (configName _x); private _idd = getNumber (_x >> "idd"); @@ -40,6 +40,6 @@ TRACE_1("Caching Condition",_x); } forEach (configProperties [_x >> "conditions"]); - GVAR(configCache) setVariable [_class, [_idd, _elements, _location, _conditions]]; + GVAR(configCache) set [_class, [_idd, _elements, _location, _conditions]]; }; } forEach ("true" configClasses (configFile >> "ACE_UI")); diff --git a/addons/ui/functions/fnc_handlePlayerChanged.sqf b/addons/ui/functions/fnc_handlePlayerChanged.sqf deleted file mode 100644 index 94f317a18cd..00000000000 --- a/addons/ui/functions/fnc_handlePlayerChanged.sqf +++ /dev/null @@ -1,32 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: veteran29 - * Handles switching units. - * - * Arguments: - * 0: New Unit - * 1: Old Unit - * - * Return Value: - * None - * - * Example: - * [newbob, oldbob] call ace_ui_fnc_handlePlayerChanged - * - * Public: No - */ -params ["_newUnit", "_oldUnit"]; -TRACE_2("unit changed",_newUnit,_oldUnit); - -if (!isNull _oldUnit) then { - _oldUnit removeEventHandler ["AnimChanged", _oldUnit getVariable [QGVAR(animHandler), -1]]; - _oldUnit setVariable [QGVAR(animHandler), nil]; - TRACE_1("remove old",_oldUnit getVariable QGVAR(animHandler)); -}; - -// Don't add a new EH if the unit respawned -if (_newUnit getVariable [QGVAR(animHandler), -1] == -1) then { - private _animHandler = _newUnit addEventHandler ["AnimChanged", LINKFUNC(onAnimChanged)]; - TRACE_1("add new",_animHandler); - _newUnit setVariable [QGVAR(animHandler), _animHandler]; -}; diff --git a/addons/ui/functions/fnc_setAdvancedElement.sqf b/addons/ui/functions/fnc_setAdvancedElement.sqf index 6751d9700c3..86a11348020 100644 --- a/addons/ui/functions/fnc_setAdvancedElement.sqf +++ b/addons/ui/functions/fnc_setAdvancedElement.sqf @@ -20,7 +20,9 @@ params ["_element", "_show", ["_showHint", false, [true]], ["_force", false, [true]]]; -private _cachedElement = GVAR(configCache) getVariable _element; +_element = toLowerANSI _element; + +private _cachedElement = GVAR(configCache) get _element; if (isNil "_cachedElement") exitWith {TRACE_1("nil element",_this)}; if (!_force && {!GVAR(allowSelectiveUI)}) exitWith { @@ -56,7 +58,7 @@ if ( // Get setting from scripted API if (!_force) then { - private _setElement = GVAR(elementsSet) getVariable _element; + private _setElement = GVAR(elementsSet) get _element; if (!isNil "_setElement") then { _setElement params ["_sourceSet", "_showSet"]; if (_showHint) then { diff --git a/addons/ui/functions/fnc_setElementVisibility.sqf b/addons/ui/functions/fnc_setElementVisibility.sqf index 89b8684af75..938fb2da7de 100644 --- a/addons/ui/functions/fnc_setElementVisibility.sqf +++ b/addons/ui/functions/fnc_setElementVisibility.sqf @@ -29,15 +29,14 @@ if (_source == "" || {_element == ""}) exitWith { WARNING("Source or Element may not be empty strings!"); }; -_element = toLower _element; +_element = toLowerANSI _element; // Verify element is bound -private _cachedElement = GVAR(configCache) getVariable _element; -if (isNil "_cachedElement") exitWith { +if !(_element in GVAR(configCache)) exitWith { WARNING_2("Element '%1' does not exist - modification by '%2' failed.",_element,_source); }; -private _setElement = GVAR(elementsSet) getVariable _element; +private _setElement = GVAR(elementsSet) get _element; private _return = false; if (isNil "_setElement") then { @@ -45,7 +44,7 @@ if (isNil "_setElement") then { private _success = [_element, _show, false, true] call FUNC(setAdvancedElement); if (_success) then { - GVAR(elementsSet) setVariable [_element, [_source, _show]]; + GVAR(elementsSet) set [_element, [_source, _show]]; _return = true; }; } else { @@ -57,7 +56,7 @@ if (isNil "_setElement") then { }; } else { TRACE_3("Unsetting element",_sourceSet,_element,_show); - GVAR(elementsSet) setVariable [_element, nil]; + GVAR(elementsSet) set [_element, nil]; [_element, _show, false, true] call FUNC(setAdvancedElement); _return = true; diff --git a/addons/ui/stringtable.xml b/addons/ui/stringtable.xml index 562abe2765a..2245d88b026 100644 --- a/addons/ui/stringtable.xml +++ b/addons/ui/stringtable.xml @@ -168,6 +168,7 @@ Filigrana per versione in fase di sviluppo 开发建设水印 개발용 빌드 워터마크 + Marca d'agua de versão de desenvolvimento Weapon Name @@ -645,7 +646,7 @@ A modificação da interface do usuário está desabilitada. La personnalisation de l'Interface Utilisateur est désactivée. Изменение пользовательского интерфейса запрещено. - ユーザ インターフェースの変更は無効化されています。 + ユーザ インタフェースの変更は無効化されています。 Modyfikacja interfejsu użytkownika jest wyłączona. Die Modifizierung des UI ist deaktiviert. 사용자 인터페이스 변경이 비활성화 되어 있습니다. @@ -659,7 +660,7 @@ Não é possível modificar um elemento forçado da interface do usuário. Impossible de modifier un élément forcé de l'Interface Utilisateur. Невозможно изменить зафиксированный элемент пользовательского интерфейса. - ユーザ インターフェース要素の強制はできません。 + ユーザ インタフェース要素の強制はできません。 Nie można modyfikować wymuszonego elementu interfejsu użytkownika. Gesperrte UI-Elemente können nicht modifiziert werden. 강제 사용자 인터페이스는 변경하실 수 없습니다. @@ -680,6 +681,7 @@ 启用移动速度指示器 이동 속도 표시기 활성화 Habilitar indicador de velocidad de movimiento + Habilitar indicador de velocidade de movimento Enables movement speed indicator for player character. @@ -692,6 +694,7 @@ 为玩家角色启用移动速度指示器。 플레이어 캐릭터를 위한 이동속도 표시기를 활성화합니다. Habilita el indicador de velocidad de movimiento para el personaje del jugador. + Habilita o indicador de velocidade de movimento do personagem do jogador. Hide Default Action Icon @@ -704,6 +707,7 @@ Standardaktionssymbol ausblenden Masquer l'icône d'action par défaut Nascondi Icona dell'Interazione Standard + Esconder ícone padrão de ação 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. @@ -716,6 +720,16 @@ 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. + Esconde o ícone mostrado automaticamente quando algo está a frente do cursor. É preciso reiniciar o jogo.\nAviso: Não remove a ação em si! É recomendado desvincular a tecla de "Usar ação padrão" para previnir interações indesejadas. + + + Hide all UI + 全てのUIを隠す + Cacher toute l'interface utilisateur. + Скрыть весь интерфейс + 모든 UI 숨기기 + Nascondi tutta l'IU + Ocultar toda la IU diff --git a/addons/vector/RscInGameUI.hpp b/addons/vector/RscInGameUI.hpp index 7e2f7057650..b7a6f25022b 100644 --- a/addons/vector/RscInGameUI.hpp +++ b/addons/vector/RscInGameUI.hpp @@ -51,88 +51,88 @@ class RscInGameUI { class ACE_ScriptedDisplayControlsGroup: RscControlsGroupNoScrollbars { onLoad = "uiNamespace setVariable ['ACE_dlgVector', ctrlParent (_this select 0)];"; idc = 170; - x = "safezoneX"; - y = "safezoneY"; - w = "safezoneW"; - h = "safezoneH"; + x = "safeZoneX"; + y = "safeZoneY"; + w = "safeZoneW"; + h = "safeZoneH"; class controls { class Center: RscPicture { idc = IDC_CENTER; colorText[] = {1,0,0,0.5}; - x = "0.5 - (0.8 / 16 * safezoneW)/2 - safezoneX"; - y = "0.5 - (0.8 / 9 * safezoneH)/2 - safezoneY"; - w = "0.8 / 16 * safezoneW"; - h = "0.8 / 9 * safezoneH"; + x = "0.5 - (0.8 / 16 * safeZoneW)/2 - safeZoneX"; + y = "0.5 - (0.8 / 9 * safeZoneH)/2 - safeZoneY"; + w = "0.8 / 16 * safeZoneW"; + h = "0.8 / 9 * safeZoneH"; }; class Crosshair: Center { idc = IDC_CROSSHAIR; - x = "0.5 - (0.7 / 16 * safezoneW)/2 - safezoneX"; - y = "0.5 - (0.7 / 9 * safezoneH)/2 - safezoneY"; - w = "0.7 / 16 * safezoneW"; - h = "0.7 / 9 * safezoneH"; + x = "0.5 - (0.7 / 16 * safeZoneW)/2 - safeZoneX"; + y = "0.5 - (0.7 / 9 * safeZoneH)/2 - safeZoneY"; + w = "0.7 / 16 * safeZoneW"; + h = "0.7 / 9 * safeZoneH"; }; class Digit0: Center { idc = IDC_DIGIT_0; - x = "(0.54 + 0 * 0.02) * safezoneW"; - y = "0.54 * safezoneH"; - w = "0.5 / 16 * safezoneW"; - h = "0.5 / 9 * safezoneH"; + x = "(0.54 + 0 * 0.02) * safeZoneW"; + y = "0.54 * safeZoneH"; + w = "0.5 / 16 * safeZoneW"; + h = "0.5 / 9 * safeZoneH"; }; class Digit1: Digit0 { idc = IDC_DIGIT_1; - x = "(0.54 + 1 * 0.02) * safezoneW"; + x = "(0.54 + 1 * 0.02) * safeZoneW"; }; class Digit2: Digit0 { idc = IDC_DIGIT_2; - x = "(0.54 + 2 * 0.02) * safezoneW"; + x = "(0.54 + 2 * 0.02) * safeZoneW"; }; class Digit3: Digit0 { idc = IDC_DIGIT_3; - x = "(0.54 + 3 * 0.02) * safezoneW"; + x = "(0.54 + 3 * 0.02) * safeZoneW"; }; class Digit4: Digit0 { idc = IDC_DIGIT_4; - x = "(0.54 + 4 * 0.02) * safezoneW"; + x = "(0.54 + 4 * 0.02) * safeZoneW"; }; class Digit5: Digit0 { idc = IDC_DIGIT_5; - x = "(0.35 + 0 * 0.02) * safezoneW"; + x = "(0.35 + 0 * 0.02) * safeZoneW"; }; class Digit6: Digit0 { idc = IDC_DIGIT_6; - x = "(0.35 + 1 * 0.02) * safezoneW"; + x = "(0.35 + 1 * 0.02) * safeZoneW"; }; class Digit7: Digit0 { idc = IDC_DIGIT_7; - x = "(0.35 + 2 * 0.02) * safezoneW"; + x = "(0.35 + 2 * 0.02) * safeZoneW"; }; class Digit8: Digit0 { idc = IDC_DIGIT_8; - x = "(0.35 + 3 * 0.02) * safezoneW"; + x = "(0.35 + 3 * 0.02) * safeZoneW"; }; class Digit9: Digit0 { idc = IDC_DIGIT_9; - x = "(0.35 + 4 * 0.02) * safezoneW"; + x = "(0.35 + 4 * 0.02) * safeZoneW"; }; class DigitE1: Digit0 { idc = IDC_DIGIT_E1; - x = "(0.39 + 0 * 0.02) * safezoneW"; - y = "0.42 * safezoneH"; + x = "(0.39 + 0 * 0.02) * safeZoneW"; + y = "0.42 * safeZoneH"; }; class DigitE2: DigitE1 { idc = IDC_DIGIT_E2; - x = "(0.39 + 1 * 0.02) * safezoneW"; + x = "(0.39 + 1 * 0.02) * safeZoneW"; }; class DigitE3: DigitE1 { idc = IDC_DIGIT_E3; - x = "(0.39 + 2 * 0.02) * safezoneW"; + x = "(0.39 + 2 * 0.02) * safeZoneW"; }; class DigitE4: DigitE1 { idc = IDC_DIGIT_E4; - x = "(0.39 + 3 * 0.02) * safezoneW"; + x = "(0.39 + 3 * 0.02) * safeZoneW"; }; }; }; diff --git a/addons/vector/functions/fnc_onKeyDown.sqf b/addons/vector/functions/fnc_onKeyDown.sqf index 24a22a5782c..082f22e483e 100644 --- a/addons/vector/functions/fnc_onKeyDown.sqf +++ b/addons/vector/functions/fnc_onKeyDown.sqf @@ -38,7 +38,7 @@ private _fnc_setPFH = { }; GVAR(currentMode) = _this; - GVAR(holdKeyHandler) = [FUNC(onKeyHold), 0, _this] call CBA_fnc_addPerFrameHandler; + GVAR(holdKeyHandler) = [LINKFUNC(onKeyHold), 0, _this] call CBA_fnc_addPerFrameHandler; }; switch (_this select 0) do { diff --git a/addons/vector/functions/fnc_onKeyHold.sqf b/addons/vector/functions/fnc_onKeyHold.sqf index 60a38ba96da..f19039851b6 100644 --- a/addons/vector/functions/fnc_onKeyHold.sqf +++ b/addons/vector/functions/fnc_onKeyHold.sqf @@ -16,7 +16,7 @@ * Public: No */ -if (!((currentWeapon ACE_player) isKindOf ["ACE_Vector", configFile >> "CfgWeapons"])) exitWith { +if !((currentWeapon ACE_player) isKindOf ["ACE_Vector", configFile >> "CfgWeapons"]) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; GVAR(currentMode) = ""; diff --git a/addons/vector/functions/fnc_onKeyUp.sqf b/addons/vector/functions/fnc_onKeyUp.sqf index 11310eb5cf5..b660331e65d 100644 --- a/addons/vector/functions/fnc_onKeyUp.sqf +++ b/addons/vector/functions/fnc_onKeyUp.sqf @@ -22,7 +22,7 @@ private _fnc_setPFH = { }; GVAR(currentMode) = _this;// - GVAR(holdKeyHandler) = [FUNC(onKeyHold), 0, _this] call CBA_fnc_addPerFrameHandler; + GVAR(holdKeyHandler) = [LINKFUNC(onKeyHold), 0, _this] call CBA_fnc_addPerFrameHandler; }; switch (_this select 0) do { diff --git a/addons/vehicle_damage/CfgAmmo.hpp b/addons/vehicle_damage/CfgAmmo.hpp index 408c3e7b157..ad84fbc53cd 100644 --- a/addons/vehicle_damage/CfgAmmo.hpp +++ b/addons/vehicle_damage/CfgAmmo.hpp @@ -21,9 +21,6 @@ class CfgAmmo { 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); diff --git a/addons/vehicle_damage/CfgEventHandlers.hpp b/addons/vehicle_damage/CfgEventHandlers.hpp index 74ffec132ee..f6503c2479b 100644 --- a/addons/vehicle_damage/CfgEventHandlers.hpp +++ b/addons/vehicle_damage/CfgEventHandlers.hpp @@ -1,19 +1,17 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; -class Extended_PostInit_EventHandlers { +class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; -class Extended_PreInit_EventHandlers { +class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; - diff --git a/addons/vehicle_damage/CfgVehicles.hpp b/addons/vehicle_damage/CfgVehicles.hpp index 9ea47711ea9..96a6e956e67 100644 --- a/addons/vehicle_damage/CfgVehicles.hpp +++ b/addons/vehicle_damage/CfgVehicles.hpp @@ -28,6 +28,7 @@ class CfgVehicles { GVAR(engineFireProb) = 0.5; GVAR(detonationDuringFireProb) = 0.2; GVAR(canHaveFireRing) = 0; + EGVAR(cookoff,canHaveFireJet) = 1; }; class Wheeled_APC_F: Car_F { GVAR(hullDetonationProb) = 0.2; @@ -38,6 +39,7 @@ class CfgVehicles { GVAR(engineFireProb) = 0.5; GVAR(detonationDuringFireProb) = 0.2; GVAR(canHaveFireRing) = 0; + EGVAR(cookoff,canHaveFireJet) = 1; }; class APC_Tracked_01_base_F: Tank_F {}; class B_APC_Tracked_01_base_F: APC_Tracked_01_base_F {}; @@ -288,4 +290,3 @@ class CfgVehicles { GVAR(canHaveFireRing) = 1; }; }; - diff --git a/addons/vehicle_damage/XEH_PREP.hpp b/addons/vehicle_damage/XEH_PREP.hpp index 524fe6ea9dd..20075cbd4af 100644 --- a/addons/vehicle_damage/XEH_PREP.hpp +++ b/addons/vehicle_damage/XEH_PREP.hpp @@ -1,13 +1,13 @@ PREP(abandon); PREP(addEventHandler); +PREP(blowOffTurret); PREP(handleBail); -PREP(handleVehicleDamage); PREP(handleCookoff); -PREP(detonate); -PREP(processHit); -PREP(handleDetonation); PREP(handleDamage); -PREP(knockOut); -PREP(addDamage); PREP(handleDamageEjectIfDestroyed); -PREP(blowOffTurret); +PREP(handleDetonation); +PREP(handleVehicleDamage); +PREP(knockOut); +PREP(medicalDamage); +PREP(processHit); +PREP(setDamage); diff --git a/addons/vehicle_damage/XEH_postInit.sqf b/addons/vehicle_damage/XEH_postInit.sqf index ce563302e3d..5e15599735e 100644 --- a/addons/vehicle_damage/XEH_postInit.sqf +++ b/addons/vehicle_damage/XEH_postInit.sqf @@ -1,63 +1,65 @@ #include "script_component.hpp" -["ace_settingsInitialized", { - TRACE_1("settings init",GVAR(enabled)); - if (GVAR(enabled)) then { - [QGVAR(bailOut), { - params ["_center", "_crewman", "_vehicle"]; - TRACE_3("bailOut",_center,_crewman,_vehicle); +// Init eject from destroyed vehicles +// See https://github.com/acemod/ACE3/pull/6330 +// Still valid for Arma 2.16 +{ + [_x, "Init", { + params ["_vehicle"]; - if (isPlayer _crewman) exitWith {}; - if (!alive _crewman || { !( [_crewman] call EFUNC(common,isAwake))} ) exitWith {}; + if (!alive _vehicle) exitWith {}; - unassignVehicle _crewman; - _crewman leaveVehicle _vehicle; - doGetOut _crewman; + TRACE_2("ejectIfDestroyed init",_vehicle,typeOf _vehicle); - private _angle = floor (random 360); - private _dist = (30 + (random 10)); - private _escape = _center getPos [_dist, _angle]; + _vehicle addEventHandler ["HandleDamage", {call FUNC(handleDamageEjectIfDestroyed)}]; + }, true, [], true] call CBA_fnc_addClassEventHandler; +} forEach EJECT_IF_DESTROYED_VEHICLES; - _crewman doMove _escape; - _crewman setSpeedMode "FULL"; - }] call CBA_fnc_addEventHandler; +["CBA_settingsInitialized", { + TRACE_1("settings init",GVAR(enabled)); - ["Tank", "init", LINKFUNC(addEventHandler), true, [], true] call CBA_fnc_addClassEventHandler; - ["Wheeled_APC_F", "init", LINKFUNC(addEventHandler), true, [], true] call CBA_fnc_addClassEventHandler; + if (!GVAR(enabled)) exitWith {}; - if (GVAR(enableCarDamage)) then { - ["Car", "init", LINKFUNC(addEventHandler), true, [], true] call CBA_fnc_addClassEventHandler; - }; + [QGVAR(medicalDamage), LINKFUNC(medicalDamage)] call CBA_fnc_addEventHandler; - // blow off turret effect - /* - Disabled temporarily due to issues with being able to repair tanks after death. Needs work - */ - /*["Tank", "killed", { - if (random 1 < 0.15) then { - (_this select 0) call FUNC(blowOffTurret); - }; - }, true, [], true] call CBA_fnc_addClassEventHandler;*/ - - // event to add a turret to a curator if the vehicle already belonged to that curator - if (isServer) then { - [QGVAR(addTurretToEditable), { - params ["_vehicle", "_turret"]; - - { - _x addCuratorEditableObjects [[_turret], false]; - } forEach (objectCurators _vehicle); - }] call CBA_fnc_addEventHandler; - }; + if (isServer) then { + // To set source and instigator, setDamage must be executed on the server + [QGVAR(setDamage), {(_this select 0) setDamage (_this select 1)}] call CBA_fnc_addEventHandler; }; - // 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; + [QGVAR(bailOut), { + params ["_vehicle", "_unit"]; + + TRACE_2("bailOut",_vehicle,_unit); + + // Ignore players and the dead + if (_unit call EFUNC(common,isPlayer) || {!(_unit call EFUNC(common,isAwake))}) exitWith {}; + + unassignVehicle _unit; + _unit leaveVehicle _vehicle; + doGetOut _unit; + + private _angle = floor (random 360); + private _dist = 30 + (random 10); + private _escape = _vehicle getPos [_dist, _angle]; + + _unit doMove _escape; + _unit setSpeedMode "FULL"; + }] call CBA_fnc_addEventHandler; + + GVAR(vehicleClassesHitPointHash) = createHashMap; + + ["Tank", "Init", LINKFUNC(addEventHandler), true, [], true] call CBA_fnc_addClassEventHandler; + + // Wheeled_APC_F inherits from Car + [["Wheeled_Apc_F", "Car"] select GVAR(enableCarDamage), "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); + }; + }] call CBA_fnc_addClassEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/vehicle_damage/config.cpp b/addons/vehicle_damage/config.cpp index 6b4f7cf685d..24b2abda5ba 100644 --- a/addons/vehicle_damage/config.cpp +++ b/addons/vehicle_damage/config.cpp @@ -7,7 +7,7 @@ class CfgPatches { weapons[] = {}; requiredVersion = REQUIRED_VERSION; // ammo/vehicle config defines touch all of these - requiredAddons[] = { "ace_common", "ace_cookoff" }; + requiredAddons[] = {"ace_common", "ace_cookoff"}; author = ECSTRING(common,ACETeam); authors[] = {"tcvm"}; url = ECSTRING(main,URL); diff --git a/addons/vehicle_damage/functions/fnc_abandon.sqf b/addons/vehicle_damage/functions/fnc_abandon.sqf index 6a9d4eeb296..3539e21a976 100644 --- a/addons/vehicle_damage/functions/fnc_abandon.sqf +++ b/addons/vehicle_damage/functions/fnc_abandon.sqf @@ -4,27 +4,34 @@ * Forces the AI currently in a vehicle to bail out. * * Arguments: - * 0: The vehicle in which to bail out + * 0: Vehicle * * Return Value: * None * * Example: - * [tank2] call ace_vehicle_damage_fnc_abandon; + * cursorObject call ace_vehicle_damage_fnc_abandon * * Public: No */ params ["_vehicle"]; -TRACE_2("abandon",_vehicle,(crew _vehicle) select {alive _x}); + +// Check for API +if (_vehicle getVariable [QGVAR(allowCrewInImmobile), false]) exitWith { + TRACE_1("API prevented crew from dismounting",_vehicle); +}; + +TRACE_1("abandon",_vehicle); [{ params ["_vehicle"]; + _vehicle allowCrewInImmobile false; - private _center = getPosASL _vehicle; - TRACE_2("bailing out crew after delay",_vehicle,_center); + TRACE_2("bailing out crew after delay",_vehicle,crew _vehicle); + { - [QGVAR(bailOut), [_center, _x, _vehicle], _x] call CBA_fnc_targetEvent; - } forEach crew _vehicle; -}, _this, random MAX_CREW_BAILOUT_TIME] call CBA_fnc_waitAndExecute; + [QGVAR(bailOut), [_vehicle, _x], _x] call CBA_fnc_targetEvent; + } forEach (crew _vehicle); +}, _vehicle, 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 deleted file mode 100644 index 75d72da3406..00000000000 --- a/addons/vehicle_damage/functions/fnc_addDamage.sqf +++ /dev/null @@ -1,42 +0,0 @@ -#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 isEqualTo "hitengine" && { _damage > 0.9 }) then { - _vehicle call EFUNC(cookoff,engineFire); -}; diff --git a/addons/vehicle_damage/functions/fnc_addEventHandler.sqf b/addons/vehicle_damage/functions/fnc_addEventHandler.sqf index 3697ff2cf9d..3fdbf9ec20c 100644 --- a/addons/vehicle_damage/functions/fnc_addEventHandler.sqf +++ b/addons/vehicle_damage/functions/fnc_addEventHandler.sqf @@ -1,110 +1,137 @@ #include "..\script_component.hpp" /* - * Author: tcvm + * Author: tcvm, johnb43 * Adds the event handler to a vehicle. * * Arguments: - * 0: The vehicle in which to add the event handler to + * 0: Vehicle * * Return Value: * None * * Example: - * [tank2] call ace_vehicle_damage_fnc_addEventHandler; + * cursorObject call ace_vehicle_damage_fnc_addEventHandler * * Public: No */ -params["_vehicle"]; +params ["_vehicle"]; TRACE_2("addEventHandler",_vehicle,GVAR(enabled)); -if !(GVAR(enabled)) exitWith { +if (!GVAR(enabled)) exitWith { #ifdef DEBUG_MODE_FULL - [{ ["Warning: Vehicle Damage not enabled...", 2] call CBA_fnc_notify; }, [], 5] call CBA_fnc_waitAndExecute; + [CBA_fnc_notify, ["Warning: Vehicle Damage not enabled", 2], 5] call CBA_fnc_waitAndExecute; #endif }; -private _hitpointHash = [[], nil] call CBA_fnc_hashCreate; +if (!isNil {_vehicle getVariable QGVAR(handleDamage)}) exitWith {}; + +_vehicle allowCrewInImmobile true; + +// No clue why, but for some reason this needs to be exec'd next frame or else it isn't the last event handler in the system. +// Maybe its overridden somewhere else, but this makes sure it is the last one +[{ + params ["_vehicle"]; + + if (!isNil {_vehicle getVariable QGVAR(handleDamage)}) exitWith {}; + + TRACE_1("added eh",_vehicle); + + _vehicle setVariable [QGVAR(hitHash), createHashMap]; + _vehicle setVariable [QGVAR(handleDamage), _vehicle addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}]]; +}, _vehicle] call CBA_fnc_execNextFrame; + +private _typeOf = typeOf _vehicle; + +if (_typeOf in GVAR(vehicleClassesHitPointHash)) exitWith {}; + +private _hitPointHash = createHashMap; 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; +private _hitPointsConfig = _vehicleConfig >> "HitPoints"; // Add hitpoint names to config for quick lookup { - _x params ["_hitpoints", "_type"]; + _x params ["_hitPoints", "_hitArea"]; + { - [_hitpointHash, toLower _x, [_type, _hitpointsConfig >> _x, _x]] call CBA_fnc_hashSet; - } forEach _hitpoints; + _hitPointHash set [toLowerANSI _x, [_hitArea, abs getNumber (_hitPointsConfig >> _x >> "minimalHit")]]; + } 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"]; +// Gun and turret hitpoints aren't hardcoded anymore - dig through config to find correct names +private _fnc_iterateThroughConfig = { + params ["_config"]; TRACE_1("checking config",_config); - private _configName = 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 _configName = toLowerANSI configName _config; + private _isGun = getNumber (_config >> "isGun") == 1; + private _isTurret = getNumber (_config >> "isTurret") == 1; private _isEra = _configName in _eraHitpoints; private _isSlat = _configName in _slatHitpoints; private _isMisc = false; - // prevent incompatibilites with old mods - if ((toLower _configName) isEqualTo "hitturret") then { + // Prevent incompatibilites with old mods + if (_configName == "hitturret") then { _isTurret = true; }; - if ((toLower _configName) isEqualTo "hitgun") then { + + if (_configName == "hitgun") then { _isGun = true; }; - private _hash = _vehicle getVariable QGVAR(hitpointHash); { - _x params ["_hitType", "_hitPoints"]; - if ((toLower _configName) in _hitPoints) then { - [_hash, toLower _configName, [_hitType, _config, _configName]] call CBA_fnc_hashSet; + _x params ["_hitArea", "_hitPoints"]; + + if (_configName in _hitPoints) then { + _hitPointHash set [_configName, [_hitArea, abs getNumber (_config >> "minimalHit")]]; _isMisc = true; }; - } forEach _hitpointAliases; + } 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, toLower _configName, ["gun", _config, _configName]] call CBA_fnc_hashSet; + _hitPointHash set [_configName, ["gun", abs getNumber (_config >> "minimalHit")]]; }; if (_isTurret) then { - [_hash, toLower _configName, ["turret", _config, _configName]] call CBA_fnc_hashSet; + _hitPointHash set [_configName, ["turret", abs getNumber (_config >> "minimalHit")]]; }; if (_isEra) then { - [_hash, toLower _configName, ["era", _config, _configName]] call CBA_fnc_hashSet; + _hitPointHash set [_configName, ["era", abs getNumber (_config >> "minimalHit")]]; }; if (_isSlat) then { - [_hash, toLower _configName, ["slat", _config, _configName]] call CBA_fnc_hashSet; + _hitPointHash set [_configName, ["slat", abs getNumber (_config >> "minimalHit")]]; }; - _vehicle setVariable [QGVAR(hitpointHash), _hash]; + + TRACE_6("found gun/turret/era/slat/misc",_isGun,_isTurret,_isEra,_isSlat,_isMisc,_hash); } else { { - [_vehicle, _x, _iterateThroughConfig, _hitpointAliases] call _iterateThroughConfig; + _x call _fnc_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; +private _turretConfig = _vehicleConfig >> "Turrets"; +private _eraHitpoints = (getArray (_vehicleConfig >> QGVAR(eraHitpoints))) apply {toLowerANSI _x}; +private _slatHitpoints = (getArray (_vehicleConfig >> QGVAR(slatHitpoints))) apply {toLowerANSI _x}; -_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; +private _fnc_toLowerCase = { + _this apply { + if (_x isEqualType []) then { + _x call _fnc_toLowerCase + } else { + toLowerANSI _x + }; + }; }; + +// Convert areas to lower case +private _hitPointAliases = (getArray (_vehicleConfig >> QGVAR(hitpointAlias))) call _fnc_toLowerCase; + +TRACE_1("hitpoint alias",_hitPointAliases); + +_hitPointsConfig call _fnc_iterateThroughConfig; +_turretConfig call _fnc_iterateThroughConfig; + +GVAR(vehicleClassesHitPointHash) set [_typeOf, _hitPointHash]; + +nil diff --git a/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf b/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf index a036f0045b5..9c9e5036da6 100644 --- a/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf +++ b/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf @@ -4,24 +4,24 @@ * Blow off turret effect. * * Arguments: - * 0: Vehicle + * 0: Vehicle * * Return Value: * None * * Example: - * (vehicle player) call ace_vehicle_damage_fnc_blowOffTurret + * cursorObject 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 +// 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"]; + TRACE_1("blowOffTurret",_vehicle); - private _config = _vehicle call CBA_fnc_getObjectConfig; - getArray (_config >> QGVAR(turret)) params [["_model", "", [""]], ["_offset", [0,0,0], [[]], 3]]; + (getArray (configOf _vehicle >> QGVAR(turret))) params [["_model", "", [""]], ["_offset", [0, 0, 0], [[]], 3]]; if (_model isEqualTo "") exitWith {}; @@ -31,6 +31,8 @@ _turret setVectorUp [random 1, random 1, 1]; _turret setVelocity [random 7, random 7, 8 + random 5]; - // add turret to all curators that already own the wreck - [QGVAR(addTurretToEditable), [_vehicle, _turret]] call CBA_fnc_serverEvent; + // Add turret to all curators that already own the wreck + if (["ace_zeus"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(zeus,addObjects), [[_turret], objectCurators _vehicle]] call CBA_fnc_serverEvent; + }; }, _this, 1] call CBA_fnc_waitAndExecute; diff --git a/addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf b/addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf deleted file mode 100644 index 813e97a7667..00000000000 --- a/addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf +++ /dev/null @@ -1,118 +0,0 @@ -#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 toLower _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 deleted file mode 100644 index 67d64da442b..00000000000 --- a/addons/vehicle_damage/functions/fnc_detonate.sqf +++ /dev/null @@ -1,35 +0,0 @@ -#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) - * 2: An array of vehicle ammo in vehicle (default: []) - * - * Return Value: - * None - * - * Example: - * [tank2] call ace_vehicle_damage_fnc_detonate; - * - * Public: No - */ - -params ["_vehicle", ["_injurer", objNull], ["_vehicleAmmo", []]]; - -if (_vehicleAmmo isEqualTo []) then { - _vehicleAmmo = [_vehicle] call EFUNC(cookoff,getVehicleAmmo); -}; - -([_vehicle] + _vehicleAmmo) call EFUNC(cookoff,detonateAmmunition); - -if ((_vehicleAmmo select 1) > 0) then { - { - // random amount of injuries - for "_i" from 0 to random 5 do { - [_x, random 1 , selectRandom ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"], selectRandom ["bullet", "shell", "explosive"], _injurer] call EFUNC(medical,addDamageToUnit); - }; - } forEach crew _vehicle; -}; diff --git a/addons/vehicle_damage/functions/fnc_handleBail.sqf b/addons/vehicle_damage/functions/fnc_handleBail.sqf index 97aad2cd321..6c9f23c82bc 100644 --- a/addons/vehicle_damage/functions/fnc_handleBail.sqf +++ b/addons/vehicle_damage/functions/fnc_handleBail.sqf @@ -4,64 +4,66 @@ * Handles whether or not the crew should bail. * * Arguments: - * 0: The vehicle - * 1: Can the vehicle move? - * 2: Can the vehicle shoot? + * 0: Vehicle * * Return Value: * None * * Example: - * [tank1, false, true] call ace_vehicle_damage_fnc_handleBail + * cursorObject call ace_vehicle_damage_fnc_handleBail * * Public: No */ -params ["_vehicle", "_canMove", "_canShoot"]; -private _isCar = (_vehicle isKindOf "Car" && { !(_vehicle isKindOf "Wheeled_APC_F") }); +params ["_vehicle"]; +TRACE_1("handleBail",_vehicle); -if (_canMove) then { - _canMove = alive driver _vehicle; -}; +private _isCar = _vehicle isKindOf "Car" && {!(_vehicle isKindOf "Wheeled_APC_F")}; -if (_canShoot) then { - _canShoot = alive gunner _vehicle; -}; +// canFire command is broken, hence the variable +private _canMove = (_vehicle getVariable [QGVAR(canMove), true]) && {alive driver _vehicle}; +private _canShoot = (_vehicle getVariable [QGVAR(canShoot), true]) && {alive gunner _vehicle}; -_vehicle setVariable[QGVAR(canMove), _canMove]; -_vehicle setVariable[QGVAR(canShoot), _canShoot]; +_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); + if (!_canMove) then { + _vehicle call FUNC(abandon); + + TRACE_3("car immobile - bailing",_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 you can't move and you can't shoot, you better GTFO + if (!_canMove && !_canShoot) exitWith { + _vehicle call FUNC(abandon); + + TRACE_3("immobile and can't shoot - bailing",_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); + if (!_canShoot) then { + // 50% chance of bailing out if turret/gun is disabled + if (BAILOUT_CHANCE_SHOOT > _rand) then { + _vehicle call FUNC(abandon); + + TRACE_4("can't shoot - bailing",_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); + + TRACE_4("fleeing",_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); + if (!_canMove) then { + // 80% Chance of bailing out if engine is disabled + if (BAILOUT_CHANCE_MOVE > _rand) then { + _vehicle call FUNC(abandon); + + TRACE_4("immobile - bailing",_vehicle,_rand,_canMove,_canShoot); } else { - LOG_4("[%1] Cannot move and is bunkering with chance [%2] [%3 | %4]",_vehicle,_rand,_canMove,_canShoot); + TRACE_4("immobile - bunkering",_vehicle,_rand,_canMove,_canShoot); }; }; }; - - diff --git a/addons/vehicle_damage/functions/fnc_handleCookoff.sqf b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf index a6e73355425..4b84e9a76e9 100644 --- a/addons/vehicle_damage/functions/fnc_handleCookoff.sqf +++ b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf @@ -1,71 +1,82 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Checks hitpoint damage and determines if a vehicle should cookoff. + * Checks hitpoint damage and determines if a vehicle should cook off. * * Arguments: - * 0: The vehicle + * 0: 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) + * 3: Source of damage + * 4: Person who caused damage + * 5: Part of vehicle which got hit (default: "") + * 6: Whether or not the vehicle can spawn ring-fire effect (default: false) + * 7: Whether or not the vehicle can spawn jet-fire effect (default: true) * * Return Value: - * If cooked off + * If vehicle started or already cooking off * * Example: - * [tank2, 0.1, 5] call ace_vehicle_damage_fnc_handleCookoff; + * [cursorObject, 0.1, 5, player, player] call ace_vehicle_damage_fnc_handleCookoff * * Public: No */ -params ["_vehicle", "_chanceOfFire", "_intensity", ["_injurer", objNull], ["_hitPart", ""], ["_canRing", false], ["_canJet", true]]; - -private _alreadyCookingOff = _vehicle getVariable [QGVAR(cookingOff), false]; - -if (!_alreadyCookingOff && { _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 (toLower _hitPart isEqualTo "engine") then { - _source = ["hit_engine_point", "HitPoints"]; - }; - - // sending nil for _maxIntensity (9th param) to use default value in ace_cookoff_fnc_cookOff - [QEGVAR(cookOff,cookOff), [_vehicle, _intensity, _injurer, _delayWithSmoke, _fireDetonateChance, _detonateAfterCookoff, _source, _canRing, nil, _canJet]] call CBA_fnc_localEvent; - _vehicle setVariable [QGVAR(cookingOff), true]; - LOG_4("Cooking-off [%1] with a chance-of-fire [%2] - Delayed Smoke | Detonate after cookoff [%3 | %4]",_vehicle,_chanceOfFire,_delayWithSmoke,_detonateAfterCookoff); - [_vehicle] spawn FUNC(abandon); - LOG_1("[%1] is on fire is bailing",_vehicle); - - // cant setVehicleAmmo 0 here because it removes FFV unit's ammo - if (GVAR(removeAmmoDuringCookoff)) then { - private _ammo = [_vehicle] call EFUNC(cookoff,getVehicleAmmo); - _ammo params ["_magazines"]; - TRACE_1("removing magazines",_magazines); - { - _x params ["_magazine"]; - _vehicle removeMagazines _magazine; - } forEach _magazines; - }; - true +params ["_vehicle", "_chanceOfFire", "_intensity", "_source", "_instigator", ["_hitPart", ""], ["_canRing", true], ["_canJet", true]]; +TRACE_8("handleCookoff",_vehicle,_chanceOfFire,_intensity,_source,_instigator,_hitPart,_canRing,_canJet); + +// Ignore if the vehicle is already cooking off +if (_vehicle getVariable [QEGVAR(cookoff,isCookingOff), false]) exitWith { + TRACE_3("already cooking off",_vehicle,_chanceOfFire,_intensity); + + true // return +}; + +_chanceOfFire = _chanceOfFire * EGVAR(cookoff,probabilityCoef); + +// Failure to cook off +if (_chanceOfFire == 0 || {_chanceOfFire < random 1}) exitWith { + TRACE_3("no cook-off",_vehicle,_chanceOfFire,_intensity); + + false // return +}; + +// Vehicle will cook off +private _configOf = configOf _vehicle; +private _fireDetonateChance = getNumber (_configOf >> QGVAR(detonationDuringFireProb)); + +if (_canRing) then { + _canRing = getNumber (_configOf >> QGVAR(canHaveFireRing)) == 1; +}; + +if (_canJet) then { + _canJet = getNumber (_configOf >> QEGVAR(cookoff,canHaveFireJet)) == 1; +}; + +private _delaySmoke = _chanceOfFire < random 1; +private _detonateAfterCookoff = (_fireDetonateChance / 4) > random 1; + +private _sourceHitpoint = ""; + +// Passed to the selectionPosition command in cookoff +if (_hitPart == "engine") then { + private _hitPoints = getAllHitPointsDamage _vehicle; + + if (_hitPoints isEqualTo []) exitWith {}; + + // Get hitpoint for engine + private _index = (_hitPoints select 0) findIf {_x == "hitengine"}; + + if (_index == -1) exitWith {}; + + // Get corresponding selection + _sourceHitpoint = [(_hitPoints select 1) select _index, "HitPoints", "AveragePoint"]; }; -// Avoid RPT spam -if (_alreadyCookingOff) exitWith { true }; +[QEGVAR(cookOff,cookOffServer), [_vehicle, _intensity, _source, _instigator, _delaySmoke, _fireDetonateChance, _detonateAfterCookoff, _sourceHitpoint, _canRing, _canJet]] call CBA_fnc_serverEvent; +TRACE_4("cooking-off",_vehicle,_chanceOfFire,_delaySmoke,_detonateAfterCookoff); + +// Abandon vehicle +_vehicle call FUNC(abandon); -LOG_2("[%1] No Cook-off - Chance of fire [%2]",_vehicle,_chanceOfFire); -false +true // return diff --git a/addons/vehicle_damage/functions/fnc_handleDamage.sqf b/addons/vehicle_damage/functions/fnc_handleDamage.sqf index 51bf1be97da..09a2b6f4c2b 100644 --- a/addons/vehicle_damage/functions/fnc_handleDamage.sqf +++ b/addons/vehicle_damage/functions/fnc_handleDamage.sqf @@ -4,91 +4,91 @@ * 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) + * 0: Vehicle + * 1: Selection + * 2: New level of damage + * 3: Source of damage * 4: Projectile that caused damage - * 5: Hit part index of hit point - * 6: Instigator of damage (unused) - * 7: Hit point config name + * 5: Hit index + * 6: Person who caused damage + * 7: Hit point * * Return Value: - * Current or maximum damage of part + * Current or maximum damage of part * * Example: - * [myVehicle, projectile, 5, 0.663] call ace_vehicle_damage_fnc_handleDamage; + * [cursorObject, "hit_engine_point", 0.5, player, projectile, 1, player, "HitEngine"] 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); +params ["_vehicle", "_selection", "_newDamage", "_source", "_projectile", "_hitIndex", "_instigator", "_hitPoint", "", "_context"]; +TRACE_9("handleDamage",_vehicle,_selection,_newDamage,_source,_projectile,_hitIndex,_instigator,_hitPoint,_context); -private _returnHit = if (_hitSelection isNotEqualTo "") then { +if (!local _vehicle) exitWith {}; + +// Killing units via End key is an edge case (#10375) +if (_context == 0 && {_newDamage == 1 && _projectile == "" && isNull _source && isNull _instigator}) exitWith {_newDamage}; + +private _currentDamage = if (_selection != "") 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]; + // If an invalid hit, don't process it + if (_newDamage <= 0 || {"#light" in _hitPoint}) exitWith {}; + + // Set up hit array so we can execute all damage next frame. Always in order of hit done. + private _hitHash = _vehicle getVariable QGVAR(hitHash); + private _currentFrameArray = _hitHash getOrDefault [diag_frameNo, [], true]; + + if (_currentFrameArray isEqualTo []) then { + [{ + params ["_vehicle", "_processingFrame"]; + + private _hitHash = _vehicle getVariable QGVAR(hitHash); + private _hitArray = _hitHash deleteAt _processingFrame; + + if (_hitArray isEqualTo []) exitWith {}; + + TRACE_3("processing data from old frame",diag_frameNo,_processingFrame,_hitArray); + + // Start from newest damage and work backwards + { + _x params ["_vehicle", "_selection", "_newDamage", "_source", "_projectile", "_hitIndex", "_instigator", "_hitPoint"]; + + private _currentDamage = if (_selection != "") then { + _vehicle getHitIndex _hitIndex + } else { + damage _vehicle + }; + + private _addedDamage = _newDamage - _currentDamage; + + TRACE_1("handleDamage",_currentDamage); + + if !([_vehicle, _hitPoint, _hitIndex, _selection, _addedDamage, _projectile, _source, _instigator] call FUNC(handleVehicleDamage)) exitWith { + TRACE_2("cancelling rest of vehicle damage queue",(count (_hitArray#1)) - _forEachIndex,count (_hitArray#1)) + }; + } forEachReversed _hitArray; + }, [_vehicle, diag_frameNo]] call CBA_fnc_execNextFrame; }; + + _currentFrameArray pushBack _this; }; -// 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)); +// 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 == _hitPoint}; + +if (_criticalDamageIndex != -1) then { + _currentDamage = _currentDamage min (CRITICAL_HITPOINTS_THRESHOLDS select _criticalDamageIndex); }; -if (_hitPoint isEqualTo "" && _hitIndex < 0) then { - _returnHit = _returnHit min 0.89; +if (_hitPoint == "" && {_hitIndex < 0}) then { + _currentDamage = _currentDamage min 0.89; }; -_returnHit +_currentDamage diff --git a/addons/vehicle_damage/functions/fnc_handleDamageEjectIfDestroyed.sqf b/addons/vehicle_damage/functions/fnc_handleDamageEjectIfDestroyed.sqf index fdf6f9c6d3a..8169e140e2c 100644 --- a/addons/vehicle_damage/functions/fnc_handleDamageEjectIfDestroyed.sqf +++ b/addons/vehicle_damage/functions/fnc_handleDamageEjectIfDestroyed.sqf @@ -20,7 +20,7 @@ params ["_vehicle", "", "", "", "_ammo"]; if (alive _vehicle) exitWith {}; -TRACE_2("ejectIfDestroyed HDEH",typeOf _vehicle,_this); +TRACE_2("handleDamageEjectIfDestroyed",typeOf _vehicle,_this); if (!IS_EXPLOSIVE_AMMO(_ammo)) then { { @@ -30,4 +30,5 @@ if (!IS_EXPLOSIVE_AMMO(_ammo)) then { } forEach crew _vehicle; }; +//IGNORE_PRIVATE_WARNING ["_thisEventHandler"]; _vehicle removeEventHandler ["HandleDamage", _thisEventHandler]; diff --git a/addons/vehicle_damage/functions/fnc_handleDetonation.sqf b/addons/vehicle_damage/functions/fnc_handleDetonation.sqf index 9556cea424d..9fdaa3b0c27 100644 --- a/addons/vehicle_damage/functions/fnc_handleDetonation.sqf +++ b/addons/vehicle_damage/functions/fnc_handleDetonation.sqf @@ -1,38 +1,59 @@ #include "..\script_component.hpp" /* - * Author: tcvm - * Checks hitpoint damage and determines if a vehicle should cookoff. + * Author: tcvm, johnb43 + * Checks hitpoint damage and determines if a vehicle should detonate its ammo. * * Arguments: - * 0: The vehicle + * 0: 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) + * 2: If the vehicle should be knocked out + * 3: If the crew should be injured + * 4: Source of damage + * 5: Person who caused damage * * Return Value: - * Detonated + * None * * Example: - * [tank2, 0.5] call ace_vehicle_damage_fnc_handleDetonation; + * [cursorObject, 0.5, true, player, player] call ace_vehicle_damage_fnc_handleDetonation * * Public: No */ -params ["_vehicle", "_chanceOfDetonate", "_vehicleAmmo", "_explosiveAmmoCount", "_nonExplosiveAmmoCount", ["_injurer", objNull]]; -private _alreadyDetonating = _vehicle getVariable [QGVAR(detonating), false]; -private _isKnockedOut = _explosiveAmmoCount > 0; +params ["_vehicle", "_chanceToDetonate", "_knockOut", "_injureCrew", "_source", "_instigator"]; -if (!_alreadyDetonating && { _chanceOfDetonate >= random 1 }) exitWith { - [_vehicle, _injurer, _vehicleAmmo] call FUNC(detonate); - LOG_2("Detonating [%1] with a chance-to-detonate [%2]",_vehicle,_chanceOfDetonate); - _vehicle setVariable [QGVAR(detonating), true]; - _isKnockedOut +// Ignore if the vehicle is already detonating ammo +if (_vehicle getVariable [QEGVAR(cookoff,isAmmoDetonating), false]) exitWith { + TRACE_2("already detonating",_vehicle,_chanceToDetonate); + + if (_knockOut) then { + [_vehicle, _source, _instigator] call FUNC(knockOut); + }; + + _knockOut // return +}; + +// Failure to detonate +if (_chanceToDetonate == 0 || {_chanceToDetonate < random 1}) exitWith { + TRACE_2("no detonation",_vehicle,_chanceToDetonate); + + false // return }; -// Avoid RPT spam -if (_alreadyDetonating) exitWith { _isKnockedOut }; +// Vehicle will be detonated +if (_injureCrew) then { + { + [QGVAR(medicalDamage), [_x, _source, _instigator], _x] call CBA_fnc_targetEvent; + } forEach (crew _vehicle); +}; + +TRACE_2("detonation",_vehicle,_chanceToDetonate); + +// Detonate the vehicle +[QEGVAR(cookoff,detonateAmmunitionServer), [_vehicle, false, _source, _instigator]] call CBA_fnc_serverEvent; + +if (_knockOut) then { + [_vehicle, _source, _instigator] call FUNC(knockOut); +}; -LOG_2("[%1] No Detonation - Chance of detonation [%2]",_vehicle,_chanceOfDetonate); -false +_knockOut // return diff --git a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf index 01f098efb05..b0540de484f 100644 --- a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf +++ b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf @@ -4,96 +4,101 @@ * 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 + * 0: Vehicle + * 1: Hit point + * 2: Hit index + * 3: Selection + * 4: Added damage to part + * 5: Projectile + * 6: Source of damage + * 7: Person who caused damage * * Return Value: - * Whether or not to continue handling last frame's damage + * Whether or not to continue handling last frame's damage * * Example: - * [ace_vehicle_damage_fnc_handleVehicleDamage, tank1, "Hit_Engine", 12]] call CBA_fnc_execNextFrame + * [ace_vehicle_damage_fnc_handleVehicleDamage, [cursorObject, "HitEngine", 12, "hit_engine_point", 0.25, projectile, player, player]] 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]; +params ["_vehicle", "_hitPoint", "_hitIndex", "_selection", "_addedDamage", "_projectile", "_source", "_instigator"]; +TRACE_8("handleVehicleDamage",_vehicle,_hitPoint,_hitIndex,_selection,_addedDamage,_projectile,_source,_instigator); + +if (!alive _vehicle) exitWith { + private _handleDamageEH = _vehicle getVariable [QGVAR(handleDamage), nil]; + + if (!isNil "_handleDamageEH") then { + _vehicle removeEventHandler ["HandleDamage", _handleDamageEH]; }; - LOG_1("Vehicle [%1] no longer alive",_vehicle); - true -}; -_hitPoint = toLower _hitPoint; -private _hitpointHash = _vehicle getVariable [QGVAR(hitpointHash), []]; -private _type = if (_hitpointHash isEqualTo []) then { - "exit" -} else { - ([_hitpointHash, _hitPoint] call CBA_fnc_hashGet) select 0 -}; + TRACE_1("vehicle no longer alive",_vehicle); -if (isNil "_type") then { - _type = "exit"; + false }; -// generic structural damage will be transfered into hull damage for simulation's sake +_hitPoint = toLowerANSI _hitPoint; +private _hitPointHash = GVAR(vehicleClassesHitPointHash) getOrDefault [typeOf _vehicle, createHashMap]; +private _type = (_hitPointHash getOrDefault [_hitPoint, []]) select 0; + +// Generic structural damage will be transfered into hull damage for simulation's sake private _structural = false; -if (_selection isEqualTo "") then { + +if (_selection == "") then { _type = "hull"; _hitPoint = "hithull"; _structural = true; + TRACE_1("structural damage",_selection); - _newDamage = abs _newDamage; + + _addedDamage = abs _addedDamage; }; -if (_type isEqualTo "exit") exitWith { LOG_1("No relevant hitpoints hit [%1]. Exiting",_hitPoint); true }; +if (isNil "_type") exitWith { + TRACE_1("no relevant hitpoints hit, 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]]]; + _vehicle setVariable [QGVAR(hitTime), [CBA_missionTime, _source, [_hitPoint]]]; } else { private _hitPointInOldArray = _hitPoint in (_multHit select 2); - private _withinTime = (CBA_missionTime <= (_multHit select 0) + CONST_TIME) && { _injurer == (_multHit select 1) }; + private _withinTime = (CBA_missionTime <= (_multHit select 0) + CONST_TIME) && {_source == (_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 { + if (_hitPointInOldArray) then { + _vehicle setVariable [QGVAR(hitTime), [CBA_missionTime, _source, [_hitPoint]]]; + } else { private _oldHitPoints = _multHit select 2; _oldHitPoints pushBack _hitPoint; - _vehicle setVariable [QGVAR(hitTime), [CBA_missionTime, _injurer, _oldHitPoints]]; + _vehicle setVariable [QGVAR(hitTime), [CBA_missionTime, _source, _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); + TRACE_3("ignoring multiple hits done to vehicle",_vehicle,_source,_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 }; +TRACE_3("processing hit done to vehicle",_vehicle,_source,CBA_missionTime); -private _canMove = _vehicle getVariable[QGVAR(canMove), true]; -private _canShoot = _vehicle getVariable[QGVAR(canShoot), true]; +if !([_vehicle, _hitPoint, _hitIndex, _addedDamage, _projectile, _source, _instigator] call FUNC(processHit)) exitWith {false}; -if !(_ignoreBailCheck) then { - [_vehicle, _canMove, _canShoot] call FUNC(handleBail); +if (!_ignoreBailCheck) then { + _vehicle call FUNC(handleBail); }; true diff --git a/addons/vehicle_damage/functions/fnc_knockOut.sqf b/addons/vehicle_damage/functions/fnc_knockOut.sqf index 5c8d1697a6f..753255c99f9 100644 --- a/addons/vehicle_damage/functions/fnc_knockOut.sqf +++ b/addons/vehicle_damage/functions/fnc_knockOut.sqf @@ -1,37 +1,37 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Knock out vehicle from battle. Destroy all internal hitpoints. + * Knock out a vehicle from battle by destroying all internal hitpoints. * * Arguments: - * 0: The vehicle + * 0: Vehicle + * 1: Source of damage + * 2: Person who caused damage * * Return Value: * None * * Example: - * [vehicle player] call ace_vehicle_damage_fnc_knockOut + * [cursorObject, player, player] call ace_vehicle_damage_fnc_knockOut * * Public: No */ -params ["_vehicle"]; -private _hash = _vehicle getVariable [QGVAR(hitpointHash), nil]; -if (isNil "_hash") exitWith {}; +params ["_vehicle", "_source", "_instigator"]; +TRACE_3("knockOut",_vehicle,_source,_instigator); -[_hash, { - private _hitpointAlias = _value#0; - if (_hitpointAlias isEqualTo "hull") then { - [_vehicle, -1, _key, 0.89] call FUNC(addDamage); +{ + private _hitArea = _y select 0; + + if (_hitArea == "hull") then { + [_vehicle, _x, -1, 0.89, _source, _instigator] call FUNC(setDamage); } 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); + if (_hitArea in ["fuel", "turret", "gun", "engine"]) then { + if ((0.3 > random 1) || {_hitArea == "engine"}) then { + [_vehicle, _x, -1, 1, _source, _instigator] call FUNC(setDamage); } else { - private _currentDamage = _vehicle getHitpointDamage _key; - [_vehicle, -1, _key, (_currentDamage + (0.3 max random 1)) min 1] call FUNC(addDamage); + [_vehicle, _x, -1, ((_vehicle getHitPointDamage _x) + (0.3 max random 1)) min 1, _source, _instigator] call FUNC(setDamage); }; }; }; -}] call CBA_fnc_hashEachPair; - +} forEach (GVAR(vehicleClassesHitPointHash) getOrDefault [typeOf _vehicle, createHashMap]); diff --git a/addons/vehicle_damage/functions/fnc_medicalDamage.sqf b/addons/vehicle_damage/functions/fnc_medicalDamage.sqf new file mode 100644 index 00000000000..c5234cf1c12 --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_medicalDamage.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Applies medical damage to a unit. + * + * Arguments: + * 0: Target + * 1: Source + * 2: Instigator + * 3: Guarantee death? (default: false) + * + * Return Value: + * None + * + * Example: + * [cursorObject, player, player] call ace_vehicle_damage_fnc_medicalDamage; + * + * Public: No + */ + +params ["_unit", "_source", "_instigator", ["_guaranteeDeath", false]]; + +// Check if unit is invulnerable +if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) exitWith {}; + +if (GETEGVAR(medical,enabled,false)) then { + for "_i" from 0 to floor (4 + random 3) do { + [_unit, random [0, 0.66, 1], selectRandom ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"], selectRandom ["bullet", "shell", "explosive"], _instigator] call EFUNC(medical,addDamageToUnit); + }; +} else { + { + _unit setHitPointDamage [_x, (_unit getHitPointDamage _x) + random [0, 0.66, 1], true, _source, _instigator]; + } forEach ["HitFace", "HitNeck", "HitHead", "HitPelvis", "HitAbdomen", "HitDiaphragm", "HitChest", "HitBody", "HitArms", "HitHands", "HitLegs"]; +}; + +// If guaranteed death is wished +if (_guaranteeDeath && {alive _unit}) then { + [_unit, QGVAR(medicalDamage), _source, _instigator] call EFUNC(common,setDead); +}; diff --git a/addons/vehicle_damage/functions/fnc_processHit.sqf b/addons/vehicle_damage/functions/fnc_processHit.sqf index 17575e8f38f..9c87c4b0374 100644 --- a/addons/vehicle_damage/functions/fnc_processHit.sqf +++ b/addons/vehicle_damage/functions/fnc_processHit.sqf @@ -1,135 +1,132 @@ #include "..\script_component.hpp" /* - * Author: tcvm + * Author: tcvm, johnb43 * 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 + * 0: Vehicle + * 1: Hit point + * 2: Hit index + * 3: Added damage to part + * 4: Projectile + * 5: Source of damage + * 6: Person who caused damage * * Return Value: - * None + * Whether or not to continue handling last frame's damage * * Example: - * [myVehicle, projectile, 5, 0.663] call ace_vehicle_damage_fnc_processHit; + * [cursorObject, "HitEngine", 1, 0.25, projectile, player, player] call ace_vehicle_damage_fnc_processHit * * Public: No */ -params ["_vehicle", "_projectile", "_hitIndex", "_newDamage", "_hitpointData", "_injurer"]; -_hitpointData params ["_hitArea", "_hitpointConfig", "_hitpointName"]; +params ["_vehicle", "_hitPoint", "_hitIndex", "_addedDamage", "_projectile", "_source", "_instigator"]; +TRACE_7("processHit",_vehicle,_hitPoint,_hitIndex,_addedDamage,_projectile,_source,_instigator); -private _return = true; - -if (_newDamage < 0) then { - _newDamage = -_newDamage; -}; +_addedDamage = abs _addedDamage; 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 +private _newPartDamage = _currentPartDamage + _addedDamage; + +// Damage is high enough for immediate destruction +if (_addedDamage >= 15) exitWith { + TRACE_2("immediate destruction - high damage",_addedDamage,_currentPartDamage); + + // Kill everyone inside for very insane damage { - _x setDamage 1; - _x setVariable [QEGVAR(medical,lastDamageSource), _injurer]; - _x setVariable [QEGVAR(medical,lastInstigator), _injurer]; - } forEach crew _vehicle; - _vehicle setDamage 1; - _return = false; - _return + [QGVAR(medicalDamage), [_x, _source, _instigator, true], _x] call CBA_fnc_targetEvent; + } forEach (crew _vehicle); + + // setDamage triggers "Killed" EH in cookoff, which starts ammo cook-off + [QGVAR(setDamage), [_vehicle, [1, true, _source, _instigator]]] call CBA_fnc_serverEvent; + + false }; 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 _warheadTypeStr = toLowerANSI getText (_projectileConfig >> "warheadName"); +private _warheadType = ["he", "ap", "heat", "tandemheat"] find _warheadTypeStr; // numerical index for warhead type for quicker checks. Numbers defined in script_macros.hpp -private _minDamage = [_hitpointConfig >> "minimalHit", "NUMBER", 0] call CBA_fnc_getConfigEntry; -if (_minDamage < 0) then { - _minDamage = -_minDamage; -}; +private _incendiary = [_projectileConfig >> QGVAR(incendiary), "NUMBER", [0.3, 0.1, 1, 1, 0] select _warheadType] call CBA_fnc_getConfigEntry; -private _ammoEffectiveness = 0; -private _projectileExplosive = [_projectileConfig >> "explosive", "NUMBER", 0] call CBA_fnc_getConfigEntry; -private _indirectHit = [_projectileConfig >> "indirectHit", "NUMBER", 0] call CBA_fnc_getConfigEntry; +private _hitPointHash = GVAR(vehicleClassesHitPointHash) getOrDefault [typeOf _vehicle, createHashMap]; +(_hitPointHash getOrDefault [_hitPoint, []]) params ["_hitArea", "_minDamage"]; -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 _projectileExplosive = getNumber (_projectileConfig >> "explosive"); +private _indirectHit = getNumber (_projectileConfig >> "indirectHit"); + +if (_warheadType == WARHEAD_TYPE_AP) then { + // Change damage based on projectile speed (doesn't do this in vanilla Arma believe it or not) + if (!isNull _source) then { + private _airFriction = getNumber (_projectileConfig >> "airFriction"); + private _distance = _source distance _vehicle; + _addedDamage = (1 - _projectileExplosive) * _addedDamage * 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); + +// Added damage can't be 0, so don't need to worry about 0 division here +if (_addedDamage < _minDamage) then { + _penChance = _addedDamage / _minDamage; + + TRACE_5("minimum damage modifying hit",_addedDamage,_penChance,_minDamage,_warheadTypeStr,_hitArea); }; if (_penChance < random 1) exitWith { TRACE_1("didn't penetrate",_penChance); - _return + + true }; if (_minDamage == 0) then { _minDamage = 1; }; -if (_warheadType isEqualTo WARHEAD_TYPE_HE) then { +if (_warheadType == WARHEAD_TYPE_HE) then { private _modifiedIndirectHit = _indirectHit / 100; - if (_newDamage > _modifiedIndirectHit) then { - _newDamage = _newDamage / 2; + + if (_addedDamage > _modifiedIndirectHit) then { + _addedDamage = _addedDamage / 2; }; - _newDamage = (_newDamage * (_newDamage / _modifiedIndirectHit)) min _newDamage; + + _addedDamage = (_addedDamage * (_addedDamage / _modifiedIndirectHit)) min _addedDamage; }; -_ammoEffectiveness = if (_warheadType isEqualTo WARHEAD_TYPE_AP) then { - 0.15 max _newDamage +private _ammoEffectiveness = if (_warheadType == WARHEAD_TYPE_AP) then { + 0.15 max _addedDamage } else { - if (_warheadType isEqualTo WARHEAD_TYPE_HE) then { - (_newDamage / (_minDamage + (_indirectHit / 100)) * 0.2) + if (_warheadType == WARHEAD_TYPE_HE) then { + (_addedDamage / (_minDamage + (_indirectHit / 100)) * 0.2) } else { - ((_newDamage / _minDamage) * 0.4) min 1 + ((_addedDamage / _minDamage) * 0.4) min 1 }; }; -TRACE_4("ammo effectiveness",_ammoEffectiveness,_newDamage,_minDamage,_warheadTypeStr); + +TRACE_4("ammo effectiveness",_ammoEffectiveness,_addedDamage,_minDamage,_warheadTypeStr); _incendiary = _incendiary * _ammoEffectiveness; -private _isCar = (_vehicle isKindOf "Car" && { !(_vehicle isKindOf "Wheeled_APC_F") }); +private _isCar = _vehicle isKindOf "Car" && {!(_vehicle isKindOf "Wheeled_APC_F")}; + if (_isCar) then { - _ammoEffectiveness = (_ammoEffectiveness + (_ammoEffectiveness * 0.5)) min 1; + _ammoEffectiveness = (_ammoEffectiveness * 1.5) min 1; }; -private _currentVehicleAmmo = [_vehicle] call EFUNC(cookoff,getVehicleAmmo); +(_vehicle call EFUNC(cookoff,getVehicleAmmo)) params ["_magazines", "_totalAmmo"]; private _chanceOfDetonation = 0; private _explosiveAmmoCount = 0; -private _nonExplosiveAmmoCount = 0; -if (count (_currentVehicleAmmo select 0) isNotEqualTo 0) then { +if (_magazines 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; @@ -137,215 +134,241 @@ if (count (_currentVehicleAmmo select 0) isNotEqualTo 0) then { 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 { + + if (_explosive > 0.5 || {_hit > 50}) then { _explosiveAmmoCount = _explosiveAmmoCount + 1; - } else { - _nonExplosiveAmmoCount = _nonExplosiveAmmoCount + 1; }; - } forEach (_currentVehicleAmmo select 0); + } forEach _magazines; + if (_countOfExplodableAmmo != 0) then { _chanceOfDetonation = _chanceOfDetonation / _countOfExplodableAmmo; }; }; -private _chanceToDetonate = 0; -private _chanceOfFire = 0; -private _currentFuel = fuel _vehicle; -private _vehicleConfig = _vehicle call CBA_fnc_getObjectConfig; + +private _return = true; + 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 _vehicleConfig = configOf _vehicle; + private _currentFuel = fuel _vehicle; + private _chanceToDetonate = getNumber (_vehicleConfig >> QGVAR(engineDetonationProb)) * _incendiary * _currentFuel * _penChance; - private _cookoffIntensity = 4 * _currentFuel; - TRACE_6("hit engine",_chanceToDetonate,_chanceOfFire,_incendiary,_chanceOfDetonation,_currentFuel,_cookoffIntensity); + TRACE_4("hit engine",_chanceToDetonate,_incendiary,_chanceOfDetonation,_currentFuel); - if (_isCar) then { - _chanceOfFire = 0; // no cookoff for cars - }; + // Knock out and detonate vehicle if necessary + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount > 0, _totalAmmo > 0, _source, _instigator] call FUNC(handleDetonation)) exitWith {}; - if ([_vehicle, _chanceToDetonate, _currentVehicleAmmo, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { - [_vehicle] call FUNC(knockOut); - }; + // Cap damage at 0.9 to avoid hard coded blow up + _newPartDamage = 0.9 min _newPartDamage; - // cap damage at 0.9 to avoid hard coded blow up - _nextPartDamage = (0.9 min _nextPartDamage); + // Fatal engine/drive system damage (engine and tracks stop working at 0.9) + if (0.8 * _ammoEffectiveness > random 1) then { + _newPartDamage = 0.9; + }; - // fatal engine/drive system damage - if (_nextPartDamage == 0.9 || { 0.8 * _ammoEffectiveness > random 1 }) then { - [_vehicle, _hitIndex, _hitpointName, 0.9 * _penChance] call FUNC(addDamage); + if (_newPartDamage == 0.9) then { _vehicle setVariable [QGVAR(canMove), false]; - } else { - [_vehicle, _hitIndex, _hitpointName, _nextPartDamage * _penChance] call FUNC(addDamage); }; - [_vehicle, _chanceOfFire, _cookoffIntensity, _injurer, _hitArea, false] call FUNC(handleCookoff); + [_vehicle, _hitPoint, _hitIndex, _newPartDamage * _penChance, _source, _instigator] call FUNC(setDamage); + + // No cookoff for cars + if (_isCar) exitWith {}; + + private _chanceOfFire = getNumber (_vehicleConfig >> QGVAR(engineFireProb)) * _incendiary * _currentFuel * _penChance; + private _cookoffIntensity = 4 * _currentFuel; + + [_vehicle, _chanceOfFire, _cookoffIntensity, _source, _instigator, "engine", false, 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 _vehicleConfig = configOf _vehicle; + private _currentFuel = fuel _vehicle; + private _chanceToDetonate = getNumber (_vehicleConfig >> QGVAR(hullDetonationProb)) * _incendiary * ((_chanceOfDetonation + _currentFuel) / 2) * _penChance; - private _cookoffIntensity = 1.5 + (_explosiveAmmoCount * _chanceOfFire); - TRACE_6("hit hull",_chanceToDetonate,_chanceOfFire,_incendiary,_chanceOfDetonation,_currentFuel,_cookoffIntensity); + TRACE_4("hit hull",_chanceToDetonate,_incendiary,_chanceOfDetonation,_currentFuel); - if (_isCar) then { - _chanceOfFire = 0; // no cookoff for cars + // Knock out and detonate vehicle if necessary + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount > 0, _totalAmmo > 0, _source, _instigator] call FUNC(handleDetonation)) exitWith { + [_vehicle, _hitPoint, _hitIndex, 0.89 * _penChance, _source, _instigator] call FUNC(setDamage); }; - if ([_vehicle, _chanceToDetonate, _currentVehicleAmmo, _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; + [_vehicle, _hitPoint, _hitIndex, 0.89 * _penChance, _source, _instigator] call FUNC(setDamage); + + // Iterate through all keys and find appropriate turret + { + if ((_y select 0) == "turret") then { + _partKill pushBack _x; }; - }] call CBA_fnc_hashEachPair; + } forEach _hitPointHash; + _vehicle setVariable [QGVAR(canShoot), false]; }; case (_rand < 0.5): { - [_vehicle, _hitIndex, _hitpointName, 0.89 * _penChance] call FUNC(addDamage); - _partKill = _partKill + ENGINE_HITPOINTS#0; + [_vehicle, _hitPoint, _hitIndex, 0.89 * _penChance, _source, _instigator] call FUNC(setDamage); + + _partKill append (ENGINE_HITPOINTS select 0); + if !(_vehicle isKindOf "Wheeled_APC_F") then { - _partKill = _partKill + TRACK_HITPOINTS#0; + _partKill append (TRACK_HITPOINTS select 0); }; _vehicle setVariable [QGVAR(canMove), false]; }; case (_rand < 0.75): { - [_vehicle, _hitIndex, _hitpointName, 0.89 * _penChance] call FUNC(addDamage); - _partKill = _partKill + ENGINE_HITPOINTS#0; + [_vehicle, _hitPoint, _hitIndex, 0.89 * _penChance, _source, _instigator] call FUNC(setDamage); + + _partKill append (ENGINE_HITPOINTS select 0); + if !(_vehicle isKindOf "Wheeled_APC_F") then { - _partKill = _partKill + TRACK_HITPOINTS#0; + _partKill append (TRACK_HITPOINTS select 0); }; - // iterate through all keys and find appropriate turret - [_hash, { - if (_value#0 isEqualTo "turret") then { - _partKill pushBack _key; + // Iterate through all keys and find appropriate turret + { + if ((_y select 0) == "turret") then { + _partKill pushBack _x; }; - }] call CBA_fnc_hashEachPair; + } forEach _hitPointHash; _vehicle setVariable [QGVAR(canMove), false]; _vehicle setVariable [QGVAR(canShoot), false]; }; - default{}; }; }; { + [_vehicle, _x, -1, _penChance, _source, _instigator] call FUNC(setDamage); + 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); + // No cookoff for cars + if (_isCar) exitWith {}; + + private _chanceOfFire = getNumber (_vehicleConfig >> QGVAR(hullFireProb)) * _incendiary * ((_chanceOfDetonation + _currentFuel) / 2) * _penChance; + private _cookoffIntensity = 1.5 + (_explosiveAmmoCount * _chanceOfFire); + + [_vehicle, _chanceOfFire, _cookoffIntensity, _source, _instigator] 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); + private _vehicleConfig = configOf _vehicle; + private _chanceToDetonate = getNumber (_vehicleConfig >> QGVAR(turretDetonationProb)) * _incendiary * _chanceOfDetonation * _penChance; - if (_isCar) then { - _chanceOfFire = 0; // no cookoff for cars - }; + TRACE_3("hit turret",_chanceToDetonate,_incendiary,_chanceOfDetonation); - if ([_vehicle, _chanceToDetonate, _currentVehicleAmmo, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { - [_vehicle] call FUNC(knockOut); - }; + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount > 0, _totalAmmo > 0, _source, _instigator] call FUNC(handleDetonation)) exitWith {}; if (0.8 * _ammoEffectiveness > random 1) then { TRACE_1("damaged turret",_ammoEffectiveness * 0.8); - [_vehicle, _hitIndex, _hitpointName, 1 * _penChance] call FUNC(addDamage); + + [_vehicle, _hitPoint, _hitIndex, _penChance, _source, _instigator] call FUNC(setDamage); + _vehicle setVariable [QGVAR(canShoot), false]; }; - [_vehicle, _chanceOfFire, _cookoffIntensity, _injurer, "", true] call FUNC(handleCookoff); + // No cookoff for cars + if (_isCar) exitWith {}; + + private _chanceOfFire = getNumber (_vehicleConfig >> QGVAR(turretFireProb)) * _incendiary * _chanceOfDetonation * _penChance; + private _cookoffIntensity = _explosiveAmmoCount * _chanceOfFire; + + [_vehicle, _chanceOfFire, _cookoffIntensity, _source, _instigator] call FUNC(handleCookoff); }; case "gun": { - TRACE_5("hit gun",_chanceToDetonate,_chanceOfFire,_incendiary,_chanceOfDetonation,_currentFuel); + TRACE_2("hit gun",_addedDamage,_minDamage); + if (0.8 * _ammoEffectiveness > random 1) then { TRACE_1("damaged gun",_ammoEffectiveness * 0.8); - [_vehicle, _hitIndex, _hitpointName, 1 * _penChance] call FUNC(addDamage); + + [_vehicle, _hitPoint, _hitIndex, _penChance, _source, _instigator] call FUNC(setDamage); + _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); + private _damage = (0.1 max (0.1 * _addedDamage / _minDamage)) min 1; + + [_vehicle, _hitPoint, _hitIndex, (_currentPartDamage + _damage) * _penChance] call FUNC(setDamage); + + TRACE_3("damaged track",_damage,_addedDamage,_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); + [_vehicle, _hitPoint, _hitIndex, (_currentPartDamage + _addedDamage) * _penChance, _source, _instigator] call FUNC(setDamage); + + TRACE_1("damaged wheel",_addedDamage); }; case "fuel": { - _chanceOfFire = (_incendiary * _currentFuel * _penChance) / 2; - private _cookoffIntensity = _currentFuel * 5; - TRACE_2("damaged fuel",_chanceOfFire,_cookoffIntensity); + private _damage = (0.1 max (0.1 * _addedDamage / _minDamage)) min 1; + [_vehicle, _hitPoint, _hitIndex, (_currentPartDamage + _damage) * _penChance, _source, _instigator] call FUNC(setDamage); - if (_isCar) then { - _chanceOfFire = 0; // no cookoff for cars - }; + // No cookoff for cars + if (_isCar) exitWith {}; + + private _currentFuel = fuel _vehicle; + private _chanceOfFire = (_incendiary * _currentFuel * _penChance) / 2; + private _cookoffIntensity = _currentFuel * 5; - [_vehicle, _chanceOfFire, _cookoffIntensity, _injurer, "", false] call FUNC(handleCookoff); + TRACE_4("damaged fuel",_chanceOfFire,_incendiary,_cookoffIntensity,_currentFuel); - private _damage = (0.1 max (0.1 * _newDamage / _minDamage)) min 1; - [_vehicle, _hitIndex, _hitpointName, (_currentPartDamage + _damage) * _penChance] call FUNC(addDamage); + [_vehicle, _chanceOfFire, _cookoffIntensity, _source, _instigator, "", false, false] call FUNC(handleCookoff); }; 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 { + + // Incredibly small chance of AP destroying SLAT + if (_warheadType in [WARHEAD_TYPE_HE, WARHEAD_TYPE_AP, WARHEAD_TYPE_HEAT, WARHEAD_TYPE_TANDEM] || {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); + if (_warheadType in [WARHEAD_TYPE_HEAT, WARHEAD_TYPE_TANDEM, WARHEAD_TYPE_AP]) then { + [_vehicle, _hitPoint, _hitIndex, 1, _source, _instigator] call FUNC(setDamage); } else { - [_vehicle, _hitIndex, _hitpointName, _currentDamage + (0.5 max random 1)] call FUNC(addDamage); + [_vehicle, _hitPoint, _hitIndex, _currentDamage + (0.5 max random 1), _source, _instigator] call FUNC(setDamage); }; - if (_currentDamage < 1 && _warheadType isEqualTo WARHEAD_TYPE_HEAT) then { + if (_currentDamage < 1 && {_warheadType == 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 { + + if (_warheadType in [WARHEAD_TYPE_AP, WARHEAD_TYPE_HEAT, 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 { + [_vehicle, _hitPoint, _hitIndex, 1, _source, _instigator] call FUNC(setDamage); + + // Don't process anymore damage if this is HEAT - shouldn't happen anyway but Arma says it does so you know + if (_currentDamage < 1 && {_warheadType == WARHEAD_TYPE_HEAT}) then { _return = false; }; }; }; default { TRACE_1("hit unknown hitpoint??",_hitArea); - } + }; }; _return diff --git a/addons/vehicle_damage/functions/fnc_setDamage.sqf b/addons/vehicle_damage/functions/fnc_setDamage.sqf new file mode 100644 index 00000000000..8b75bff1f7a --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_setDamage.sqf @@ -0,0 +1,45 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Sets vehicle damage based on HitIndex. Failing that it falls back to HitPoint name. + * + * Arguments: + * 0: Vehicle + * 1: Hit point + * 2: Hit index + * 3: Damage + * 4: Source of damage + * 5: Person who caused damage + * + * Return Value: + * None + * + * Example: + * [cursorObject, "HitEngine", 1, 0.25, player, player] call ace_vehicle_damage_fnc_setDamage + * + * Public: No + */ + +params ["_vehicle", "_hitPoint", "_hitIndex", "_damage", "_source", "_instigator"]; +TRACE_6("setDamage",_vehicle,_hitPoint,_hitIndex,_damage,_source,_instigator); + +private _currentDamage = _vehicle getHitPointDamage _hitPoint; + +if (_damage < _currentDamage) exitWith { + TRACE_3("capping damage at current",_damage,_currentDamage,_hitPoint); +}; + +if (_hitPoint == "#structural") then { + _hitPoint = "hithull"; + _hitIndex = -1; +}; + +if (_hitIndex >= 0) then { + _vehicle setHitIndex [_hitIndex, _damage, true, _source, _instigator]; +} else { + _vehicle setHitPointDamage [_hitPoint, _damage, true, _source, _instigator]; +}; + +if (_hitPoint == "HitEngine" && {_damage >= 0.9}) then { + [QEGVAR(cookoff,engineFireServer), _vehicle] call CBA_fnc_serverEvent; +}; diff --git a/addons/vehicle_damage/initSettings.inc.sqf b/addons/vehicle_damage/initSettings.inc.sqf index ae322a6fd88..3a1bcf568ab 100644 --- a/addons/vehicle_damage/initSettings.inc.sqf +++ b/addons/vehicle_damage/initSettings.inc.sqf @@ -1,29 +1,21 @@ [ - QGVAR(enabled), "CHECKBOX", + QGVAR(enabled), + "CHECKBOX", [ELSTRING(common,Enabled), LSTRING(setting_description)], LSTRING(category_displayName), - false, // default value - true, // isGlobal + false, + 1, {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, true // Needs mission restart -] call CBA_settings_fnc_init; +] call CBA_fnc_addSetting; [ - QGVAR(removeAmmoDuringCookoff), "CHECKBOX", - [LSTRING(removeAmmoAfterCookoff_setting_enable), LSTRING(removeAmmoAfterCookoff_setting_description)], - LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(removeAmmoDuringCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart -] call CBA_settings_fnc_init; - -[ - QGVAR(enableCarDamage), "CHECKBOX", + QGVAR(enableCarDamage), + "CHECKBOX", [LSTRING(carDamage_setting_enable), LSTRING(carDamage_setting_description)], LSTRING(category_displayName), - false, // default value - true, // isGlobal + false, + 1, {[QGVAR(enableCarDamage), _this] call EFUNC(common,cbaSettings_settingChanged)}, true // Needs mission restart -] call CBA_settings_fnc_init; +] call CBA_fnc_addSetting; diff --git a/addons/vehicle_damage/script_macros.hpp b/addons/vehicle_damage/script_macros.hpp index 84f3120ac15..43bac7e2f80 100644 --- a/addons/vehicle_damage/script_macros.hpp +++ b/addons/vehicle_damage/script_macros.hpp @@ -7,21 +7,23 @@ #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 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 CRITICAL_HITPOINTS ["hithull", "hitbody", "#structural", "hitengine"] +#define CRITICAL_HITPOINTS_THRESHOLDS [0.89, 0.89, 0.89, 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; } +#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 index 5581408f745..90203b6bf9e 100644 --- a/addons/vehicle_damage/stringtable.xml +++ b/addons/vehicle_damage/stringtable.xml @@ -3,7 +3,7 @@ ACE Advanced Vehicle Damage - ACE アドバンスドビークルダメージ + ACE 高度な乗り物ダメージ ACE Dégâts de véhicule avancés ACE Erweiterter Fahrzeugsschaden ACE Danni Veicolo Avanzati @@ -12,66 +12,43 @@ ACE 고급 차량 피해 ACE Продвинутое повреждение техники ACE Daño avanzado de vehículos + ACE Dano avançãdo de veículos - Enable/Disable advanced vehicle damage - アドバンスドビークルダメージを有効/無効にする + Enable advanced vehicle damage Active les dégâts de véhicule avancés. - Aktiviert/Deaktiviert den Erweiterten Fahrzeugsschaden + Aktiviert 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) + Włącz zaawansowane uszkodzenia pojazdów + Включить продвинутое повреждение техники + Habilitar el daño avanzado de vehículos + Ativar dano avançado de veículo + 乗り物(Vehicle)に対しての高度なダメージ計算を有効化します + 고급 차량 피해 활성화 - Enable/Disable advanced car damage - アドバンスド車ダメージを有効/無効にする + Enable advanced car damage Dégâts de voiture avancés - Aktiviert/Deaktiviert erweiterten Autoschaden + Aktiviert erweiterten Autoschaden Abilita danni avanzati alle macchine - Włącz/Wyłącz zaawansowane uszkodzenia w samochodach - 启用/禁用高级车辆损坏 - 고급 차량 피해 활성화/비활성화 - Продвинутое повреждение машин - Habilitar/Deshabilitar daño avanzado de coche (Experimental) + Włącz zaawansowane uszkodzenia w samochodach + Habilitar daño avanzado de coche + Habilitar dano avançado para carros + 高度な車ダメージを有効化 + Включить продвинутое повреждение автомобиля + 고급 자동차 피해 활성화 - - Removes all vehicle ammo after cook-off - 誘爆後に車両から全ての弾薬を削除 - Retire toutes les munitions des véhicules après une auto-inflammation. - Entfernt die gesamte Munition nach dem Durchzünden der Munition eines Fahrzeuges. - Rimuove tutte le munizioni dal veicolo dopo l'esplosione delle stesse - Usuwa całą amunicję z pojazdu po samozapłonie - 殉爆后移除所有车辆弹药 - 쿡오프 현상 후 차량에서 모든 탄약을 제거합니다. - Удалять все боеприпасы из техники после их детонации - Elimina toda la munición del vehículo despues ser inducida a detonar por calor - - - Enable/Disable Ammo Removal During Cook-Off - 誘爆中の弾薬除去を有効/無効にする - Retirer les munitions durant l'auto-inflammation - Aktiviert/Deaktiviert Entfernung der Munition beim Durchzünden - 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 + + Enable advanced car damage (Experimental) + Active les dégâts avancés sur les voitures (expérimental). + Aktiviert den Erweiterten Fahrzeugsschaden (Experimentell) + Abilita danni avanzati ai veicoli (sperimentale) + Włącz zaawansowane uszkodzenia w samochodach (eksperymentalne) + Включить продвинутое повреждение машин (экспериментальное) + Habilitar daño avanzado de coche (Experimental) + Habilitar dano avançado para carros (Experimental) + 車(Car)に対しての高度なダメージ計算を有効化します (試験的機能) + 고급 자동차 피해 활성화 (실험용) Wreck (Turret) diff --git a/addons/vehiclelock/XEH_postInit.sqf b/addons/vehiclelock/XEH_postInit.sqf index 40afaf32afc..d16b47aef5d 100644 --- a/addons/vehiclelock/XEH_postInit.sqf +++ b/addons/vehiclelock/XEH_postInit.sqf @@ -1,14 +1,14 @@ #include "script_component.hpp" //Add Event Handlers -[QGVAR(setupCustomKey), {_this call FUNC(serverSetupCustomKeyEH)}] call CBA_fnc_addEventHandler; -[QGVAR(setVehicleLock), {_this call FUNC(setVehicleLockEH)}] call CBA_fnc_addEventHandler; +[QGVAR(setupCustomKey), LINKFUNC(serverSetupCustomKeyEH)] call CBA_fnc_addEventHandler; +[QGVAR(setVehicleLock), LINKFUNC(setVehicleLockEH)] call CBA_fnc_addEventHandler; ["CBA_settingsInitialized", { TRACE_2("SettingsInitialized eh",GVAR(LockVehicleInventory),GVAR(VehicleStartingLockState)); if (hasInterface && {GVAR(LockVehicleInventory)}) then { - ["CAManBase", "InventoryOpened", {_this call FUNC(onOpenInventory)}] call CBA_fnc_addClassEventHandler; + ["CAManBase", "InventoryOpened", LINKFUNC(onOpenInventory)] call CBA_fnc_addClassEventHandler; }; if (isServer && {GVAR(VehicleStartingLockState) != -1}) then { [{ diff --git a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf index d730589b36d..4d0f065c06a 100644 --- a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf @@ -23,14 +23,18 @@ if (!params [["_unit", objNull, [objNull]], ["_veh", objNull, [objNull]], ["_use }; TRACE_3("params",_unit,_veh,_useCustom); -if (isNull _unit) exitWith {ERROR("null unit");}; -if (isNull _veh) exitWith {ERROR("null vehicle");}; +if (isNull _unit) exitWith { + ERROR("null unit"); +}; +if (isNull _veh) exitWith { + ERROR("null vehicle"); +}; if (_useCustom) then { private _previousMags = magazinesDetail _unit; _unit addMagazine ["ACE_key_customKeyMagazine", 1]; //addMagazine array has global effects private _newMags = (magazinesDetail _unit) - _previousMags; - if ((count _newMags) == 0) exitWith {ERROR("failed to add magazine (inventory full?)");}; + if (_newMags isEqualTo []) exitWith {ERROR("failed to add magazine (inventory full?)");}; private _keyMagazine = _newMags select 0; TRACE_2("setting up key on server",_veh,_keyMagazine); //Have the server run add the key to the vehicle's key array: diff --git a/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf b/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf index c5f7e0e35a0..ec58a6fa2c5 100644 --- a/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf @@ -34,4 +34,4 @@ if (_sideKeyName in _items) exitWith {true}; private _customKeys = _veh getVariable [QGVAR(customKeys), []]; private _magazines = magazinesDetail _unit; -(_customKeys findIf {_x in _magazines}) != -1 +_customKeys findAny _magazines != -1 diff --git a/addons/vehiclelock/functions/fnc_lockpick.sqf b/addons/vehiclelock/functions/fnc_lockpick.sqf index 4ef3289b458..7bb29395f0e 100644 --- a/addons/vehiclelock/functions/fnc_lockpick.sqf +++ b/addons/vehiclelock/functions/fnc_lockpick.sqf @@ -33,7 +33,10 @@ if ((locked _veh) == 0) exitWith {false}; if !("ACE_key_lockpick" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; private _vehLockpickStrength = _veh getVariable[QGVAR(lockpickStrength), GVAR(DefaultLockpickStrength)]; -if (!(_vehLockpickStrength isEqualType 0)) exitWith {ERROR("ACE_vehicleLock_LockpickStrength invalid"); false}; +if !(_vehLockpickStrength isEqualType 0) exitWith { + ERROR("ACE_vehicleLock_LockpickStrength invalid"); + false +}; //-1 indicates unpickable lock if (_vehLockpickStrength < 0) exitWith {false}; @@ -45,7 +48,7 @@ private _condition = { ((_unit distance _veh) < 5) && {(speed _veh) < 0.1} }; -if (!([[_unit, _veh]] call _condition)) exitWith {false}; +if !([[_unit, _veh]] call _condition) exitWith {false}; private _returnValue = _funcType in ["canLockpick", "startLockpick", "finishLockpick"]; switch (_funcType) do { diff --git a/addons/vehiclelock/functions/fnc_moduleSync.sqf b/addons/vehiclelock/functions/fnc_moduleSync.sqf index c29c7a06d29..a269fbd6e54 100644 --- a/addons/vehiclelock/functions/fnc_moduleSync.sqf +++ b/addons/vehiclelock/functions/fnc_moduleSync.sqf @@ -22,7 +22,7 @@ if (!isServer) exitWith {}; params ["_logic", "_syncedObjects", "_activated"]; TRACE_3("params",_logic,_syncedObjects,_activated); -if !(_activated) exitWith {WARNING("Vehicle Lock Sync Module - placed but not active");}; +if (!_activated) exitWith {WARNING("Vehicle Lock Sync Module - placed but not active");}; [{ params ["_syncedObjects"]; diff --git a/addons/vehiclelock/initSettings.inc.sqf b/addons/vehiclelock/initSettings.inc.sqf index 9f68c77e7c3..dcb520e7e21 100644 --- a/addons/vehiclelock/initSettings.inc.sqf +++ b/addons/vehiclelock/initSettings.inc.sqf @@ -3,8 +3,7 @@ [LSTRING(DefaultLockpickStrength_DisplayName), LSTRING(DefaultLockpickStrength_Description)], LSTRING(DisplayName), [-1,60,10,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(defaultLockpickStrength), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ diff --git a/addons/vehiclelock/stringtable.xml b/addons/vehiclelock/stringtable.xml index 55600489e84..7c501f74c54 100644 --- a/addons/vehiclelock/stringtable.xml +++ b/addons/vehiclelock/stringtable.xml @@ -79,8 +79,8 @@ Взламываем замок... Scassinando il veicolo... Usando Mixa... - 鍵をこじ開けている・・・ - 문따는 중... + 鍵をこじ開けています・・・ + 문 따는 중... 正在开锁... 解鎖中... Maymuncuklanıyor... @@ -144,7 +144,7 @@ Ключ для открытия большинства машин Красных. Una chiave che apre la maggior parte dei veicoli occidentali Uma chave que abre a maioria dos veículos ocidentais - このキーは多くの同盟軍車両を開けられます。 + このキーは多くのBLUFOR軍車両を開けられます。 거의 모든 청군 진영 차량을 여는 열쇠입니다. 一组解锁钥匙(可解锁大部份蓝方载具) 一組解鎖鑰匙 (可解鎖大部份藍方載具) @@ -176,7 +176,7 @@ Ключ для открытия большинства машин Независимых. Una chiave che apre la maggior parte dei veicoli degli indipendenti. Uma chave que abre a maioria dos veículos independentes - このキーは多くの独立軍車両を開けられます。 + このキーは多くのINDEPENDENT軍車両を開けられます。 거의 모든 무소속군 진영 차량을 여는 열쇠입니다. 一组解锁钥匙(可解锁大部份独立方载具) 一組解鎖鑰匙 (可解鎖大部份獨立方載具) @@ -288,6 +288,7 @@ Unklaren Sperrzustand entfernen 移除不明确的上锁状态 불분명한 잠금상태 제거 + Remover estado de bloqueio ambíguo As Is @@ -365,7 +366,7 @@ Alapértelmezett idő a zárfeltöréshez (másodpercben). Alapértelmezett: 10 Время для взлома замка отмычкой (в секундах). По умолчанию: 10 Tempo Default richiesto per forzare serrature (in secondi). Predefinito: 10 - Lockpickを使った作業の所要時間の標準設定。(秒) デフォルト: 10 + Lockpickを使った作業の所要時間の標準設定。 (秒単位) デフォルト: 10 해정을 위해 들이는 기본시간입니다(초 단위). 기본설정: 10 开锁时间(秒)。预设:10 開鎖時間(秒)。預設:10 diff --git a/addons/vehicles/CfgWeapons.hpp b/addons/vehicles/CfgWeapons.hpp index 2fbe4e52466..0c2eb0e4de4 100644 --- a/addons/vehicles/CfgWeapons.hpp +++ b/addons/vehicles/CfgWeapons.hpp @@ -13,8 +13,7 @@ class CfgWeapons { 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" - magazines[] = {"PylonWeapon_2000Rnd_65x39_belt", "1000Rnd_65x39_Belt","1000Rnd_65x39_Belt_Green","1000Rnd_65x39_Belt_Tracer_Green","1000Rnd_65x39_Belt_Tracer_Red","1000Rnd_65x39_Belt_Tracer_Yellow","1000Rnd_65x39_Belt_Yellow","2000Rnd_65x39_Belt","2000Rnd_65x39_Belt_Green","2000Rnd_65x39_Belt_Tracer_Green","2000Rnd_65x39_Belt_Tracer_Green_Splash","2000Rnd_65x39_Belt_Tracer_Red","2000Rnd_65x39_Belt_Tracer_Yellow","2000Rnd_65x39_Belt_Tracer_Yellow_Splash","2000Rnd_65x39_Belt_Yellow","2000Rnd_762x51_Belt_T_Green","2000Rnd_762x51_Belt_T_Red","2000Rnd_762x51_Belt_T_Yellow","200Rnd_65x39_Belt","200Rnd_65x39_Belt_Tracer_Green","200Rnd_65x39_Belt_Tracer_Red","200Rnd_65x39_Belt_Tracer_Yellow","5000Rnd_762x51_Belt","5000Rnd_762x51_Yellow_Belt","500Rnd_65x39_Belt","500Rnd_65x39_Belt_Tracer_Red_Splash","500Rnd_65x39_Belt_Tracer_Green_Splash","500Rnd_65x39_Belt_Tracer_Yellow_Splash"}; + magazines[] += {"2000Rnd_762x51_Belt_T_Green","2000Rnd_762x51_Belt_T_Red","2000Rnd_762x51_Belt_T_Yellow","5000Rnd_762x51_Belt","5000Rnd_762x51_Yellow_Belt"}; }; class HMG_127: LMG_RCWS { diff --git a/addons/vehicles/stringtable.xml b/addons/vehicles/stringtable.xml index 741901d75c7..6148bcdd25e 100644 --- a/addons/vehicles/stringtable.xml +++ b/addons/vehicles/stringtable.xml @@ -29,6 +29,7 @@ Круиз-контроль включён Control de crucero encendido Régulateur de vitesse activé + Controle de cruzeiro ativado Speed Limiter off @@ -58,6 +59,7 @@ Круиз-контроль выключен Control de crucero apagado Régulateur de vitesse désactivé + Controle de cruzeiro desativado Speed Limit diff --git a/addons/viewdistance/functions/fnc_changeViewDistance.sqf b/addons/viewdistance/functions/fnc_changeViewDistance.sqf index 84ba31d285a..b7fb192db21 100644 --- a/addons/viewdistance/functions/fnc_changeViewDistance.sqf +++ b/addons/viewdistance/functions/fnc_changeViewDistance.sqf @@ -41,7 +41,7 @@ if (_objectViewDistanceCoeff isEqualType 0) then { } else { if (isNil QGVAR(fovBasedPFHminimalViewDistance)) then { GVAR(fovBasedPFHminimalViewDistance) = getObjectViewDistance select 0; // Minimal view distance holder and PFH isRunning variable - [FUNC(setFovBasedOvdPFH), 0, []] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(setFovBasedOvdPFH), 0, []] call CBA_fnc_addPerFrameHandler; }; }; diff --git a/addons/viewdistance/stringtable.xml b/addons/viewdistance/stringtable.xml index 0d97fe1f963..5012e905e2d 100644 --- a/addons/viewdistance/stringtable.xml +++ b/addons/viewdistance/stringtable.xml @@ -96,8 +96,8 @@ 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) @@ -128,6 +128,8 @@ 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 + Estabelecer em 0 utilizará as configurações padrão de vídeo Client View Distance (On Foot) diff --git a/addons/viewports/dev/debugPoints.sqf b/addons/viewports/dev/debugPoints.sqf index 53fe016b628..2ffc81f512a 100644 --- a/addons/viewports/dev/debugPoints.sqf +++ b/addons/viewports/dev/debugPoints.sqf @@ -22,8 +22,8 @@ #define IDD_3DEN 313 [] spawn { - INFO_2("Pre-Init [is3den %1][3den display: %2]",is3den,!isNull findDisplay IDD_3DEN); - if (!is3den) exitWith {}; + INFO_2("Pre-Init [is3den %1][3den display: %2]",is3DEN,!isNull findDisplay IDD_3DEN); + if (!is3DEN) exitWith {}; GVAR(3denIndex) = 0; GVAR(3denViewports) = []; @@ -99,7 +99,7 @@ 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 _pointMS = _vehicle worldToModel ASLToAGL _pointASL; private _name = format ["view_%1",GVAR(3denIndex)]; // [_name, _type, _camLocation, _camAttach, _screenLocation, _maxDistance, _compartments, _roles] @@ -114,7 +114,7 @@ addMissionEventHandler ["Draw3D", { private _vehicle = vehicle player; private _viewports = _vehicle getVariable [QGVAR(viewports), []]; - if (is3den) then { + if (is3DEN) then { _vehicle = (get3DENSelected "object") param [0, objNull]; if (isNull _vehicle) exitWith {}; _viewports = [_vehicle] call FUNC(getViewports); @@ -127,7 +127,7 @@ addMissionEventHandler ["Draw3D", { 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], 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"]; }; // { diff --git a/addons/viewports/functions/fnc_eachFrame.sqf b/addons/viewports/functions/fnc_eachFrame.sqf index 6bb452baad9..55971172945 100644 --- a/addons/viewports/functions/fnc_eachFrame.sqf +++ b/addons/viewports/functions/fnc_eachFrame.sqf @@ -27,7 +27,7 @@ private _newIndex = -1; if (cba_events_control) then { if (cameraView != "INTERNAL") exitWith {}; if (isTurnedOut _player) exitWith {}; - if (!([_player, _vehicle, []] call EFUNC(common,canInteractWith))) exitWith {}; + if !([_player, _vehicle, []] call EFUNC(common,canInteractWith)) exitWith {}; BEGIN_COUNTER(newIndex); if ((_shownIndex > -1) && {currentVisionMode _player != _lastVisionMode}) then { @@ -36,15 +36,15 @@ if (cba_events_control) then { _shownIndex = -1; }; - ([_player] call FUNC(getSeatInfo)) params ["_role", "", "", "_comparment"]; + ([_player] call FUNC(getSeatInfo)) params ["_role", "", "", "_compartment"]; private _newIndexAngle = 45; // Controls the max angle - private _eyesPosASL = AGLtoASL (positionCameraToWorld [0, 0, 0]); - private _eyesDir = (AGLtoASL (positionCameraToWorld [0, 0, 1])) vectorDiff _eyesPosASL; + 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 _viewASL = AGLToASL (_vehicle modelToWorldVisual _screenLocation); private _viewDiff = _viewASL vectorDiff _eyesPosASL; private _viewAngle = acos (_viewDiff vectorCos _eyesDir); #ifdef DEBUG_MODE_FULL @@ -52,8 +52,8 @@ if (cba_events_control) then { #endif if ( (_viewAngle < _newIndexAngle) - && {(_compartments isEqualTo []) || {(toLower _comparment) in _compartments}} - && {(_roles isEqualTo []) || {(toLower _role) in _roles}} + && {(_compartments isEqualTo []) || {(toLowerANSI _compartment) in _compartments}} + && {(_roles isEqualTo []) || {(toLowerANSI _role) in _roles}} && {(vectorMagnitude _viewDiff) < _maxDistance} ) then { _newIndex = _forEachIndex; diff --git a/addons/viewports/functions/fnc_getSeatInfo.sqf b/addons/viewports/functions/fnc_getSeatInfo.sqf index 86dccebdd19..01c71c3cfeb 100644 --- a/addons/viewports/functions/fnc_getSeatInfo.sqf +++ b/addons/viewports/functions/fnc_getSeatInfo.sqf @@ -41,6 +41,6 @@ private _compartment = switch (_role) do { }; }; -if (!(_compartment isEqualType "")) then { _compartment = format ["Compartment%1",_compartment] }; +if !(_compartment isEqualType "") then {_compartment = format ["Compartment%1",_compartment]}; [_role, _cargoIndex, _turretPath, _compartment] diff --git a/addons/viewports/functions/fnc_getViewports.sqf b/addons/viewports/functions/fnc_getViewports.sqf index 32f97e18f6c..744b9731514 100644 --- a/addons/viewports/functions/fnc_getViewports.sqf +++ b/addons/viewports/functions/fnc_getViewports.sqf @@ -61,9 +61,9 @@ if (isNil "_viewports") then { _maxDistance = 0.8; }; // compartments [ARRAY] - Optional - private _compartments = (getArray (_x >> "compartments")) apply {toLower _x}; + private _compartments = (getArray (_x >> "compartments")) apply {toLowerANSI _x}; // roles [ARRAY] - Optional - private _roles = (getArray (_x >> "roles")) apply {toLower _x}; + private _roles = (getArray (_x >> "roles")) apply {toLowerANSI _x}; [_name, _type, _camLocation, _camAttach, _screenLocation, _maxDistance, _compartments, _roles] }; diff --git a/addons/viewports/functions/fnc_viewCreate.sqf b/addons/viewports/functions/fnc_viewCreate.sqf index 8b08da95756..7d9e45864b0 100644 --- a/addons/viewports/functions/fnc_viewCreate.sqf +++ b/addons/viewports/functions/fnc_viewCreate.sqf @@ -68,12 +68,12 @@ switch (true) do { 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 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 ctrlSetPosition [safeZoneX + 0.5 * safeZoneW - 0.5 * _viewWidth, safeZoneY + 0.5 * safeZoneH - 0.5 * _viewHeight, _viewWidth, _viewHeight]; _ctrlOverlay ctrlCommit 0; if (_usingGoggles) then { @@ -82,7 +82,7 @@ switch (true) do { 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 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 @@ -106,20 +106,20 @@ switch (true) do { 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 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 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 ctrlSetPosition [safeZoneX + 0.5 * safeZoneW - 0.5 * _viewWidth, safeZoneY + 0.5 * safeZoneH - 0.5 * _viewHeight, _viewWidth, _viewHeight]; _ctrlOverlay ctrlCommit 0; }; }; diff --git a/addons/viewports/stringtable.xml b/addons/viewports/stringtable.xml index be78cdc9957..22f7d77813b 100644 --- a/addons/viewports/stringtable.xml +++ b/addons/viewports/stringtable.xml @@ -12,6 +12,7 @@ Periscopios Sichtfenster Périscopes + Periscópios Allows crew to look through periscopes @@ -24,6 +25,7 @@ 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. + Permite que a tripulação olhe através de periscópios diff --git a/addons/viewrestriction/functions/fnc_changeCamera.sqf b/addons/viewrestriction/functions/fnc_changeCamera.sqf index 6a1f7d03ff6..eb6907386a4 100644 --- a/addons/viewrestriction/functions/fnc_changeCamera.sqf +++ b/addons/viewrestriction/functions/fnc_changeCamera.sqf @@ -18,7 +18,7 @@ params ["_newCameraView", "_cameraOn"]; -if (! ([_newCameraView, _cameraOn] call FUNC(canChangeCamera))) exitWith {}; +if !([_newCameraView, _cameraOn] call FUNC(canChangeCamera)) exitWith {}; TRACE_1("View Restricted",XGVAR(mode)); diff --git a/addons/viewrestriction/initSettings.inc.sqf b/addons/viewrestriction/initSettings.inc.sqf index 3ed47c10efb..80382f5b198 100644 --- a/addons/viewrestriction/initSettings.inc.sqf +++ b/addons/viewrestriction/initSettings.inc.sqf @@ -6,7 +6,7 @@ [[0, 1, 2, 3], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson), LSTRING(Selective)], 0], true, {[QGVAR(mode), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -17,7 +17,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveFoot), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -28,7 +28,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveLand), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -39,7 +39,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveAir), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -50,7 +50,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveSea), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ diff --git a/addons/viewrestriction/stringtable.xml b/addons/viewrestriction/stringtable.xml index fee4a9bf336..7356e6412f5 100644 --- a/addons/viewrestriction/stringtable.xml +++ b/addons/viewrestriction/stringtable.xml @@ -15,6 +15,7 @@ Ограничение обзора Görüntüyü Kısıtla Reestricción de Vista + Restrição do Modo de Visão View restriction settings to limit the usage of 1st or 3rd person views globally or per vehicle type. @@ -29,6 +30,7 @@ Настройки ограничения обзора при виде от 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. + A restrição do modo de visão limita o uso de 1ª ou 3ª pessoa globalmente ou por tipo de veículo. Mode @@ -44,6 +46,7 @@ Режим установок Mod Modo + Modo Sets global mode. Default: Disabled @@ -59,6 +62,7 @@ Общие установки для всех. По умолчанию: Отключено. Global modu ayarlar. Varsayılan: Devre Dışı Establece el modo global. Defecto: Deshabilitado + Define o modo global. Padrão: Desabilitado (Selective) Foot @@ -74,6 +78,7 @@ (Выборочные) Пешком (Seçilebilir) Ayakta (Selectivo) Pie + (Seletivo) A pé Selective mode on Foot. Default: Disabled (Requires Mode: Selective) @@ -89,6 +94,7 @@ Выборочные установки без техники. По умолчанию: Отключено (требуется режим: Выборочные) Ayakta iken seçilen görüş modu. Varsayılan: Etkin Değil Modo selectivo a pie. Defecto: Deshabilitado (Requiere Modo: Selectivo) + Modo seletivo a pé. Padrão: Desabilitado (Modo necessário: Seletivo) (Selective) Land Vehicles @@ -104,6 +110,7 @@ (Выборочные) Наземная техника (Seçilebilir) Kara Araçları (Selectivo) Vehículos de tierra + (Seletivo) Veículos terrestres Selective mode in Land Vehicles. Default: Disabled (Requires Mode: Selective) @@ -119,6 +126,7 @@ Выборочные установки для наземной техники. По умолчанию: Отключено (требуется режим: Выборочные) 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) + Modo seletivo em veículos terrestres. Padrão: Desabilitado (Modo necessário: Seletivo) (Selective) Air Vehicles @@ -134,6 +142,7 @@ (Выборочные) Авиатехника (Seçilebilir) Hava Araçları (Selectivo) Vehículos aéreos + (Seletivo) Aeronaves Selective mode in Air Vehicles. Default: Disabled (Requires Mode: Selective) @@ -149,6 +158,7 @@ Выборочные установки для авиатехники. По умолчанию: Отключено (требуется режим: Выборочные) 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) + Modo seletivo em aeronaves. Padrão: Desabilitado (Modo necessário: Seletivo) (Selective) Sea Vehicles @@ -164,6 +174,7 @@ (Выборочные) Водный транспорт (Seçilebilir) Deniz Araçları (Selectivo) Vehículos marítimos + (Seletivo) Veículos aquáticos Selective mode in Sea Vehicles. Default: Disabled (Requires Mode: Selective) @@ -179,6 +190,7 @@ Выборочные установки для водного транспорта. По умолчанию: Отключено (требуется режим: Выборочные) 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) + Modo seletivo em veículos aquáticos. Padrão: Desabilitado (Modo necessário: Seletivo) (Selective) UAVs @@ -194,6 +206,7 @@ (Выборочные) Беспиплотники (Seçilebilir) IHA'lar (Selectivo) VANTs + (Seletivo) VANTs Selective mode in UAVs. Default: Disabled (Requires Mode: Selective) @@ -209,6 +222,7 @@ Выборочные установки для беспилотников. По умолчанию: Отключено (требуется режим: Выборочные) IHA araçlarında iken seçilen görüş modu. Varsayılan: Etkin Değil Modo selectivo en VANTs. Defecto: Deshabilitado (Requiere Modo: Selectivo) + Modo seletivo em VANTs. Padrão: Desabilitado (Modo necessário: Seletivo) Disabled @@ -224,6 +238,7 @@ Отключено Devre Dışı Deshabilitado + Desabilitado Forced 1st Person @@ -238,6 +253,7 @@ От 1-го лица (принудительно) 1. Kişi Görüşüne Zorla Forzada 1º persona + Forçada 1ª pessoa Forced 3rd Person @@ -252,6 +268,7 @@ От 3-го лица (принудительно) 3. Kişi Görüşüne Zorla Forzada 3º persona + Forçada 3ª pessoa Selective @@ -267,6 +284,7 @@ Выборочный Seçilebilinir Selectivo + Seletivo Preserve view for vehicle types @@ -281,6 +299,7 @@ 차량 타입에 따른 시야 정보 저장 Preservar vista para los tipos de vehículos Conserver la vue pour les types de véhicules + Mantém o modo de visão por tipo de veículo Switch view on vehicle change to last used in this vehicle type (Requires Mode: Disabled) @@ -295,6 +314,7 @@ 해당 차량 타입에서 마지막으로 사용했던 시야로 설정하여 봅니다 (모드 - 사용 안함 필요) 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é). + Ao trocar de veículo, troca o modo de visão para aquele usado anteriormente no mesmo tipo de veículo (Modo necessário: Desabilitado) diff --git a/addons/volume/XEH_postInitClient.sqf b/addons/volume/XEH_postInitClient.sqf index 2ce8f03a106..ae774f2f51d 100644 --- a/addons/volume/XEH_postInitClient.sqf +++ b/addons/volume/XEH_postInitClient.sqf @@ -23,10 +23,10 @@ if (!hasInterface) exitWith {}; if (!XGVAR(lowerInVehicles)) exitWith {}; - if (vehicle _unit != _unit) then { - call FUNC(lowerVolume); - } else { + if (isNull objectParent _unit) then { call FUNC(restoreVolume); + } else { + call FUNC(lowerVolume); }; }] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/volume/initSettings.inc.sqf b/addons/volume/initSettings.inc.sqf index 8735f81527f..44bb464a1ee 100644 --- a/addons/volume/initSettings.inc.sqf +++ b/addons/volume/initSettings.inc.sqf @@ -3,9 +3,6 @@ "CHECKBOX", [ELSTRING(common,Enabled), LSTRING(KeybindDescription)], format ["ACE %1", LLSTRING(Name)], - false, - false, - {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, false ] call CBA_fnc_addSetting; @@ -14,10 +11,7 @@ "LIST", [LSTRING(Reduction), LSTRING(ReductionDescription)], format ["ACE %1", LLSTRING(Name)], - [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"], 5], - false, - {[QGVAR(reduction), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"], 5] ] call CBA_fnc_addSetting; [ @@ -25,10 +19,7 @@ "LIST", [LSTRING(FadeDelay), LSTRING(FadeDelayDescription)], format ["ACE %1", LLSTRING(Name)], - [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0s", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"], 1], - false, - {[QGVAR(fadeDelay), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0s", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"], 1] ] call CBA_fnc_addSetting; [ @@ -36,9 +27,6 @@ "CHECKBOX", [LSTRING(LowerInVehicles), LSTRING(LowerInVehiclesDescription)], format ["ACE %1", LLSTRING(Name)], - false, - false, - {[QGVAR(lowerInVehicles), _this] call EFUNC(common,cbaSettings_settingChanged)}, false ] call CBA_fnc_addSetting; @@ -47,10 +35,7 @@ "CHECKBOX", [LSTRING(ShowNotification), LSTRING(ShowNotificationDescription)], format ["ACE %1", LLSTRING(Name)], - true, - false, - {[QGVAR(showNotification), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + true ] call CBA_fnc_addSetting; [ @@ -58,8 +43,5 @@ "CHECKBOX", [LSTRING(RemindIfLowered), LSTRING(RemindIfLoweredDescription)], format ["ACE %1", LLSTRING(Name)], - false, - false, - {[QGVAR(remindIfLowered), _this] call EFUNC(common,cbaSettings_settingChanged)}, false ] call CBA_fnc_addSetting; diff --git a/addons/volume/stringtable.xml b/addons/volume/stringtable.xml index ea0eabf4eb8..08aae728a1b 100644 --- a/addons/volume/stringtable.xml +++ b/addons/volume/stringtable.xml @@ -14,6 +14,7 @@ Głosność Ses Volumen + Volume Toggle Volume @@ -28,6 +29,7 @@ Przełącz Głosność Sesi Aç/Kapat Activar control de volumen + Alternar volume Toggle volume reduction. @@ -42,6 +44,7 @@ Przełącz redukcje głosności Ses azaltmayı aç / kapat. Activar reducción de volumen. + Alternar redução de volume Lowered volume @@ -56,6 +59,7 @@ Zmniejszona głosność Azaltılmış ses Volumen reducido + Volume reduzido Restored volume @@ -69,6 +73,7 @@ Громкость восстановлена Przywrócona głosność Volumen restaurado + Volume restaurado Reduction @@ -82,6 +87,7 @@ Уменьшение Redukcja Reducción + Redução Reduce volume by this percentage. @@ -95,6 +101,7 @@ Уменьшает громкость Zmniejsz głosność o tyle procent Reducir el volumen este porcentaje. + Reduzir o volume por esta porcentagem. Lower in vehicles @@ -109,6 +116,7 @@ Zmniejsz w pojazdach Araçlarda Daha Düşük Reducir en vehículos + Reduzir em veículos Automatically lower volume when inside vehicles. @@ -123,6 +131,7 @@ Automatycznie zmniejsz głosność będąc w pojeździe Araçlara binince sesi azalt. Reduce automáticamente el volumen dentro de vehículos. + Reduz automaticamente o volume dentro de veículos. Show notification @@ -137,6 +146,7 @@ Pokaż powiadomienie Bildirim Göster Mostrar notificación + Mostrar notificação Show notification when lowering/restoring volume. @@ -151,6 +161,7 @@ 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. + Mostrar notificação quando o volume for reduzido/restaurado Fade delay @@ -164,11 +175,12 @@ Задержка затухания Opoznienie wyciszenia Retardo en disminución gradual + Atraso de alteração gradual de volume 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. 페이드 인/아웃 되는데 걸리는 시간(초) 设定音量淡出/入时所需的秒数。 @@ -177,6 +189,7 @@ Время (сек.) для затухания/восстановления звука. 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 + Tempo de atraso (em segundos) para que o volume do som sofra alteração gradual Reminder if lowered @@ -191,6 +204,7 @@ Przypomnij o zmniejszonej głosności dźwięku Eğer Düşükse Hatırlat Recordatorio s reducido + Lembrete de redução sonora Reminds you every minute if your volume is lowered. @@ -205,6 +219,7 @@ 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. + Te notifica a cada minuto se o volume sonoro estiver reduzido. Volume still lowered @@ -219,6 +234,7 @@ Dźwięk jest nadal zmniejszony Ses hala düşük Volumen todavía reducido + Volume ainda está reduzido diff --git a/addons/weaponselect/XEH_postInit.sqf b/addons/weaponselect/XEH_postInit.sqf index 4d2c6464b29..e9f05de8bbd 100644 --- a/addons/weaponselect/XEH_postInit.sqf +++ b/addons/weaponselect/XEH_postInit.sqf @@ -198,7 +198,7 @@ if (!hasInterface) exitWith {}; ["ACE3 Vehicles", QGVAR(CollisionLights), localize LSTRING(CollisionLights), { // Conditions: canInteract - if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if ((ACE_player isEqualTo (vehicle ACE_player)) || {ACE_player != (driver (vehicle ACE_player))}) exitWith {false}; @@ -210,4 +210,4 @@ if (!hasInterface) exitWith {}; [0, [false, false, false]]] call CBA_fnc_addKeybind; // Register fire event handler -["ace_firedPlayer", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; +["ace_firedPlayer", LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler; diff --git a/addons/weaponselect/XEH_preInit.sqf b/addons/weaponselect/XEH_preInit.sqf index 25d6b9b5d53..e699f3d2f38 100644 --- a/addons/weaponselect/XEH_preInit.sqf +++ b/addons/weaponselect/XEH_preInit.sqf @@ -11,20 +11,22 @@ 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.inc.sqf" diff --git a/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf b/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf index 16bac855cc6..8b9fcf94b78 100644 --- a/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf +++ b/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf @@ -22,7 +22,7 @@ private _weapons = _vehicle weaponsTurret _turret; if ( count _weapons > 1 - || {count _weapons > 0 && {!(_weapons select 0 in ["SmokeLauncher", "BWA3_SmokeLauncher"])}} // @todo somebody might use custom smoke launcher weapons aswell, maybe ... + || {_weapons isNotEqualTo [] && {!(_weapons select 0 in ["SmokeLauncher", "BWA3_SmokeLauncher"])}} // @todo somebody might use custom smoke launcher weapons aswell, maybe ... ) then { //This doesn't work reliably for vehilces with additional weapons for the commander. Select smoke launcher instead. diff --git a/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf b/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf index 2be2d740eac..641787a394e 100644 --- a/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf +++ b/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf @@ -30,8 +30,10 @@ _sound params ["_filename", ["_volume", 1], ["_soundPitch", 1], ["_distance", 0] if (_filename == "") exitWith {}; // add file extension .wss as default -if !(toLower (_filename select [count _filename - 4]) in [".wav", ".ogg", ".wss"]) then { +if !(toLowerANSI (_filename select [count _filename - 4]) in [".wav", ".ogg", ".wss"]) then { _filename = format ["%1.wss", _filename]; }; playSound3D [_filename, objNull, false, _position, _volume, _soundPitch, _distance]; + +nil // return diff --git a/addons/weaponselect/functions/fnc_selectNextGrenade.sqf b/addons/weaponselect/functions/fnc_selectNextGrenade.sqf index 195bbc326bf..ad17c7f18d9 100644 --- a/addons/weaponselect/functions/fnc_selectNextGrenade.sqf +++ b/addons/weaponselect/functions/fnc_selectNextGrenade.sqf @@ -37,8 +37,7 @@ private _grenades = []; if (_x in _magazines) then { _grenades pushBack _x; }; - false -} count ([GVAR(GrenadesAll), GVAR(GrenadesFrag), GVAR(GrenadesNonFrag)] select _type); +} forEach ([GVAR(GrenadesAll), GVAR(GrenadesFrag), GVAR(GrenadesNonFrag)] select _type); // abort if no grenades are available if (_grenades isEqualTo []) exitWith {false}; @@ -62,14 +61,14 @@ private _vestGrenades = vestItems _unit select {_x in GVAR(GrenadesAll) private _backpackGrenades = backpackItems _unit select {_x in GVAR(GrenadesAll) && {_x != _nextGrenade}}; // remove all grenades except those we are switching to --> this breaks the selector -{_unit removeItemFromUniform _x; false} count _uniformGrenades; -{_unit removeItemFromVest _x; false} count _vestGrenades; -{_unit removeItemFromBackpack _x; false} count _backpackGrenades; +{_unit removeItemFromUniform _x} forEach _uniformGrenades; +{_unit removeItemFromVest _x} forEach _vestGrenades; +{_unit removeItemFromBackpack _x} forEach _backpackGrenades; // readd grenades -{_unit addItemToUniform _x; false} count _uniformGrenades; -{_unit addItemToVest _x; false} count _vestGrenades; -{_unit addItemToBackpack _x; false} count _backpackGrenades; +{_unit addItemToUniform _x} forEach _uniformGrenades; +{_unit addItemToVest _x} forEach _vestGrenades; +{_unit addItemToBackpack _x} forEach _backpackGrenades; [_nextGrenade, {_x == _nextGrenade} count _magazines] call FUNC(displayGrenadeTypeAndNumber); diff --git a/addons/weaponselect/functions/fnc_selectWeaponMode.sqf b/addons/weaponselect/functions/fnc_selectWeaponMode.sqf index f2810bb512c..3a63e1097fa 100644 --- a/addons/weaponselect/functions/fnc_selectWeaponMode.sqf +++ b/addons/weaponselect/functions/fnc_selectWeaponMode.sqf @@ -18,35 +18,23 @@ params ["_unit", "_weapon"]; -if (_weapon == "") exitWith {}; +if (_weapon == "" || {!(_unit hasWeapon _weapon)}) exitWith {}; + +private _currentWeaponMode = (_unit weaponState _weapon) select 2; +private _muzzle = (_weapon call EFUNC(common,getWeaponMuzzles)) select 0; if (currentWeapon _unit != _weapon) exitWith { - _unit selectWeapon _weapon; + _unit selectWeapon [_weapon, _muzzle, _currentWeaponMode]; }; -// unlock safety -if (_weapon in (_unit getVariable [QEGVAR(safemode,safedWeapons), []])) exitWith { - [_unit, _weapon, _weapon] call EFUNC(safemode,unlockSafety); +// Unlock safety +if ((["ace_safemode"] call EFUNC(common,isModLoaded)) && {[_unit, _weapon] call EFUNC(safemode,getWeaponSafety)}) exitWith { + [_unit, _weapon, false] call EFUNC(safemode,setWeaponSafety); }; -private _muzzles = [_weapon] call EFUNC(common,getWeaponMuzzles); -private _modes = [_weapon] call EFUNC(common,getWeaponModes); - -private _index = (_modes find currentWeaponMode _unit) + 1; - -if (_index > count _modes - 1) then {_index = 0}; +private _modes = _weapon call EFUNC(common,getWeaponModes); -private _muzzle = _muzzles select 0; -private _mode = _modes select _index; - -_index = 0; - -while { - _index < 299 && {currentMuzzle _unit != _muzzle || {currentWeaponMode _unit != _mode}} -} do { - _unit action ["SwitchWeapon", _unit, _unit, _index]; - _index = _index + 1; -}; +_unit selectWeapon [_weapon, _muzzle, _modes select (((_modes find _currentWeaponMode) + 1) % (count _modes))]; -// play fire mode selector sound +// Play fire mode selector sound [_unit, _weapon] call FUNC(playChangeFiremodeSound); diff --git a/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf b/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf index 9a27a515add..38822535734 100644 --- a/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf +++ b/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf @@ -18,32 +18,22 @@ params ["_unit", "_weapon"]; -if (_weapon == "") exitWith {}; +if (_weapon == "" || {!(_unit hasWeapon _weapon)}) exitWith {}; private _muzzles = _weapon call EFUNC(common,getWeaponMuzzles); -if (currentWeapon _unit != _weapon) exitWith { - if (count _muzzles > 1) then { +if (count _muzzles <= 1) exitWith {}; - // unlock safety - /*if (_weapon in (_unit getVariable [QEGVAR(safemode,safedWeapons), []])) exitWith { - [_unit, _weapon, _muzzles select 1] call EFUNC(safemode,unlockSafety); - };*/ +private _muzzle = (_unit weaponState _weapon) select 1; - _unit selectWeapon (_muzzles select 1); - }; +private _index = if (currentWeapon _unit == _weapon) then { + (((_muzzles find currentMuzzle _unit) + 1) % (count _muzzles)) max 1 +} else { + 1 }; -private _index = (_muzzles find currentMuzzle _unit) + 1; - -if (_index > count _muzzles - 1) then {_index = 1}; - private _muzzle = _muzzles select _index; -_index = 0; -while { - _index < 299 && {currentMuzzle _unit != _muzzle} -} do { - _unit action ["SwitchWeapon", _unit, _unit, _index]; - _index = _index + 1; -}; +_unit selectWeapon [_weapon, _muzzle, ([_weapon, _muzzle] call EFUNC(common,getWeaponModes)) select 0]; + +nil // return diff --git a/addons/weaponselect/initSettings.inc.sqf b/addons/weaponselect/initSettings.inc.sqf index 029c5201cb6..f5695748b40 100644 --- a/addons/weaponselect/initSettings.inc.sqf +++ b/addons/weaponselect/initSettings.inc.sqf @@ -2,7 +2,5 @@ QGVAR(displayText), "CHECKBOX", [LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], ELSTRING(common,ACEKeybindCategoryWeapons), - true, // default value - false, // isGlobal - {[QGVAR(displayText), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // default value ] call CBA_fnc_addSetting; diff --git a/addons/weather/XEH_postInit.sqf b/addons/weather/XEH_postInit.sqf index 51350226e1a..98909dc2d40 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 da694bb5f1e..2c20f672fe7 100644 --- a/addons/weather/XEH_postServerInit.sqf +++ b/addons/weather/XEH_postServerInit.sqf @@ -9,8 +9,8 @@ if (GVAR(windSimulation)) then { call FUNC(initWind); - [FUNC(updateWind), 1] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(updateWind), 1] call CBA_fnc_addPerFrameHandler; }; - [FUNC(updateWeather), GVAR(updateInterval)] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(updateWeather), GVAR(updateInterval)] call CBA_fnc_addPerFrameHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/weather/functions/fnc_calculateWindSpeed.sqf b/addons/weather/functions/fnc_calculateWindSpeed.sqf index 2ae1d94eecc..d24322bef09 100644 --- a/addons/weather/functions/fnc_calculateWindSpeed.sqf +++ b/addons/weather/functions/fnc_calculateWindSpeed.sqf @@ -47,19 +47,18 @@ if (_terrainEffectEnabled) then { private _newWindSpeed = 0; { private _windSource = [100, _windDirAdjusted, _x] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; _windSource = [100, _windDirAdjusted + _x, 0] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; _windSource = [100, _windDirAdjusted - _x, 0] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; - nil - } count [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + } forEach [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; _windSpeed = _newWindSpeed; }; }; @@ -70,19 +69,18 @@ if (_obstacleEffectEnabled) then { private _newWindSpeed = 0; { private _windSource = [20, _windDirAdjusted, _x] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; _windSource = [20, _windDirAdjusted + _x, 0] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; _windSource = [20, _windDirAdjusted - _x, 0] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; - nil - } count [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]; + } forEach [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]; _windSpeed = _newWindSpeed; }; }; diff --git a/addons/weather/functions/fnc_displayWindInfo.sqf b/addons/weather/functions/fnc_displayWindInfo.sqf index 23a87ecbf4f..aeb7d580ae9 100644 --- a/addons/weather/functions/fnc_displayWindInfo.sqf +++ b/addons/weather/functions/fnc_displayWindInfo.sqf @@ -35,7 +35,13 @@ TRACE_1("Starting Wind Info PFEH",GVAR(WindInfo)); disableSerialization; params ["", "_pfID"]; - if ((!GVAR(WindInfo)) || {!([ACE_player, ACE_player, []] call EFUNC(common,canInteractWith))}) exitWith { + // 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"]; @@ -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_getMapData.sqf b/addons/weather/functions/fnc_getMapData.sqf index d80573c286c..555704fc870 100644 --- a/addons/weather/functions/fnc_getMapData.sqf +++ b/addons/weather/functions/fnc_getMapData.sqf @@ -15,7 +15,7 @@ * Public: No */ -private _worldName = toLower worldName; +private _worldName = toLowerANSI worldName; TRACE_1("getting map data",_worldName); // Set default values @@ -48,34 +48,35 @@ GVAR(currentHumidity) = 0; GVAR(currentOvercast) = 0; // Get all non inherited arrays to filter maps that inherit from Stratis/Altis/Tanoa -private _nonInheritedArrays = configProperties [configFile >> "CfgWorlds" >> _worldName, "isArray _x", false]; +private _cfgPath = configFile >> "CfgWorlds" >> _worldName; +private _nonInheritedArrays = configProperties [_cfgPath, "isArray _x", false]; // And check if any custom non-inherited weather is defined through config and use that if so -if ((configFile >> "CfgWorlds" >> _worldName >> "ACE_TempDay") in _nonInheritedArrays) exitWith { - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempDay")) then { - GVAR(TempDay) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempDay"); +if ((_cfgPath >> "ACE_TempDay") in _nonInheritedArrays) exitWith { + if (isArray (_cfgPath >> "ACE_TempDay")) then { + GVAR(TempDay) = getArray (_cfgPath >> "ACE_TempDay"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempNight")) then { - GVAR(TempNight) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempNight"); + if (isArray (_cfgPath >> "ACE_TempNight")) then { + GVAR(TempNight) = getArray (_cfgPath >> "ACE_TempNight"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_Humidity")) then { - GVAR(Humidity) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_Humidity"); + if (isArray (_cfgPath >> "ACE_Humidity")) then { + GVAR(Humidity) = getArray (_cfgPath >> "ACE_Humidity"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMin")) then { - GVAR(WindSpeedMin) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMin"); + if (isArray (_cfgPath >> "ACE_WindSpeedMin")) then { + GVAR(WindSpeedMin) = getArray (_cfgPath >> "ACE_WindSpeedMin"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMean")) then { - GVAR(WindSpeedMean) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMean"); + if (isArray (_cfgPath >> "ACE_WindSpeedMean")) then { + GVAR(WindSpeedMean) = getArray (_cfgPath >> "ACE_WindSpeedMean"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMax")) then { - GVAR(WindSpeedMax) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMax"); + if (isArray (_cfgPath >> "ACE_WindSpeedMax")) then { + GVAR(WindSpeedMax) = getArray (_cfgPath >> "ACE_WindSpeedMax"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindDirectionProbabilities")) then { - GVAR(WindDirectionProbabilities) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindDirectionProbabilities"); + if (isArray (_cfgPath >> "ACE_WindDirectionProbabilities")) then { + GVAR(WindDirectionProbabilities) = getArray (_cfgPath >> "ACE_WindDirectionProbabilities"); }; }; // Check if the map is among the most popular -if (_worldName in ["chernarus", "bootcamp_acr", "woodland_acr", "utes"]) then { +if (_worldName in ["chernarus", "bootcamp_acr", "woodland_acr", "utes"]) exitWith { // Source: http://www.iten-online.ch/klima/europa/tschechien/prag.htm GVAR(TempDay) = [1, 3, 9, 14, 19, 23, 25, 24, 21, 13, 7, 2]; GVAR(TempNight) = [-4, -3, 0, 4, 9, 12, 14, 14, 10, 6, 2, -2]; @@ -239,3 +240,17 @@ if (_worldName in ["kunduz"]) exitWith { [0.04, 0.02, 0.05, 0.14, 0.19, 0.07, 0.10, 0.07] // December ]; }; + + +// Catches any "Winter" Map that hasnt been defined otherwise - this should stay at the end of the file +// Values are not based on any RL reference since the snow terrain textures persists regardless the date +_cfgPath = _cfgPath >> "RainParticles"; +if ( + "winter" in _worldName || + {"snow" in getText (_cfgPath >> "rainDropTexture")} || + {getNumber (_cfgPath >> "snow") != 0} +) exitWith { + GVAR(TempDay) = [-10,-9,-8,-7,-6,-5,-6,-7,-8,-9,-10,-11]; + GVAR(TempNight) = [-15,-14,-13,-12,-11,-10,-9,-10,-11,-12,-13,-17]; + GVAR(Humidity) = [82, 80, 81, 82, 83, 82, 81, 82, 83, 82, 83, 82]; +}; diff --git a/addons/weather/functions/fnc_updateTemperature.sqf b/addons/weather/functions/fnc_updateTemperature.sqf index 3036171145d..34338f9d79e 100644 --- a/addons/weather/functions/fnc_updateTemperature.sqf +++ b/addons/weather/functions/fnc_updateTemperature.sqf @@ -16,7 +16,7 @@ */ private _month = date select 1; -private _timeRatio = abs(daytime - 12) / 12; +private _timeRatio = abs(dayTime - 12) / 12; GVAR(currentTemperature) = (GVAR(TempDay) select (_month - 1)) * (1 - _timeRatio) + (GVAR(TempNight) select (_month - 1)) * _timeRatio; GVAR(currentTemperature) = GVAR(currentTemperature) + GVAR(temperatureShift) - GVAR(badWeatherShift) * GVAR(currentOvercast); diff --git a/addons/weather/init3DEN.sqf b/addons/weather/init3DEN.sqf index 34b7dc2d5bc..74af5fbaf1b 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 index fb11e31e753..26f44420840 100644 --- a/addons/weather/initSettings.inc.sqf +++ b/addons/weather/initSettings.inc.sqf @@ -34,6 +34,5 @@ private _category = [format ["ACE %1", LLSTRING(Module_DisplayName)]]; QGVAR(showCheckAirTemperature), "CHECKBOX", [LSTRING(showCheckAirTemperature_DisplayName), LELSTRING(common,showActionInSelfInteraction)], _category, - true, // default value - false // isGlobal + true // default value ] call CBA_fnc_addSetting; diff --git a/addons/weather/stringtable.xml b/addons/weather/stringtable.xml index 55306f4a01e..ece79abe4a5 100644 --- a/addons/weather/stringtable.xml +++ b/addons/weather/stringtable.xml @@ -130,7 +130,7 @@ 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 - 天候を更新する間隔を定義します。(秒) + 天候を更新する間隔 (秒) を定義します 기후를 갱신하는 간격을 초 단위로 정합니다. 设定天气更新的时间间隔(秒) 設定天氣更新的時間間隔(秒) @@ -142,7 +142,7 @@ Simulazione del Vento (basato sulla mappa) 風力模擬(基於地圖) 风力模拟(基于地图) - 風シミュレーション (マップを基に) + 風シミュレーション (マップに基づく) 바람 시뮬레이션 (지도 기반) Symulacja Wiatru (bazowana na mapie) Симуляция ветра (на основе местности) @@ -158,7 +158,7 @@ Abilita la simulazione del vento basato sulla mappa (sovrascrive il vento vanilla) 啟用後將遵照地圖特色進行風力模擬(覆蓋掉官方原版的風力模擬) 启用后将遵照地图特色进行风力模拟(覆盖掉官方原版的风力模拟) - マップを基にした風シミュレーションを有効化 (ゲーム標準の風を上書き) + マップに基づいた風シミュレーションを有効化 (ゲーム標準の風を上書き) 지도 기반의 바람 시뮬레이션을 활성화합니다. (바닐라 바람을 덮어 씀) Aktywuje symulację wiatru bazującą na mapie (nadpisuje wind z domyślnej wersji gry) Включает симуляцию ветра на основе текущей местности (переписывает ванильный ветер) diff --git a/addons/winddeflection/XEH_postInit.sqf b/addons/winddeflection/XEH_postInit.sqf index fbdfdfc8689..a4140583494 100644 --- a/addons/winddeflection/XEH_postInit.sqf +++ b/addons/winddeflection/XEH_postInit.sqf @@ -9,12 +9,12 @@ GVAR(trackedBullets) = []; if (!GVAR(enabled)) exitWith {}; // Register fire event handler - ["ace_firedPlayer", DFUNC(handleFired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerNonLocal", DFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerNonLocal", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; if (GVAR(vehicleEnabled)) then { - ["ace_firedPlayerVehicle", DFUNC(handleFired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicleNonLocal", DFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicle", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicleNonLocal", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; }; [] call FUNC(updateTrajectoryPFH); diff --git a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf index 4ebea1f507c..6f54dfbba10 100644 --- a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf +++ b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf @@ -25,7 +25,6 @@ _args set [0, CBA_missionTime]; private _isWind = (vectorMagnitude wind > 0); - private _deleted = false; { _x params ["_bullet", "_airFriction"]; @@ -33,8 +32,7 @@ private _bulletSpeedSqr = vectorMagnitudeSqr _bulletVelocity; if ((!alive _bullet) || {(_bullet isKindOf "BulletBase") && {_bulletSpeedSqr < 10000}}) then { - GVAR(trackedBullets) set [_forEachIndex, objNull]; - _deleted = true; + GVAR(trackedBullets) deleteAt _forEachIndex; } else { if (_isWind) then { private _trueVelocity = _bulletVelocity vectorDiff wind; @@ -50,11 +48,7 @@ }; _bullet setVelocity _bulletVelocity; }; - } forEach GVAR(trackedBullets); - - if (_deleted) then { - GVAR(trackedBullets) = GVAR(trackedBullets) - [objNull]; - }; + } forEachReversed GVAR(trackedBullets); // END_COUNTER(pfeh); }, GVAR(simulationInterval), [CBA_missionTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/xm157/functions/fnc_ballistics_calculator.sqf b/addons/xm157/functions/fnc_ballistics_calculator.sqf index a39b09a7059..46b09170e3b 100644 --- a/addons/xm157/functions/fnc_ballistics_calculator.sqf +++ b/addons/xm157/functions/fnc_ballistics_calculator.sqf @@ -41,14 +41,14 @@ private _barometricPressure = _altitude call EFUNC(weather,calculateBarometricPr private _bulletPos = [0,0,-(_boreHeight / 100)]; private _lastBulletPos = +_bulletPos; -private _bulletVelocity = [0,Cos(_scopeBaseAngle) * _muzzleVelocity,Sin(_scopeBaseAngle) * _muzzleVelocity]; +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])); + _bc = parseNumber (("ace" callExtension ["ballistics:atmospheric_correction", [_bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel]]) select 0); }; private _deltaT = 1 / 60; @@ -58,7 +58,7 @@ while {(_TOF < 5) && {(_bulletPos # 1) < _targetRange}} do { 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])); + private _drag = parseNumber (("ace" callExtension ["ballistics:retard", [_dragModel, _bc, _trueSpeed, _temperature]]) select 0); (vectorNormalized _trueVelocity) vectorMultiply (-1 * _drag); } else { _trueVelocity vectorMultiply (_trueSpeed * _airFriction); diff --git a/addons/xm157/functions/fnc_ballistics_getData.sqf b/addons/xm157/functions/fnc_ballistics_getData.sqf index 828db8e4ae2..f366216e49a 100644 --- a/addons/xm157/functions/fnc_ballistics_getData.sqf +++ b/addons/xm157/functions/fnc_ballistics_getData.sqf @@ -56,8 +56,7 @@ if ((_weaponInfo isEqualTo []) && {_magazineClass != ""}) then { }; // Scope Base Angle - private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; - private _scopeBaseAngle = parseNumber _zeroAngle; + private _scopeBaseAngle = parseNumber (("ace" callExtension ["ballistics:zero_vanilla", [_zeroRange, _muzzleVelocity, _airFriction, _boreHeight]]) select 0); _weaponInfo = [_scopeBaseAngle,_boreHeight,_airFriction,_muzzleVelocity,_bc,_dragModel,_atmosphereModel,_barrelTwist,_twistDirection,_caliber,_bulletLength,_bulletMass]; GVAR(data) set [_key, _weaponInfo]; diff --git a/addons/xm157/functions/fnc_keyPress.sqf b/addons/xm157/functions/fnc_keyPress.sqf index c5e4760563e..684fdedefd2 100644 --- a/addons/xm157/functions/fnc_keyPress.sqf +++ b/addons/xm157/functions/fnc_keyPress.sqf @@ -19,11 +19,11 @@ params ["_func", "_keyDown"]; if (!GVAR(shown)) exitWith { false }; // fast exit if not shown -if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith { false }; -if (!(ACE_player call CBA_fnc_canUseWeapon)) exitWith { false }; +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith { false }; +if !(ACE_player call CBA_fnc_canUseWeapon) exitWith { false }; if (currentMuzzle ACE_player != currentWeapon ACE_player) exitWith { false }; -private _display = uinamespace getVariable [QGVAR(display), displayNull]; +private _display = uiNamespace getVariable [QGVAR(display), displayNull]; if (isNull _display) exitWith { ERROR("keyPress-no display"); false }; if (_keyDown) then { playSound QGVAR(click); }; diff --git a/addons/xm157/functions/fnc_weaponInfo_onLoad.sqf b/addons/xm157/functions/fnc_weaponInfo_onLoad.sqf index dfefca30d43..e490c6e14d0 100644 --- a/addons/xm157/functions/fnc_weaponInfo_onLoad.sqf +++ b/addons/xm157/functions/fnc_weaponInfo_onLoad.sqf @@ -18,7 +18,7 @@ params ["_display"]; TRACE_1("weaponInfo_onLoad",_display); -uinamespace setVariable [QGVAR(display), _display]; +uiNamespace setVariable [QGVAR(display), _display]; [_display, true] call cba_optics_fnc_loadScriptedOptic; // pass thru to cba diff --git a/addons/yardage450/XEH_postInit.sqf b/addons/yardage450/XEH_postInit.sqf index 2959360f7df..1f3cb1a1cfa 100644 --- a/addons/yardage450/XEH_postInit.sqf +++ b/addons/yardage450/XEH_postInit.sqf @@ -1,5 +1,7 @@ #include "script_component.hpp" +if (!hasInterface) exitWith {}; + #include "initKeybinds.inc.sqf" GVAR(active) = false; diff --git a/addons/yardage450/functions/fnc_acquireTarget.sqf b/addons/yardage450/functions/fnc_acquireTarget.sqf index d5aea3a800f..88f85f29cc3 100644 --- a/addons/yardage450/functions/fnc_acquireTarget.sqf +++ b/addons/yardage450/functions/fnc_acquireTarget.sqf @@ -45,7 +45,7 @@ GVAR(distanceIndex) = -1; private _range = (_min + _max) / 2; if (_range >= MIN_DISTANCE && _range <= MAX_DISTANCE) then { GVAR(targetAcquired) = true; - GVAR(targetRangeText) = Str(round(_range)); + GVAR(targetRangeText) = str(round(_range)); }; }; }; diff --git a/addons/yardage450/functions/fnc_turnOn.sqf b/addons/yardage450/functions/fnc_turnOn.sqf index e30798c5234..62bb135a2c2 100644 --- a/addons/yardage450/functions/fnc_turnOn.sqf +++ b/addons/yardage450/functions/fnc_turnOn.sqf @@ -15,12 +15,12 @@ * Public: No */ -#define __dsp (uiNamespace getVariable "ACE_RscYardage450") -#define __ctrlTarget (__dsp displayCtrl 720041) -#define __ctrlLaser (__dsp displayCtrl 720042) -#define __ctrlRange (__dsp displayCtrl 720043) -#define __ctrlMeters (__dsp displayCtrl 720044) -#define __ctrlYards (__dsp displayCtrl 720045) +#define DISPLAY_YARDAGE (uiNamespace getVariable "ACE_RscYardage450") +#define CTRL_TARGET (DISPLAY_YARDAGE displayCtrl 720041) +#define CTRL_LASER (DISPLAY_YARDAGE displayCtrl 720042) +#define CTRL_RANGE (DISPLAY_YARDAGE displayCtrl 720043) +#define CTRL_METERS (DISPLAY_YARDAGE displayCtrl 720044) +#define CTRL_YARDS (DISPLAY_YARDAGE displayCtrl 720045) if (currentWeapon ACE_player != "ACE_Yardage450" || cameraView != "GUNNER") exitWith {}; @@ -33,25 +33,28 @@ GVAR(active) = true; [{ if (CBA_missionTime - GVAR(powerOnTime) > 30) exitWith { GVAR(active) = false; - 74210 cutText ["", "PLAIN"]; + QUOTE(ADDON) cutText ["", "PLAIN"]; [_this select 1] call CBA_fnc_removePerFrameHandler; }; if (currentWeapon ACE_player == "ACE_Yardage450" && cameraView == "GUNNER") then { - 74210 cutRsc ["ACE_RscYardage450", "PLAIN", 1, false]; + 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]; + }; - __ctrlLaser ctrlShow GVAR(lasing); + CTRL_LASER ctrlShow GVAR(lasing); if (GVAR(targetAcquired)) then { - __ctrlTarget ctrlSetText "Target Acquired"; - __ctrlRange ctrlSetText GVAR(targetRangeText); + CTRL_TARGET ctrlSetText "Target Acquired"; + CTRL_RANGE ctrlSetText GVAR(targetRangeText); } else { - __ctrlTarget ctrlSetText ""; - __ctrlRange ctrlSetText "---"; + CTRL_TARGET ctrlSetText ""; + CTRL_RANGE ctrlSetText "---"; }; - __ctrlMeters ctrlShow !GVAR(useYards); - __ctrlYards ctrlShow GVAR(useYards); + 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/zeus/CfgVehicles.hpp b/addons/zeus/CfgVehicles.hpp index 2a1f2611256..5fb4a4f61a5 100644 --- a/addons/zeus/CfgVehicles.hpp +++ b/addons/zeus/CfgVehicles.hpp @@ -256,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); diff --git a/addons/zeus/XEH_PREP.hpp b/addons/zeus/XEH_PREP.hpp index 8de15147bd5..69dd7b18a63 100644 --- a/addons/zeus/XEH_PREP.hpp +++ b/addons/zeus/XEH_PREP.hpp @@ -34,6 +34,7 @@ PREP(moduleSetMedicalVehicle); PREP(moduleSetRepairFacility); PREP(moduleSetRepairVehicle); PREP(moduleSimulation); +PREP(moduleSpectator); PREP(moduleSuicideBomber); PREP(moduleSuppressiveFire); PREP(moduleSuppressiveFireLocal); @@ -56,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 b4d1302ab5b..15b4c15f769 100644 --- a/addons/zeus/XEH_postInit.sqf +++ b/addons/zeus/XEH_postInit.sqf @@ -11,6 +11,7 @@ QGVAR(GlobalSkillAI) addPublicVariableEventHandler FUNC(moduleGlobalSetSkill); [QGVAR(moduleSearchNearby), CBA_fnc_searchNearby] call CBA_fnc_addEventHandler; [QGVAR(moduleSearchArea), CBA_fnc_taskSearchArea] call CBA_fnc_addEventHandler; [QGVAR(suppressiveFire), LINKFUNC(moduleSuppressiveFireLocal)] call CBA_fnc_addEventHandler; +[QGVAR(moduleSpectator), LINKFUNC(moduleSpectator)] call CBA_fnc_addEventHandler; // Editable object commands must be ran on server, this events are used in the respective module if (isServer) then { diff --git a/addons/zeus/XEH_preInit.sqf b/addons/zeus/XEH_preInit.sqf index 12bd3598660..46e95431a1e 100644 --- a/addons/zeus/XEH_preInit.sqf +++ b/addons/zeus/XEH_preInit.sqf @@ -7,12 +7,12 @@ PREP_RECOMPILE_START; PREP_RECOMPILE_END; if (isServer) then { - [QGVAR(zeusUnitAssigned), FUNC(handleZeusUnitAssigned)] call CBA_fnc_addEventHandler; + [QGVAR(zeusUnitAssigned), LINKFUNC(handleZeusUnitAssigned)] call CBA_fnc_addEventHandler; // Only add an InitPost EH if setting is enabled (and apply retroactively) ["CBA_settingsInitialized", { if (GVAR(autoAddObjects)) then { - ["AllVehicles", "InitPost", FUNC(addObjectToCurator), true, [], true] call CBA_fnc_addClassEventHandler; + ["AllVehicles", "InitPost", LINKFUNC(addObjectToCurator), true, [], true] call CBA_fnc_addClassEventHandler; }; }] call CBA_fnc_addEventHandler; }; diff --git a/addons/zeus/config.cpp b/addons/zeus/config.cpp index 2714c247b05..d90c9062949 100644 --- a/addons/zeus/config.cpp +++ b/addons/zeus/config.cpp @@ -99,6 +99,11 @@ class CfgPatches { QGVAR(moduleLayTrench) }; }; + class GVAR(spectator): ADDON { + units[] = { + QGVAR(moduleSpectator) + }; + }; }; class ACE_Curator { @@ -112,6 +117,7 @@ class ACE_Curator { GVAR(arsenal) = "ace_arsenal"; GVAR(fire) = "ace_fire"; GVAR(trenches) = "ace_trenches"; + GVAR(spectator) = "ace_spectator"; }; #include "CfgFactionClasses.hpp" diff --git a/addons/zeus/functions/fnc_addObjectToCurator.sqf b/addons/zeus/functions/fnc_addObjectToCurator.sqf index 9651630ccce..4b87904d0f6 100644 --- a/addons/zeus/functions/fnc_addObjectToCurator.sqf +++ b/addons/zeus/functions/fnc_addObjectToCurator.sqf @@ -17,7 +17,7 @@ params ["_object"]; -if (!(_object getVariable [QGVAR(addObject), GVAR(autoAddObjects)])) exitWith {}; +if !(_object getVariable [QGVAR(addObject), GVAR(autoAddObjects)]) exitWith {}; [{ TRACE_1("Delayed addCuratorEditableObjects",_this); diff --git a/addons/zeus/functions/fnc_bi_moduleArsenal.sqf b/addons/zeus/functions/fnc_bi_moduleArsenal.sqf index 7378cae65e9..76f723b2dd3 100644 --- a/addons/zeus/functions/fnc_bi_moduleArsenal.sqf +++ b/addons/zeus/functions/fnc_bi_moduleArsenal.sqf @@ -21,15 +21,15 @@ params ["_logic", "", "_activated"]; if (_activated && local _logic) then { - _unit = _logic getvariable ["bis_fnc_curatorAttachObject_object",objnull]; + _unit = _logic getVariable ["bis_fnc_curatorAttachObject_object",objNull]; //--- Check if the unit is suitable _error = ""; switch true do { - case (isnull _unit): {_error = localize "str_a3_BIS_fnc_showCuratorFeedbackMessage_506";}; + 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 group _unit || !(side group _unit in [east,west,resistance,civilian])): {_error = localize "str_a3_BIS_fnc_moduleArsenal_errorBrain";}; + case (!isNull objectParent _unit || effectiveCommander _unit != _unit): {_error = localize "str_a3_BIS_fnc_moduleArsenal_errorVehicle";}; }; if (_error == "") then { @@ -51,10 +51,10 @@ if (_activated && local _logic) then { } else { if !(isPlayer _unit) then { - ([] call bis_fnc_rscLayer) cuttext ["","black out",0.5]; + ([] call bis_fnc_rscLayer) cutText ["","black out",0.5]; ["#(argb,8,8,3)color(0,0,0,1)",false,nil,0,[0.5,0]] call bis_fnc_textTiles; ["Open",[true,nil,_unit]] call bis_fnc_arsenal; - ([] call bis_fnc_rscLayer) cuttext ["","plain"]; + ([] call bis_fnc_rscLayer) cutText ["","plain"]; } else { [objNull, localize "str_a3_BIS_fnc_moduleArsenal_errorDead"] call bis_fnc_showCuratorFeedbackMessage; diff --git a/addons/zeus/functions/fnc_bi_moduleCurator.sqf b/addons/zeus/functions/fnc_bi_moduleCurator.sqf index ec04a12d241..a10807dbe70 100644 --- a/addons/zeus/functions/fnc_bi_moduleCurator.sqf +++ b/addons/zeus/functions/fnc_bi_moduleCurator.sqf @@ -23,149 +23,149 @@ params ["_logic", "_units", "_activated"]; if (_activated) then { - //--- 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; + // 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 - _ownerVar = _logic getvariable ["owner",""]; - _ownerUID = parsenumber _ownerVar; - if (cheatsenabled) then { - _ownerVarArray = toarray _ownerVar; + // Get curator owner + _ownerVar = _logic getVariable ["owner",""]; + _ownerUID = parseNumber _ownerVar; + if (cheatsEnabled) then { + _ownerVarArray = toArray _ownerVar; _ownerVarArray resize 3; - if (tostring _ownerVarArray == "DEV") then {_ownerUID = 1;}; + if (toString _ownerVarArray == "DEV") then {_ownerUID = 1;}; }; - if (_ownerVar == "" && !ismultiplayer) then { + if (_ownerVar == "" && !isMultiplayer) then { ["Curator owner not defined, player used instead in singleplayer."] call bis_fnc_error; _ownerVar = player call bis_fnc_objectvar; }; - if (_ownerUID > 0 && !ismultiplayer) then { + if (_ownerUID > 0 && !isMultiplayer) then { _ownerVar = player call bis_fnc_objectvar; }; _isAdmin = _ownerVar == "#adminLogged" || _ownerVar == "#adminVoted"; - //--- Wipe out the variable so clients can't access it - _logic setvariable ["owner",nil]; + // Wipe out the variable so clients can't access it + _logic setVariable ["owner",nil]; - //--- Server - if (isserver) then { + // 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"]; _adminVar = "admin_"; for "_i" from 0 to 9 do {_adminVar = _adminVar + selectRandom _letters}; - _logic setvariable ["adminVar",_adminVar,true]; + _logic setVariable ["adminVar",_adminVar,true]; }; - //--- Get allowed addons - _addonsType = _logic getvariable ["Addons",2]; + // 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"; + _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];}; + if (isClass _class) then {_addons set [count _addons,configName _class];}; }; // 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; + removeAllCuratorAddons _logic; + _logic addCuratorAddons _addons; }; - //--- All active + // All active case 2: {}; - //--- All mission + // All mission case 1: { _addonsList = []; { - _addonsList = _addonsList + (unitaddons typeof _x); - } foreach (entities "all"); - removeallcuratoraddons _logic; - _logic addcuratoraddons _addonsList; + _addonsList = _addonsList + (unitAddons typeOf _x); + } forEach (entities "all"); + removeAllCuratorAddons _logic; + _logic addCuratorAddons _addonsList; }; - //--- None + // None case 0: { - removeallcuratoraddons _logic; + removeAllCuratorAddons _logic; }; }; - //--- Handle ownership + // Handle ownership [_logic,_ownerVar,_ownerUID,_adminVar] spawn { - scriptname "BIS_fnc_moduleCurator: Owner"; + scriptName "BIS_fnc_moduleCurator: Owner"; params ["_logic", "_ownerVar", "_ownerUID", "_adminVar"]; if (_adminVar != "") then {_ownerVar = _adminVar;}; - _forced = _logic getvariable ["forced",0] > 0; - _name = _logic getvariable ["name",""]; + _forced = _logic getVariable ["forced",0] > 0; + _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 - _addons = curatoraddons _logic; + // Refresh addon list, so it's broadcasted to clients + _addons = curatorAddons _logic; removeAllCuratorAddons _logic; - _logic addcuratoraddons _addons; + _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 { + waitUntil { sleep 0.01; - {getplayeruid _x == _ownerVar} count playableunits > 0 || isnull _logic + {getPlayerUID _x == _ownerVar} count playableUnits > 0 || isNull _logic }; }; default { - waituntil {isplayer (missionnamespace getvariable [_ownerVar,objnull]) || isnull _logic}; + waitUntil {isPlayer (missionNamespace getVariable [_ownerVar,objNull]) || isNull _logic}; }; }; - if (isnull _logic) exitwith {}; + if (isNull _logic) exitWith {}; - //--- Assign - _player = objnull; + // Assign + _player = objNull; switch true do { case (_ownerUID > 0): { { - if (getplayeruid _x == _ownerVar) exitwith {_player = _x;}; - } foreach playableunits; + if (getPlayerUID _x == _ownerVar) exitWith {_player = _x;}; + } forEach playableUnits; }; default { - _player = missionnamespace getvariable [_ownerVar,objnull]; + _player = missionNamespace getVariable [_ownerVar,objNull]; }; }; - waituntil {unassigncurator _logic; isnull (getassignedcuratorunit _logic) || isnull _logic}; - waituntil {_player assignCurator _logic; getassignedcuratorunit _logic == _player || isnull _logic}; - if (isnull _logic) exitwith {}; + waitUntil {unassignCurator _logic; isNull (getAssignedCuratorUnit _logic) || isNull _logic}; + 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",[]]); + _x radioChannelAdd [_player]; + } forEach (_logic getVariable ["channels",[]]); // Added by ace_zeus to delay ascension message code 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 { + if (isPlayer _x) then { [["CuratorAssign",[_name,name _player]],"bis_fnc_showNotification",_x] call bis_fnc_mp; }; - } forEach (curatoreditableobjects _logic); + } forEach (curatorEditableObjects _logic); }; }; @@ -181,28 +181,28 @@ 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 { + waitUntil { sleep 0.01; - {getplayeruid _x == _ownerVar} count playableunits == 0 || isnull _logic + {getPlayerUID _x == _ownerVar} count playableUnits == 0 || isNull _logic }; }; default { - waituntil {_player != missionnamespace getvariable [_ownerVar,objnull] || isnull _logic}; + waitUntil {_player != missionNamespace getVariable [_ownerVar,objNull] || isNull _logic}; }; }; - if (isnull _logic) exitwith {}; + if (isNull _logic) exitWith {}; - //--- Add radio channels + // Add radio channels { - _x radiochannelremove [_player]; - } foreach (_logic getvariable ["channels",[]]); + _x radioChannelRemove [_player]; + } forEach (_logic getVariable ["channels",[]]); - //--- Unassign - waituntil {unassigncurator _logic; isnull (getassignedcuratorunit _logic) || isnull _logic}; - if (isnull _logic) exitwith {}; + // Unassign + waitUntil {unassignCurator _logic; isNull (getAssignedCuratorUnit _logic) || isNull _logic}; + if (isNull _logic) exitWith {}; }; }; @@ -211,20 +211,20 @@ 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"]; + _bird = createVehicle [_birdType,[100,100,100],[],0,"none"]; _logic setVariable ["bird",_bird,true]; }; - //--- Locality changed - _logic addeventhandler [ - "local", + // Locality changed + _logic addEventHandler [ + "Local", { _logic = _this select 0; - _bird = _logic getVariable ["bird",objnull]; - _bird setowner owner _logic; + _bird = _logic getVariable ["bird",objNull]; + _bird setOwner owner _logic; } ]; }; @@ -237,73 +237,73 @@ if (_activated) then { [_logic] call _birdCode; }; - //--- Activated all future addons + // Activated all future addons _addons = []; { - if (typeof _x == "ModuleCuratorAddAddons_F") then { - _paramAddons = call compile ("[" + (_x getvariable ["addons",""]) + "]"); + if (typeOf _x == "ModuleCuratorAddAddons_F") then { + _paramAddons = call compile ("[" + (_x getVariable ["addons",""]) + "]"); { if !(_x in _addons) then {_addons set [count _addons,_x];}; { if !(_x in _addons) then {_addons set [count _addons,_x];}; - } foreach (unitaddons _x); - } foreach _paramAddons; + } forEach (unitAddons _x); + } forEach _paramAddons; }; - } foreach (synchronizedobjects _logic); + } forEach (synchronizedObjects _logic); // 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 - if (hasinterface) then { - waituntil {local player}; + // Player + if (hasInterface) then { + waitUntil {local player}; _serverCommand = ["#kick", "#shutdown"] select (_ownerVar == "#adminLogged"); - //--- Black effect until the interface is open - _forced = _logic getvariable ["forced",0] > 0; + // Black effect until the interface is open + _forced = _logic getVariable ["forced",0] > 0; if (_forced) then { _isCurator = switch true do { case (_ownerUID > 0): { - getplayeruid player == _ownerVar + getPlayerUID player == _ownerVar }; case (_isAdmin): { - isserver || servercommandavailable _serverCommand + isServer || serverCommandAvailable _serverCommand }; default { - player == missionnamespace getvariable [_ownerVar,objnull] + player == missionNamespace getVariable [_ownerVar,objNull] }; }; if (_isCurator) then { [true,true] spawn bis_fnc_forceCuratorInterface; - ("RscDisplayCurator" call bis_fnc_rscLayer) cuttext ["","black in",1e10]; + ("RscDisplayCurator" call bis_fnc_rscLayer) cutText ["","black in",1e10]; }; }; - //--- 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 - missionnamespace setvariable [_adminVar,player]; + _adminVar = _logic getVariable ["adminVar",""]; + _logic setVariable ["adminVar",nil]; + if (isServer) then { + // Host + missionNamespace setVariable [_adminVar,player]; } else { - //--- Client + // Client [_logic,_adminVar,_serverCommand] spawn { - scriptname "BIS_fnc_moduleCurator: Admin check"; + scriptName "BIS_fnc_moduleCurator: Admin check"; _logic = _this select 0; _adminVar = _this select 1; _serverCommand = _this select 2; while {true} do { - waituntil {sleep 0.1; servercommandavailable _serverCommand}; - missionnamespace setvariable [_adminVar,player]; - publicvariable _adminVar; - _respawn = player addeventhandler ["respawn",format ["%1 = _this select 0; publicvariable '%1';",_adminVar]]; - - waituntil {sleep 0.1; !servercommandavailable _serverCommand}; - missionnamespace setvariable [_adminVar,objnull]; - publicvariable _adminVar; - player removeeventhandler ["respawn",_respawn]; + waitUntil {sleep 0.1; serverCommandAvailable _serverCommand}; + missionNamespace setVariable [_adminVar,player]; + publicVariable _adminVar; + _respawn = player addEventHandler ["Respawn",format ["%1 = _this select 0; publicvariable '%1';",_adminVar]]; + + waitUntil {sleep 0.1; !serverCommandAvailable _serverCommand}; + missionNamespace setVariable [_adminVar,objNull]; + publicVariable _adminVar; + player removeEventHandler ["Respawn",_respawn]; }; }; }; @@ -312,10 +312,10 @@ if (_activated) then { [_logic] spawn { _logic = _this select 0; sleep 1; - waituntil {alive player}; + waitUntil {alive player}; - //--- Show warning when Zeus key is not assigned - if (count (actionkeys "curatorInterface") == 0) then { + // Show warning when Zeus key is not assigned + if (count (actionKeys "curatorInterface") == 0) then { [ format [ localize "str_a3_cfgvehicles_modulecurator_f_keyNotAssigned", @@ -324,32 +324,32 @@ 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"} + isNil {profileNamespace getVariable "bis_fnc_curatorPinged_done"} && {isTutHintsEnabled} && - {isnull getassignedcuratorlogic player} + {isNull getAssignedCuratorLogic player} && - {player in curatoreditableobjects _logic} + {player in curatorEditableObjects _logic} ) then { sleep 0.5; [["Curator","Ping"]] call bis_fnc_advHint; }; }; - //--- 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;}]; - _logic addeventhandler ["curatorObjectEdited",{_this call bis_fnc_curatorObjectEdited;}]; - _logic addeventhandler ["curatorWaypointPlaced",{_this call bis_fnc_curatorWaypointPlaced;}]; - - _logic addeventhandler ["curatorObjectDoubleClicked",{(_this select 1) call bis_fnc_showCuratorAttributes;}]; - _logic addeventhandler ["curatorGroupDoubleClicked",{(_this select 1) call bis_fnc_showCuratorAttributes;}]; - _logic addeventhandler ["curatorWaypointDoubleClicked",{(_this select 1) call bis_fnc_showCuratorAttributes;}]; - _logic addeventhandler ["curatorMarkerDoubleClicked",{(_this select 1) call bis_fnc_showCuratorAttributes;}]; + // 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;}]; + _logic addEventHandler ["CuratorObjectEdited",{_this call bis_fnc_curatorObjectEdited;}]; + _logic addEventHandler ["CuratorWaypointPlaced",{_this call bis_fnc_curatorWaypointPlaced;}]; + + _logic addEventHandler ["CuratorObjectDoubleClicked",{(_this select 1) call bis_fnc_showCuratorAttributes;}]; + _logic addEventHandler ["CuratorGroupDoubleClicked",{(_this select 1) call bis_fnc_showCuratorAttributes;}]; + _logic addEventHandler ["CuratorWaypointDoubleClicked",{(_this select 1) call bis_fnc_showCuratorAttributes;}]; + _logic addEventHandler ["CuratorMarkerDoubleClicked",{(_this select 1) call bis_fnc_showCuratorAttributes;}]; player call bis_fnc_curatorRespawn; }; diff --git a/addons/zeus/functions/fnc_bi_moduleMine.sqf b/addons/zeus/functions/fnc_bi_moduleMine.sqf index 0bd8ba574ff..509efa0a1c5 100644 --- a/addons/zeus/functions/fnc_bi_moduleMine.sqf +++ b/addons/zeus/functions/fnc_bi_moduleMine.sqf @@ -21,18 +21,18 @@ params ["_logic", "_units", "_activated"]; if (_activated) then { - _explosive = gettext (configOf _logic >> "explosive"); + _explosive = getText (configOf _logic >> "explosive"); if (_explosive != "") then { - _explosive = createvehicle [_explosive,position _logic,[],0,"none"]; - _explosive attachto [_logic]; + _explosive = createVehicle [_explosive,position _logic,[],0,"none"]; + _explosive attachTo [_logic]; // Added by ace_zeus to control if mines are revealed 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); + _side = (getAssignedCuratorUnit _x) call bis_fnc_objectSide; + _side revealMine _explosive; + } forEach (objectCurators _logic); if (GVAR(revealMines) == MINE_REVEAL_FULL) then { //--- Mark minefields in the map @@ -43,8 +43,8 @@ if (_activated) then { //--- Show hint to curator who placed the object [[["Curator","PlaceMines"],nil,nil,nil,nil,nil,nil,true],"bis_fnc_advHint",_logic] call bis_fnc_mp; - waituntil {sleep 0.1; isnull _explosive || isnull _logic || !alive _logic}; - if (isnull _logic) then {deletevehicle _explosive;} else {_explosive setdamage 1;}; - deletevehicle _logic; + waitUntil {sleep 0.1; isNull _explosive || isNull _logic || !alive _logic}; + if (isNull _logic) then {deleteVehicle _explosive;} else {_explosive setDamage 1;}; + deleteVehicle _logic; }; }; diff --git a/addons/zeus/functions/fnc_bi_moduleProjectile.sqf b/addons/zeus/functions/fnc_bi_moduleProjectile.sqf index 135ed538cdd..94771354ba4 100644 --- a/addons/zeus/functions/fnc_bi_moduleProjectile.sqf +++ b/addons/zeus/functions/fnc_bi_moduleProjectile.sqf @@ -23,26 +23,26 @@ _logic = _this select 0; _units = _this select 1; _activated = _this select 2; -if ({local _x} count (objectcurators _logic) > 0) then { +if ({local _x} count (objectCurators _logic) > 0) then { //--- Reveal the circle to curators - _logic hideobject false; - _logic setpos position _logic; + _logic hideObject false; + _logic setPos position _logic; }; -if !(isserver) exitwith {}; +if !(isServer) exitWith {}; if (_activated) then { - _ammo = _logic getvariable ["type",gettext (configOf _logic >> "ammo")]; + _ammo = _logic getVariable ["type",getText (configOf _logic >> "ammo")]; if (_ammo != "") then { - _cfgAmmo = configfile >> "cfgammo" >> _ammo; + _cfgAmmo = configFile >> "cfgammo" >> _ammo; //if !(isclass _cfgAmmo) exitwith {["CfgAmmo class '%1' not found.",_ammo] call bis_fnc_error;}; // It seems BI broke this part... // _dirVar = _fnc_scriptname + typeof _logic; // _logic setdir (missionnamespace getvariable [_dirVar,direction _logic]); //--- Restore custom direction - _pos = getposatl _logic; + _pos = getPosATL _logic; _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; @@ -58,7 +58,7 @@ if (_activated) then { _altitude = 1000; _velocity = [0,0,-100]; _radio = "SentGenIncoming"; - _sounds = if (getnumber (_cfgAmmo >> "hit") < 200) then {["mortar1","mortar2"]} else {["shell1","shell2","shell3","shell4"]}; + _sounds = if (getNumber (_cfgAmmo >> "hit") < 200) then {["mortar1","mortar2"]} else {["shell1","shell2","shell3","shell4"]}; _sound = selectRandom _sounds; _hint = ["Curator","PlaceOrdnance"]; _shakeStrength = 0.01; @@ -66,7 +66,7 @@ if (_activated) then { }; case "shotsubmunitions": { _posAmmo = [_posAmmo,500,_dir + 180] call bis_fnc_relpos; - _altitude = 1000 - ((getterrainheightasl _posAmmo) - (getterrainheightasl _pos)); + _altitude = 1000 - ((getTerrainHeightASL _posAmmo) - (getTerrainHeightASL _pos)); _posAmmo set [2,_altitude]; _velocity = [sin _dir * 68,cos _dir * 68,-100]; _radio = "SentGenIncoming"; @@ -102,22 +102,22 @@ if (_activated) then { }; }; }; - } foreach allPlayers; + } 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 _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_parseNumberSafe; - _radio = _logic getvariable ["radio",_radio]; + _altitude = (_logic getVariable ["altitude",_altitude]) call BIS_fnc_parseNumberSafe; + _radio = _logic getVariable ["radio",_radio]; //--- Create projectile _posAmmo set [2,_altitude]; - _projectile = createvehicle [_ammo,_posAmmo,[],0,"none"]; - _projectile setpos _posAmmo; - _projectile setvelocity _velocity; - if (_attach) then {_projectile attachto [_logic,[0,0,_altitude]];}; + _projectile = createVehicle [_ammo,_posAmmo,[],0,"none"]; + _projectile setPos _posAmmo; + _projectile setVelocity _velocity; + if (_attach) then {_projectile attachTo [_logic,[0,0,_altitude]];}; // Added by ace_zeus for ace_frag compatibility if (!isNil QEFUNC(frag,addPfhRound)) then { @@ -128,7 +128,7 @@ if (_activated) then { if (_sound != "") then {[[_logic,_sound,"say3D"],"bis_fnc_sayMessage"] call bis_fnc_mp;}; //--- Create sound source - _soundSource = if (_soundSourceClass != "") then {createSoundSource [_soundSourceClass,_pos,[],0]} else {objnull}; + _soundSource = if (_soundSourceClass != "") then {createSoundSource [_soundSourceClass,_pos,[],0]} else {objNull}; // Added by ace_zeus to toggle ordnance radio message if (GVAR(radioOrdnance)) then { @@ -138,54 +138,54 @@ if (_activated) then { //--- Update if (_attach) then { - waituntil { - _soundSource setposatl getposatl _projectile; + waitUntil { + _soundSource setPosATL getPosATL _projectile; sleep 1; - isnull _projectile || isnull _logic + isNull _projectile || isNull _logic }; } else { - waituntil { - _soundSource setposatl getposatl _projectile; + waitUntil { + _soundSource setPosATL getPosATL _projectile; - if (getposatl _logic distance _pos > 0 || direction _logic != _dir) then { - _posNew = getposasl _logic; + if (getPosATL _logic distance _pos > 0 || direction _logic != _dir) then { + _posNew = getPosASL _logic; _dirDiff = direction _logic - _dir; - _posNew = [_posNew,[getposasl _projectile,_pos] call bis_fnc_distance2d,direction _logic + 180] call bis_fnc_relpos; - _posNew set [2,getposasl _projectile select 2]; - _projectile setvelocity ([velocity _projectile,-_dirDiff] call bis_fnc_rotatevector2d); - _projectile setposasl _posNew; - _pos = getposatl _logic; + _posNew = [_posNew,[getPosASL _projectile,_pos] call bis_fnc_distance2d,direction _logic + 180] call bis_fnc_relpos; + _posNew set [2,getPosASL _projectile select 2]; + _projectile setVelocity ([velocity _projectile,-_dirDiff] call bis_fnc_rotatevector2d); + _projectile setPosASL _posNew; + _pos = getPosATL _logic; _dir = direction _logic; //missionnamespace setvariable [_dirVar,_dir]; See L37 }; sleep 0.1; - isnull _projectile || isnull _logic + isNull _projectile || isNull _logic }; }; - deletevehicle _projectile; - deletevehicle _soundSource; - if (count objectcurators _logic > 0) then { + deleteVehicle _projectile; + deleteVehicle _soundSource; + if (count objectCurators _logic > 0) then { //--- Delete curator spawned logic if (_shakeStrength > 0) then { if (_simulation == "shotsubmunitions") then {sleep 0.5;}; [[_shakeStrength,0.7,[position _logic,_shakeRadius]],"bis_fnc_shakeCuratorCamera"] call bis_fnc_mp; }; - deletevehicle _logic; + deleteVehicle _logic; } else { //--- Repeat to achieve permanent effect - _repeat = _logic getvariable ["repeat",0] > 0; + _repeat = _logic getVariable ["repeat",0] > 0; if (_repeat) then { [_logic,_units,_activated] call bis_fnc_moduleprojectile; } else { - deletevehicle _logic; + deleteVehicle _logic; }; }; } else { - deletevehicle _logic; + deleteVehicle _logic; }; } else { - ["Cannot create projectile, 'ammo' config attribute is missing in %1",typeof _logic] call bis_fnc_error; + ["Cannot create projectile, 'ammo' config attribute is missing in %1",typeOf _logic] call bis_fnc_error; }; }; diff --git a/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf b/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf index 2aa438be532..dcc546ce3be 100644 --- a/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf +++ b/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf @@ -22,38 +22,38 @@ _logic = _this select 0; _units = _this select 1; _activated = _this select 2; -if (_activated && local _logic && !isnull curatorcamera) then { +if (_activated && local _logic && !isNull curatorCamera) then { //--- Terminate when remote control is already in progress - if !(isnull (missionnamespace getvariable ["bis_fnc_moduleRemoteControl_unit",objnull])) exitwith {}; + if !(isNull (missionNamespace getVariable ["bis_fnc_moduleRemoteControl_unit",objNull])) exitWith {}; //--- Get unit under cursor - _unit = objnull; - _mouseOver = missionnamespace getvariable ["bis_fnc_curatorObjectPlaced_mouseOver",[""]]; + _unit = objNull; + _mouseOver = missionNamespace getVariable ["bis_fnc_curatorObjectPlaced_mouseOver",[""]]; if ((_mouseOver select 0) == "OBJECT") then {_unit = _mouseOver select 1;}; - _unit = effectivecommander _unit; + _unit = effectiveCommander _unit; //--- Temp owner - private _tempOwner = _unit getvariable ["bis_fnc_moduleRemoteControl_owner", objnull]; + private _tempOwner = _unit getVariable ["bis_fnc_moduleRemoteControl_owner", objNull]; //--- Check if the unit is suitable _error = ""; if !(side group _unit in [east,west,resistance,civilian]) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorEmpty";}; - if (isplayer _unit) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorPlayer";}; + if (isPlayer _unit) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorPlayer";}; if !(alive _unit) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorDestroyed";}; - if (isnull _unit) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorNull";}; - if (!isnull _tempOwner && {_tempOwner in allPlayers}) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorControl";}; - if (isuavconnected vehicle _unit) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorControl";}; + if (isNull _unit) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorNull";}; + if (!isNull _tempOwner && {_tempOwner in allPlayers}) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorControl";}; + if (isUAVConnected vehicle _unit) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorControl";}; if (_error == "") then { _unit spawn { - scriptname "bis_fnc_moduleRemoteControl: Loop"; + scriptName "bis_fnc_moduleRemoteControl: Loop"; _unit = _this; _vehicle = vehicle _unit; - _vehicleRole = str assignedvehiclerole _unit; + _vehicleRole = str assignedVehicleRole _unit; bis_fnc_moduleRemoteControl_unit = _unit; - _unit setvariable ["bis_fnc_moduleRemoteControl_owner",player,true]; + _unit setVariable ["bis_fnc_moduleRemoteControl_owner",player,true]; // Added by ace_zeus to toggle remote control wind sound if (GVAR(remoteWind)) then { @@ -61,125 +61,125 @@ if (_activated && local _logic && !isnull curatorcamera) then { [format ["wind%1",ceil random 5],"bis_fnc_playsound"] call bis_fnc_mp; }; - _blur = ppeffectcreate ["RadialBlur",144]; - _blur ppeffectenable true; - _blur ppeffectadjust [0,0,0.3,0.3]; - _blur ppeffectcommit 0; - _blur ppeffectadjust [0.03,0.03,0.1,0.1]; - _blur ppeffectcommit 1; - - _cam = "camera" camcreate getposatl curatorcamera; - _cam cameraeffect ["internal","back"]; - _cam campreparetarget (screentoworld [0.5,0.5]); - _cam camcommitprepared 0; - _cam campreparetarget _unit; - _cam campreparefov 0.1; - _cam camcommitprepared 1; + _blur = ppEffectCreate ["RadialBlur",144]; + _blur ppEffectEnable true; + _blur ppEffectAdjust [0,0,0.3,0.3]; + _blur ppEffectCommit 0; + _blur ppEffectAdjust [0.03,0.03,0.1,0.1]; + _blur ppEffectCommit 1; + + _cam = "camera" camCreate getPosATL curatorCamera; + _cam cameraEffect ["internal","back"]; + _cam camPrepareTarget (screenToWorld [0.5,0.5]); + _cam camCommitPrepared 0; + _cam camPrepareTarget _unit; + _cam camPrepareFov 0.1; + _cam camCommitPrepared 1; sleep 0.75; - ("bis_fnc_moduleRemoteCurator" call bis_fnc_rscLayer) cuttext ["","black out",0.25]; + ("bis_fnc_moduleRemoteCurator" call bis_fnc_rscLayer) cutText ["","black out",0.25]; sleep 0.25; //--- Wait for interface to close - (finddisplay 312) closedisplay 2; - waituntil {isnull curatorcamera}; + (findDisplay 312) closeDisplay 2; + waitUntil {isNull curatorCamera}; //--- Switch - player remotecontrol _unit; - if (cameraon != _vehicle) then { - _vehicle switchcamera cameraview; + player remoteControl _unit; + if (cameraOn != _vehicle) then { + _vehicle switchCamera cameraView; }; - ppeffectdestroy _blur; - _cam cameraeffect ["terminate","back"]; - camdestroy _cam; + ppEffectDestroy _blur; + _cam cameraEffect ["terminate","back"]; + camDestroy _cam; - _color = ppeffectcreate ["colorCorrections",1896]; - _color ppeffectenable true; - _color ppeffectadjust [1,1,0,[0,0,0,1],[1,1,1,1],[0,0,0,0],[0.9,0.0,0,0,0,0.5,1]]; - _color ppeffectcommit 0; + _color = ppEffectCreate ["colorCorrections",1896]; + _color ppEffectEnable true; + _color ppEffectAdjust [1,1,0,[0,0,0,1],[1,1,1,1],[0,0,0,0],[0.9,0.0,0,0,0,0.5,1]]; + _color ppEffectCommit 0; - _curator = getassignedcuratorlogic player; + _curator = getAssignedCuratorLogic player; [_curator,"curatorObjectRemoteControlled",[_curator,player,_unit,true]] call bis_fnc_callScriptedEventHandler; [["Curator","RemoteControl"],nil,nil,nil,nil,nil,nil,true] call bis_fnc_advHint; sleep 0.3; - _color ppeffectadjust [1,1,0,[0,0,0,1],[1,1,1,1],[0,0,0,0],[0.9,0.85,0,0,0,0.5,1]]; - _color ppeffectcommit 0.3; - ("bis_fnc_moduleRemoteCurator" call bis_fnc_rscLayer) cuttext ["","black in",0.5]; + _color ppEffectAdjust [1,1,0,[0,0,0,1],[1,1,1,1],[0,0,0,0],[0.9,0.85,0,0,0,0.5,1]]; + _color ppEffectCommit 0.3; + ("bis_fnc_moduleRemoteCurator" call bis_fnc_rscLayer) cutText ["","black in",0.5]; //--- Back to player _vehicle = vehicle _unit; - _vehicleRole = str assignedvehiclerole _unit; + _vehicleRole = str assignedVehicleRole _unit; _rating = rating player; - waituntil { + waitUntil { //--- Refresh when vehicle or vehicle role changes - if ((vehicle _unit != _vehicle || str assignedvehiclerole _unit != _vehicleRole) && {alive _unit}) then { - player remotecontrol _unit; + if ((vehicle _unit != _vehicle || str assignedVehicleRole _unit != _vehicleRole) && {alive _unit}) then { + player remoteControl _unit; _vehicle = vehicle _unit; - _vehicleRole = str assignedvehiclerole _unit; + _vehicleRole = str assignedVehicleRole _unit; }; if (rating player < _rating) then { - player addrating (-rating player + _rating); + player addRating (-rating player + _rating); }; sleep 0.01; - !isnull curatorcamera + !isNull curatorCamera || - {cameraon == vehicle player} + {cameraOn == vehicle player} || {!alive _unit} //--- Also isnull check, objNull is not alive || {!alive player} || - {isnull getassignedcuratorlogic player} + {isNull getAssignedCuratorLogic player} }; - player addrating (-rating player + _rating); - objnull remotecontrol _unit; - _unit setvariable ["bis_fnc_moduleRemoteControl_owner",nil,true]; + player addRating (-rating player + _rating); + objNull remoteControl _unit; + _unit setVariable ["bis_fnc_moduleRemoteControl_owner",nil,true]; if (alive player) then { //--- Death screen if ( - isnull curatorcamera + isNull curatorCamera && - {cameraon != vehicle player} + {cameraOn != vehicle player} && - {!isnull _unit} + {!isNull _unit} && - {!isnull getassignedcuratorlogic player} + {!isNull getAssignedCuratorLogic player} //&& //{(_unit getvariable ["bis_fnc_moduleRemoteControl_owner",objnull] == player)} ) then { sleep 2; - ("bis_fnc_moduleRemoteCurator" call bis_fnc_rscLayer) cuttext ["","black out",1]; + ("bis_fnc_moduleRemoteCurator" call bis_fnc_rscLayer) cutText ["","black out",1]; sleep 1; }; - if !(isnull _unit) then { - _unitPos = getposatl _unit; + if !(isNull _unit) then { + _unitPos = getPosATL _unit; _camPos = [_unitPos,10,direction _unit + 180] call bis_fnc_relpos; - _camPos set [2,(_unitPos select 2) + (getterrainheightasl _unitPos) - (getterrainheightasl _camPos) + 10]; + _camPos set [2,(_unitPos select 2) + (getTerrainHeightASL _unitPos) - (getTerrainHeightASL _camPos) + 10]; //[_camPos,_unit] call bis_fnc_setcuratorcamera; - (getassignedcuratorlogic player) setvariable ["bis_fnc_modulecuratorsetcamera_params",[_camPos,_unit]]; + (getAssignedCuratorLogic player) setVariable ["bis_fnc_modulecuratorsetcamera_params",[_camPos,_unit]]; }; sleep 0.1; //--- Engine needs a delay in case controlled unit was deleted - ("bis_fnc_moduleRemoteCurator" call bis_fnc_rscLayer) cuttext ["","black in",1e10]; - opencuratorinterface; - ppeffectdestroy _color; + ("bis_fnc_moduleRemoteCurator" call bis_fnc_rscLayer) cutText ["","black in",1e10]; + openCuratorInterface; + ppEffectDestroy _color; - waituntil {!isnull curatorcamera}; + waitUntil {!isNull curatorCamera}; } else { - ppeffectdestroy _color; + ppEffectDestroy _color; }; - player switchcamera cameraview; + player switchCamera cameraView; bis_fnc_moduleRemoteControl_unit = nil; - ("bis_fnc_moduleRemoteCurator" call bis_fnc_rscLayer) cuttext ["","black in",1]; + ("bis_fnc_moduleRemoteCurator" call bis_fnc_rscLayer) cutText ["","black in",1]; [_curator,"curatorObjectRemoteControlled",[_curator,player,_unit,false]] call bis_fnc_callScriptedEventHandler; sleep 0.01; }; } else { - [objnull,_error] call bis_fnc_showCuratorFeedbackMessage; + [objNull,_error] call bis_fnc_showCuratorFeedbackMessage; }; - deletevehicle _logic; + deleteVehicle _logic; }; diff --git a/addons/zeus/functions/fnc_getModuleDestination.sqf b/addons/zeus/functions/fnc_getModuleDestination.sqf index b328201d6ce..763f9b48cac 100644 --- a/addons/zeus/functions/fnc_getModuleDestination.sqf +++ b/addons/zeus/functions/fnc_getModuleDestination.sqf @@ -109,13 +109,13 @@ GVAR(moduleDestination_mapDrawEH) = [((findDisplay 312) displayCtrl 50), "draw", 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];; + 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; diff --git a/addons/zeus/functions/fnc_moduleBurn.sqf b/addons/zeus/functions/fnc_moduleBurn.sqf index 4cf2017b670..9fb3b085af8 100644 --- a/addons/zeus/functions/fnc_moduleBurn.sqf +++ b/addons/zeus/functions/fnc_moduleBurn.sqf @@ -17,26 +17,22 @@ params ["_logic"]; -if !(local _logic) exitWith {}; +if (!local _logic) exitWith {}; private _unit = attachedTo _logic; deleteVehicle _logic; switch (false) do { - case !(isNull _unit): { + case (!isNull _unit): { [LSTRING(NothingSelected)] call FUNC(showMessage); }; - case (_unit isKindOf "CAManBase"): { + case (_unit isKindOf "CAManBase" && {getNumber (configOf _unit >> "isPlayableLogic") == 0}): { [LSTRING(OnlyInfantry)] call FUNC(showMessage); }; - case (alive _unit): { - [LSTRING(OnlyAlive)] call FUNC(showMessage); - }; case (["ace_fire"] call EFUNC(common,isModLoaded)): { [LSTRING(RequiresAddon)] call FUNC(showMessage); }; default { - [QEGVAR(fire,burn), [_unit, 5]] call CBA_fnc_globalEvent; + [QEGVAR(fire,burn), [_unit, 5], _unit] call CBA_fnc_targetEvent; }; }; - diff --git a/addons/zeus/functions/fnc_moduleCaptive.sqf b/addons/zeus/functions/fnc_moduleCaptive.sqf index ad359575e96..e16a701f055 100644 --- a/addons/zeus/functions/fnc_moduleCaptive.sqf +++ b/addons/zeus/functions/fnc_moduleCaptive.sqf @@ -29,7 +29,7 @@ if (isNil QEFUNC(captives,setHandcuffed)) then { if ((_mouseOver select 0) != "OBJECT") then { [LSTRING(NothingSelected)] call FUNC(showMessage); } else { - private _unit = effectivecommander (_mouseOver select 1); + private _unit = effectiveCommander (_mouseOver select 1); if !(_unit isKindOf "CAManBase") then { [LSTRING(OnlyInfantry)] call FUNC(showMessage); diff --git a/addons/zeus/functions/fnc_moduleCargoParadrop.sqf b/addons/zeus/functions/fnc_moduleCargoParadrop.sqf index 69d90d310d6..ed009832756 100644 --- a/addons/zeus/functions/fnc_moduleCargoParadrop.sqf +++ b/addons/zeus/functions/fnc_moduleCargoParadrop.sqf @@ -30,13 +30,13 @@ TRACE_4("moduleCargoParadrop placed",_logic,typeOf _vehicle,_pilot,typeOf _pilot deleteVehicle _logic; // cleanup logic now, we just needed it to get the attached vehicle -if (!(missionNamespace getVariable [QEGVAR(cargo,enable), false])) exitWith { +if !(missionNamespace getVariable [QEGVAR(cargo,enable), false]) exitWith { [LSTRING(RequiresAddon)] call FUNC(showMessage); }; if (isNull _vehicle) exitWith { [LSTRING(NothingSelected)] call FUNC(showMessage); }; -if (!(_vehicle isKindOf "Air")) exitWith { +if !(_vehicle isKindOf "Air") exitWith { [format ["%1 %2", localize "str_dn_aircraft", localize "str_msg_no_veh_select"]] call FUNC(showMessage); }; if ((!alive _vehicle) || {!alive _pilot}) exitWith { @@ -62,7 +62,7 @@ if ((_vehicle getVariable [QEGVAR(cargo,loaded), []]) isEqualTo []) exitWith { [_group] call CBA_fnc_clearWaypoints; - private _wp = _group addWaypoint [ASLtoAGL _mousePosASL, 0]; + private _wp = _group addWaypoint [ASLToAGL _mousePosASL, 0]; _wp setWaypointType "SCRIPTED"; _wp setWaypointScript QPATHTOF(functions\DOUBLES(fnc,moduleCargoParadropWaypoint).sqf); diff --git a/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf b/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf index dded460710b..cc6f9f0a012 100644 --- a/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf +++ b/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf @@ -22,8 +22,8 @@ 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 (_cargo isEqualTo []) exitWith {WARNING_1("no cargo",_cargo); true}; +if !(_vehicle isKindOf "Air") exitWith {WARNING_1("not in a air vehicle %1",typeOf _vehicle); true}; +if (_cargo isEqualTo []) exitWith {WARNING_1("no cargo %1",_cargo); true}; private _previousSpeedMode = speedMode _vehicleGroup; private _nextMoveUpdate = -1; diff --git a/addons/zeus/functions/fnc_moduleHeal.sqf b/addons/zeus/functions/fnc_moduleHeal.sqf index 9a49375003d..4bf0525ea75 100644 --- a/addons/zeus/functions/fnc_moduleHeal.sqf +++ b/addons/zeus/functions/fnc_moduleHeal.sqf @@ -43,7 +43,7 @@ switch (false) do { }; // Heal validated target -if (["ace_medical"] call EFUNC(common,isModLoaded)) then { +if (GETEGVAR(medical,enabled,false)) then { TRACE_1("healing with ace_medical",_unit); [QEGVAR(medical_treatment,fullHealLocal), [_unit], _unit] call CBA_fnc_targetEvent; } else { diff --git a/addons/zeus/functions/fnc_moduleSetMedic.sqf b/addons/zeus/functions/fnc_moduleSetMedic.sqf index f66ca9132da..2393de0ebfa 100644 --- a/addons/zeus/functions/fnc_moduleSetMedic.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedic.sqf @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ace_medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); @@ -29,7 +29,7 @@ if !(["ace_medical"] call EFUNC(common,isModLoaded)) then { if ((_mouseOver select 0) != "OBJECT") then { [LSTRING(NothingSelected)] call FUNC(showMessage); } else { - private _unit = effectivecommander (_mouseOver select 1); + private _unit = effectiveCommander (_mouseOver select 1); if !(_unit isKindOf "CAManBase") then { [LSTRING(OnlyInfantry)] call FUNC(showMessage); diff --git a/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf b/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf index 1f982129357..b6742a25a44 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ace_medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); @@ -40,7 +40,7 @@ if !(["ace_medical"] call EFUNC(common,isModLoaded)) then { if (GETVAR(_unit,EGVAR(captives,isHandcuffed),false)) then { [LSTRING(OnlyNonCaptive)] call FUNC(showMessage); } else { - if (!(GETVAR(_unit,EGVAR(medical,isMedicalFacility),false))) then { + if !(GETVAR(_unit,EGVAR(medical,isMedicalFacility),false)) then { _unit setVariable [QEGVAR(medical,isMedicalFacility), true, true]; }; }; diff --git a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf index e8189b377e6..26bb3fcfe95 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ace_medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); diff --git a/addons/zeus/functions/fnc_moduleSpectator.sqf b/addons/zeus/functions/fnc_moduleSpectator.sqf new file mode 100644 index 00000000000..fb9ca2a63b1 --- /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 8346eb42665..6db261da534 100644 --- a/addons/zeus/functions/fnc_moduleSuicideBomber.sqf +++ b/addons/zeus/functions/fnc_moduleSuicideBomber.sqf @@ -30,8 +30,9 @@ #endif TRACE_1("params",_this); +params ["_unit", "", "", "", "_autoSeek"]; -if (isNull (_this select 0)) exitWith {}; +if (isNull _unit) exitWith {}; // Prevent another suicide bomber module being attached _unit setVariable [QGVAR(suicideBomber), true, true]; @@ -57,7 +58,7 @@ if (_autoSeek) then { LOG("Unit deleted or killed, PFH removed"); }; - if (!([_unit] call EFUNC(common,isAwake))) exitWith {}; + if !([_unit] call EFUNC(common,isAwake)) exitWith {}; // Detonation private _nearObjects = (_unit nearObjects _activationRadius) select {side _x == _activationSide && {_x != _unit} && {alive _x}}; diff --git a/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf b/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf index 2a013fa4c23..2860f624f22 100644 --- a/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf +++ b/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf @@ -59,7 +59,7 @@ if ([_unit] call EFUNC(common,isPlayer)) exitWith { } forEach getArtilleryAmmo [_vehicle]; TRACE_1("getArtilleryAmmo",_artilleryMag); if (_artilleryMag == "") exitWith {_targetASL = [];}; - private _eta = _vehicle getArtilleryETA [ASLtoAGL _targetASL, _artilleryMag]; + private _eta = _vehicle getArtilleryETA [ASLToAGL _targetASL, _artilleryMag]; TRACE_1("getArtilleryETA",_eta); if (_eta < 0) exitWith { [ELSTRING(Interaction,NotInRange)] call FUNC(showMessage); @@ -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 f09211b034b..39efec6d921 100644 --- a/addons/zeus/functions/fnc_moduleSuppressiveFireLocal.sqf +++ b/addons/zeus/functions/fnc_moduleSuppressiveFireLocal.sqf @@ -21,7 +21,7 @@ params ["_unit", "_targetASL", "_artilleryMag"]; TRACE_4("moduleSuppressiveFireLocal",_unit,local _unit,_targetASL,_artilleryMag); if (_artilleryMag != "") exitWith { - (vehicle _unit) doArtilleryFire [ASLtoAGL _targetASL, _artilleryMag, 4]; + (vehicle _unit) doArtilleryFire [ASLToAGL _targetASL, _artilleryMag, 4]; TRACE_3("doArtilleryFire",_unit,_targetASL,_artilleryMag); }; diff --git a/addons/zeus/functions/fnc_moduleSurrender.sqf b/addons/zeus/functions/fnc_moduleSurrender.sqf index 07517d7e710..b8071a8cd52 100644 --- a/addons/zeus/functions/fnc_moduleSurrender.sqf +++ b/addons/zeus/functions/fnc_moduleSurrender.sqf @@ -29,7 +29,7 @@ if (isNil QEFUNC(captives,setSurrendered)) then { if ((_mouseOver select 0) != "OBJECT") then { [LSTRING(NothingSelected)] call FUNC(showMessage); } else { - private _unit = effectivecommander (_mouseOver select 1); + private _unit = effectiveCommander (_mouseOver select 1); if !(_unit isKindOf "CAManBase") then { [LSTRING(OnlyInfantry)] call FUNC(showMessage); diff --git a/addons/zeus/functions/fnc_moduleUnconscious.sqf b/addons/zeus/functions/fnc_moduleUnconscious.sqf index 7eede3cdece..7ca0a824c2d 100644 --- a/addons/zeus/functions/fnc_moduleUnconscious.sqf +++ b/addons/zeus/functions/fnc_moduleUnconscious.sqf @@ -29,7 +29,7 @@ if (isNil QEFUNC(medical,setUnconscious)) then { if ((_mouseOver select 0) != "OBJECT") then { [LSTRING(NothingSelected)] call FUNC(showMessage); } else { - private _unit = effectivecommander (_mouseOver select 1); + private _unit = effectiveCommander (_mouseOver select 1); if !(_unit isKindOf "CAManBase") then { [LSTRING(OnlyInfantry)] call FUNC(showMessage); diff --git a/addons/zeus/functions/fnc_showMessage.sqf b/addons/zeus/functions/fnc_showMessage.sqf index 8bbd7d510dc..53094dbfb3f 100644 --- a/addons/zeus/functions/fnc_showMessage.sqf +++ b/addons/zeus/functions/fnc_showMessage.sqf @@ -18,7 +18,7 @@ * Public: Yes */ -if (!(_this isEqualTypeParams [""])) exitWith {ERROR_1("First arg must be string [%1]",_this);}; +if !(_this isEqualTypeParams [""]) exitWith {ERROR_1("First arg must be string [%1]",_this);}; private _message = _this apply {if ((_x isEqualType "") && {isLocalized _x}) then {localize _x} else {_x}}; [objNull, format _message] call BIS_fnc_showCuratorFeedbackMessage; diff --git a/addons/zeus/functions/fnc_ui_globalSetSkill.sqf b/addons/zeus/functions/fnc_ui_globalSetSkill.sqf index 31f41d76c6b..1586ce2f460 100644 --- a/addons/zeus/functions/fnc_ui_globalSetSkill.sqf +++ b/addons/zeus/functions/fnc_ui_globalSetSkill.sqf @@ -24,7 +24,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Specific on-load stuff: private _fnc_sliderMove = { @@ -47,7 +47,7 @@ private _fnc_sliderMove = { (_display displayCtrl 16189) cbSetChecked (GVAR(GlobalSkillAI) select 5); private _fnc_onUnload = { - private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); if (isNull _logic) exitWith {}; deleteVehicle _logic; @@ -57,7 +57,7 @@ private _fnc_onConfirm = { params [["_ctrlButtonOK", controlNull, [controlNull]]]; TRACE_1("_fnc_onConfirm params",_this); - private _display = ctrlparent _ctrlButtonOK; + private _display = ctrlParent _ctrlButtonOK; if (isNull _display) exitWith {}; GVAR(GlobalSkillAI) = [ @@ -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 4dff592f621..9c243d5642a 100644 --- a/addons/zeus/functions/fnc_ui_groupSide.sqf +++ b/addons/zeus/functions/fnc_ui_groupSide.sqf @@ -24,7 +24,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Validate the module target: private _unit = effectiveCommander (attachedTo _logic); @@ -101,11 +101,11 @@ private _fnc_onSelection = { _ctrl ctrlSetTextColor _color; - _ctrl ctrlAddEventHandler ["buttonclick", _fnc_onSelection]; + _ctrl ctrlAddEventHandler ["ButtonClick", _fnc_onSelection]; } forEach IDCs; private _fnc_onUnload = { - private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); if (isNull _logic) exitWith {}; if (_this select 1 == 2) then { @@ -116,10 +116,10 @@ private _fnc_onUnload = { private _fnc_onConfirm = { params ["_ctrlButtonOK"]; - private _display = ctrlparent _ctrlButtonOK; + private _display = ctrlParent _ctrlButtonOK; if (isNull _display) exitWith {}; - private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); if (isNull _logic) exitWith {}; private _unit = effectiveCommander (attachedTo _logic); @@ -129,5 +129,5 @@ private _fnc_onConfirm = { deleteVehicle _logic; }; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_ctrlButtonOK ctrlAddEventHandler ["buttonClick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_setEngineer.sqf b/addons/zeus/functions/fnc_ui_setEngineer.sqf index b2515c311dd..e19b04c04c0 100644 --- a/addons/zeus/functions/fnc_ui_setEngineer.sqf +++ b/addons/zeus/functions/fnc_ui_setEngineer.sqf @@ -23,7 +23,7 @@ private _ctrlButtonOK = _display displayCtrl 1; // IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; // Validate module target private _unit = attachedTo _logic; @@ -64,7 +64,7 @@ private _fnc_onConfirm = { private _display = ctrlParent _ctrlButtonOK; if (isNull _display) exitWith {}; - private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); if (isNull _logic) exitWith {}; private _value = lbCurSel (_display displayCtrl 86947); diff --git a/addons/zeus/functions/fnc_ui_spectator.sqf b/addons/zeus/functions/fnc_ui_spectator.sqf new file mode 100644 index 00000000000..04d2a067630 --- /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 26184518710..ab74b398745 100644 --- a/addons/zeus/functions/fnc_ui_suicideBomber.sqf +++ b/addons/zeus/functions/fnc_ui_suicideBomber.sqf @@ -65,7 +65,7 @@ private _fnc_onSelection = { params [["_activeCtrl", controlNull, [controlNull]]]; private _display = ctrlParent _activeCtrl; - if (isNUll _display) exitWith {}; + if (isNull _display) exitWith {}; // Update button colours and scales { diff --git a/addons/zeus/functions/fnc_ui_teleportPlayers.sqf b/addons/zeus/functions/fnc_ui_teleportPlayers.sqf index 1becc040048..9d32d8cfc02 100644 --- a/addons/zeus/functions/fnc_ui_teleportPlayers.sqf +++ b/addons/zeus/functions/fnc_ui_teleportPlayers.sqf @@ -23,7 +23,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Specific on-load stuff: private _listbox = _display displayCtrl 16189; @@ -66,7 +66,7 @@ private _fnc_onKeyUp = { private _fnc_onUnload = { params ["_display"]; - private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); if (isNull _logic) exitWith {}; // Store checkbox value for reopening @@ -76,10 +76,10 @@ private _fnc_onUnload = { private _fnc_onConfirm = { params [["_ctrlButtonOK", controlNull, [controlNull]]]; - private _display = ctrlparent _ctrlButtonOK; + private _display = ctrlParent _ctrlButtonOK; if (isNull _display) exitWith {}; - private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); if (isNull _logic) exitWith {}; private _lb = _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/stringtable.xml b/addons/zeus/stringtable.xml index bb78c86c1ac..b970d75b64b 100644 --- a/addons/zeus/stringtable.xml +++ b/addons/zeus/stringtable.xml @@ -61,7 +61,7 @@ Felemelkedési üzenetek Сообщения о вознесении Messaggi di Ascesa - 転生の布告 + Zeus転生通知 재림 메세지 宙斯上任信息 宙斯上任訊息 @@ -1097,6 +1097,22 @@ 需要一個不存在的插件 현재 없는 애드온을 필요로 합니다 + + Only Players + プレイヤーのみ + Nur Spieler + 오직 플레이어만 + Tylko gracze + Joueurs seulement + Solo Giocatori + 仅玩家 + 只有玩家 + Только игроки + Apenas Jogadores + Pouze hráči + Solo jugadores + Sadece Oyuncular + None Keiner @@ -1321,6 +1337,8 @@ 貨物室から降ろす 화물 내리기 Выгрузить из отсека + Décharger de la cargaison + Descargar de la carga Toggle NVGs @@ -1482,7 +1500,7 @@ Fill from top to bottom Von oben nach unten befüllen Remplir de haut en bas - 上から下まで占拠 + 上から下へと占拠 Riempi dall'alto al basso 由上而下進行填滿 由上而下进行填满 @@ -1761,7 +1779,7 @@ Explosionsgröße Robbanásméret Dimensione dell'Esplosione - 爆発サイズ + 爆発の大きさ 폭발 크기 Rozmiar wybuchu Tamanho da Explosão @@ -1966,6 +1984,8 @@ 医療メニューは無効になっています 의료 메뉴가 비활성화되었습니다 Медицинское меню отключено + Le Menu médical est désactivé + El menú médico está deshabilitado Lay Trenchline @@ -1976,6 +1996,7 @@ Piazza Trincea 塹壕溝線を敷設 Проложить траншею + Poner una Trinchera +SHIFT to force (Can only lay N/S or E/W) @@ -1983,9 +2004,80 @@ + 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 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 + Force le mode spectateur en empêchant le joueur de la fermer avec la touche Echap. + Fuerza la interfaz del espectador a prevenir al jugador de cerrarla pulsando la tecla de Escape + + + Hide player + プレイヤーを隠す + Скрыть игрока + 플레이어 숨기기 + Spieler ausblenden + Nascondi giocatore + Cacher le joueur + Ocultar jugador + + + 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 + Cache le joueur en le rendant invisible, invulnérable, muet et en le retirant de son groupe. + Oculta al jugador haciéndolo invisible, invulnerable, silenciado, y eliminándole del grupo + + + Sets the sides that are available to spectate + 指定の陣営を観戦可能に設定します + Устанавливает стороны, доступные для режима spectator + 관전 가능한 진영을 설정합니다. + Bestimmt die Seiten denen man zuschauen kann + Imposta le fazioni che lo spettatore può osservare + Définit les côtés disponibles pour le mode spectateur + Establece los bandos que tienen disponible ser espectador + + + White Hot + 白=熱源 + Белый + 백색 열원 + Weiß-Schwarz + Bianco-caldo + Blanc-noir + Blanco Caliente + + + Black Hot + 黒=熱源 + Чёрный + 흑색 열원 + Schwarz-Weiß + Nero-caldo + Noir et blanc + Negro Caliente + + + Toggle All + 全てを切り替え + Выключить все + 전부 토글 + Alle wechseln + Cambia tutti + Tout afficher + Alternar todo diff --git a/addons/zeus/ui/RscAttributes.hpp b/addons/zeus/ui/RscAttributes.hpp index 0ff21b145f6..da3f53364fb 100644 --- a/addons/zeus/ui/RscAttributes.hpp +++ b/addons/zeus/ui/RscAttributes.hpp @@ -915,3 +915,231 @@ class GVAR(RscSuicideBomber): RscDisplayAttributes { class ButtonCancel: ButtonCancel {}; }; }; + +class GVAR(RscSpectator): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscSpectator))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscSpectator))] call FUNC(zeusAttributes)); + class Controls: Controls { + class Background: Background {}; + class Title: Title {}; + class Content: Content { + class Controls { + class spectator: RscControlsGroupNoScrollbars { + onSetFocus = QUOTE(_this call FUNC(ui_spectator)); + idc = 92530; + x = 0; + y = 0; + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(10.7)); + class controls { + class ForceInterfaceLabel: RscText { + idc = -1; + text = "$STR_a3_cfgvehicles_modulecurator_f_arguments_forced"; + tooltip = CSTRING(ModuleSpectator_ForceInterface_Tooltip); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(1)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class ForceInterface: ctrlToolbox { + idc = 92531; + x = QUOTE(W_PART(10.1)); + y = 0; + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); + rows = 1; + columns = 2; + strings[] = {ECSTRING(common,No), ECSTRING(common,Yes)}; + }; + class HidePlayerLabel: ForceInterfaceLabel { + text = CSTRING(ModuleSpectator_HidePlayer); + tooltip = CSTRING(ModuleSpectator_HidePlayer_Tooltip); + y = QUOTE(H_PART(1.1)); + }; + class HidePlayer: ForceInterface { + idc = 92532; + y = QUOTE(H_PART(1.1)); + }; + class SpectateSides: RscControlsGroupNoScrollbars { + idc = 92533; + x = 0; + y = QUOTE(H_PART(2.2)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.5)); + class controls { + class Label: RscText { + idc = -1; + text = "$STR_A3_Spectator_Eden_WhitelistedSides_Name"; + tooltip = CSTRING(ModuleSpectator_SpectableSides_Tooltip); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x = QUOTE(W_PART(10)); + y = 0; + w = QUOTE(W_PART(16)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class BLUFOR: RscActivePicture { + idc = 92541; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_west_ca.paa"; + x = QUOTE(W_PART(12.5)); + y = QUOTE(H_PART(0.25)); + w = QUOTE(W_PART(2)); + h = QUOTE(H_PART(2)); + tooltip = "$STR_WEST"; + }; + class OPFOR: BLUFOR { + idc = 92540; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_east_ca.paa"; + x = QUOTE(W_PART(15.5)); + tooltip = "$STR_EAST"; + }; + class Independent: BLUFOR { + idc = 92542; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_guer_ca.paa"; + x = QUOTE(W_PART(18.5)); + tooltip = "$STR_guerrila"; + }; + class Civilian: BLUFOR { + idc = 92543; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_civ_ca.paa"; + x = QUOTE(W_PART(21.5)); + tooltip = "$STR_Civilian"; + }; + }; + }; + class CameraModes: RscControlsGroupNoScrollbars { + idc = 92534; + x = 0; + y = QUOTE(H_PART(4.8)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.5)); + class controls { + class Label: RscText { + idc = -1; + text = ECSTRING(spectator,modes_DisplayName); + tooltip = ECSTRING(spectator,modes_Description); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x =QUOTE(W_PART(10)); + y = 0; + w = QUOTE(W_PART(16)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class Free: RscActivePicture { + idc = 92550; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Free.paa"; + x = QUOTE(W_PART(13.375)); + y = QUOTE(H_PART(0.375)); + w = QUOTE(W_PART(1.75)); + h = QUOTE(H_PART(1.75)); + tooltip = "$STR_A3_Spectator_free_camera_tooltip"; + }; + class Follow: Free { + idc = 92552; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Follow.paa"; + x = QUOTE(W_PART(17.125)); + tooltip = "$STR_A3_Spectator_3pp_camera_tooltip"; + }; + class FirstPerson: Free { + idc = 92551; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Fps.paa"; + x = QUOTE(W_PART(20.875)); + tooltip = "$STR_A3_Spectator_1pp_camera_tooltip"; + }; + }; + }; + class VisionModes: RscControlsGroupNoScrollbars { + idc = 92535; + x = 0; + y = QUOTE(H_PART(7.4)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(3.3)); + class controls { + class Label: RscText { + idc = -1; + text = ECSTRING(spectator,visions_DisplayName); + tooltip = ECSTRING(spectator,visions_Description); + x = 0; + y = 0; + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(1)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x = 0; + y = QUOTE(H_PART(1)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.3)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class AllCheckBox: RscCheckBox { + idc = 92557; + tooltip = CSTRING(ToggleAll); + x = QUOTE(W_PART(25)); + y = 0; + w = QUOTE(W_PART(1)); + h = QUOTE(H_PART(1)); + }; + class NormalLabel: Label { + text = "$STR_speed_normal"; + tooltip = ""; + x = QUOTE(W_PART(1)); + y = QUOTE(H_PART(1.1)); + w = QUOTE(W_PART(10.8)); + colorBackground[] = {0, 0, 0, 0.6}; + }; + class Normal: AllCheckBox { + idc = 92558; + x = QUOTE(W_PART(11.9)); + y = QUOTE(H_PART(1.1)); + }; + class NightVisionLabel: NormalLabel { + text = "$STR_usract_night_vision"; + y = QUOTE(H_PART(2.2)); + }; + class NightVision: Normal { + idc = 92559; + y = QUOTE(H_PART(2.2)); + }; + class WhiteHotLabel: NormalLabel { + text = CSTRING(ModuleSpectator_WhiteHot); + x = QUOTE(W_PART(13.1)); + }; + class WhiteHot: Normal { + idc = 92560; + x = QUOTE(W_PART(24)); + }; + class BlackHotLabel: WhiteHotLabel { + text = CSTRING(ModuleSpectator_BlackHot); + y = QUOTE(Y_PART(2.2)); + }; + class BlackHot: WhiteHot { + idc = 92561; + y = QUOTE(H_PART(2.2)); + }; + }; + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; diff --git a/docs/Gemfile b/docs/Gemfile index 053c27dc351..486c7aac0fb 100644 --- a/docs/Gemfile +++ b/docs/Gemfile @@ -1,2 +1,4 @@ source 'https://rubygems.org' gem 'github-pages' +gem 'tzinfo-data' +gem 'webrick' diff --git a/docs/README_DE.md b/docs/README_DE.md index 160fb111b23..beb9467ab9e 100644 --- a/docs/README_DE.md +++ b/docs/README_DE.md @@ -48,7 +48,7 @@ Die Mod ist **modular aufgebaut**. Beinahe jede PBO kann entfernt werden, sodass - Tragen und Ziehen - Waffen und Fahrzeuge tragen die Namen ihrer Vorbilder aus der echten Welt - Ein Feuerleitsystem (FLS) für Hubschrauber und Panzer -- Viele Funktionen werden in C/C++ Erweiterungen berechnet +- Viele Funktionen werden in Rust Erweiterungen berechnet - Rückstrahlzonen- und Überdrucksimulation - Einwegwaffen - Realistische G-Kräfte diff --git a/docs/README_PL.md b/docs/README_PL.md index b1917f4080e..717ea01a0fe 100644 --- a/docs/README_PL.md +++ b/docs/README_PL.md @@ -43,7 +43,7 @@ Modyfikacja ta jest **budowana modułowo**, dzięki temu prawie każdy dostarczo - Przeciąganie i przenoszenie - Realistyczne nazwy pojazdów i broni - System kontroli ognia (SKO) dla pojazdów opancerzonych oraz śmigłowców -- Realistyczna balistyka/SKO obliczana w rozszerzeniach C/C++ +- Realistyczna balistyka/SKO obliczana w rozszerzeniach Rust - Symulacja strefy backblastu i podciśnienia - Jednorazowe wyrzutnie - Realistyczne siły G diff --git a/docs/_config.yml b/docs/_config.yml index bc7440eee34..08fdb51a642 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -8,9 +8,9 @@ ace: githubUrl: https://github.com/acemod/ACE3 version: major: 3 - minor: 16 - patch: 3 - build: 79 + minor: 18 + patch: 0 + build: 90 markdown: kramdown diff --git a/docs/_config_dev.yml b/docs/_config_dev.yml index 0d0cf1b7fce..3a57f2aad5f 100644 --- a/docs/_config_dev.yml +++ b/docs/_config_dev.yml @@ -8,9 +8,9 @@ ace: githubUrl: https://github.com/acemod/ACE3 version: major: 3 - minor: 16 - patch: 3 - build: 79 + minor: 18 + patch: 0 + build: 90 markdown: kramdown diff --git a/docs/_includes/_footer.html b/docs/_includes/_footer.html index ec55355d999..b13d9d47b54 100644 --- a/docs/_includes/_footer.html +++ b/docs/_includes/_footer.html @@ -36,6 +36,12 @@

Social Media

+
+

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

diff --git a/docs/_includes/_header.html b/docs/_includes/_header.html index 7123c5968a8..8c6cd8c39e1 100644 --- a/docs/_includes/_header.html +++ b/docs/_includes/_header.html @@ -27,6 +27,7 @@ + diff --git a/docs/_posts/2024-04-01-ace3-version3170.md b/docs/_posts/2024-04-01-ace3-version3170.md new file mode 100644 index 00000000000..fddc71642a7 --- /dev/null +++ b/docs/_posts/2024-04-01-ace3-version3170.md @@ -0,0 +1,48 @@ +--- +title: ACEREP #00012 +description: Status report on ACE3 version 3.17.0 +parent: posts +image: +author: Jonpas +layout: post +--- + +This post accompanies the release of ACE3 v3.17.0, a smaller but not any less significant release. We will also take a peek at at our new experimental project. + + + +### Release Cadence + +With improved tooling such as [HEMTT](https://github.com/BrettMayson/HEMTT) simplifying our release processes, we have been aiming aiming to do releases more often than in the past. This is one of the first bigger releases following the set cadence. + +While releases are expected to be smaller as less time passes between them resulting in fewer changes, the new cadence should effectively contribute to higher quality and stability of ACE3 overall. + +We are maintaining our philosophy of "no schedule, no ETAs" and simply release when the team is able to and opts to do so. Work done on the project should not affect this and we aim to release more often even if there are only little or insignificant changes. + +### Integrated CUP Compatibility + +[Community Upgrade Project](https://www.cup-arma3.org/) has always provided compatibility and support for ACE3. Originally it has been hosted and maintained by the CUP Team. With the availability of automatically loading a compatibility patch if the given mod is loaded, we have worked together with the CUP Team to bring ACE3 Compatibility for CUP directly into the ACE3 mod. + +**This means you should remove any compatibility patches provided by CUP** and instead simply use ACE3 together with CUP. In addition to integrated compatibility, some additional improvements were also made. + +### ACE Anvil + +
+
+ ACE Anvil Logo +
+
+ +[ACE Anvil](https://github.com/acemod/ACE-Anvil) is an **experimental** realism mod for Arma Reforger, the first Arma game running on the Enfusion engine. + +Anvil is not expected to reach feature parity with ACE3. It is heavily experimental and we invite you to contribute to it. As Arma Reforger is a test platform, go wild, we are happy to add any realism or quality of life features, even some that might not be strictly within ACE's usual scope. + +Learn more about ACE Anvil at the [Anvil Documentation](https://anvil.acemod.org/)! + +### The End Things + +The change log for ACE3 v3.17.0 can be found [here](https://github.com/acemod/ACE3/releases/v3.17.0){:target="_blank"}. + +We are still in need for translations for some languages within the ACE3 project. Please have a look at [this GitHub issue to track the progress and what languages lack translations](https://github.com/acemod/ACE3/issues/367){:target="_blank"}. Any and all help with this is very appreciated. + +Make sure to [follow us on Twitter](https://twitter.com/intent/follow?screen_name=ace3mod&tw_p=followbutton){:target="_blank"} and to [like our Facebook page](https://www.facebook.com/ACE3Mod/){:target="_blank"}. diff --git a/docs/docker-compose.yml b/docs/docker-compose.yml index ca25a38c0a8..5645a80000f 100644 --- a/docs/docker-compose.yml +++ b/docs/docker-compose.yml @@ -1,5 +1,3 @@ -version: "3.2" - services: docs: container_name: ace3mod_jekyll diff --git a/docs/img/news/240401_ace_anvil_logo.webp b/docs/img/news/240401_ace_anvil_logo.webp new file mode 100644 index 00000000000..8a679e7a599 Binary files /dev/null and b/docs/img/news/240401_ace_anvil_logo.webp differ diff --git a/docs/index.html b/docs/index.html index 1b830ece202..c15d7887988 100644 --- a/docs/index.html +++ b/docs/index.html @@ -8,7 +8,7 @@ exclude: "yes" --- -Fork me on GitHub +Fork me on GitHub
diff --git a/docs/team.md b/docs/team.md index f8fe165bf9b..d5d9d03bfa2 100644 --- a/docs/team.md +++ b/docs/team.md @@ -11,6 +11,8 @@ This page lists all current maintainers for the ACE3 projects with their areas o This lists all the maintainers responsible for project management and the overall direction of the ACE3 project. +- [BaerMitUmlaut](https://github.com/BaerMitUmlaut){:target="_blank"} + - Scripting, Config - [bux](https://github.com/bux){:target="_blank"} - Scripting, Testing - [Felix Wiegand](https://github.com/koffeinflummi){:target="_blank"} @@ -23,13 +25,13 @@ This lists all the maintainers responsible for project management and the overal - Coding, Modeling, Performance, SME - [PabstMirror](https://github.com/PabstMirror){:target="_blank"} - Scripting, Config +- [veteran29](https://github.com/veteran29){:target="_blank"} + - Scripting, Config - [ViperMaul](https://github.com/vipermaul){:target="_blank"} - Project management ## Core Maintainers -- [BaerMitUmlaut](https://github.com/BaerMitUmlaut){:target="_blank"} - - Scripting, Config - [commy2](https://github.com/commy2){:target="_blank"} - Scripting, Config - [esteldunedain](https://github.com/esteldunedain){:target="_blank"} @@ -58,18 +60,19 @@ This lists all the maintainers responsible for project management and the overal - gundy - Janus - [johnb43](https://github.com/johnb432){:target="_blank"} +- [Kex](https://github.com/kexanone){:target="_blank"} - [Kieran](https://github.com/kieran-s){:target="_blank"} - [mharis001](https://github.com/mharis001){:target="_blank"} - [tcvm](https://github.com/TheCandianVendingMachine){:target="_blank"} - [TheMagnetar](https://github.com/TheMagnetar){:target="_blank"} - Scripting - tpM -- [veteran29](https://github.com/veteran29){:target="_blank"} ## Moderators - [drofseh](https://github.com/Drofseh){:target="_blank"} - [MikeMF](https://github.com/Mike-MF){:target="_blank"} +- [MiszczuZPolski](https://github.com/MiszczuZPolski){:target="_blank"} ## Contributors diff --git a/docs/tools/document_functions.py b/docs/tools/document_functions.py index dab567d2088..7ed20eade3a 100644 --- a/docs/tools/document_functions.py +++ b/docs/tools/document_functions.py @@ -339,6 +339,8 @@ def document_functions(addons_dir, components): return errors +def getFunctionPath(func): + return func.path.casefold() def crawl_dir(addons_dir, directory, debug=False, lint_private=False): components = {} @@ -360,7 +362,11 @@ def crawl_dir(addons_dir, directory, debug=False, lint_private=False): if function.is_public() and not debug: # Add functions to component key (initalise key if necessary) component = os.path.basename(os.path.dirname(root)) - components.setdefault(component, []).append(function) + + # Sort functions alphabetically + functions = components.setdefault(component, []) + functions.append(function) + functions.sort(key=getFunctionPath) function.feedback("Publicly documented") else: diff --git a/docs/wiki/class-names.md b/docs/wiki/class-names.md index d8537f06458..0dcf014da16 100644 --- a/docs/wiki/class-names.md +++ b/docs/wiki/class-names.md @@ -232,6 +232,7 @@ ACE_bodyBag | Bodybag | ACE_ItemCore | ACE_bodyBagObject | Bodybag (packed) | | ACE_epinephrine | Epinephrine auto injector | ACE_ItemCore | ACE_morphine | Morphine auto injector | ACE_ItemCore | +ACE_painkillers | Painkillers | ACE_ItemCore | ACE_packingBandage | Packing Bandage | ACE_ItemCore | ACE_personalAidKit | Personal Aid Kit | ACE_ItemCore | ACE_plasmaIV | Plasma IV (1000ml) | ACE_ItemCore | @@ -240,6 +241,7 @@ ACE_plasmaIV_250 | Plasma IV (250ml) | ACE_ItemCore | ACE_salineIV | Saline IV (1000ml) | ACE_ItemCore | ACE_salineIV_500 | Saline IV (500ml) | ACE_ItemCore | ACE_salineIV_250 | Saline IV (250ml) | ACE_ItemCore | +ACE_suture | Suture | ACE_ItemCore | ACE_surgicalKit | Surgical Kit | ACE_ItemCore | ACE_tourniquet | Tourniquet (CAT) | ACE_ItemCore | ACE_medicalSupplyCrate | Simple ACE Medical Supply Crate | ammo box | diff --git a/docs/wiki/development/ace3-config-entries.md b/docs/wiki/development/ace3-config-entries.md index 9e656ad48c9..8ff22438a10 100644 --- a/docs/wiki/development/ace3-config-entries.md +++ b/docs/wiki/development/ace3-config-entries.md @@ -13,29 +13,78 @@ Entries found in the `CfgVehicles.hpp` files ```cpp -ace_nightvision_grain -ace_nightvision_blur -ace_recoil_enablecamshake -ace_dragging_cancarry -ace_dragging_carryposition -ace_dragging_carrydirection -ace_dragging_candrag -ace_dragging_dragposition -ace_dragging_dragdirection +ace_artillerytables_showGunLaying +ace_cargo_canLoad +ace_cargo_hasCargo +ace_cargo_loadmasterTurrets +ace_cargo_noRename +ace_cargo_size +ace_cargo_space +ace_casings_model +ace_cookoff_canHaveFireJet +ace_cookoff_cookoffSelections +ace_dragging_canCarry +ace_dragging_canDrag +ace_dragging_carryPosition +ace_dragging_carryDirection +ace_dragging_dragPosition +ace_dragging_dragDirection ace_fastroping_enabled -ace_fastroping_friesType ace_fastroping_friesAttachmentPoint +ace_fastroping_friesType ace_fastroping_onCut ace_fastroping_onPrepare ace_fastroping_ropeOrigins -ace_gforcecoef -ace_offset -ace_hasReserveParachute -ace_reserveParachute +ace_fcs_distanceInterval +ace_fcs_enabled +ace_fcs_maxDistance +ace_fcs_minDistance +ace_hunterkiller +ace_intelitems_magazine +ace_interaction_canPush +ace_interaction_bodyLength +ace_interaction_bodyWidth +ace_interaction_replaceTerrainObject +ace_logitics_wirecutter_isFence +ace_medical_treatment_patientSeats +ace_minedetector_detectable +ace_parachute_failureDelay +ace_rearm_defaultSupply +ace_refuel_canReceive ace_refuel_flowRate ace_refuel_fuelCapacity ace_refuel_fuelCargo ace_refuel_hooks +ace_repair_hitpointPositions +ace_tagging_canTag +ace_trenches_diggingDuration +ace_trenches_grassCuttingPoints +ace_trenches_noGeoClass +ace_trenches_placementData +ace_trenches_removalDuration +ace_vehicle_damage_canHaveFireRing +ace_vehicle_damage_detonationDuringFireProb +ace_vehicle_damage_engineDetonationProb +ace_vehicle_damage_engineFireProb +ace_vehicle_damage_eraHitpoints +ace_vehicle_damage_hullDetonationProb +ace_vehicle_damage_hullFireProb +ace_vehicle_damage_slatHitpoints +ace_vehicle_damage_turretDetonationProb +ace_vehicle_damage_turretFireProb +ace_vehicles_engineStartDelay + +acex_field_rations_offset +acex_field_rations_waterSupply +acex_sitting_canSit +acex_sitting_interactPosition +acex_sitting_sitDirection +acex_sitting_sitPosition + +ACE_Attachable +ACE_GForceCoef +ace_hasReserveParachute +ace_reserveParachute ``` @@ -140,7 +189,6 @@ ace_isbelt ace_attachable ace_placeable ace_setupobject -ace_delaytime ace_triggers ace_magazines_forcemagazinemuzzlevelocity ``` diff --git a/docs/wiki/development/arma-3-issues.md b/docs/wiki/development/arma-3-issues.md index 506bfde2221..379fb7d5bbc 100644 --- a/docs/wiki/development/arma-3-issues.md +++ b/docs/wiki/development/arma-3-issues.md @@ -14,7 +14,6 @@ Keeping track of Arma 3 issues that need to be fixed. - [bux578: T79355: MineDetector equipable in Launcher slot](https://feedback.bistudio.com/T79355) - [bux578: T79534: Zeus / Curator Add Remote Controlled Event](https://feedback.bistudio.com/T79534) -- [bux578: T79827: Add script commands "addPrimaryWeaponMagazine" and "addSecondaryWeaponMagazine"](https://feedback.bistudio.com/T79827) - [bux578: T80358: Add/Alter script command to add perfectly configured weapons to cargo](https://feedback.bistudio.com/T80358) - [commy2: T79801: Unexpected behavior of += array in configs](https://feedback.bistudio.com/T79801) - [commy2: T81029: setVariable is not always JIP persistent](https://feedback.bistudio.com/T81029) @@ -23,11 +22,12 @@ Keeping track of Arma 3 issues that need to be fixed. - [Jaynus: T82046: Display event handler return values for mouse buttons should be respected](https://feedback.bistudio.com/T82046) - [Heisenberg: T82108: Switching between optic modes of a sniper scope (AMS, DMS, MOS) will result in a blurred vision](https://feedback.bistudio.com/T82108) - [BaerMitUmlaut: T120030: Particles do not render properly since 1.62](https://feedback.bistudio.com/T120030) -- [Killzone_Kid: T79689: magazineTurretAmmo and setMagazineTurretAmmo do not function as expected if there are multiple magazines of the same type](https://feedback.bistudio.com/T79689) -- [nekoarrow: T122981: setMagazineTurretAmmo locality issue](https://feedback.bistudio.com/T122981) **Resolved:** - [Nou: T79119: Memory points rfemur, lfemur, and other leg memory points returned incorrectly with SQF command selectionPosition](https://feedback.bistudio.com/T79119) - [commy2: T81503: isLightOn doesn't recognize destroyed light bulbs for streetlamps](https://feedback.bistudio.com/T81503) - [commy2: T83771: splitString scripting command causes game crash](https://feedback.bistudio.com/T83771) +- [bux578: T79827: Add script commands "addPrimaryWeaponMagazine" and "addSecondaryWeaponMagazine"](https://feedback.bistudio.com/T79827) +- [Killzone_Kid: T79689: magazineTurretAmmo and setMagazineTurretAmmo do not function as expected if there are multiple magazines of the same type](https://feedback.bistudio.com/T79689) +- [nekoarrow: T122981: setMagazineTurretAmmo locality issue?](https://feedback.bistudio.com/T122981) diff --git a/docs/wiki/development/arma-3-scheduler-and-our-practices.md b/docs/wiki/development/arma-3-scheduler-and-our-practices.md index 440f0f95572..d2ffda2a07f 100644 --- a/docs/wiki/development/arma-3-scheduler-and-our-practices.md +++ b/docs/wiki/development/arma-3-scheduler-and-our-practices.md @@ -36,7 +36,7 @@ Code running in the unscheduled environment uses linear execution, that means it ## 2. What is the scheduler and why do I care? -The Arma 3 script scheduler basically gives a fair-share execution to all running scripts, FSMs, and SQS files running on any given client or server at any given time. See the [Biki article](https://community.bistudio.com/wiki/Biki2.0:Performance_Considerations){:target="_blank"} for a in-depth explanation of this. What this basically means though, is that all scripts get a fair share; this also means scheduled execution is drastically affected by other mods that use scheduled execution. For example, if 2 different spawn's are running in a tight loop of `while {true} do {...};`, they will both get exactly 50% of the scheduling time. +The Arma 3 script scheduler basically gives a fair-share execution to all running scripts, FSMs, and SQS files running on any given client or server at any given time. See the [Biki article](https://community.bistudio.com/wiki/Biki2.0:Performance_Considerations){:target="_blank"} for an in-depth explanation of this. What this basically means though, is that all scripts get a fair share; this also means scheduled execution is drastically affected by other mods that use scheduled execution. For example, if 2 different spawn's are running in a tight loop of `while {true} do {...};`, they will both get exactly 50% of the scheduling time. With the way mission makers and mod makers generally use `spawn`/`execVM`, this means you're actually getting drastically less execution time in the scheduled environment than you might think. This leads to visible delay issues all the way up to massive delay on execution. You can easily test and prove this by looping spawns and watching the execution times extend. diff --git a/docs/wiki/development/coding-guidelines.md b/docs/wiki/development/coding-guidelines.md index 786a5d74e89..fe9f0bfdf09 100644 --- a/docs/wiki/development/coding-guidelines.md +++ b/docs/wiki/development/coding-guidelines.md @@ -381,11 +381,19 @@ However the following is allowed: _value = (_array select 0) select 1; ``` -Any conditions in statements shall always be wrapped around brackets. +Any conditions in statements shall always be wrapped around brackets. Both uses of the `!` operator below are allowed. ```sqf -if (!_value) then {}; if (_value) then {}; +if (!_value) then {}; +if !(_value) then {}; +``` + +Use of the `!` operator on the lefthand-side of brackets can be more readable, particularly for more complex conditions or macros: + +```sqf +if !(_value && _otherValue && {_thirdValue call _something}) then {}; +if !(GETEGVAR(addon,globalVariableName,defaultValue)) then {}; ``` ### 5.6 Magic Numbers @@ -632,81 +640,6 @@ player addEventHandler ["Fired", FUNC(handleFired)]; // bad player addEventHandler ["Fired", {call FUNC(handleFired)}]; // good ``` -### 7.4 Hashes - -When a key value pair is required, make use of the hash implementation from ACE3. - -Hashes are a variable type that store key value pairs. They are not implemented natively in SQF, so there are a number of macros and functions for their usage in ACE3. If you are unfamiliar with the idea, they are similar in function to `setVariable`/`getVariable` but do not require an object to use. - -The following example is a simple usage using our macros which will be explained further below. - -```sqf -_hash = HASHCREATE; -HASH_SET(_hash,"key","value"); -if (HASH_HASKEY(_hash,"key")) then { - player sideChat format ["val: %1", HASH_GET(_hash,"key"); // will print out "val: value" -}; -HASH_REM(_hash,"key"); -if (HASH_HASKEY(_hash,"key")) then { - // this will never execute because we removed the hash key/val pair "key" -}; -``` - -A description of the above macros is below. - -| Macro | Use | -| ------|-------| -|`HASHCREATE` | Used to create an empty hash. | -|`HASH_SET(hash,key,val)` | Will set the hash key to that value, a key can be anything, even objects. | -|`HASH_GET(hash,key)` | Will return the value of that key (or nil if it doesn't exist). | -|`HASH_HASKEY(hash,key)` | Will return true/false if that key exists in the hash. | -|`HASH_REM(hash,key)` | Will remove that hash key. | - -#### 7.4.1 Hashlists - -A hashlist is an extension of a hash. It is a list of hashes! The reason for having this special type of storage container rather than using a normal array is that an array of normal hashes that are similar will duplicate a large amount of data in their storage of keys. A hashlist on the other hand uses a common list of keys and an array of unique value containers. The following will demonstrate its usage. - -```sqf -_defaultKeys = ["key1", "key2", "key3"]; -// create a new hashlist using the above keys as default -_hashList = HASHLIST_CREATELIST(_defaultKeys); - -//lets get a blank hash template out of this hashlist -_hash = HASHLIST_CREATEHASH(_hashList); - -//_hash is now a standard hash... -HASH_SET(_hash,"key1","1"); - -//to store it to the list we need to push it to the list -HASHLIST_PUSH(_hashList, _hash); - -//now lets get it out and store it in something else for fun -//it was pushed to an empty list, so it's index is 0 -_anotherHash = HASHLIST_SELECT(_hashList,0); - -// this should print "val: 1" -player sideChat format["val: %1", HASH_GET(_anotherHash,"key1")]; - -//Say we need to add a new key to the hashlist -//that we didn't initialize it with? We can simply -//set a new key using the standard HASH_SET macro -HASH_SET(_anotherHash,"anotherKey","another value"); -``` - -As you can see above working with hashlists are fairly simple, a more in depth explanation of the macros is below. - -| Macro | Use | -| -------|---------| -|`HASHLIST_CREATELIST(keys)` | Creates a new hashlist with the default keys, pass [] for no default keys. | -|`HASHLIST_CREATEHASH(hashlist)` | Returns a blank hash template from a hashlist. | -|`HASHLIST_PUSH(hashList, hash)` | Pushes a new hash onto the end of the list. | -|`HASHLIST_SELECT(hashlist, index)` | Returns the hash at that index in the list. | -|`HASHLIST_SET(hashlist, index, hash)` | Sets a specific index to that hash. | - -##### 7.4.1.1 A note on pass by reference and hashes - -Hashes and hashlists are implemented with SQF arrays, and as such they are passed by reference to other functions. Remember to make copies (using the `+` operator) if you intend for the hash or hashlist to be modified with out the need for changing the original value. - ## 8. Performance Considerations ### 8.1 Adding Elements to Arrays diff --git a/docs/wiki/development/dependencies.md b/docs/wiki/development/dependencies.md index b43371034c5..c6d0f87d63d 100644 --- a/docs/wiki/development/dependencies.md +++ b/docs/wiki/development/dependencies.md @@ -21,16 +21,18 @@ Because `ace_zeus` is being removed you must also remove any components that req ## 2. Dependencies -{% assign pages_by_title = site.pages | sort: "title" %} +{% assign pages_by_title = site.pages | sort_natural: "title" %} {% for page in pages_by_title %} {%- if page.group == 'feature' and page.component -%} - ### {{ page.title }} - - {% capture component %}{{ page.component }}{% endcapture %} - {% include dependencies_list.md component=component %} - - {%- if page.core_component -%} - _Note: This module is required by nearly all other modules. Do NOT remove it!_ - {% endif %} + {%- unless page.version.removed -%} + ### {{ page.title }} + + {% capture component %}{{ page.component }}{% endcapture %} + {% include dependencies_list.md component=component %} + + {%- if page.core_component -%} + _Note: This module is required by nearly all other modules. Do NOT remove it!_ + {% endif %} + {% endunless %} {% endif %} {% endfor %} diff --git a/docs/wiki/development/extension-guidelines.md b/docs/wiki/development/extension-guidelines.md index d7f4fe08a67..36178d86f54 100644 --- a/docs/wiki/development/extension-guidelines.md +++ b/docs/wiki/development/extension-guidelines.md @@ -7,87 +7,59 @@ parent: wiki order: 9 --- -## 1. Basics +## 1. Setup ### 1.1 Requirements -- A compiler (VS/GCC/Clang) - - If starting with Visual Studio, you need to make sure to use the Visual studio command prompt -- cmake 3.0 or later in your path +- [Rust](https://rustup.rs/) +- [cargo-make](https://crates.io/crates/cargo-make) +`cargo install --no-default-features --force cargo-make` -### 1.2 Cross-Platform Guidelines +### 1.2 Recomendations -### 1.3 C++ basic style and naming guide +- [VSCode](https://code.visualstudio.com/) +- [Rust Analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) +- [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb) -### 1.4 ace_common cpp library +### 1.3 Rust Resources ---- +- [Learn Rust](https://www.rust-lang.org/learn) -## 2 Building Extensions on Windows +--- -### 2.1 Compiling +## 2 Development -#### 2.1.1 Windows - Creating a Visual Studio Project -1. Open your compiling command prompt (which has cmake and your compiler) -2. From this directory, you need to use cmake to build the appropriate build files. Change the -G property appropriately. run cmake --help to get a list of the options. +### 2.1 Code Standards -``` -cd extensions\build -cmake .. -G "Visual Studio 15 2017 Win64" -``` +1. [Rust API Guidelines for naming](https://rust-lang.github.io/api-guidelines/naming.html) should be followed +2. All code should be formatted with `cargo fmt` +3. All code should be free from errors and warnings +4. Tests should be written where applicable -A Visual studio project file will now be generated in your build directory. +### 2.2 Local Development -#### 2.1.2 Windows - Visual Studio - Compile only (nmake) -1. Open your compiling command prompt (which has cmake and your compiler) -2. From this directory, you need to use cmake to build the appropriate build files. Change the -G property appropriately. run cmake --help to get a list of the options. - -``` -cd extensions\build -cmake .. -G "NMake Makefiles" -nmake -``` +Running `cargo make debug` will compile the project for x32 and x64 and move the built libraries to `ace.dll` and `ace_x64.dll`. -The extensions will not be built in its appropriate project folder, for example: +The library can be debugged with the following `.vscode/launch.json` file. Replace all sections in `{}` with the appropriate path. +```json +{ + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug", + "program": "{Path to Arma}\\arma3_x64.exe", + "args": ["-mod=\"{Path to CBA};{Path to ACE development folder}\""], + "cwd": "{Path to Arma}" + } + ] +} ``` -extensions\ - build\ - fcs\ace_fcs.dll - somethingElse\ace_somethingElse.dll -``` - -### 2.2 Creating a new Extension - -#### 2.2.1 Arma Config - -ACE3 loads extensions defined in `ACE_Extensions` root config class and supports the following entries: -```cpp -// Platform -windows = 1; // Load on Windows -linux = 1; // Load on Linux +Use the `Run and Debug` tab in VSCode to launch Arma, or Press `F5`. -// Type -client = 1; // Load on Client -server = 1; // Load on Server -``` - -```cpp -class ACE_Extensions { - // Windows Client only extension - class tag_extension { - windows = 1; - client = 1; - }; - - // Any platform Server extension - class tag_extension2 { - windows = 1; - linux = 1; - server = 1; - }; -}; -``` +### 2.3 Release -Combining platform and client/server values is possible to get all combinations currently supported by the game and more. +Release versions can be built using `cargo make release`. diff --git a/docs/wiki/development/setting-up-the-development-environment.md b/docs/wiki/development/setting-up-the-development-environment.md index e2c94430395..822da19fa40 100644 --- a/docs/wiki/development/setting-up-the-development-environment.md +++ b/docs/wiki/development/setting-up-the-development-environment.md @@ -139,7 +139,7 @@ Different `make.py` command line options include: - `increment_patch` - increments _patch_ version number (ignored with `increment_minor` or `increment_major`) - `increment_minor` - increments _minor_ version number and resets _patch_ version number to `0` (ignored with `increment_major`) - `increment_major` - increments _major_ version number and resets _minor_ and _patch_ version numbers to `0` -- `force` - force rebuild all PBOs, even those already present in the `release` directory (combined with `compile` it will also rebuild all extensions) +- `force` - force rebuild all PBOs, even those already present in the `release` directory - `checkexternal` - check external references (incompatible only with ` ` and `force `) - `release` - create release packages/archives - ` ` - build only specified component(s) (incompatible with `release`) diff --git a/docs/wiki/feature/artillerytables.md b/docs/wiki/feature/artillerytables.md new file mode 100644 index 00000000000..4bdfb5c5d53 --- /dev/null +++ b/docs/wiki/feature/artillerytables.md @@ -0,0 +1,30 @@ +--- +layout: wiki +title: Artillery Tables +component: artillerytables +description: Adds universal rangetables for artillery. +group: feature +category: equipment +parent: wiki +mod: ace +version: + major: 3 + minor: 13 + patch: 0 +--- + +## 1. Overview + +### 1.1 Features +- Adds a rangetable to accurately take out your target without the artillery computer. +- Shows accurate elevation and azimuth. +- Optionally adds wind deflection and air friction for shells. +- Optionally disables artillery computers. + +## 2. Usage + +### 2.1 Opening a rangetable +- Enter a piece of artillery. +- Use Self Interact Ctrl+⊞ Win (ACE3 default). +- Select `Equipment`. +- Select the rangetable of the piece of artillery you are in. diff --git a/docs/wiki/feature/cargo.md b/docs/wiki/feature/cargo.md new file mode 100644 index 00000000000..304ba709445 --- /dev/null +++ b/docs/wiki/feature/cargo.md @@ -0,0 +1,41 @@ +--- +layout: wiki +title: Cargo +component: cargo +description: Adds the ability to transport cargo using vehicles. +group: feature +category: interaction +parent: wiki +mod: ace +version: + major: 3 + minor: 3 + patch: 0 +--- + +## 1. Overview +Adds the ability to load and unload cargo from vehicles. Unloading can happen via two methods: Regular unloading and deploying, where you can preplace the item before it's unloaded. + +## 2. Usage + +### 2.1 Loading an object +- Interact with the object to be loaded ⊞ win. +- Select the `Load` option. +- Select which vehicle you want to load the object in. +- Wait for the progress bar to finish. To cancel loading, press Escape. + +### 2.2 Checking a vehicle's cargo +- Interact with the vehicle whose cargo is to b e checked ⊞ win. +- Select the `Cargo` option. + +### 2.3 Unloading an object from a vehicle +- Open the vehicle's cargo menu (see "Checking a vehicle's cargo") +- Press `Unload`. +- Wait for the progress bar to finish. To cancel unloading, press Escape. + +### 2.4 Deploying an object from a vehicle +- Open the vehicle's cargo menu (see "Checking a vehicle's cargo") +- Press `Deploy`. +- Use the mouse to fine tune the placement of the object. +- When ready to place, press left click to start deploying the object. +- Wait for the progress bar to finish. To cancel deploying, press Escape. diff --git a/docs/wiki/feature/casings.md b/docs/wiki/feature/casings.md new file mode 100644 index 00000000000..8bcf24a6969 --- /dev/null +++ b/docs/wiki/feature/casings.md @@ -0,0 +1,17 @@ +--- +layout: wiki +title: Casings +component: casings +description: Adds infantry bullet casings on the ground when weapons are fired. +group: feature +category: realism +parent: wiki +mod: ace +version: + major: 3 + minor: 15 + patch: 0 +--- + +## 1. Overview +Spits out casings from infantry weapons when fired. diff --git a/docs/wiki/feature/cookoff.md b/docs/wiki/feature/cookoff.md new file mode 100644 index 00000000000..19a32893882 --- /dev/null +++ b/docs/wiki/feature/cookoff.md @@ -0,0 +1,22 @@ +--- +layout: wiki +title: Cook-off +component: cookoff +description: Adds cook-off effects to vehicles and ammunition boxes that have had their ammunition detonated or that have been destroyed. +group: feature +category: realism +parent: wiki +mod: ace +version: + major: 3 + minor: 7 + patch: 0 +--- + +## 1. Overview + +### 1.1 Features +- Adds engine fires when a vehicle's engine is damaged heavily. +- Optionally adds fire if a vehicle suffers ammunition detonations (requires `Vehicle Damage` to be enabled). +- Optionally adds ammunition detonation if a vehicle is destroyed. +- Optionally adds ammunition detonation if an ammunition box is destroyed or hit with explosive, incendiary or tracer ammunition. diff --git a/docs/wiki/feature/dogtags.md b/docs/wiki/feature/dogtags.md new file mode 100644 index 00000000000..9f1d27e371d --- /dev/null +++ b/docs/wiki/feature/dogtags.md @@ -0,0 +1,40 @@ +--- +layout: wiki +title: Dog Tags +component: dogtags +description: Adds dog tags to units. +group: feature +category: realism +parent: wiki +mod: ace +version: + major: 3 + minor: 7 + patch: 0 +--- + +## 1. Overview +Provides dog tags to units, which include name, social security number and blood type as information. + +## 2. Usage + +### 2.1 Checking a unit's dog tags +- Interact with the unconscious or dead unit whose dog tags are to be checked ⊞ win. +- Select the `Dog Tag` option. +- Select the `Check` option. + +### 2.2 Taking a unit's dog tags +- Interact with the unconscious or dead unit whose dog tags are to be checked ⊞ win. +- Select the `Dog Tag` option. +- Select the `Take` option. +- If the one of the two dog tags has already been taken, it will inform you and not give you the 2nd dog tag + +### 2.3 Checking what dog tags you have via self-interaction +- Use Self Interact Ctrl+⊞ Win (ACE3 default). +- Select the `Equipment` option. +- Select the `Check Dog Tag` option. + +### 2.4 Checking what dog tags you have via context menu +- Open your inventory and find the dog tag you want to inspect. +- Double click the item. +- Click `Check Dog Tag`. diff --git a/docs/wiki/feature/dragging.md b/docs/wiki/feature/dragging.md index 0d42240a238..aa462d2e64d 100644 --- a/docs/wiki/feature/dragging.md +++ b/docs/wiki/feature/dragging.md @@ -20,7 +20,9 @@ This adds the option to drag or carry units or objects. ## 2. Usage ### 2.1 Dragging / Carrying units and objects -- You can only drag or carry an unconscious unit. +- You can drag or carry dead or unconscious units. These units can't be in a ragdoll state. +- You can drag or carry units whose legs are broken. +- You can't carry if you have broken legs. - Interact with the unit or object ⊞ Win (ACE3 default key bind `Interact Key`). - Select `Drag` or `Carry`. - To release, use the mouse wheel and select `Release` or use Self Interaction Ctrl+⊞ Win and select `Release`. diff --git a/docs/wiki/feature/field-rations.md b/docs/wiki/feature/field-rations.md new file mode 100644 index 00000000000..63daad99631 --- /dev/null +++ b/docs/wiki/feature/field-rations.md @@ -0,0 +1,30 @@ +--- +layout: wiki +title: Field Rations +component: field_rations +description: Adds a thirst and hunger system, along with food to replenish those. +group: feature +category: realism +parent: wiki +mod: acex +version: + major: 3 + minor: 4 + patch: 0 +--- + +## 1. Overview +Simulates hunger and thirst which need to be replenished. This system is affected by other modules, such as weather and medical, and can in turn affect fatigue. + +## 2. Usage + +### 2.1 Satiate hunger/Quench thirst via self-interaction +- Pick up a drink. +- Use Self Interact Ctrl+⊞ Win (ACE3 default). +- Select the `Survival` option. +- Choose an item to consume. + +### 2.2 Satiate hunger/Quench thirst via context menu +- Open your inventory and find the item you want to consume. +- Double click the item. +- Click `Eat/Drink`. diff --git a/docs/wiki/feature/fieldmanual.md b/docs/wiki/feature/fieldmanual.md new file mode 100644 index 00000000000..bf6af86fe24 --- /dev/null +++ b/docs/wiki/feature/fieldmanual.md @@ -0,0 +1,23 @@ +--- +layout: wiki +title: Field Manual +component: fieldmanual +description: Adds ACE3 content to the field manual. +group: feature +category: general +parent: wiki +mod: ace +version: + major: 3 + minor: 16 + patch: 0 +--- + +## 1. Overview +Provides information on items and mechanics that ACE3 adds. + +## 2. Usage + +### 2.1 Opening the field manual +- Press Escape. +- Press `Field Manual`. diff --git a/docs/wiki/feature/gestures.md b/docs/wiki/feature/gestures.md new file mode 100644 index 00000000000..30be084be38 --- /dev/null +++ b/docs/wiki/feature/gestures.md @@ -0,0 +1,32 @@ +--- +layout: wiki +title: Gestures +component: gestures +description: Adds gestures that can be used for communication. +group: feature +category: interaction +parent: wiki +mod: ace +version: + major: 3 + minor: 4 + patch: 0 +--- + +## 1. Overview +Adds the ability to use 14 gestures for communication. + +## 2. Usage + +### 2.1 Using gestures via self-interaction + +- Use Self Interact Ctrl+⊞ Win (ACE3 default). +- Select the `Gestures` option. + +### 2.2 Rebinding keybinds for gestures + +- Press Escape. +- Select `Options`. +- Select `Controls`. +- Select `Configure Addons`. +- Select `ACE Gestures`. diff --git a/docs/wiki/feature/grenades.md b/docs/wiki/feature/grenades.md index 679b309b1ec..2b60c08d4ec 100644 --- a/docs/wiki/feature/grenades.md +++ b/docs/wiki/feature/grenades.md @@ -23,6 +23,8 @@ version: ### 1.1 Throw modes Provides different modes for throwing grenades (high throw, precision throw and drop mode). +A grenade is only rollable if the fuse time (`explosionTime`) is >= 1 second and the player isn't in a vehicle. + ### 1.2 Hand flares Adds throwable hand flares in the colors white, red, green and yellow. Additionally buffs existing flares by making them brighter and last longer. diff --git a/docs/wiki/feature/gunbag.md b/docs/wiki/feature/gunbag.md new file mode 100644 index 00000000000..35e2dd5e59a --- /dev/null +++ b/docs/wiki/feature/gunbag.md @@ -0,0 +1,32 @@ +--- +layout: wiki +title: Gun Bag +component: gunbag +description: Adds a gun bag that can be used to store a weapon. +group: feature +category: equipment +parent: wiki +mod: ace +version: + major: 3 + minor: 6 + patch: 0 +--- + +## 1. Overview +Adds easy handling and storage of an additional weapon in a backpack. + +## 2. Usage + +### 2.1 Interacting with your gun bag via self-interaction +- Use Self Interact Ctrl+⊞ Win (ACE3 default). +- Select the `Equipment` option. +- Select the `Gunbag` option. + +### 2.2 Interacting with your gun bag via the ACE arsenal +- Open an ACE arsenal. +- Get yourself a gun bag if you don't have one already. +- Select the primary weapon or backpack tab to interact with weapon. + +### 2.3 Interacting with another unit's gun bag +- Interact with the unit ⊞ win. diff --git a/docs/wiki/feature/hitreactions.md b/docs/wiki/feature/hitreactions.md index 7d12c1cb12d..a84d1c0b78b 100644 --- a/docs/wiki/feature/hitreactions.md +++ b/docs/wiki/feature/hitreactions.md @@ -18,3 +18,6 @@ version: ### 1.1 Falling under fire If a unit is shot while running it falls to the ground in a prone position, the area where the shot lands does not matters. Note that the shot needs to inflict a certain amount of damage to make the unit fall, a small cut won't make the unit stumble. + +### 1.2 Weapon dropping +If a unit's arm is shot it will cause the gun to be dropped based on the chance set. The default is 0. diff --git a/docs/wiki/feature/index.md b/docs/wiki/feature/index.md index 41fd0fdeea6..1c7039dfd29 100644 --- a/docs/wiki/feature/index.md +++ b/docs/wiki/feature/index.md @@ -19,7 +19,7 @@ redirect_from: "/wiki/featurex"

General

+### 1.3 Adding predefined cargo via config + +```cpp +class CfgVehicles { + class yourVehicleClass { + ace_cargo_space = 4; // Add if necessary + ace_cargo_hasCargo = 1; // Add if necessary + class ace_cargo { + class cargo { + class ACE_medicalSupplyCrate { // Doesn't have to have the same name as the item you're adding + type = "ACE_medicalSupplyCrate"; + amount = 1; + }; + }; + }; + }; +}; +``` ## 2. Events @@ -96,7 +114,17 @@ Note that this function can be used to make objects loadable/unloadable (set to * [object, 3] call ace_cargo_fnc_setSize ``` -### 4.3 Adjusting cargo space of a vehicle +### 4.3 Setting Custom Load/Unload Time + +```sqf +object setVariable ["ace_cargo_delay",