mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merge branch 'master' into markinglaser
This commit is contained in:
commit
4f726d6bc0
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
@ -36,7 +36,7 @@ We welcome anyone to contribute to this repository. Issues that we are actively
|
||||
|
||||
When contributing to this repository, please first discuss the change you wish to make via issue or [Discord](https://acemod.org/discord) with the [ACE3 project maintainers](https://ace3.acemod.org/team.html) before making a change. This may not be necessary if you are contributing for something which has an existing issue in our repository already.
|
||||
|
||||
1. Please make a pull request (PR) as early as possible. This lets use help you in the proces of developing it. When opening a work in progress pull request, mark your PR with a `WIP:` prefix.
|
||||
1. Please make a pull request (PR) as early as possible. This lets use help you in the proces of developing it. When opening a work in progress pull request, use GitHub's draft feature. This will mark the PR as a work in progress and will prevent it from being merged until you mark it as ready for review.
|
||||
2. Describe what this pull request will do and how it solves this in the description of your PR. A clear intent and description of the way the issue is resolved will help us to review the PR more efficiently.
|
||||
3. Please follow our [Development Guidelines](https://ace3.acemod.org/wiki/development/).
|
||||
|
||||
|
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -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]
|
||||
<!-- Make sure to reproduce the issue with only CBA and ACE3 on a newly created mission! -->
|
||||
|
||||
**Description:**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Steps to reproduce:**
|
||||
_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 ..._
|
||||
|
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -4,6 +4,6 @@
|
||||
|
||||
### IMPORTANT
|
||||
|
||||
- [ ] If the contribution affects [the documentation](https://github.com/acemod/ACE3/tree/master/docs), please include your changes in this pull request so the documentation will appear on the [website](https://ace3.acemod.org/).
|
||||
- [ ] [Development Guidelines](https://ace3.acemod.org/wiki/development/) are read, understood and applied.
|
||||
- [ ] Title of this PR uses our standard template `Component - Add|Fix|Improve|Change|Make|Remove {changes}`.
|
||||
- If the contribution affects [the documentation](https://github.com/acemod/ACE3/tree/master/docs), please include your changes in this pull request so the documentation will appear on the [website](https://ace3.acemod.org/).
|
||||
- [Development Guidelines](https://ace3.acemod.org/wiki/development/) are read, understood and applied.
|
||||
- Title of this PR uses our standard template `Component - Add|Fix|Improve|Change|Make|Remove {changes}`.
|
||||
|
19
.github/release-drafter.yml
vendored
19
.github/release-drafter.yml
vendored
@ -5,14 +5,16 @@ branches:
|
||||
name-template: 'Version $NEXT_PATCH_VERSION'
|
||||
tag-template: 'v$NEXT_PATCH_VERSION'
|
||||
|
||||
sort-by: title # sort alphabetically
|
||||
sort-direction: ascending
|
||||
|
||||
categories:
|
||||
- title: '**ADDED:**'
|
||||
labels:
|
||||
- 'kind/feature request'
|
||||
- 'kind/added feature'
|
||||
- 'kind/feature'
|
||||
- title: '**FIXED:**'
|
||||
labels:
|
||||
- 'kind/bug fix'
|
||||
- 'kind/bug-fix'
|
||||
- title: '**IMPROVED:**'
|
||||
labels:
|
||||
- 'kind/enhancement'
|
||||
@ -20,13 +22,16 @@ categories:
|
||||
- title: '**CHANGED:**'
|
||||
labels:
|
||||
- 'kind/cleanup'
|
||||
- 'area/compatibility'
|
||||
- 'kind/change'
|
||||
- title: '**SETTINGS:**'
|
||||
labels:
|
||||
- 'kind/setting'
|
||||
- title: '**TRANSLATIONS:**'
|
||||
labels:
|
||||
- 'area/translations'
|
||||
- 'kind/translation'
|
||||
|
||||
exclude-labels:
|
||||
- 'ignore changelog'
|
||||
- 'ignore-changelog'
|
||||
- 'dependencies'
|
||||
|
||||
change-template: '- $TITLE (#$NUMBER)'
|
||||
@ -39,5 +44,5 @@ template: |
|
||||
|
||||
replacers:
|
||||
# Category titles
|
||||
- search: '/\#\# (\*\*(ADDED|FIXED|IMPROVED|CHANGED|TRANSLATIONS):\*\*)/g'
|
||||
- search: '/\#\# (\*\*(ADDED|FIXED|IMPROVED|CHANGED|SETTINGS|TRANSLATIONS):\*\*)/g'
|
||||
replace: '$1'
|
||||
|
10
.github/workflows/arma.yml
vendored
10
.github/workflows/arma.yml
vendored
@ -11,7 +11,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the source code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Validate SQF
|
||||
run: python3 tools/sqf_validator.py
|
||||
- name: Validate Config
|
||||
@ -22,6 +22,8 @@ jobs:
|
||||
run: python3 tools/check_strings.py
|
||||
- name: Check for BOM
|
||||
uses: arma-actions/bom-check@master
|
||||
with:
|
||||
path: 'addons'
|
||||
- name: Validate function headers
|
||||
run: python3 docs/tools/document_functions.py --debug
|
||||
|
||||
@ -29,7 +31,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the source code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Lint (sqflint)
|
||||
uses: arma-actions/sqflint@master
|
||||
continue-on-error: true # No failure due to many false-positives
|
||||
@ -38,7 +40,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the source code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup HEMTT
|
||||
uses: arma-actions/hemtt@v1
|
||||
- name: Run HEMTT build
|
||||
@ -46,7 +48,7 @@ jobs:
|
||||
- name: Rename build folder
|
||||
run: mv .hemttout/build .hemttout/@ace
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ace3-${{ github.sha }}-nobin
|
||||
path: .hemttout/@*
|
||||
|
8
.github/workflows/documentation.yml
vendored
8
.github/workflows/documentation.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the source code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
pip3 install wheel
|
||||
@ -33,7 +33,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Extract Dependencies
|
||||
run: python3 tools/extract_dependencies.py --markdown
|
||||
@ -47,7 +47,7 @@ jobs:
|
||||
destination: docs/_site/
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: jekyll-site
|
||||
path: docs/_site/
|
||||
@ -63,7 +63,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Download Artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: jekyll-site
|
||||
path: _site/
|
||||
|
4
.github/workflows/extensions.yml
vendored
4
.github/workflows/extensions.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout the source code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
shell: cmd
|
||||
run: |
|
||||
@ -23,7 +23,7 @@ jobs:
|
||||
cd build
|
||||
cmake .. && cmake --build .
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ace3_extensions-${{ matrix.os }}-debug
|
||||
path: extensions/build
|
||||
|
44
.github/workflows/hemtt.yml
vendored
Normal file
44
.github/workflows/hemtt.yml
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
name: HEMTT
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request_target:
|
||||
|
||||
jobs:
|
||||
windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Install Arma 3 Tools
|
||||
uses: arma-actions/arma3-tools@master
|
||||
with:
|
||||
toolsUrl: ${{ secrets.ARMA3_TOOLS_URL }}
|
||||
- name: Checkout the source code
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup HEMTT
|
||||
uses: arma-actions/hemtt@v1
|
||||
- name: Checkout pull request
|
||||
uses: actions/checkout@v4
|
||||
if: ${{ github.event_name == 'pull_request_target' }}
|
||||
with:
|
||||
path: pullrequest
|
||||
ref: 'refs/pull/${{ github.event.number }}/merge'
|
||||
- name: Replace addons with pull request addons
|
||||
if: ${{ github.event_name == 'pull_request_target' }}
|
||||
run: |
|
||||
rm -r addons\
|
||||
rm -r optionals\
|
||||
rm -r include\
|
||||
xcopy /e /h /q pullrequest\addons addons\
|
||||
xcopy /e /h /q pullrequest\optionals optionals\
|
||||
xcopy /e /h /q pullrequest\include include\
|
||||
- name: Run HEMTT build
|
||||
run: hemtt build
|
||||
- name: Rename build folder
|
||||
run: mv .hemttout/build .hemttout/@ace
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ace3-${{ github.sha }}
|
||||
path: .hemttout/@*
|
15
.github/workflows/pboproject.yml
vendored
15
.github/workflows/pboproject.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
||||
Invoke-WebRequest "$env:RHSUSF_URL" -OutFile rhsusf.zip
|
||||
$files = @("arma3.zip", "rhsafrf.zip", "rhsgref.zip", "rhssaf.zip", "rhsusf.zip")
|
||||
ForEach ($file in $files) {
|
||||
Extract-7Zip -Path $file -DestinationPath .
|
||||
Expand-7ZipArchive -Path $file -DestinationPath .
|
||||
Remove-Item $file
|
||||
}
|
||||
env:
|
||||
@ -35,18 +35,18 @@ jobs:
|
||||
RHSSAF_URL: ${{ secrets.RHSSAF_URL }}
|
||||
RHSUSF_URL: ${{ secrets.RHSUSF_URL }}
|
||||
- name: Checkout CBA A3
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: x\cba
|
||||
ref: master
|
||||
repository: CBATeam/CBA_A3.git
|
||||
- name: Checkout ACE3
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: z\ace
|
||||
persist-credentials: false
|
||||
- name: Checkout pull request
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
if: ${{ github.event_name == 'pull_request_target' }}
|
||||
with:
|
||||
path: pullrequest
|
||||
@ -64,21 +64,22 @@ jobs:
|
||||
run: |
|
||||
subst P: .
|
||||
pboproject -P
|
||||
xcopy /e /h /q z\ace\tools\pDummies\A3\ui_f_enoch a3\ui_f_enoch\
|
||||
xcopy /e /h /q z\ace\tools\pDummies\gm gm\
|
||||
xcopy /e /h /q z\ace\tools\pDummies\vn vn\
|
||||
xcopy /e /h /q z\ace\tools\pDummies\WW2 WW2\
|
||||
xcopy /e /h /q z\ace\tools\pDummies\CUP CUP\
|
||||
- name: Build
|
||||
run: py P:\z\ace\tools\make.py ci
|
||||
env:
|
||||
PYTHONUNBUFFERED: 1
|
||||
- name: Archive logs
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: logs
|
||||
path: temp/*.log
|
||||
- name: Archive @ace
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '@ace3-${{ github.sha }}'
|
||||
path: z\ace\release\@ace
|
||||
|
2
.github/workflows/release-drafter.yml
vendored
2
.github/workflows/release-drafter.yml
vendored
@ -11,6 +11,6 @@ jobs:
|
||||
steps:
|
||||
- name: Release Drafter
|
||||
if: github.repository == 'acemod/ACE3'
|
||||
uses: release-drafter/release-drafter@v5
|
||||
uses: release-drafter/release-drafter@v6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -20,3 +20,4 @@ CHANGELOG.md
|
||||
sqfvm.exe
|
||||
ArmaScriptCompiler.exe
|
||||
*.sqfc
|
||||
!extras/**/*.zip
|
||||
|
4
.hemtt/hooks/post_build/01_move_readmes.rhai
Normal file
4
.hemtt/hooks/post_build/01_move_readmes.rhai
Normal file
@ -0,0 +1,4 @@
|
||||
let docs_readmes = ["README.zh-TW.md", "README_DE.md", "README_PL.md"];
|
||||
for readme in docs_readmes {
|
||||
HEMTT_VFS.join("docs").join(readme).move(HEMTT_VFS.join(readme));
|
||||
}
|
9
.hemtt/hooks/post_release/01_rename_zip.rhai
Normal file
9
.hemtt/hooks/post_release/01_rename_zip.rhai
Normal file
@ -0,0 +1,9 @@
|
||||
let releases = HEMTT_RFS.join("releases");
|
||||
|
||||
let src = releases.join(HEMTT.project().prefix() + "-" + HEMTT.project().version().to_string() + ".zip");
|
||||
let dst = releases.join(HEMTT.project().name().to_lower() + "_" + HEMTT.project().version().to_string_short() + ".zip");
|
||||
|
||||
print("Moving zip to " + dst);
|
||||
if !src.move(dst) {
|
||||
fatal("Failed to move " + src + " to " + dst);
|
||||
}
|
12
.hemtt/hooks/pre_build/01_set_version.rhai
Normal file
12
.hemtt/hooks/pre_build/01_set_version.rhai
Normal file
@ -0,0 +1,12 @@
|
||||
let modcpp = HEMTT_VFS.join("mod.cpp").open_file().read();
|
||||
modcpp.replace("0.0.0", HEMTT.project().version().to_string_short());
|
||||
HEMTT_VFS.join("mod.cpp").create_file().write(modcpp);
|
||||
print("mod.cpp version set");
|
||||
|
||||
let docs_readmes = ["README.zh-TW.md", "README_DE.md", "README_PL.md"];
|
||||
for readme in docs_readmes {
|
||||
let readmemd = HEMTT_VFS.join("docs").join(readme).open_file().read();
|
||||
readmemd.replace("0.0.0", HEMTT.project().version().to_string_short());
|
||||
HEMTT_VFS.join("docs").join(readme).create_file().write(readmemd);
|
||||
print(readme + " version set");
|
||||
}
|
@ -8,8 +8,7 @@ include = [
|
||||
"*.dll",
|
||||
"*.so",
|
||||
"mod.cpp",
|
||||
"README.md",
|
||||
"docs/README_*.md",
|
||||
"README*.md", # Translated READMEs get moved to root in a hook (virtual file system)
|
||||
"AUTHORS.txt",
|
||||
"LICENSE",
|
||||
"logo_ace3_ca.paa",
|
||||
@ -19,21 +18,50 @@ include = [
|
||||
[version]
|
||||
git_hash = 0
|
||||
|
||||
# Unused in HEMTT v1.11 or higher, kept for backwards compatibility
|
||||
[asc]
|
||||
enabled = true
|
||||
exclude = [
|
||||
"/initsettings.sqf",
|
||||
"/initkeybinds.sqf",
|
||||
"/xeh_prep.sqf",
|
||||
"dev",
|
||||
"medical_ai/statemachine.sqf",
|
||||
".inc.sqf",
|
||||
"/dev/",
|
||||
"common/functions/fnc_dummy.sqf",
|
||||
"zeus/functions/fnc_zeusAttributes.sqf",
|
||||
]
|
||||
|
||||
[hemtt.config]
|
||||
preset = "Hemtt"
|
||||
[hemtt.launch.default]
|
||||
workshop = [
|
||||
"450814997", # CBA_A3
|
||||
]
|
||||
|
||||
[hemtt.launch]
|
||||
[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
|
||||
]
|
||||
|
23
AUTHORS.txt
23
AUTHORS.txt
@ -6,24 +6,31 @@
|
||||
# request, preferably including an email address.
|
||||
|
||||
# CORE TEAM
|
||||
BaerMitUmlaut
|
||||
Brett Mayson
|
||||
bux578 <github@jonathandavid.de>
|
||||
commy2
|
||||
Dahlgren
|
||||
Dani (TCVM) <baileydanyluk@gmail.com>
|
||||
Drofseh <drofseh.arma@gmail.com>
|
||||
esteldunedain <nicolas.d.badano@gmail.com>
|
||||
Felix Wiegand <koffeinflummi@gmail.com>
|
||||
Garth "L-H" de Wet <garthofhearts@gmail.com>
|
||||
Giallustio
|
||||
Glowbal
|
||||
Grim
|
||||
Janus
|
||||
johnb43
|
||||
jokoho482 <jokoho482@gmail.com>
|
||||
Jonpas <jonpas33@gmail.com>
|
||||
Kieran
|
||||
kymckay
|
||||
mharis001 <mhariszakar@gmail.com>
|
||||
MikeMF
|
||||
MiszczuZPolski
|
||||
NouberNou
|
||||
PabstMirror <pabstmirror@gmail.com>
|
||||
Ruthberg <ulteq@web.de>
|
||||
SilentSpike <SilentSpike100@gmail.com>
|
||||
tcvm <baileydanyluk@gmail.com>
|
||||
tpM
|
||||
veteran29
|
||||
ViperMaul
|
||||
@ -42,6 +49,7 @@ aeroson
|
||||
Aggr094 <bastards4glory@gmail.com>
|
||||
alef <alefor@gmail.com>
|
||||
Aleksey EpMAK Yermakov <epmak777@gmail.com>
|
||||
AleM
|
||||
Alganthe <alganthe@live.fr>
|
||||
Andrea "AtixNeon" Verano <veranoandrea88@gmail.com>
|
||||
Anthariel <Contact@storm-simulation.com>
|
||||
@ -50,14 +58,12 @@ Arcanum417 <lubos.len@gmail.com>
|
||||
Arkhir <wonsz666@gmail.com >
|
||||
ARV187 aka Spark23
|
||||
Asgar Serran <piechottaf@web.de>
|
||||
BaerMitUmlaut
|
||||
Bamse <bamsis@gmail.com>
|
||||
Barman75
|
||||
Bla1337
|
||||
BlackPixxel <blackpixxel96@gmail.com>
|
||||
BlackQwar
|
||||
Brakoviejo
|
||||
Brett Mayson
|
||||
Brisse <brisse@outlook.com>
|
||||
Brostrom.A | Evul <andreas.brostrom.ce@gmail.com>
|
||||
BullHorn <bullhorn7@gmail.com>
|
||||
@ -77,7 +83,6 @@ diwako
|
||||
dixon13 <dixonbegay@gmail.com>
|
||||
Drift_91
|
||||
Drill <drill87@gmail.com>
|
||||
Drofseh <drofseh@gmail.com>
|
||||
Dslyecxi <dslyecxi@gmail.com>
|
||||
Dudakov aka [OMCB]Kaban <dudakov.s@gmail.com>
|
||||
Eclipser <jms@modeemi.fi>
|
||||
@ -111,7 +116,9 @@ havena <silveredenis@gmail.com>
|
||||
Hawkins
|
||||
Head <brobergsebastian@gmail.com>
|
||||
Hybrid V
|
||||
Hypoxic <martini_a@outlook.com>
|
||||
JasperRab <jasper@jasperrab.eu>
|
||||
JDT
|
||||
john681611 <john681611@hotmail.com>
|
||||
JoramD
|
||||
Karneck <dschultz26@hotmail.com>
|
||||
@ -119,6 +126,8 @@ Kavinsky <nmunozfernandez@gmail.com>
|
||||
Keithen <Keithen.Neu@gmail.com>
|
||||
Kllrt <kllrtik@gmail.com>
|
||||
KokaKolaA3
|
||||
Krzyciu
|
||||
LAxemann
|
||||
legman <juicemelon@msn.com>
|
||||
Legolasindar "Viper" <legolasindar@gmail.com>
|
||||
licht-im-Norden87 <lichtimnorden87@gmail.com>
|
||||
@ -173,7 +182,6 @@ Toaster <jonathan.pereira@gmail.com>
|
||||
Tonic
|
||||
Tourorist <tourorist@gmail.com>
|
||||
Tuupertunut
|
||||
TyroneMF <TyroneMF@hotmail.com>
|
||||
Valentin Torikian <valentin.torikian@gmail.com>
|
||||
voiper
|
||||
VyMajoris(W-Cephei)<vycanismajoriscsa@gmail.com>
|
||||
@ -183,4 +191,5 @@ wizpig64
|
||||
YetheSamartaka
|
||||
xrufix
|
||||
Zakant <Zakant@gmx.de>
|
||||
zGuba
|
||||
zGuba
|
||||
Zman6258
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 133 KiB |
12
README.md
12
README.md
@ -1,10 +1,11 @@
|
||||
<p align="center">
|
||||
<img src="https://github.com/acemod/ACE3/raw/master/extras/assets/logo/black/ACE3-Logo.jpg" width="480">
|
||||
<img src="https://github.com/acemod/ACE3/raw/master/extras/assets/logo/black/ACE3-Logo.png#gh-light-mode-only" width="480">
|
||||
<img src="https://github.com/acemod/ACE3/raw/master/extras/assets/logo/white/ACE3-Logo.png#gh-dark-mode-only" width="480">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/acemod/ACE3/releases/latest">
|
||||
<img src="https://img.shields.io/badge/Version-3.15.2-blue.svg?style=flat-square" alt="ACE3 Version">
|
||||
<img src="https://img.shields.io/github/release/acemod/ACE3.svg?style=flat-square&label=Version" alt="ACE3 Version">
|
||||
</a>
|
||||
<a href="https://github.com/acemod/ACE3/issues">
|
||||
<img src="https://img.shields.io/github/issues-raw/acemod/ACE3.svg?style=flat-square&label=Issues" alt="ACE3 Issues">
|
||||
@ -21,9 +22,6 @@
|
||||
<a href="https://acemod.org/discord">
|
||||
<img src="https://img.shields.io/badge/Discord-Join-darkviolet.svg?style=flat-square" alt="ACE3 Discord">
|
||||
</a>
|
||||
<a href="https://circleci.com/gh/acemod/ACE3">
|
||||
<img src="https://circleci.com/gh/acemod/ACE3.svg?style=svg" alt="ACE3 Build Status">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@ -97,9 +95,7 @@ Please, use our [Issue Tracker](https://github.com/acemod/ACE3/issues) to report
|
||||
|
||||
### Testing & building
|
||||
|
||||
To help us test the latest development changes, download our master branch ([directly](https://github.com/acemod/ACE3/archive/master.zip), or [with git](https://help.github.com/articles/fetching-a-remote/)), then assemble a test build:
|
||||
|
||||
- [Setting up the development environment](https://ace3.acemod.org/wiki/development/setting-up-the-development-environment.html) – step-by-step instructions on how to properly setup and build a version of ACE3 for testing purposes.
|
||||
To help us test the latest development changes, download the [artifact](https://github.com/acemod/ACE3/actions/workflows/arma.yml) of the branch you'd like to test or subscribe to "Anrop ACE3 Master" on the workshop to test `master` branch. Alternatively [build your own version](https://ace3.acemod.org/wiki/development/setting-up-the-development-environment.html).
|
||||
|
||||
### Get in touch
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
#include "initKeybinds.sqf"
|
||||
|
||||
GVAR(currentbulletID) = -1;
|
||||
|
||||
GVAR(Protractor) = false;
|
||||
@ -11,6 +9,8 @@ GVAR(currentGrid) = 0;
|
||||
|
||||
if (!hasInterface) exitWith {};
|
||||
|
||||
#include "initKeybinds.inc.sqf"
|
||||
|
||||
["CBA_settingsInitialized", {
|
||||
//If not enabled, dont't add PFEH
|
||||
if (!GVAR(enabled)) exitWith {};
|
||||
@ -19,11 +19,11 @@ if (!hasInterface) exitWith {};
|
||||
[] call FUNC(initializeTerrainExtension);
|
||||
|
||||
// Register fire event handler
|
||||
["ace_firedPlayer", DFUNC(handleFired)] call CBA_fnc_addEventHandler;
|
||||
["ace_firedPlayerNonLocal", DFUNC(handleFired)] call CBA_fnc_addEventHandler;
|
||||
["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler;
|
||||
["ace_firedPlayerNonLocal", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler;
|
||||
|
||||
// Register Perframe Handler
|
||||
[FUNC(handleFirePFH), GVAR(simulationInterval)] call CBA_fnc_addPerFrameHandler;
|
||||
[LINKFUNC(handleFirePFH), GVAR(simulationInterval)] call CBA_fnc_addPerFrameHandler;
|
||||
|
||||
//Add warnings for missing compat PBOs (only if AB is on)
|
||||
{
|
||||
|
@ -6,6 +6,6 @@ PREP_RECOMPILE_START;
|
||||
#include "XEH_PREP.hpp"
|
||||
PREP_RECOMPILE_END;
|
||||
|
||||
#include "initSettings.sqf"
|
||||
#include "initSettings.inc.sqf"
|
||||
|
||||
ADDON = true;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Ruthberg
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Ruthberg
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Ruthberg, MikeMatrix, joko // Jonas
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Ruthberg
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Ruthberg
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: esteldunedain
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Ruthberg
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Glowbal, Ruthberg, joko // Jonas
|
||||
* Handle the PFH for Bullets
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Glowbal, Ruthberg
|
||||
*
|
||||
@ -17,9 +17,9 @@
|
||||
*/
|
||||
|
||||
//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"];
|
||||
TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret);
|
||||
TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret);
|
||||
|
||||
if (!(_ammo isKindOf "BulletBase")) exitWith {};
|
||||
if !(_ammo isKindOf "BulletBase") exitWith {};
|
||||
if (!alive _projectile) exitWith {};
|
||||
if (underwater _unit) exitWith {};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Glowbal, Ruthberg
|
||||
* Module for adjusting the advanced ballistics settings
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Ruthberg
|
||||
* Initializes the advanced ballistics extension with terrain data
|
||||
@ -19,10 +19,10 @@ if (!hasInterface) exitWith {};
|
||||
if (!GVAR(enabled)) exitWith {};
|
||||
|
||||
private _initStartTime = diag_tickTime;
|
||||
private _mapSize = getNumber (configFile >> "CfgWorlds" >> worldName >> "MapSize");
|
||||
private _mapSize = worldSize;
|
||||
|
||||
if (("ace_advanced_ballistics" callExtension format["init:%1:%2", worldName, _mapSize]) == "Terrain already initialized") exitWith {
|
||||
INFO_1("Terrain already initialized [world: %1]", worldName);
|
||||
INFO_1("Terrain already initialized [world: %1]",worldName);
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
systemChat "AdvancedBallistics: Terrain already initialized";
|
||||
#endif
|
||||
@ -33,14 +33,14 @@ private _gridCells = _mapGrids * _mapGrids;
|
||||
|
||||
GVAR(currentGrid) = 0;
|
||||
|
||||
INFO_2("Starting Terrain Extension [cells: %1] [world: %2]", _gridCells, worldName);
|
||||
INFO_2("Starting Terrain Extension [cells: %1] [world: %2]",_gridCells,worldName);
|
||||
|
||||
[{
|
||||
params ["_args","_idPFH"];
|
||||
_args params ["_mapGrids", "_gridCells", "_initStartTime"];
|
||||
|
||||
if (GVAR(currentGrid) >= _gridCells) exitWith {
|
||||
INFO_2("Finished terrain initialization in %1 seconds [world: %2]", (diag_tickTime - _initStartTime) toFixed 2, worldName);
|
||||
INFO_2("Finished terrain initialization in %1 seconds [world: %2]",(diag_tickTime - _initStartTime) toFixed 2,worldName);
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
systemChat format["AdvancedBallistics: Finished terrain initialization in %1 seconds", (diag_tickTime - _initStartTime) toFixed 2];
|
||||
#endif
|
||||
@ -53,7 +53,7 @@ INFO_2("Starting Terrain Extension [cells: %1] [world: %2]", _gridCells, worldNa
|
||||
private _gridCenter = [_x + 25, _y + 25];
|
||||
private _gridHeight = round(getTerrainHeightASL _gridCenter);
|
||||
private _gridNumObjects = count (_gridCenter nearObjects ["Building", 50]);
|
||||
private _gridSurfaceIsWater = if (surfaceIsWater _gridCenter) then {1} else {0};
|
||||
private _gridSurfaceIsWater = parseNumber (surfaceIsWater _gridCenter);
|
||||
"ace_advanced_ballistics" callExtension format["set:%1:%2:%3", _gridHeight, _gridNumObjects, _gridSurfaceIsWater];
|
||||
GVAR(currentGrid) = GVAR(currentGrid) + 1;
|
||||
if (GVAR(currentGrid) >= _gridCells) exitWith {};
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Ruthberg
|
||||
*
|
||||
@ -40,10 +40,13 @@ if (_transonicStabilityCoef == 0) then {
|
||||
_transonicStabilityCoef = 0.5;
|
||||
};
|
||||
private _dragModel = getNumber(_ammoConfig >> "ACE_dragModel");
|
||||
if (!(_dragModel in [1, 2, 5, 6, 7, 8])) then {
|
||||
if !(_dragModel in [1, 2, 5, 6, 7, 8]) then {
|
||||
_dragModel = 1;
|
||||
};
|
||||
private _ballisticCoefficients = getArray(_ammoConfig >> "ACE_ballisticCoefficients");
|
||||
if (_ballisticCoefficients isEqualTo []) then {
|
||||
_ballisticCoefficients = [0.5];
|
||||
};
|
||||
private _velocityBoundaries = getArray(_ammoConfig >> "ACE_velocityBoundaries");
|
||||
private _atmosphereModel = getText(_ammoConfig >> "ACE_standardAtmosphere");
|
||||
if (_atmosphereModel isEqualTo "") then {
|
||||
@ -66,7 +69,7 @@ if ((_typicalSpeed > 0) && {_typicalSpeed < 360}) then {
|
||||
if (_inheritedBarrelConfig || _inheritedTempConfig) then {
|
||||
private _parentConfig = inheritsFrom _ammoConfig;
|
||||
private _parentSpeed = getNumber (_parentConfig >> "typicalSpeed");
|
||||
WARNING_4("Subsonic Ammo %1 (%2 m/s) missing `ACE_muzzleVelocities` or `ACE_ammoTempMuzzleVelocityShifts` configs, attempting to use parent %3 (%4m/s)",_this,_typicalSpeed,configName _parentConfig, _parentSpeed);
|
||||
WARNING_4("Subsonic Ammo %1 (%2 m/s) missing `ACE_muzzleVelocities` or `ACE_ammoTempMuzzleVelocityShifts` configs, attempting to use parent %3 (%4m/s)",_this,_typicalSpeed,configName _parentConfig,_parentSpeed);
|
||||
if (_parentSpeed <= 0) exitWith {//Handle weird or null parent
|
||||
_muzzleVelocityTable = [];
|
||||
_ammoTempMuzzleVelocityShifts = [];
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Ruthberg
|
||||
*
|
||||
@ -21,7 +21,7 @@
|
||||
private _weaponConfig = (configFile >> "CfgWeapons" >> _this);
|
||||
|
||||
private _barrelTwist = 0 max getNumber(_weaponConfig >> "ACE_barrelTwist");
|
||||
private _twistDirection = [0, 1] select (_barrelTwist != 0);
|
||||
private _twistDirection = parseNumber (_barrelTwist != 0);
|
||||
if (isNumber (_weaponConfig >> "ACE_twistDirection")) then {
|
||||
_twistDirection = getNumber (_weaponConfig >> "ACE_twistDirection");
|
||||
if !(_twistDirection in [-1, 0, 1]) then {
|
||||
|
@ -1 +0,0 @@
|
||||
#include "\z\ace\addons\advanced_ballistics\script_component.hpp"
|
@ -4,7 +4,7 @@
|
||||
<Key ID="STR_ACE_Advanced_Ballistics_WindInfoKey">
|
||||
<English>Show Wind Info</English>
|
||||
<Polish>Pokaż inf. o wietrze</Polish>
|
||||
<Italian>Mostra indicazioni del vento</Italian>
|
||||
<Italian>Mostra indicazioni vento</Italian>
|
||||
<Russian>Показать информацию о ветре</Russian>
|
||||
<French>Afficher les infos sur le vent</French>
|
||||
<Spanish>Mostrar información del viento</Spanish>
|
||||
@ -46,7 +46,7 @@
|
||||
<Hungarian>Fejlett ballisztika</Hungarian>
|
||||
<Russian>Продвинутая баллистика</Russian>
|
||||
<Italian>Balistica Avanzata</Italian>
|
||||
<Japanese>アドバンスド バリスティックス</Japanese>
|
||||
<Japanese>アドバンスド弾道計算</Japanese>
|
||||
<Korean>고급 탄도학</Korean>
|
||||
<Chinese>先進彈道系統</Chinese>
|
||||
<Chinesesimp>进阶弹道系统</Chinesesimp>
|
||||
@ -63,7 +63,7 @@
|
||||
<Hungarian>Fejlett ballisztika</Hungarian>
|
||||
<Russian>Продвинутая баллистика</Russian>
|
||||
<Italian>Balistica Avanzata</Italian>
|
||||
<Japanese>アドバンスド バリスティックスを有効化</Japanese>
|
||||
<Japanese>アドバンスド弾道計算を有効化</Japanese>
|
||||
<Korean>고급 탄도학</Korean>
|
||||
<Chinese>先進彈道系統</Chinese>
|
||||
<Chinesesimp>进阶弹道系统</Chinesesimp>
|
||||
@ -80,7 +80,7 @@
|
||||
<Hungarian>Engedélyezi a fejlett ballisztikát</Hungarian>
|
||||
<Russian>Включает продвинутую баллистику</Russian>
|
||||
<Italian>Abilita Balistica Avanzata</Italian>
|
||||
<Japanese>アドバンスド バリスティックスを有効化します。</Japanese>
|
||||
<Japanese>アドバンスド弾道計算は高度な弾道計算処理を有効化します。</Japanese>
|
||||
<Korean>고급 탄도학을 적용합니다</Korean>
|
||||
<Chinese>啟用先進彈道系統</Chinese>
|
||||
<Chinesesimp>启用进阶弹道系统</Chinesesimp>
|
||||
@ -106,8 +106,8 @@
|
||||
<English>Simulates slight variations in muzzle velocity between each shot</English>
|
||||
<Spanish>Simula variaciones ligeras de velocidad entre cada disparo</Spanish>
|
||||
<German>Simuliert leichte Variationen der Mündungsgeschwindigkeit zwischen jedem Schuss.</German>
|
||||
<Japanese>発射毎の銃口初速の変動をシミュレートします。</Japanese>
|
||||
<Italian>Simula lievi variazioni della velocità della volata tra un colpo e l'altro</Italian>
|
||||
<Japanese>各発射毎の銃口初速のわずかな変動をシミュレートします。</Japanese>
|
||||
<Italian>Simula piccole variazioni della velocità alla volata tra ogni colpo.</Italian>
|
||||
<Korean>각 사격 사이에 총구속도 변화를 시뮬레이션 합니다.</Korean>
|
||||
<Chinese>模擬每發子彈的槍口初速都略有不同</Chinese>
|
||||
<Chinesesimp>模拟每发子弹的枪口初速都略有不同</Chinesesimp>
|
||||
@ -128,8 +128,8 @@
|
||||
<French>Activer la simulation de la température</French>
|
||||
<Hungarian>Lőszer-hő szimuláció engedélyezése</Hungarian>
|
||||
<Russian>Симуляция температуры для боеприпасов</Russian>
|
||||
<Italian>Abilita simulazione della temperatura delle munizioni</Italian>
|
||||
<Japanese>弾薬温度のシミュレーションを有効化</Japanese>
|
||||
<Italian>Abilita simulazione temperatura munizioni</Italian>
|
||||
<Japanese>弾薬温度シミュレーションを有効化</Japanese>
|
||||
<Korean>탄약 온도 구현 적용</Korean>
|
||||
<Chinese>啟用彈藥溫度模擬系統</Chinese>
|
||||
<Chinesesimp>启用弹药温度模拟系统</Chinesesimp>
|
||||
@ -145,7 +145,7 @@
|
||||
<French>La vitesse initiale varie en fonction de la température des munitions.</French>
|
||||
<Hungarian>A kezdősebesség a lőszer hőmérsékletétől függően változó</Hungarian>
|
||||
<Russian>Начальная скорость пули зависит от температуры</Russian>
|
||||
<Italian>La velocità dello sparo varia a seconda della temperatura delle munizioni</Italian>
|
||||
<Italian>La velocità alla volata varia a seconda della temperatura delle munizioni.</Italian>
|
||||
<Japanese>弾薬の温度により銃口初速を変動させます。</Japanese>
|
||||
<Korean>탄약 온도에 비례해 총구 속도가 달라집니다</Korean>
|
||||
<Chinese>子彈初速將隨彈藥溫度而有所變化</Chinese>
|
||||
@ -162,8 +162,8 @@
|
||||
<French>Activer la simulation de la longueur de canon</French>
|
||||
<Hungarian>Csőhossz-szimuláció engedélyezése</Hungarian>
|
||||
<Russian>Симуляция длины ствола</Russian>
|
||||
<Italian>Abilita simulazione della lunghezza della canna</Italian>
|
||||
<Japanese>銃身長のシミュレーションを有効化</Japanese>
|
||||
<Italian>Abilita simulazione lunghezza canna</Italian>
|
||||
<Japanese>銃身長シミュレーションを有効化</Japanese>
|
||||
<Korean>총열 길이 구현 적용</Korean>
|
||||
<Chinese>啟用槍管長度模擬系統</Chinese>
|
||||
<Chinesesimp>启用枪管长度模拟系统</Chinesesimp>
|
||||
@ -179,7 +179,7 @@
|
||||
<French>La vitesse initiale varie en fonction de la longueur du canon.</French>
|
||||
<Hungarian>A kezdősebesség a cső hosszától függően változó</Hungarian>
|
||||
<Russian>Начальная скорость пули зависит от длины ствола</Russian>
|
||||
<Italian>La velocità di sparo varia a seconda della lunghezza della canna</Italian>
|
||||
<Italian>La velocità alla volata varia a seconda della lunghezza della canna.</Italian>
|
||||
<Japanese>銃身長により銃口初速を変動させます。</Japanese>
|
||||
<Korean>총구 속도가 총열에 비례해 달라집니다</Korean>
|
||||
<Chinese>子彈初速將隨槍管長度而有所變化</Chinese>
|
||||
@ -196,7 +196,7 @@
|
||||
<French>Activer l'effet de balle traçante</French>
|
||||
<Hungarian>Nyomkövető-effekt engedélyezése</Hungarian>
|
||||
<Russian>Следы пуль</Russian>
|
||||
<Italian>Abilita effetto dei Proiettili Traccianti</Italian>
|
||||
<Italian>Abilita effetto di traccia proiettile</Italian>
|
||||
<Japanese>弾丸の軌跡エフェクトを有効化</Japanese>
|
||||
<Korean>예광탄 효과 적용</Korean>
|
||||
<Chinese>啟用曳光彈效果</Chinese>
|
||||
@ -213,7 +213,7 @@
|
||||
<French>Active un effet de balle traçante pour les munitions de gros calibre (seulement visible en utilisant une optique à fort grossissement).</French>
|
||||
<Hungarian>Engedélyezi a nagy kaliberű lövedékek nyomának vizuális követését (csak nagy teljesítményű optikán keresztül látható)</Hungarian>
|
||||
<Russian>Включает эффект следов пуль для больших калибров (видны только через мощную оптику)</Russian>
|
||||
<Italian>Abilita effetto dei proiettili traccianti di alto calibro (visibile solo attraverso ottiche ad alto potenziale)</Italian>
|
||||
<Italian>Abilita effetto di traccia lasciata da proiettili di alto calibro (visibile solo attraverso ottiche ad alto ingrandimento)</Italian>
|
||||
<Japanese>大口径弾の軌跡エフェクトを有効化します。 (高性能光学機器を介してのみ見ることができます)</Japanese>
|
||||
<Korean>대구경 탄환에 예광탄 효과를 적용합니다(오직 고성능 조준경 사용시에만 보입니다)</Korean>
|
||||
<Chinese>啟用曳光彈效果給大口徑子彈 (只有透過高倍率光學瞄鏡才能看到)</Chinese>
|
||||
@ -230,7 +230,7 @@
|
||||
<French>Intervalle de simulation</French>
|
||||
<Hungarian>Szimuláció intervalluma</Hungarian>
|
||||
<Russian>Интервал симуляции</Russian>
|
||||
<Italian>Intervallo Simulazione</Italian>
|
||||
<Italian>Intervallo di Simulazione</Italian>
|
||||
<Japanese>シミュレーション間隔</Japanese>
|
||||
<Korean>구현 간격</Korean>
|
||||
<Chinese>模擬間隔</Chinese>
|
||||
@ -246,7 +246,7 @@
|
||||
<French>Définit l'intervalle entre chacune des étapes de calcul.</French>
|
||||
<Hungarian>Meghatározza a számítási lépések közötti időintervallumot</Hungarian>
|
||||
<Russian>Определяет временной интервал между вычислениями</Russian>
|
||||
<Italian>Definisce l'intervallo tra ogni step di calcolo</Italian>
|
||||
<Italian>Definisce l'intervallo tra ogni passo del calcolo</Italian>
|
||||
<Japanese>各シミュレーション毎の間隔を定義します。</Japanese>
|
||||
<Korean>각 계산 단위의 간격을 정의합니다</Korean>
|
||||
<Chinese>定義每個模擬計算之間的時間間隔</Chinese>
|
||||
@ -263,7 +263,7 @@
|
||||
<Hungarian>Szimuláció hatóköre</Hungarian>
|
||||
<Russian>Радиус симуляции</Russian>
|
||||
<Italian>Raggio Simulazione</Italian>
|
||||
<Japanese>シミュレーションの範囲</Japanese>
|
||||
<Japanese>シミュレーションの半径</Japanese>
|
||||
<Korean>구현 범위</Korean>
|
||||
<Chinese>模擬半徑</Chinese>
|
||||
<Chinesesimp>模拟半径</Chinesesimp>
|
||||
@ -279,8 +279,8 @@
|
||||
<French>Définit le rayon autour du joueur (en mètres), dans lequel la balistique avancée est appliquée aux projectiles.</French>
|
||||
<Hungarian>Meghatározza a játékos körüli hatókört (méterben), ahol a lövedékek fejlett ballisztikát használnak</Hungarian>
|
||||
<Russian>Определяет радиус вокруг игрока (в метрах), в котором продвинутая баллистика применяется к снарядам</Russian>
|
||||
<Italian>Definisce il raggio attorno al giocatore (in metri) per cui la Balistica Avanzata è applicata ai proiettili</Italian>
|
||||
<Japanese>アドバンスド バリスティックスの適用半径範囲 (プレイヤー中心、メートル単位) を定義します。</Japanese>
|
||||
<Italian>Definisce il raggio attorno al giocatore (in metri) entro il quale la Balistica Avanzata è applicata ai proiettili</Italian>
|
||||
<Japanese>アドバンスド弾道計算の適用半径範囲 (プレイヤー中心、メートル単位) を定義します。</Japanese>
|
||||
<Korean>플레이어 주위의 발사체를 고급 탄도학으로 정의하는 범위를 정합니다(미터)</Korean>
|
||||
<Chinese>以玩家的半徑距離(公尺)定義先進彈道系統啟用範圍</Chinese>
|
||||
<Chinesesimp>定义玩家周围的半径(米),在这个半径内,进阶弹道系统会被启用</Chinesesimp>
|
||||
@ -296,8 +296,8 @@
|
||||
<Hungarian>Ez a modul engedélyezi a fejlett ballisztikai szimulációt - a lövedékek röppályáját befolyásolni fogja a levegő hőmérséklete, légnyomás, páratartalom, gravitáció, a lövedék fajtája, valamint a fegyver, amiből kilőtték a lövedéket.</Hungarian>
|
||||
<Russian>Этот модуль включает симуляцию продвинутой баллистики - при этом на траекторию полета снаряда влияют различные параметры, такие как температура воздуха, атмосферное давление, влажность, гравитация, тип боеприпаса и оружия, из которого произвели выстрел.</Russian>
|
||||
<Spanish>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.</Spanish>
|
||||
<Italian>Questo modulo abilita la simulazione della Balistica Avanzata - cioè la traiettoria dei proiettili è influenzata da variabili come la temperatura dell'aria, pressione atmosferica, umidità, gravità, il tipo di munizione e l'arma da cui è sparata</Italian>
|
||||
<Japanese>アドバンスド バリスティックスのシミュレーションを有効化します。 弾道は気温・気圧・湿度・重力・弾薬の種類・発射する武器などの変化による影響を受けるようになります。</Japanese>
|
||||
<Italian>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.</Italian>
|
||||
<Japanese>アドバンスド弾道計算のシミュレーションを有効化します。 弾道は気温・気圧・湿度・重力・弾薬の種類・発射する武器などの変化による影響を受けるようになります。</Japanese>
|
||||
<Korean>이 모듈은 고급 탄도학을 적용시킵니다 - 이는 발사체의 궤적이 기온, 대기압, 습도, 중력, 탄환의 종류와 어느 무기에서 발사되는지에 따라 영향을 받습니다.</Korean>
|
||||
<Chinese>該模塊實現先進的彈道仿真 - 這意味著子彈的軌跡是由空氣溫度、大氣壓力、濕度、重力、彈藥類型以及射擊的武器所影響</Chinese>
|
||||
<Chinesesimp>该模块实现增强的弹道模拟—子弹的轨迹由空气温度、大气压力、湿度、重力、弹药类型和射击的武器等变量所影响</Chinesesimp>
|
||||
|
@ -2,9 +2,11 @@ PREP(addDutyFactor);
|
||||
PREP(createStaminaBar);
|
||||
PREP(getAnimDuty);
|
||||
PREP(getMetabolicCosts);
|
||||
PREP(getWeaponInertia);
|
||||
PREP(handleEffects);
|
||||
PREP(handlePlayerChanged);
|
||||
PREP(handleStaminaBar);
|
||||
PREP(mainLoop);
|
||||
PREP(moduleSettings);
|
||||
PREP(removeDutyFactor);
|
||||
PREP(renderDebugLines);
|
||||
|
@ -2,26 +2,33 @@
|
||||
|
||||
if (!hasInterface) exitWith {};
|
||||
|
||||
[missionNamespace, "ACE_setCustomAimCoef", QUOTE(ADDON), {
|
||||
private _unit = ACE_player;
|
||||
private _fatigue = _unit getVariable [QGVAR(aimFatigue), 0];
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
call FUNC(renderDebugLines);
|
||||
#endif
|
||||
|
||||
switch (stance _unit) do {
|
||||
case ("CROUCH"): {
|
||||
(1.0 + _fatigue ^ 2 * 0.1) * GVAR(swayFactor)
|
||||
};
|
||||
case ("PRONE"): {
|
||||
(1.0 + _fatigue ^ 2 * 2.0) * GVAR(swayFactor)
|
||||
};
|
||||
default {
|
||||
(1.5 + _fatigue ^ 2 * 3.0) * GVAR(swayFactor)
|
||||
};
|
||||
};
|
||||
}] call EFUNC(common,arithmeticSetSource);
|
||||
// recheck weapon inertia after weapon swap, change of attachments or switching unit
|
||||
["weapon", {[ACE_player] call FUNC(getWeaponInertia)}, true] call CBA_fnc_addPlayerEventHandler;
|
||||
["loadout", {[ACE_player] call FUNC(getWeaponInertia)}, true] call CBA_fnc_addPlayerEventHandler;
|
||||
["unit", {[ACE_player] call FUNC(getWeaponInertia)}, true] call CBA_fnc_addPlayerEventHandler;
|
||||
|
||||
["CBA_settingsInitialized", {
|
||||
if (!GVAR(enabled)) exitWith {};
|
||||
|
||||
["baseline", {
|
||||
private _fatigue = ACE_player getVariable [QGVAR(aimFatigue), 0];
|
||||
switch (stance ACE_player) do {
|
||||
case ("CROUCH"): {
|
||||
(1.0 + _fatigue ^ 2 * 0.1)
|
||||
};
|
||||
case ("PRONE"): {
|
||||
(1.0 + _fatigue ^ 2 * 2.0)
|
||||
};
|
||||
default {
|
||||
(1.5 + _fatigue ^ 2 * 3.0)
|
||||
};
|
||||
};
|
||||
}, QUOTE(ADDON)] call EFUNC(common,addSwayFactor);
|
||||
|
||||
// - Post process effect ------------------------------------------------------
|
||||
GVAR(ppeBlackout) = ppEffectCreate ["ColorCorrections", 4220];
|
||||
GVAR(ppeBlackout) ppEffectEnable true;
|
||||
@ -30,28 +37,26 @@ if (!hasInterface) exitWith {};
|
||||
GVAR(ppeBlackout) ppEffectCommit 0.4;
|
||||
|
||||
// - GVAR updating and initialization -----------------------------------------
|
||||
["unit", LINKFUNC(handlePlayerChanged), true] call CBA_fnc_addPlayerEventHandler;
|
||||
["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler;
|
||||
|
||||
["visibleMap", {
|
||||
params ["", "_visibleMap"]; // command visibleMap is updated one frame later
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlShow ((!_visibleMap) && {(vehicle ACE_player) == ACE_player});
|
||||
(uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]) ctrlShow (!_visibleMap && isNull objectParent ACE_player);
|
||||
}, true] call CBA_fnc_addPlayerEventHandler;
|
||||
["vehicle", {
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlShow ((!visibleMap) && {(vehicle ACE_player) == ACE_player});
|
||||
(uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]) ctrlShow (!visibleMap && isNull objectParent ACE_player);
|
||||
}, true] call CBA_fnc_addPlayerEventHandler;
|
||||
|
||||
// - Duty factors -------------------------------------------------------------
|
||||
if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then {
|
||||
if (GETEGVAR(medical,enabled,false)) then {
|
||||
[QEGVAR(medical,pain), { // 0->1.0, 0.5->1.05, 1->1.1
|
||||
linearConversion [0, 1, (_this getVariable [QEGVAR(medical,pain), 0]), 1, 1.1, true];
|
||||
linearConversion [0, 1, _this getVariable [QEGVAR(medical,pain), 0], 1, 1.1, true];
|
||||
}] call FUNC(addDutyFactor);
|
||||
[QEGVAR(medical,bloodVolume), { // 6->1.0, 5->1.167, 4->1.33
|
||||
linearConversion [6, 0, (_this getVariable [QEGVAR(medical,bloodVolume), 6]), 1, 2, true];
|
||||
linearConversion [6, 0, _this getVariable [QEGVAR(medical,bloodVolume), 6], 1, 2, true];
|
||||
}] call FUNC(addDutyFactor);
|
||||
};
|
||||
if (["ACE_Dragging"] call EFUNC(common,isModLoaded)) then {
|
||||
if (["ace_dragging"] call EFUNC(common,isModLoaded)) then {
|
||||
[QEGVAR(dragging,isCarrying), {
|
||||
[1, 3] select (_this getVariable [QEGVAR(dragging,isCarrying), false]);
|
||||
}] call FUNC(addDutyFactor);
|
||||
@ -59,7 +64,7 @@ if (!hasInterface) exitWith {};
|
||||
// Weather has an off switch, Dragging & Medical don't.
|
||||
if (missionNamespace getVariable [QEGVAR(weather,enabled), false]) then {
|
||||
[QEGVAR(weather,temperature), { // 35->1, 45->2
|
||||
linearConversion [35, 45, (missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25]), 1, 2, true];
|
||||
linearConversion [35, 45, missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25], 1, 2, true];
|
||||
}] call FUNC(addDutyFactor);
|
||||
};
|
||||
|
||||
|
@ -6,10 +6,12 @@ PREP_RECOMPILE_START;
|
||||
#include "XEH_PREP.hpp"
|
||||
PREP_RECOMPILE_END;
|
||||
|
||||
#include "initSettings.sqf"
|
||||
#include "initSettings.inc.sqf"
|
||||
|
||||
GVAR(staminaBarWidth) = 10 * (((safezoneW / safezoneH) min 1.2) / 40);
|
||||
GVAR(dutyList) = createHashMap;
|
||||
GVAR(setAnimExclusions) = [];
|
||||
GVAR(inertia) = 0;
|
||||
GVAR(inertiaCache) = createHashMap;
|
||||
|
||||
ADDON = true;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Adds a duty factor.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Creates the stamina bar.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Calculates the duty of the current animation.
|
||||
* Calculates the duty ('postureWeight') of the current animation.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
@ -37,13 +37,14 @@ if (_animType in ["idl", "mov", "adj"]) then {
|
||||
};
|
||||
};
|
||||
|
||||
if (currentWeapon _unit != handgunWeapon _unit) then {
|
||||
if (currentWeapon _unit != "") then {
|
||||
if (_animName select [13, 3] == "ras") then {
|
||||
// low ready jog
|
||||
_duty = _duty * 1.2;
|
||||
if (_animName select [9, 3] == "tac") then {
|
||||
// high ready jog/walk
|
||||
_duty = _duty * 1.5;
|
||||
_duty = _duty * (1 + 0.8*GVAR(inertia));
|
||||
} else {
|
||||
// low ready jog
|
||||
_duty = _duty * (1 + 0.2*GVAR(inertia));
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,51 +1,74 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Calculates the current metabolic costs for a unit.
|
||||
* Author: BaerMitUmlaut, ulteq
|
||||
* Calculates the current metabolic costs.
|
||||
* Calculation is done according to the Pandolf/Wojtowicz formulas.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Speed <NUMBER>
|
||||
* 0: Duty of animation
|
||||
* 1: Mass of unit <NUMBER>
|
||||
* 2: Terrain gradient <NUMBER>
|
||||
* 3: Terrain factor <NUMBER>
|
||||
* 4: Speed <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* Metabolic cost <NUMBER>
|
||||
*
|
||||
* Example:
|
||||
* [player, 3.3] call ace_advanced_fatigue_fnc_getMetabolicCosts
|
||||
* [1, 840, 20, 1, 4] call ace_advanced_fatigue_fnc_getMetabolicCosts
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
params ["_unit", "_velocity"];
|
||||
|
||||
private _gearMass = ((_unit getVariable [QEGVAR(movement,totalLoad), loadAbs _unit]) / 22.046) * GVAR(loadFactor);
|
||||
params ["_duty", "_gearMass", "_terrainGradient", "_terrainFactor", "_speed"];
|
||||
|
||||
private _terrainAngle = asin (1 - ((surfaceNormal getPosASL _unit) select 2));
|
||||
private _terrainGradient = (_terrainAngle / 45 min 1) * 5 * GVAR(terrainGradientFactor);
|
||||
private _duty = GVAR(animDuty);
|
||||
// Metabolic cost for walking and running is different
|
||||
if (_speed > 2) then {
|
||||
// Running
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
private _baseline = 2.1 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + (SIM_BODYMASS + _gearMass) * 0.9 * (_speed ^ 2);
|
||||
private _graded = 2.1 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.9 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient);
|
||||
private _terrainImpact = abs ((_graded / _baseline) - 1);
|
||||
hintSilent format ["FwdAngle: %1 | SideAngle: %2 \n TerrainFactor: %3 | TerrainGradient: %4 \n TerrainImpact: %5 \n Speed: %6 | CarriedLoad: %7 \n Duty: %8 | Work: %9",
|
||||
_fwdAngle toFixed 1,
|
||||
_sideAngle toFixed 1,
|
||||
_terrainFactor toFixed 2,
|
||||
_terrainGradient toFixed 1,
|
||||
_terrainImpact toFixed 2,
|
||||
_speed toFixed 2,
|
||||
_gearMass toFixed 1,
|
||||
_duty toFixed 2,
|
||||
round (_graded * BIOMECH_EFFICIENCY * _duty)
|
||||
];
|
||||
#endif
|
||||
|
||||
{
|
||||
if (_x isEqualType 0) then {
|
||||
_duty = _duty * _x;
|
||||
} else {
|
||||
_duty = _duty * (_unit call _x);
|
||||
};
|
||||
} forEach (values GVAR(dutyList));
|
||||
|
||||
if (GVAR(isSwimming)) then {
|
||||
_terrainGradient = 0;
|
||||
};
|
||||
|
||||
if (_velocity > 2) then {
|
||||
(
|
||||
2.10 * SIM_BODYMASS
|
||||
2.1 * SIM_BODYMASS
|
||||
+ 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2)
|
||||
+ (SIM_BODYMASS + _gearMass) * (0.90 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient)
|
||||
) * 0.23 * _duty
|
||||
+ _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.9 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient)
|
||||
) * BIOMECH_EFFICIENCY * _duty
|
||||
} else {
|
||||
// Walking
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
private _baseline = 1.05 * SIM_BODYMASS + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + (SIM_BODYMASS + _gearMass) * 1.15 * (_speed ^ 2);
|
||||
private _graded = 1.05 * SIM_BODYMASS + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient);
|
||||
private _terrainImpact = abs ((_graded / _baseline) - 1);
|
||||
hintSilent format ["FwdAngle: %1 | SideAngle: %2 \n TerrainFactor: %3 | TerrainGradient: %4 \n TerrainImpact: %5 \n Speed: %6 | CarriedLoad: %7 \n Duty: %8 | Work: %9",
|
||||
_fwdAngle toFixed 1,
|
||||
_sideAngle toFixed 1,
|
||||
_terrainFactor toFixed 2,
|
||||
_terrainGradient toFixed 1,
|
||||
_terrainImpact toFixed 2,
|
||||
_speed toFixed 2,
|
||||
_gearMass toFixed 1,
|
||||
_duty toFixed 2,
|
||||
round (_graded * BIOMECH_EFFICIENCY * _duty)
|
||||
];
|
||||
#endif
|
||||
|
||||
(
|
||||
1.05 * SIM_BODYMASS
|
||||
+ 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2)
|
||||
+ (SIM_BODYMASS + _gearMass) * (1.15 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient)
|
||||
) * 0.23 * _duty
|
||||
+ 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2)
|
||||
+ _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient)
|
||||
) * BIOMECH_EFFICIENCY * _duty
|
||||
};
|
||||
|
38
addons/advanced_fatigue/functions/fnc_getWeaponInertia.sqf
Normal file
38
addons/advanced_fatigue/functions/fnc_getWeaponInertia.sqf
Normal file
@ -0,0 +1,38 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Pterolatypus
|
||||
* Calculates total weapon inertia, accounting for attachments.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Total inertia <NUMBER>
|
||||
*
|
||||
* Example:
|
||||
* [ACE_player] call ace_advanced_fatigue_fnc_getWeaponInertia
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
params [["_unit", ACE_player, [objNull]]];
|
||||
|
||||
private _cache = GVAR(inertiaCache);
|
||||
private _weapon = currentWeapon _unit;
|
||||
private _weaponAndItems = [_weapon] + (_unit weaponAccessories _weapon);
|
||||
|
||||
private _inertia = _cache get _weaponAndItems;
|
||||
if (isNil "_inertia") then {
|
||||
_inertia = 0;
|
||||
private _cfgWeapons = configFile >> "CfgWeapons";
|
||||
{
|
||||
// if item is "" or inertia property is undefined, just ignore it
|
||||
private _itemInertia = getNumber (_cfgWeapons >> _x >> "inertia");
|
||||
if (isNil "_itemInertia") then { continue };
|
||||
|
||||
_inertia = _inertia + _itemInertia;
|
||||
} forEach _weaponAndItems;
|
||||
_cache set [_weaponAndItems, _inertia];
|
||||
};
|
||||
|
||||
GVAR(inertia) = _inertia;
|
||||
_inertia
|
@ -1,44 +1,44 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Author: BaerMitUmlaut, ulteq
|
||||
* Handles any audible, visual and physical effects of fatigue.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Fatigue <NUMBER>
|
||||
* 2: Speed <NUMBER>
|
||||
* 3: Overexhausted <BOOL>
|
||||
* 2: Overexhausted <BOOL>
|
||||
* 3: Forward Angle <NUMBER>
|
||||
* 4: Side Angle <NUMBER>
|
||||
*
|
||||
* 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);
|
||||
};
|
||||
};
|
||||
@ -94,6 +98,3 @@ if (_overexhausted) then {
|
||||
};
|
||||
|
||||
_unit setVariable [QGVAR(aimFatigue), _fatigue];
|
||||
|
||||
private _aimCoef = [missionNamespace, "ACE_setCustomAimCoef", "max"] call EFUNC(common,arithmeticGetResult);
|
||||
_unit setCustomAimCoef _aimCoef;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Handles switching units (once on init and afterwards via Zeus).
|
||||
* Author: BaerMitUmlaut, ulteq
|
||||
* Handles switching units (once on init and afterwards via Zeus). Also handles CBA setting change for performance factor.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: New Unit <OBJECT>
|
||||
@ -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;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Handles visual changes of the stamina bar.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Author: BaerMitUmlaut, ulteq
|
||||
* Main looping function that updates fatigue values.
|
||||
*
|
||||
* Arguments:
|
||||
@ -17,67 +17,131 @@
|
||||
|
||||
// Dead people don't breathe, will also handle null (map intros)
|
||||
if (!alive ACE_player) exitWith {
|
||||
[FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute;
|
||||
[LINKFUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute;
|
||||
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlSetFade 1;
|
||||
_staminaBarContainer ctrlCommit 1;
|
||||
};
|
||||
|
||||
private _velocity = velocity ACE_player;
|
||||
private _normal = surfaceNormal (getPosWorld ACE_player);
|
||||
private _movementVector = vectorNormalized _velocity;
|
||||
private _sideVector = vectorNormalized (_movementVector vectorCrossProduct _normal);
|
||||
private _fwdAngle = asin (_movementVector select 2);
|
||||
private _sideAngle = asin (_sideVector select 2);
|
||||
|
||||
private _currentWork = REE;
|
||||
private _currentSpeed = (vectorMagnitude (velocity ACE_player)) min 6;
|
||||
private _currentSpeed = (vectorMagnitude _velocity) min 6;
|
||||
|
||||
// fix #4481. Diving to the ground is recorded as PRONE stance with running speed velocity. Cap maximum speed to fix.
|
||||
if (GVAR(isProne)) then {
|
||||
_currentSpeed = _currentSpeed min 1.5;
|
||||
};
|
||||
|
||||
if ((vehicle ACE_player == ACE_player) && {_currentSpeed > 0.1} && {isTouchingGround ACE_player || {underwater ACE_player}}) then {
|
||||
_currentWork = [ACE_player, _currentSpeed] call FUNC(getMetabolicCosts);
|
||||
// Get the current duty
|
||||
private _duty = GVAR(animDuty);
|
||||
|
||||
{
|
||||
if (_x isEqualType 0) then {
|
||||
_duty = _duty * _x;
|
||||
} else {
|
||||
_duty = _duty * (ACE_player call _x);
|
||||
};
|
||||
} forEach (values GVAR(dutyList));
|
||||
|
||||
private _terrainGradient = abs _fwdAngle;
|
||||
private _terrainFactor = 1;
|
||||
private _gearMass = 0 max (((ACE_player getVariable [QEGVAR(movement,totalLoad), loadAbs ACE_player]) / 22.046 - UNDERWEAR_WEIGHT) * GVAR(loadFactor));
|
||||
|
||||
if (isNull objectParent ACE_player && {_currentSpeed > 0.1} && {isTouchingGround ACE_player || {underwater ACE_player}}) then {
|
||||
if (!GVAR(isSwimming)) then {
|
||||
// If the unit is going downhill, it's much less demanding
|
||||
if (_fwdAngle < 0) then {
|
||||
_terrainGradient = 0.15 * _terrainGradient;
|
||||
};
|
||||
|
||||
// Used to simulate the unevenness/roughness of the terrain
|
||||
if ((getPosATL ACE_player) select 2 < 0.01) then {
|
||||
private _sideGradient = abs (_sideAngle / 45) min 1;
|
||||
|
||||
_terrainFactor = 1 + _sideGradient ^ 4;
|
||||
};
|
||||
};
|
||||
|
||||
_currentWork = [_duty, _gearMass, _terrainGradient * GVAR(terrainGradientFactor), _terrainFactor, _currentSpeed] call FUNC(getMetabolicCosts);
|
||||
_currentWork = _currentWork max REE;
|
||||
};
|
||||
|
||||
// Oxygen calculation
|
||||
private _oxygen = if (GETEGVAR(medical,enabled,false) && {EGVAR(medical_vitals,simulateSpo2)}) then { // Defer to medical
|
||||
(ACE_player getVariable [QEGVAR(medical,spo2), 97]) / 100
|
||||
} else {
|
||||
1 - 0.131 * GVAR(respiratoryRate) ^ 2 // Default AF oxygen saturation
|
||||
};
|
||||
// Calculate muscle damage increase
|
||||
// Note: Muscle damage recovery is ignored as it takes multiple days
|
||||
GVAR(muscleDamage) = GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3.2 * 0.00004;
|
||||
private _muscleIntegritySqrt = sqrt (1 - GVAR(muscleDamage));
|
||||
GVAR(muscleDamage) = GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3.2 * MUSCLE_TEAR_RATE;
|
||||
|
||||
// Calculate muscle damage recovery
|
||||
GVAR(muscleDamage) = 0 max (GVAR(muscleDamage) - MUSCLE_RECOVERY * GVAR(recoveryFactor)) min 1;
|
||||
private _muscleIntegrity = 1 - GVAR(muscleDamage);
|
||||
private _muscleFactor = sqrt _muscleIntegrity;
|
||||
|
||||
// Calculate available power
|
||||
private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * OXYGEN * _muscleIntegritySqrt;
|
||||
private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * OXYGEN * _muscleIntegritySqrt;
|
||||
private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * _oxygen * _muscleFactor;
|
||||
private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * _oxygen * _muscleFactor;
|
||||
private _aePathwayPowerFatigued = _ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued;
|
||||
private _anPathwayPowerFatigued = GVAR(anPathwayPower) * sqrt (GVAR(anReserve) / AN_MAXRESERVE) * _oxygen * _muscleIntegrity;
|
||||
|
||||
// Calculate how much power is consumed from each reserve
|
||||
private _ae1Power = _currentWork min _ae1PathwayPowerFatigued;
|
||||
private _ae2Power = ((_currentWork - _ae1Power) max 0) min _ae2PathwayPowerFatigued;
|
||||
private _anPower = (_currentWork - _ae1Power - _ae2Power) max 0;
|
||||
private _ae2Power = (_currentWork - _ae1Power) min _ae2PathwayPowerFatigued;
|
||||
private _anPower = 0 max (_currentWork - _ae1Power - _ae2Power);
|
||||
|
||||
// Remove ATP from reserves for current work
|
||||
GVAR(ae1Reserve) = GVAR(ae1Reserve) - _ae1Power / WATTSPERATP;
|
||||
GVAR(ae2Reserve) = GVAR(ae2Reserve) - _ae2Power / WATTSPERATP;
|
||||
GVAR(anReserve) = GVAR(anReserve) - _anPower / WATTSPERATP;
|
||||
// Increase anearobic fatigue
|
||||
GVAR(anFatigue) = GVAR(anFatigue) + _anPower * (0.057 / GVAR(peakPower)) * 1.1;
|
||||
GVAR(ae1Reserve) = 0 max (GVAR(ae1Reserve) - _ae1Power / GVAR(aeWattsPerATP));
|
||||
GVAR(ae2Reserve) = 0 max (GVAR(ae2Reserve) - _ae2Power / GVAR(aeWattsPerATP));
|
||||
GVAR(anReserve) = 0 max (GVAR(anReserve) - _anPower / GVAR(anWattsPerATP));
|
||||
|
||||
// Acidosis accumulation
|
||||
GVAR(anFatigue) = GVAR(anFatigue) + _anPower * GVAR(maxPowerFatigueRatio) * 1.1;
|
||||
|
||||
// Aerobic ATP reserve recovery
|
||||
GVAR(ae1Reserve) = ((GVAR(ae1Reserve) + OXYGEN * 6.60 * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower) * GVAR(recoveryFactor)) min AE1_MAXRESERVE) max 0;
|
||||
GVAR(ae2Reserve) = ((GVAR(ae2Reserve) + OXYGEN * 5.83 * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower) * GVAR(recoveryFactor)) min AE2_MAXRESERVE) max 0;
|
||||
GVAR(ae1Reserve) = (GVAR(ae1Reserve) + _oxygen * GVAR(recoveryFactor) * AE1_ATP_RECOVERY * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower)) min AE1_MAXRESERVE;
|
||||
GVAR(ae2Reserve) = (GVAR(ae2Reserve) + _oxygen * GVAR(recoveryFactor) * AE2_ATP_RECOVERY * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower)) min AE2_MAXRESERVE;
|
||||
|
||||
// Anaerobic ATP reserver and fatigue recovery
|
||||
GVAR(anReserve) = ((GVAR(anReserve)
|
||||
+ (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) / GVAR(VO2MaxPower) * 56.7 * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor)
|
||||
) min AN_MAXRESERVE) max 0;
|
||||
private _aeSurplus = _ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power;
|
||||
|
||||
GVAR(anFatigue) = ((GVAR(anFatigue)
|
||||
- (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) * (0.057 / GVAR(peakPower)) * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor)
|
||||
) min 1) max 0;
|
||||
// Anaerobic ATP reserve recovery
|
||||
GVAR(anReserve) = 0 max (GVAR(anReserve) + _aeSurplus / GVAR(VO2MaxPower) * AN_ATP_RECOVERY * GVAR(recoveryFactor) * (GVAR(anFatigue) max linearConversion [AN_MAXRESERVE, 0, GVAR(anReserve), 0, 0.75, true]) ^ 2) min AN_MAXRESERVE; // max linearConversion ensures that if GVAR(anFatigue) is very low, it will still regenerate reserves
|
||||
// Acidosis recovery
|
||||
GVAR(anFatigue) = 0 max (GVAR(anFatigue) - _aeSurplus * GVAR(maxPowerFatigueRatio) * GVAR(recoveryFactor) * GVAR(anFatigue) ^ 2) min 1;
|
||||
|
||||
private _aeReservePercentage = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2;
|
||||
private _anReservePercentage = GVAR(anReserve) / AN_MAXRESERVE;
|
||||
private _perceivedFatigue = 1 - (_anReservePercentage min _aeReservePercentage);
|
||||
// Respiratory rate decrease
|
||||
GVAR(respiratoryRate) = GVAR(respiratoryRate) * GVAR(respiratoryBufferDivisor);
|
||||
|
||||
[ACE_player, _perceivedFatigue, _currentSpeed, GVAR(anReserve) == 0] call FUNC(handleEffects);
|
||||
// Respiratory rate increase
|
||||
private _aePowerRatio = (GVAR(aePathwayPower) / _aePathwayPowerFatigued) min 2;
|
||||
private _respiratorySampleDivisor = 1 / (RESPIRATORY_BUFFER * 4.72 * GVAR(VO2Max));
|
||||
GVAR(respiratoryRate) = (GVAR(respiratoryRate) + _currentWork * _respiratorySampleDivisor * _aePowerRatio) min 1;
|
||||
|
||||
// Calculate a pseudo-perceived fatigue, which is used for effects
|
||||
GVAR(aeReservePercentage) = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2;
|
||||
GVAR(anReservePercentage) = GVAR(anReserve) / AN_MAXRESERVE;
|
||||
private _perceivedFatigue = 1 - (GVAR(anReservePercentage) min GVAR(aeReservePercentage));
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
systemChat format ["---- muscleDamage: %1 ----", GVAR(muscleDamage) toFixed 8];
|
||||
systemChat format ["---- ae2: %1 - an: %2 ----", (GVAR(ae2Reserve) / AE2_MAXRESERVE) toFixed 2, (GVAR(anReserve) / AN_MAXRESERVE) toFixed 2];
|
||||
systemChat format ["---- anFatigue: %1 - perceivedFatigue: %2 ----", GVAR(anFatigue) toFixed 2, _perceivedFatigue toFixed 2];
|
||||
systemChat format ["---- velocity %1 - respiratoryRate: %2 ----", (vectorMagnitude _velocity) toFixed 2, GVAR(respiratoryRate) toFixed 2];
|
||||
// systemChat format ["---- aePower: %1 ----", _aePathwayPowerFatigued toFixed 1];
|
||||
#endif
|
||||
|
||||
[ACE_player, _perceivedFatigue, GVAR(anReserve) == 0, _fwdAngle, _sideAngle] call FUNC(handleEffects);
|
||||
|
||||
if (GVAR(enableStaminaBar)) then {
|
||||
[GVAR(anReserve) / AN_MAXRESERVE] call FUNC(handleStaminaBar);
|
||||
};
|
||||
|
||||
[FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute;
|
||||
[LINKFUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Initializes the module settings.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Removes a duty factor.
|
||||
|
40
addons/advanced_fatigue/functions/fnc_renderDebugLines.sqf
Normal file
40
addons/advanced_fatigue/functions/fnc_renderDebugLines.sqf
Normal file
@ -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]];
|
||||
}];
|
@ -1 +0,0 @@
|
||||
#include "\z\ace\addons\advanced_fatigue\script_component.hpp"
|
92
addons/advanced_fatigue/initSettings.inc.sqf
Normal file
92
addons/advanced_fatigue/initSettings.inc.sqf
Normal file
@ -0,0 +1,92 @@
|
||||
[
|
||||
QGVAR(enabled),
|
||||
"CHECKBOX",
|
||||
[LSTRING(Enabled), LSTRING(Enabled_Description)],
|
||||
LSTRING(DisplayName),
|
||||
true,
|
||||
1,
|
||||
{
|
||||
if (!_this) then {
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlSetFade 1;
|
||||
_staminaBarContainer ctrlCommit 0;
|
||||
};
|
||||
|
||||
[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)
|
||||
},
|
||||
true // Needs mission restart
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(enableStaminaBar),
|
||||
"CHECKBOX",
|
||||
[LSTRING(EnableStaminaBar), LSTRING(EnableStaminaBar_Description)],
|
||||
LSTRING(DisplayName),
|
||||
true,
|
||||
1,
|
||||
{
|
||||
if (!_this) then {
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlSetFade 1;
|
||||
_staminaBarContainer ctrlCommit 0;
|
||||
};
|
||||
}
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(fadeStaminaBar),
|
||||
"CHECKBOX",
|
||||
[LSTRING(FadeStaminaBar), LSTRING(FadeStaminaBar_Description)],
|
||||
LSTRING(DisplayName),
|
||||
true,
|
||||
0,
|
||||
{
|
||||
if (!_this && GVAR(enabled) && GVAR(enableStaminaBar)) then {
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlSetFade 0;
|
||||
_staminaBarContainer ctrlCommit 0;
|
||||
};
|
||||
}
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(performanceFactor),
|
||||
"SLIDER",
|
||||
[LSTRING(PerformanceFactor), LSTRING(PerformanceFactor_Description)],
|
||||
LSTRING(DisplayName),
|
||||
[0, 10, 1, 2],
|
||||
1,
|
||||
{
|
||||
// Recalculate values if the setting is changed mid-mission
|
||||
if (GVAR(enabled) && hasInterface && !isNull ACE_player) then {
|
||||
[ACE_player, ACE_player] call FUNC(handlePlayerChanged);
|
||||
};
|
||||
}
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(recoveryFactor),
|
||||
"SLIDER",
|
||||
[LSTRING(RecoveryFactor), LSTRING(RecoveryFactor_Description)],
|
||||
LSTRING(DisplayName),
|
||||
[0, 10, 1, 2],
|
||||
1
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(loadFactor),
|
||||
"SLIDER",
|
||||
[LSTRING(LoadFactor), LSTRING(LoadFactor_Description)],
|
||||
LSTRING(DisplayName),
|
||||
[0, 5, 1, 2],
|
||||
1
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(terrainGradientFactor),
|
||||
"SLIDER",
|
||||
[LSTRING(TerrainGradientFactor), LSTRING(TerrainGradientFactor_Description)],
|
||||
LSTRING(DisplayName),
|
||||
[0, 5, 1, 2],
|
||||
1
|
||||
] call CBA_fnc_addSetting;
|
@ -1,91 +0,0 @@
|
||||
[
|
||||
QGVAR(enabled),
|
||||
"CHECKBOX",
|
||||
[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;
|
||||
};
|
||||
[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)
|
||||
},
|
||||
true // Needs mission restart
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(enableStaminaBar),
|
||||
"CHECKBOX",
|
||||
[LSTRING(EnableStaminaBar), LSTRING(EnableStaminaBar_Description)],
|
||||
LSTRING(DisplayName),
|
||||
true,
|
||||
true, {
|
||||
if (!_this) then {
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlSetFade 1;
|
||||
_staminaBarContainer ctrlCommit 0;
|
||||
};
|
||||
}
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(fadeStaminaBar),
|
||||
"CHECKBOX",
|
||||
[LSTRING(FadeStaminaBar), LSTRING(FadeStaminaBar_Description)],
|
||||
LSTRING(DisplayName),
|
||||
true,
|
||||
false, {
|
||||
if (!_this && GVAR(enabled) && GVAR(enableStaminaBar)) then {
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlSetFade 0;
|
||||
_staminaBarContainer ctrlCommit 0;
|
||||
};
|
||||
}
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(performanceFactor),
|
||||
"SLIDER",
|
||||
[LSTRING(PerformanceFactor), LSTRING(PerformanceFactor_Description)],
|
||||
LSTRING(DisplayName),
|
||||
[0, 5, 1, 1],
|
||||
true
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(recoveryFactor),
|
||||
"SLIDER",
|
||||
[LSTRING(RecoveryFactor), LSTRING(RecoveryFactor_Description)],
|
||||
LSTRING(DisplayName),
|
||||
[0, 5, 1, 1],
|
||||
true
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(loadFactor),
|
||||
"SLIDER",
|
||||
[LSTRING(LoadFactor), LSTRING(LoadFactor_Description)],
|
||||
LSTRING(DisplayName),
|
||||
[0, 5, 1, 1],
|
||||
true
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(terrainGradientFactor),
|
||||
"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;
|
@ -16,14 +16,28 @@
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
|
||||
#define UNDERWEAR_WEIGHT 3.5
|
||||
|
||||
#define ANTPERCENT 0.8
|
||||
#define SIM_BODYMASS 70
|
||||
#define JOULES_PER_ML_O2 20.9
|
||||
#define VO2MAX_STRENGTH 4.1
|
||||
#define REE 18.83 //((0.5617 * SIM_BODYMASS + 42.57) * 0.23)
|
||||
#define OXYGEN 0.9
|
||||
#define WATTSPERATP 7
|
||||
#define BIOMECH_EFFICIENCY 0.23
|
||||
#define REE 18.83 // ((0.5617 * SIM_BODYMASS + 42.57) * BIOMECH_EFFICIENCY)
|
||||
|
||||
#define AE1_MAXRESERVE 4000000
|
||||
#define AE2_MAXRESERVE 84000
|
||||
#define AN_MAXRESERVE 2300
|
||||
#define RESPIRATORY_BUFFER 60
|
||||
|
||||
#define MUSCLE_TEAR_RATE 0.00004
|
||||
#define MUSCLE_RECOVERY 0.00000386
|
||||
|
||||
#define AE1_ATP_RELEASE_RATE 13.3 // mmol
|
||||
#define AE2_ATP_RELEASE_RATE 16.7 // mmol
|
||||
#define AN_ATP_RELEASE_RATE 113.3 // mmol
|
||||
|
||||
#define AE1_ATP_RECOVERY 6.60 // mmol
|
||||
#define AE2_ATP_RECOVERY 5.83 // mmol
|
||||
#define AN_ATP_RECOVERY 56.70 // mmol
|
||||
|
||||
#define AE1_MAXRESERVE 4000000 // mmol
|
||||
#define AE2_MAXRESERVE 84000 // mmol
|
||||
#define AN_MAXRESERVE 2300 // mmol
|
||||
|
@ -7,7 +7,7 @@
|
||||
<German>ACE Erweiterte Ausdauer</German>
|
||||
<Chinese>ACE 進階疲勞</Chinese>
|
||||
<Chinesesimp>ACE 进阶体力</Chinesesimp>
|
||||
<Japanese>ACE アドバンスド ファティーグ</Japanese>
|
||||
<Japanese>ACE アドバンスド疲労</Japanese>
|
||||
<Italian>ACE Fatica Avanzata</Italian>
|
||||
<Korean>ACE 고급 피로도</Korean>
|
||||
<French>ACE Fatigue avancée</French>
|
||||
@ -41,10 +41,10 @@
|
||||
<Polish>Wpływa na ogólną wydolność organizmu u wszystkich graczy bez ustawionego niestandardowego współczynnika. Więcej znaczy lepiej.</Polish>
|
||||
<Korean>모든 성능이 임의로 설정된 값 없이 영향받습니다. 값이 클수록 더 나은 성능을 발휘합니다</Korean>
|
||||
<French>Impacte la performance globale de tous les joueurs n'ayant pas de facteur personnalisé.\nPlus la valeur est élevée, plus le joueur est performant.</French>
|
||||
<Italian>Influenza qualsiasi prestazione di tutti i giocatori smuniti di un fattore personalizzato. Maggiore significa migliore.</Italian>
|
||||
<Italian>Influenza la prestazione generale di tutti i giocatori smuniti di un fattore personalizzato. Maggiore significa migliore.</Italian>
|
||||
<Chinese>影響所有玩家的體力表現,值越高代表體力越好</Chinese>
|
||||
<Chinesesimp>影响所有玩家的体力表现,值越高代表体力越好</Chinesesimp>
|
||||
<Russian>Влияет на общую производительность игроков, у которых не задано персональное значение.</Russian>
|
||||
<Russian>Влияет на общую производительность игроков, у которых не задано персональное значение. Чем выше, тем лучше.</Russian>
|
||||
<Portuguese>Influencia na performance geral de todos os jogadores sem nenhum fator personalizado. Quanto maior, melhor.</Portuguese>
|
||||
<Czech>Ovlivňuje celkový výkon všech hráčů bez vlastního faktoru. Vyšší znamená lépe.</Czech>
|
||||
</Key>
|
||||
@ -56,10 +56,10 @@
|
||||
<Polish>Wpływa na ogólną wydolność tej jednostki. Więcej znaczy lepiej.</Polish>
|
||||
<Korean>모든 성능이 이 단위로 영향을 받습니다. 값이 클수록 더 나은 성능을 발휘합니다</Korean>
|
||||
<French>Impacte la performance globale de cette unité.\nPlus la valeur est élevée, plus l'unité est performante.</French>
|
||||
<Italian>Influenza qualsiasi prestazione di questa unità. Maggiore significa migliore.</Italian>
|
||||
<Italian>Influenza la prestazione personalizzata di questa unità. Maggiore significa migliore.</Italian>
|
||||
<Chinese>影響這個單位的體力表現,值越高代表體力越好</Chinese>
|
||||
<Chinesesimp>影响这个单位的体力表现,值越高代表体力越好</Chinesesimp>
|
||||
<Russian>Влияет на общую производительность юнита.</Russian>
|
||||
<Russian>Влияет на общую производительность юнита.Чем выше, тем лучше.</Russian>
|
||||
<Portuguese>Influencia na performance geral dessa unidade. Quanto maior, melhor.</Portuguese>
|
||||
<Czech>Ovlivňuje celkový výkon této jednotky. Vyšší znamená lépe.</Czech>
|
||||
</Key>
|
||||
@ -87,7 +87,7 @@
|
||||
<Polish>Wpływa na czas regeneracji podczas postoju. Więcej znaczy szybciej.</Polish>
|
||||
<Korean>얼마나 빨리 회복하는지를 바꿉니다. 값이 클수록 더 나은 성능을 발휘합니다</Korean>
|
||||
<French>Modifie la vitesse à laquelle le joueur récupère lorsqu'il se repose.\nPlus la valeur est élevée, plus la récupération est rapide.</French>
|
||||
<Italian>Determina in quanto tempo il giocatore recupera quando rilassato. Maggiore significa migliore.</Italian>
|
||||
<Italian>Determina quanto velocemente il giocatore recupera le energie quando si ferma. Maggiore significa migliore.</Italian>
|
||||
<Chinese>決定玩家休息多久就能回復體力,值越高恢復越快</Chinese>
|
||||
<Chinesesimp>决定玩家休息多久就能恢复体力,值越高恢复越快</Chinesesimp>
|
||||
<Russian>Изменяет скорость восстановления игрока во время отдыха. Чем выше, тем быстрее.</Russian>
|
||||
@ -102,7 +102,7 @@
|
||||
<Polish>Współczynnik masy ekwipunku</Polish>
|
||||
<Korean>부담 요인</Korean>
|
||||
<French>Facteur de charge</French>
|
||||
<Italian>Fattore Caricamento</Italian>
|
||||
<Italian>Fattore Carico</Italian>
|
||||
<Chinese>負重量</Chinese>
|
||||
<Chinesesimp>重量系数</Chinesesimp>
|
||||
<Russian>Фактор нагрузки</Russian>
|
||||
@ -117,7 +117,7 @@
|
||||
<Polish>Zmniejsza lub zwiększa wpływ ciężaru ekwipunku na wydolność gracza. Zero oznacza kompletny brak wpływu na wydolność.</Polish>
|
||||
<Korean>플레이어가 무게에 따라 얼마나 영향받는지를 증가시키거나 감소시킵니다. 0의 경우 플레이어가 장비 무게에 영향받지 않습니다.</Korean>
|
||||
<French>Augmente ou diminue l'influence du poids sur les performances du joueur.\nUne valeur nulle indique que le poids de l'équipement n'a aucun impact sur les performances.</French>
|
||||
<Italian>Incrementa o decrementa quanto il peso influenza le prestazioni dei giocatori. Zero significa che il peso dell'equipaggiamento non ha alcuna influenza nelle prestazioni.</Italian>
|
||||
<Italian>Determina quanto il peso trasportato influenza le prestazioni dei giocatori. Zero significa che il peso dell'equipaggiamento non influisce sulle prestazioni.</Italian>
|
||||
<Chinese>增加或降低玩家所能承受的負重量. 如設定值為0, 代表裝備的重量將不會影響到玩家的體力表現</Chinese>
|
||||
<Chinesesimp>增加或降低玩家所能承受的负重量。如设定值为0,代表装备的重量将不会影响到玩家的体力表现</Chinesesimp>
|
||||
<Russian>Увеличивает или уменьшает вес, влияющий на производительность игроков. Ноль означает, что вес снаряжения не влияет на производительность</Russian>
|
||||
@ -147,52 +147,22 @@
|
||||
<Polish>Wpływa na to w jakim stopniu stromy teren wpływa na utratę wytrzymałości. Więcej oznacza szybszą utratę wytrzymałości.</Polish>
|
||||
<Korean>경사도에 따라 얼마나 피로해지는지를 정합니다. 값이 클수록 더 많은 피로를 유발합니다.</Korean>
|
||||
<French>Définit à quel point un terrain escarpé réduit l'endurance du joueur.\nPlus la valeur est élevée, moins le joueur est endurant.</French>
|
||||
<Italian>Stabilisce quanto la pendenza del terreno incrementa la perdita della stamina. Maggiore significa più stamina persa.</Italian>
|
||||
<Italian>Determina quanto la pendenza del terreno incrementa la perdita della stamina. Maggiore significa più stamina persa.</Italian>
|
||||
<Chinese>設定陡峭的地形將會影響多少體力的流失,值越高代表體力流失越快</Chinese>
|
||||
<Chinesesimp>设定陡峭的地形将会影响多少体力的流失速度,值越高代表体力流失越快</Chinesesimp>
|
||||
<Russian>Устанавливает, насколько крутая местность увеличивает потерю выносливости. Чем выше, тем быстрее теряется выносливость.</Russian>
|
||||
<Portuguese>Define o quanto que um terreno íngrime aumenta na perda de estamina. Quanto maior, maior a perda de estamina.</Portuguese>
|
||||
<Czech>Nastavuje, o kolik strmý terén zvyšuje ztrátu výdrže. Vyšší znamená vyšší ztrátu výdrže.</Czech>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_SwayFactor">
|
||||
<English>Sway factor</English>
|
||||
<Spanish>Factor de balanceo de mira</Spanish>
|
||||
<German>Verwacklungsfaktor</German>
|
||||
<Japanese>手ぶれ因数</Japanese>
|
||||
<Chinesesimp>抖动系数</Chinesesimp>
|
||||
<Chinese>抖動因素</Chinese>
|
||||
<French>Facteur de tremblement</French>
|
||||
<Italian>Fattore di oscillazione</Italian>
|
||||
<Polish>Czynnik kołysania</Polish>
|
||||
<Russian>Фактор колебания прицела</Russian>
|
||||
<Portuguese>Fator de Balanço de Mira</Portuguese>
|
||||
<Czech>Faktor kývání</Czech>
|
||||
<Korean>손떨림 정도</Korean>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_SwayFactor_Description">
|
||||
<English>Influences the amount of weapon sway. Higher means more sway.</English>
|
||||
<Spanish>Afecta al la estabilidad de la mira. Más alto significa más balanceo</Spanish>
|
||||
<German>Beeinflusst den Faktor, wie ruhig man eine Waffe halten kann. Ein höherer Wert bedeutet weniger Stabilisierung</German>
|
||||
<Japanese>武器を持つ手のぶれ度合いを設定します。 値が高ければ高いほど、手ぶれが強くなります。</Japanese>
|
||||
<Chinesesimp>影响手持武器的晃动程度,数值越高,抖动的越厉害。</Chinesesimp>
|
||||
<Chinese>影響手持武器晃動程度,數值越高抖動越厲害</Chinese>
|
||||
<French>Influe sur l'amplitude du tremblement de l'arme. Une valeur plus élevée signifie plus de tremblement.</French>
|
||||
<Italian>Influenza l'ammontare di oscillazione dell'arma. Maggiore significa più oscillazione.</Italian>
|
||||
<Polish>Wpływa na poziom kołysania broni. Większa ilość znaczy większe kołysanie.</Polish>
|
||||
<Russian>Влияет на колебания прицела оружия. Чем выше - тем больше.</Russian>
|
||||
<Portuguese>Influencia a quantidade de balanço da mira da arma. Quanto maior, mais balanço.</Portuguese>
|
||||
<Czech>Ovlivňuje množství kývání zbraní. Vyšší znamená více kývání.</Czech>
|
||||
<Korean>손떨림의 정도를 정합니다. 높을 수록 많이 휘적입니다.</Korean>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_Enabled">
|
||||
<English>Enabled</English>
|
||||
<Spanish>Activada</Spanish>
|
||||
<German>Aktiv</German>
|
||||
<Japanese>アドバンスド ファティーグを有効化</Japanese>
|
||||
<Japanese>有効化</Japanese>
|
||||
<Polish>Włączone</Polish>
|
||||
<Korean>활성화</Korean>
|
||||
<French>Activé</French>
|
||||
<Italian>Abilitato</Italian>
|
||||
<Italian>Abilitata</Italian>
|
||||
<Chinese>啟用</Chinese>
|
||||
<Chinesesimp>启用</Chinesesimp>
|
||||
<Russian>Включена</Russian>
|
||||
@ -203,14 +173,14 @@
|
||||
<English>Enables/disables Advanced Fatigue.</English>
|
||||
<Spanish>Activa/desactiva la fatiga avanzada</Spanish>
|
||||
<German>Aktiviert/deaktiviert Advanced Fatigue.</German>
|
||||
<Japanese>アドバンスド ファティーグを有効化します。</Japanese>
|
||||
<Japanese>アドバンスド疲労は高度な疲労管理システムを有効化します。</Japanese>
|
||||
<Polish>Włącza/wyłącza zaawansowaną wytrzymałość</Polish>
|
||||
<Korean>고급 피로도 활성화/비활성화</Korean>
|
||||
<French>Active/Désactive la fatigue avancée.</French>
|
||||
<Italian>Abilita/disabilita la Fatica Avanzata.</Italian>
|
||||
<Italian>Abilita/Disabilita la Fatica Avanzata.</Italian>
|
||||
<Chinese>啟用/關閉進階體力.</Chinese>
|
||||
<Chinesesimp>启用/关闭进阶体力。</Chinesesimp>
|
||||
<Russian>Включает / Отключает Продвинутую усталость</Russian>
|
||||
<Russian>Включает/отключает Продвинутую усталость</Russian>
|
||||
<Portuguese>Ativa/Desativa Fadiga Avançada.</Portuguese>
|
||||
<Czech>Aktivuje / deaktivuje Pokročilou únavu.</Czech>
|
||||
</Key>
|
||||
@ -251,7 +221,7 @@
|
||||
<German>Blende Ausdauerleiste automatisch aus</German>
|
||||
<Chinese>體力條自動淡去</Chinese>
|
||||
<Chinesesimp>自动淡化体力条</Chinesesimp>
|
||||
<Italian>Dissolvenza automatica della barra della stamina</Italian>
|
||||
<Italian>Nascondi in automatico la barra della stamina</Italian>
|
||||
<Czech>Automaticky schovat lištu výdrže</Czech>
|
||||
<French>Fondu automatique de la barre d'endurance</French>
|
||||
<Japanese>自動的にスタミナバーを非表示</Japanese>
|
||||
|
@ -1,26 +1,19 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
// Fired XEH
|
||||
[QGVAR(throwFiredXEH), FUNC(throwFiredXEH)] call CBA_fnc_addEventHandler;
|
||||
GVAR(ammoEventHandlers) = createHashMap;
|
||||
[QGVAR(throwFiredXEH), LINKFUNC(throwFiredXEH)] call CBA_fnc_addEventHandler;
|
||||
|
||||
// Exit on HC
|
||||
if (!hasInterface) exitWith {};
|
||||
|
||||
// Ammo/Magazines look-up hash for correctness of initSpeed
|
||||
GVAR(ammoMagLookup) = call CBA_fnc_createNamespace;
|
||||
{
|
||||
{
|
||||
private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo");
|
||||
if (_ammo != "") then { GVAR(ammoMagLookup) setVariable [_ammo, _x]; };
|
||||
} count (getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines"));
|
||||
nil
|
||||
} count getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles");
|
||||
|
||||
// Temporary Wind Info indication
|
||||
GVAR(tempWindInfo) = false;
|
||||
|
||||
// Add keybinds
|
||||
["ACE3 Weapons", QGVAR(prepare), localize LSTRING(Prepare), {
|
||||
// Condition
|
||||
if (!([ACE_player] call FUNC(canPrepare))) exitWith {false};
|
||||
if !([ACE_player] call FUNC(canPrepare)) exitWith {false};
|
||||
if (EGVAR(common,isReloading)) exitWith {true};
|
||||
|
||||
// Statement
|
||||
|
@ -6,6 +6,6 @@ PREP_RECOMPILE_START;
|
||||
#include "XEH_PREP.hpp"
|
||||
PREP_RECOMPILE_END;
|
||||
|
||||
#include "initSettings.sqf"
|
||||
#include "initSettings.inc.sqf"
|
||||
|
||||
ADDON = true;
|
||||
|
@ -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];
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Checks if a throwable can be prepared.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Checks if a throwable can be thrown.
|
||||
@ -19,7 +19,7 @@ params ["_unit"];
|
||||
|
||||
if !(_unit getVariable [QGVAR(inHand), false]) exitWith {false};
|
||||
|
||||
if (vehicle _unit != _unit) exitWith {
|
||||
if (!isNull objectParent _unit) exitWith {
|
||||
private _startPos = eyePos _unit;
|
||||
private _aimLinePos = AGLToASL (positionCameraToWorld [0, 0, 1]);
|
||||
private _intersections = lineIntersectsSurfaces [_startPos, _aimLinePos, _unit, objNull, false];
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Zapat, Dslyecxi, Jonpas
|
||||
* Draws throw arc.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas, SilentSpike
|
||||
* Author: Dslyecxi, Jonpas, kymckay
|
||||
* Handles drawing the currently selected or cooked throwable.
|
||||
*
|
||||
* Arguments:
|
||||
@ -43,13 +43,10 @@ if ((!_primed) && {!((_throwableMag in (uniformItems ACE_player)) || {_throwable
|
||||
|
||||
// Get correct throw power for primed grenade
|
||||
if (_primed) then {
|
||||
private _ammoType = typeOf _activeThrowable;
|
||||
_throwableMag = GVAR(ammoMagLookup) getVariable _ammoType;
|
||||
if (isNil "_throwableMag") then {
|
||||
// What we're trying to throw must not be a normal throwable because it is not in our lookup hash (e.g. 40mm smoke)
|
||||
// Just use HandGrenade as it has an average initSpeed value
|
||||
_throwableMag = "HandGrenade";
|
||||
};
|
||||
// If ammo type is not found:
|
||||
// What we're trying to throw must not be a normal throwable because it is not in our lookup hash (e.g. 40mm smoke)
|
||||
// Just use HandGrenade as it has an average initSpeed value
|
||||
_throwableMag = (uiNamespace getVariable QGVAR(ammoMagLookup)) getOrDefault [typeOf _activeThrowable, "HandGrenade"];
|
||||
};
|
||||
|
||||
// Some throwables have different classname for magazine and ammo
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas
|
||||
* Exits throw mode.
|
||||
@ -53,6 +53,12 @@ _unit setVariable [QGVAR(dropDistance), DROP_DISTANCE_DEFAULT];
|
||||
// Remove controls hint (check if ever enabled is inside the function)
|
||||
call EFUNC(interaction,hideMouseHint);
|
||||
|
||||
// Hide wind info after throw, if it was temporarily enabled for the throw
|
||||
if (GVAR(tempWindInfo)) then {
|
||||
EGVAR(weather,WindInfo) = false;
|
||||
GVAR(tempWindInfo) = false;
|
||||
};
|
||||
|
||||
// Remove throw action
|
||||
[_unit, "DefaultAction", _unit getVariable [QGVAR(throwAction), -1]] call EFUNC(common,removeActionEventHandler);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Retrieve muzzle name from config.
|
||||
@ -17,9 +17,9 @@
|
||||
|
||||
params ["_magazineClassname"];
|
||||
|
||||
_magazineClassname = toLower _magazineClassname;
|
||||
_magazineClassname = toLowerANSI _magazineClassname;
|
||||
private _throwMuzzles = getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles");
|
||||
|
||||
_throwMuzzles = _throwMuzzles select {_magazineClassname in ((getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")) apply {toLower _x})};
|
||||
_throwMuzzles = _throwMuzzles select {_magazineClassname in ((getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")) apply {toLowerANSI _x})};
|
||||
|
||||
[_throwMuzzles select 0, ""] select (_throwMuzzles isEqualTo [])
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Initializes the Advanced Throwing module.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas
|
||||
* Key down event.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas
|
||||
* Mouse button down event.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas
|
||||
* Mouse scroll wheel changed event.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Picks up a throwable from the ground.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas
|
||||
* Prepares throwable or selects the next.
|
||||
@ -21,7 +21,7 @@ TRACE_1("params",_unit);
|
||||
// Select next throwable if one already in hand
|
||||
if (_unit getVariable [QGVAR(inHand), false]) exitWith {
|
||||
TRACE_1("inHand",_unit);
|
||||
if (!(_unit getVariable [QGVAR(primed), false])) then {
|
||||
if !(_unit getVariable [QGVAR(primed), false]) then {
|
||||
TRACE_1("not primed",_unit);
|
||||
// Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory)
|
||||
// selectNextGrenade relies on muzzles array (setAmmo 0 removes the muzzle from the array and current can't be found, cycles between 0 and 1 muzzles)
|
||||
@ -35,6 +35,11 @@ if (isNull (_unit getVariable [QGVAR(activeThrowable), objNull]) && {(currentThr
|
||||
TRACE_1("no throwables",_unit);
|
||||
};
|
||||
|
||||
// Temporarily enable wind info, to aid in throwing smoke grenades effectively
|
||||
if (GVAR(enableTempWindInfo) && {!(missionNamespace getVariable [QEGVAR(weather,WindInfo), false])}) then {
|
||||
[] call EFUNC(weather,displayWindInfo);
|
||||
GVAR(tempWindInfo) = true;
|
||||
};
|
||||
|
||||
_unit setVariable [QGVAR(inHand), true];
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas
|
||||
* Primes the throwable, creates global throwable vehicle and throws Fired XEH.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: PabstMirror, Jonpas
|
||||
* When interact_menu starts rendering (from "interact_keyDown" event).
|
||||
@ -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;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas
|
||||
* Throw selected throwable.
|
||||
@ -20,7 +20,7 @@ TRACE_1("params",_unit);
|
||||
|
||||
// Prime the throwable if it hasn't been cooking already
|
||||
// Next to proper simulation this also has to happen before delay for orientation of the throwable to be set
|
||||
if (!(_unit getVariable [QGVAR(primed), false])) then {
|
||||
if !(_unit getVariable [QGVAR(primed), false]) then {
|
||||
[_unit] call FUNC(prime);
|
||||
};
|
||||
|
||||
@ -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));
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: CBA Team
|
||||
* Throws Fired XEH.
|
||||
@ -20,14 +20,25 @@
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_unit", "", "_muzzle", "", "_ammo"];
|
||||
TRACE_1("Fired",_this);
|
||||
|
||||
{
|
||||
_this call _x;
|
||||
} forEach ((_this select 0) getVariable "cba_xeh_fired");
|
||||
} forEach (_unit getVariable "cba_xeh_fired");
|
||||
|
||||
// Call muzzle fired EH
|
||||
{
|
||||
_this call compile getText (_x >> "fired");
|
||||
} forEach (configProperties [configFile >> "CfgWeapons" >> "Throw" >> (_this select 2) >> "EventHandlers", "isClass _x", true]);
|
||||
} forEach (configProperties [configFile >> "CfgWeapons" >> "Throw" >> _muzzle >> "EventHandlers", "isClass _x", true]);
|
||||
|
||||
// Call ammo fired EH
|
||||
{ _this call _x } forEach (GVAR(ammoEventHandlers) getOrDefaultCall [_ammo, {
|
||||
private _cfg = configFile >> "CfgAmmo" >> _ammo >> "EventHandlers";
|
||||
private _eventHandlers = [];
|
||||
{
|
||||
private _eh = getText (_x >> "fired");
|
||||
if (_eh != "") then { _eventHandlers pushBack compile _eh };
|
||||
} forEach ([_cfg] + configProperties [_cfg, "isClass _x", true]);
|
||||
_eventHandlers
|
||||
}, true]);
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Updates controls hints based on current state.
|
||||
|
@ -1 +0,0 @@
|
||||
#include "\z\ace\addons\advanced_throwing\script_component.hpp"
|
50
addons/advanced_throwing/initSettings.inc.sqf
Normal file
50
addons/advanced_throwing/initSettings.inc.sqf
Normal file
@ -0,0 +1,50 @@
|
||||
private _category = format ["ACE %1", localize LSTRING(Category)];
|
||||
[
|
||||
QGVAR(enabled),
|
||||
"CHECKBOX",
|
||||
[LSTRING(Enable_DisplayName), LSTRING(Enable_Description)],
|
||||
_category,
|
||||
true,
|
||||
0
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(showThrowArc),
|
||||
"CHECKBOX",
|
||||
[LSTRING(ShowThrowArc_DisplayName), LSTRING(ShowThrowArc_Description)],
|
||||
_category,
|
||||
true,
|
||||
0
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(showMouseControls), "CHECKBOX",
|
||||
[LSTRING(ShowMouseControls_DisplayName), LSTRING(ShowMouseControls_Description)],
|
||||
_category,
|
||||
true,
|
||||
0
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(enablePickUp), "CHECKBOX",
|
||||
[LSTRING(EnablePickUp_DisplayName), LSTRING(EnablePickUp_Description)],
|
||||
_category,
|
||||
true,
|
||||
1
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(enablePickUpAttached), "CHECKBOX",
|
||||
[LSTRING(EnablePickUpAttached_DisplayName), LSTRING(EnablePickUpAttached_Description)],
|
||||
_category,
|
||||
true,
|
||||
1
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(enableTempWindInfo), "CHECKBOX",
|
||||
[LSTRING(EnableTempWindInfo_DisplayName), LSTRING(EnableTempWindInfo_Description)],
|
||||
_category,
|
||||
true,
|
||||
0
|
||||
] call CBA_fnc_addSetting;
|
@ -1,42 +0,0 @@
|
||||
private _category = format ["ACE %1", localize LSTRING(Category)];
|
||||
[
|
||||
QGVAR(enabled),
|
||||
"CHECKBOX",
|
||||
[LSTRING(Enable_DisplayName), LSTRING(Enable_Description)],
|
||||
_category,
|
||||
true,
|
||||
0
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(showThrowArc),
|
||||
"CHECKBOX",
|
||||
[LSTRING(ShowThrowArc_DisplayName), LSTRING(ShowThrowArc_Description)],
|
||||
_category,
|
||||
true,
|
||||
0
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(showMouseControls), "CHECKBOX",
|
||||
[LSTRING(ShowMouseControls_DisplayName), LSTRING(ShowMouseControls_Description)],
|
||||
_category,
|
||||
true,
|
||||
0
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(enablePickUp), "CHECKBOX",
|
||||
[LSTRING(EnablePickUp_DisplayName), LSTRING(EnablePickUp_Description)],
|
||||
_category,
|
||||
true,
|
||||
1
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(enablePickUpAttached), "CHECKBOX",
|
||||
[LSTRING(EnablePickUpAttached_DisplayName), LSTRING(EnablePickUpAttached_Description)],
|
||||
_category,
|
||||
true,
|
||||
1
|
||||
] call CBA_fnc_addSetting;
|
@ -5,7 +5,7 @@
|
||||
<English>Advanced Throwing</English>
|
||||
<Spanish>Lanzamiento Avanzado</Spanish>
|
||||
<Russian>Улучшенный бросок гранат</Russian>
|
||||
<Japanese>アドバンスド スローイング</Japanese>
|
||||
<Japanese>アドバンスド投擲</Japanese>
|
||||
<Polish>Zaawansowane rzucanie</Polish>
|
||||
<German>Erweitertes Wurfsystem</German>
|
||||
<Korean>고급 투척</Korean>
|
||||
@ -21,7 +21,7 @@
|
||||
<English>Allows changing advanced throwing behaviour.</English>
|
||||
<Spanish>Permite modificar el comportamiento del lanzamiento avanzado</Spanish>
|
||||
<Russian>Позволяет настраивать поведение улучшенного броска гранат.</Russian>
|
||||
<Japanese>アドバンスド スローイングの動作挙動を変更します。</Japanese>
|
||||
<Japanese>アドバンスド投擲は投擲の高度な動作挙動を変更可能にします。</Japanese>
|
||||
<Polish>Zezwala na zmianę zachowania zaawansowanego trybu rzucania.</Polish>
|
||||
<German>Erlaubt es, das Verhalten des erweiterten Wurfsystems zu ändern.</German>
|
||||
<Korean>고급 투척 행위를 허가합니다</Korean>
|
||||
@ -36,7 +36,7 @@
|
||||
<English>Enable Advanced Throwing</English>
|
||||
<Spanish>Activar Lanzamiento Avanzado</Spanish>
|
||||
<Russian>Вкл. улучшенный бросок</Russian>
|
||||
<Japanese>アドバンスド スローイングを有効化</Japanese>
|
||||
<Japanese>アドバンスド投擲を有効化</Japanese>
|
||||
<Polish>Aktywuj zaawansowane rzucanie</Polish>
|
||||
<German>Aktiviere erweitertes Wurfsystem</German>
|
||||
<Korean>고급 투척 활성화 </Korean>
|
||||
@ -52,7 +52,7 @@
|
||||
<English>Enables advanced throwing system.</English>
|
||||
<Spanish>Activa el Lanzamiento Avanzado</Spanish>
|
||||
<Russian>Включает систему улучшенного броска.</Russian>
|
||||
<Japanese>アドバンスド スローイングを有効化します。</Japanese>
|
||||
<Japanese>アドバンスド投擲は高度な投擲システムを有効化します。</Japanese>
|
||||
<Polish>Aktywuje system zaawansowanego rzucania.</Polish>
|
||||
<German>Aktiviert das erweiterte Wurfsystem.</German>
|
||||
<Korean>고급 투척을 활성화 합니다</Korean>
|
||||
@ -68,7 +68,7 @@
|
||||
<English>Show Throw Arc</English>
|
||||
<Spanish>Mostrar Arco de Lanzamiento</Spanish>
|
||||
<Russian>Показать траекторию броска</Russian>
|
||||
<Japanese>投てき軌道を表示</Japanese>
|
||||
<Japanese>投擲軌道を表示</Japanese>
|
||||
<Polish>Pokaż trasę lotu</Polish>
|
||||
<German>Zeige Wurfbogen</German>
|
||||
<Korean>투척 궤적 표시</Korean>
|
||||
@ -84,7 +84,7 @@
|
||||
<English>Enables visualization of the throw arc (where throwable will fly).</English>
|
||||
<Spanish>Activa la visualización del arco de lanzamiento (donde irá el objeto lanzado)</Spanish>
|
||||
<Russian>Включает визуализацию траектории броска (как полетит граната).</Russian>
|
||||
<Japanese>投てき軌道 (投てき物がどこに飛ぶか) の表示を有効化します。</Japanese>
|
||||
<Japanese>投擲軌道 (投擲物がどこに飛ぶか) の表示を有効化します。</Japanese>
|
||||
<Polish>Wyświetla wizualizację trasy przelotu granatu.</Polish>
|
||||
<German>Aktiviert die Visualisierung des Wurfbogens (wohin das Objekt geworfen werden wird).</German>
|
||||
<Korean>투척 궤도를 시각화 합니다(투척물이 어디로 갈지)</Korean>
|
||||
@ -99,12 +99,12 @@
|
||||
<English>Show Throwing Mouse Controls</English>
|
||||
<Spanish>Mostrar controles de ratón de lanzamiento</Spanish>
|
||||
<Russian>Показывать управление мышью</Russian>
|
||||
<Japanese>投てきのマウス操作を表示</Japanese>
|
||||
<Japanese>投擲のマウス操作を表示</Japanese>
|
||||
<Polish>Pokaż podpowiedzi sterowania myszą</Polish>
|
||||
<German>Zeige Maussteuerung beim Werfen</German>
|
||||
<Korean>마우스 조작 표시</Korean>
|
||||
<French>Afficher les contrôles à la souris du lancé</French>
|
||||
<Italian>Mostra Comandi Mouse Lancio</Italian>
|
||||
<Italian>Mostra Comandi Mouse di Lancio</Italian>
|
||||
<Chinese>顯示滑鼠投擲控制提示</Chinese>
|
||||
<Chinesesimp>显示鼠标投掷控制提示</Chinesesimp>
|
||||
<Portuguese>Mostrar os controles de mouse para Arremesso</Portuguese>
|
||||
@ -114,7 +114,7 @@
|
||||
<English>Enables visual cues for mouse controls when throwable is prepared.</English>
|
||||
<Spanish>Activa muestras visuales para los controles del ratón cuando el objeto lanzable está preparado</Spanish>
|
||||
<Russian>Включает отображение подсказок по управлению мышью, когда граната подготовлена.</Russian>
|
||||
<Japanese>投てき物を構える時、マウス操作の説明表示を有効化します。</Japanese>
|
||||
<Japanese>投擲物を構える時、マウス操作の説明表示を有効化します。</Japanese>
|
||||
<Polish>Wyświetla podpowiedzi sterowania myszą kiedy obiekt miotany jest w ręku.</Polish>
|
||||
<German>Aktiviert visuelle Hinweise zur Maussteuerung, wenn ein Objekt zum Werfen vorbereitet wird.</German>
|
||||
<Korean>투척물을 준비시 마우스 조작을 시각화해서 보여줍니다</Korean>
|
||||
@ -129,12 +129,12 @@
|
||||
<English>Enable Throwables Pick Up</English>
|
||||
<Spanish>Habilitar recoger objetos lanzados</Spanish>
|
||||
<Russian>Вкл. подбор гранат</Russian>
|
||||
<Japanese>投てき物の拾い上げを有効化</Japanese>
|
||||
<Japanese>投擲物の拾い上げを有効化</Japanese>
|
||||
<Polish>Zezwól na podnoszenie obiektów miotanych</Polish>
|
||||
<German>Aktiviere Aufheben von Wurfobjekten</German>
|
||||
<Korean>투척물 줍기 활성화</Korean>
|
||||
<French>Permettre le ramassage d'objets lançables</French>
|
||||
<Italian>Abilita Raccogli Oggetti</Italian>
|
||||
<Italian>Abilita Raccolta Lanciabili</Italian>
|
||||
<Chinese>啟用可撿取地面投擲物</Chinese>
|
||||
<Chinesesimp>启用捡取地面投掷物</Chinesesimp>
|
||||
<Portuguese>Permitir pegar arremessáveis</Portuguese>
|
||||
@ -144,12 +144,12 @@
|
||||
<English>Enables ability to pick up throwables from the ground.</English>
|
||||
<Spanish>Activa la habilidad de coger objetos lanzados del suelo</Spanish>
|
||||
<Russian>Включает возможность подбирать гранаты с земли.</Russian>
|
||||
<Japanese>地面に落ちている投てき物を拾い上げる機能を有効化します。</Japanese>
|
||||
<Japanese>地面に落ちている投擲物を拾う機能を有効化します。</Japanese>
|
||||
<Polish>Umożliwia podnoszenie obiektów miotanych z ziemi.</Polish>
|
||||
<German>Aktiviert die Möglichkeit, geworfene Objekte wieder vom Boden aufzuheben.</German>
|
||||
<Korean>땅에 떨어진 투척물을 주울 수 있게 해줍니다.</Korean>
|
||||
<French>Active la possibilité de ramasser des objets lançables du sol.</French>
|
||||
<Italian>Abilita la possibilità di raccogliere un oggetto lanciabile da terra.</Italian>
|
||||
<Italian>Permette ai giocatori di raccogliere un oggetto lanciabile da terra.</Italian>
|
||||
<Chinese>啟用後, 可撿取地面上的投擲物</Chinese>
|
||||
<Chinesesimp>启用后,可捡取地面上的投掷物</Chinesesimp>
|
||||
<Portuguese>Permite que objetos arremessados sejam pegos do chão. (ACE Menu de Interação)</Portuguese>
|
||||
@ -159,12 +159,12 @@
|
||||
<English>Enable Attached Throwables Pick Up</English>
|
||||
<Spanish>Activar coger objetos lanzables que se enganchan</Spanish>
|
||||
<Russian>Вкл. подбор прикрепленных гранат</Russian>
|
||||
<Japanese>取り付けられた投てき物の拾い上げを有効化</Japanese>
|
||||
<Japanese>装着済の投擲物の拾い上げを有効化</Japanese>
|
||||
<Polish>Zezwól na podnoszenie przyczepionych obiektów miotanych</Polish>
|
||||
<German>Aktiviere erneute Aufnahme befestigter Wurfobjekte</German>
|
||||
<Korean>부착 투척물 줍기 활성화</Korean>
|
||||
<French>Activer le ramassage d'objets lançables attachés</French>
|
||||
<Italian>Abilita Raccogli Oggetti Lanciabili da altri Oggetti</Italian>
|
||||
<Italian>Abilita Raccolta Lanciabili Attaccati</Italian>
|
||||
<Chinese>啟用可撿取附著投擲物</Chinese>
|
||||
<Chinesesimp>启用捡取附着投掷物</Chinesesimp>
|
||||
<Portuguese>Permitir pegar arremessáveis fixados</Portuguese>
|
||||
@ -174,27 +174,47 @@
|
||||
<English>Enables ability to pick up throwables from attached objects.</English>
|
||||
<Spanish>Activa la habilidad de lanzar objetos enganchados</Spanish>
|
||||
<Russian>Включает возможность подбирать гранаты, прикрепленные к объектам.</Russian>
|
||||
<Japanese>取り付けられた投てき物を拾い上げる機能を有効化します。</Japanese>
|
||||
<Japanese>オブジェクトに装着された投擲物を拾う機能を有効化します。</Japanese>
|
||||
<Polish>Umożliwia podnoszenie obiektów miotanych przyczepionych do innych obiektów.</Polish>
|
||||
<German>Aktiviert die Möglichkeit, befestigte Wurfobjekte erneut aufzunehmen.</German>
|
||||
<Korean>부착된 투척물을 주울 수 있게 해줍니다.</Korean>
|
||||
<French>Active la possibilité de ramasser des objets lançables attachés à d'autres objets.</French>
|
||||
<Italian>Abilita la possibilità di raccogliere gli oggetti lanciabili dagli altri oggetti. </Italian>
|
||||
<Italian>Permette ai giocatori di raccogliere gli oggetti lanciabili da altri oggetti attaccati.</Italian>
|
||||
<Chinese>啟用後, 可撿取附著在物件上的投擲物</Chinese>
|
||||
<Chinesesimp>启用后,可捡取附着在物体上的投掷物</Chinesesimp>
|
||||
<Portuguese>Permite que arremessáveis fixados em objetos sejam pegos.</Portuguese>
|
||||
<Czech>Zapíná schopnost zvednutí předmětů z objektů ke kterým jsou připnuté.</Czech>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_EnableTempWindInfo_DisplayName">
|
||||
<English>Show Temporary Wind Info</English>
|
||||
<German>Zeige temporäre Windinformationen</German>
|
||||
<Italian>Mostra informazioni sul vento temporaneamente</Italian>
|
||||
<Japanese>一時的に風の情報を表示</Japanese>
|
||||
<Korean>바람 정보 임시로 표시</Korean>
|
||||
<French>Afficher temporairement les informations sur le vent</French>
|
||||
<Russian>Временно показать информацию о ветре</Russian>
|
||||
<Spanish>Mostrar información del viento temporalmente</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_EnableTempWindInfo_Description">
|
||||
<English>Temporarily display Wind Info while throwing, to aid in placing smoke grenades effectively.</English>
|
||||
<German>Zeige während des werfens Windinformationen an, um Rauchgranaten effektiver zu platzieren.</German>
|
||||
<Italian>Mostra le informazioni sul vento durante il lancio di granate, facilitando il piazzamento ottimale di fumogeni.</Italian>
|
||||
<Japanese>投擲行動中に風向きの情報を一時的に表示し、発煙手榴弾の煙幕を効果的に展開しやすくします。</Japanese>
|
||||
<Korean>연막탄을 효과적으로 배치하는 데 도움이 되도록 투척하는 동안 일시적으로 바람 정보를 표시합니다.</Korean>
|
||||
<French>Affiche les informations sur le vent pendant le lancement pour placer les grenades fumigènes plus efficacement.</French>
|
||||
<Russian>Временно отображайте информацию о ветре во время броска, чтобы помочь эффективно разместить дымовые шашки.</Russian>
|
||||
<Spanish>Mostrar información del viento temporalmente mientras se lanza, para ayudar a lanzar las granadas de humo de forma efectiva.</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_Prepare">
|
||||
<English>Prepare/Change Throwable</English>
|
||||
<Spanish>Preparar/Cambiar objetos lanzables</Spanish>
|
||||
<Russian>Подготовить/заменить гранату</Russian>
|
||||
<Japanese>投てき物の準備/変更</Japanese>
|
||||
<Japanese>投擲物の準備/変更</Japanese>
|
||||
<Polish>Przygotuj/zmień ob. miotany</Polish>
|
||||
<German>Wurfobjekt vorbereiten/wechseln</German>
|
||||
<Korean>투척물 준비/변경</Korean>
|
||||
<French>Préparer/Changer d'objet lançable</French>
|
||||
<Italian>Prepara/Cambia Oggetto lanciabile</Italian>
|
||||
<Italian>Prepara/Cambia Oggetto Lanciabile</Italian>
|
||||
<Chinese>準備/變更投擲物</Chinese>
|
||||
<Chinesesimp>准备/变更投掷物</Chinesesimp>
|
||||
<Portuguese>Preparar/Mudar Arremessável</Portuguese>
|
||||
@ -204,12 +224,12 @@
|
||||
<English>Throwable Drop Mode (Hold)</English>
|
||||
<Spanish>Modo soltar objeto lanzable (Mantener pulsado)</Spanish>
|
||||
<Russian>Режим броска гранаты (удерживать)</Russian>
|
||||
<Japanese>投てきモード (押している間)</Japanese>
|
||||
<Japanese>投擲モード (押している間)</Japanese>
|
||||
<Polish>Tryb upuszczania ob. miotanego (przytrzymaj)</Polish>
|
||||
<German>Wurfobjekt Fallmodus (halten)</German>
|
||||
<Korean>투척물 떨어뜨리기 모드(꾹눌러서)</Korean>
|
||||
<French>Mode de lancé de l'objet (Tenir)</French>
|
||||
<Italian>Modalità Oggetto Gettabile (Mantenere)</Italian>
|
||||
<Italian>Modalità Gettare (Tieni premuto)</Italian>
|
||||
<Chinese>投擲模式 (按住)</Chinese>
|
||||
<Chinesesimp>投掷模式(按住)</Chinesesimp>
|
||||
<Portuguese>Modo de Arremesso (Segurar)</Portuguese>
|
||||
@ -219,12 +239,12 @@
|
||||
<English>Throwable Drop Mode (Toggle)</English>
|
||||
<Spanish>Modo soltar objeto lanzable (interruptor)</Spanish>
|
||||
<Russian>Режим броска гранаты (переключить)</Russian>
|
||||
<Japanese>投てきモード (切り替え)</Japanese>
|
||||
<Japanese>投擲モード (切り替え)</Japanese>
|
||||
<Polish>Tryb upuszczania ob. miotanego (przełącz)</Polish>
|
||||
<German>Wurfobjekt Fallmodus (umschalten)</German>
|
||||
<Korean>투척물 떨어뜨리기 모드(토글)</Korean>
|
||||
<French>Mode de lancé de l'objet (Basculer)</French>
|
||||
<Italian>Modalità Oggetto lanciabile Gettabile (Interruttore)</Italian>
|
||||
<Italian>Modalità Getta Oggetto (Cambia)</Italian>
|
||||
<Chinese>投擲模式 (切換)</Chinese>
|
||||
<Chinesesimp>投掷模式(切换)</Chinesesimp>
|
||||
<Portuguese>Modo de Arremesso (Alternar)</Portuguese>
|
||||
@ -234,12 +254,12 @@
|
||||
<English>Primed</English>
|
||||
<Spanish>Preparado</Spanish>
|
||||
<Russian>Подготовлена</Russian>
|
||||
<Japanese>点火</Japanese>
|
||||
<Japanese>を点火した</Japanese>
|
||||
<Polish>Odbezpieczony</Polish>
|
||||
<German>Scharf gemacht</German>
|
||||
<Korean>뇌관 작동</Korean>
|
||||
<French>amorcée</French>
|
||||
<Italian>Armato</Italian>
|
||||
<Italian>Innescato</Italian>
|
||||
<Chinese>引信開始燃燒</Chinese>
|
||||
<Chinesesimp>已开引信</Chinesesimp>
|
||||
<Portuguese>Preparado</Portuguese>
|
||||
@ -254,7 +274,7 @@
|
||||
<German>Werfen</German>
|
||||
<Korean>던지기</Korean>
|
||||
<French>Lancer</French>
|
||||
<Italian>Lanciare</Italian>
|
||||
<Italian>Lancia</Italian>
|
||||
<Chinese>投擲</Chinese>
|
||||
<Chinesesimp>投掷</Chinesesimp>
|
||||
<Portuguese>Arremessar</Portuguese>
|
||||
@ -270,7 +290,7 @@
|
||||
<German>(Scrollen) Modus wechseln</German>
|
||||
<Korean>(마우스 휠) 모드 변경</Korean>
|
||||
<French>(Défilement) Changer de mode</French>
|
||||
<Italian>(Scorrere) Cambio Modalità</Italian>
|
||||
<Italian>(Scorri) Cambia Modalità</Italian>
|
||||
<Chinese>(滾輪) 變更模式</Chinese>
|
||||
<Chinesesimp>(滚轮)变更模式</Chinesesimp>
|
||||
<Portuguese>(Roda do Mouse) Alternar modo</Portuguese>
|
||||
@ -286,10 +306,10 @@
|
||||
<German>(Scrollen) Erweitern</German>
|
||||
<Korean>(마우스 휠) 연장</Korean>
|
||||
<French>(Défilement) Étendre</French>
|
||||
<Italian>(Scorrere) Estendere</Italian>
|
||||
<Italian>(Scorri) Estendi</Italian>
|
||||
<Chinese>(滾輪) 延長</Chinese>
|
||||
<Chinesesimp>(滚轮)延长</Chinesesimp>
|
||||
<Portuguese>(Roda do Mouse) Extender</Portuguese>
|
||||
<Portuguese>(Roda do Mouse) Estender</Portuguese>
|
||||
<Czech>(Scrollovat) Oddálit</Czech>
|
||||
<Turkish>(Tekerlek) Uzat</Turkish>
|
||||
</Key>
|
||||
@ -302,7 +322,7 @@
|
||||
<German>(Klicken) Abkochen</German>
|
||||
<Korean>(클릭) 예열</Korean>
|
||||
<French>(Clique) Dégoupiller</French>
|
||||
<Italian>(Click) Arma</Italian>
|
||||
<Italian>(Click) Innesca</Italian>
|
||||
<Chinese>(點擊) 提早拉開引信</Chinese>
|
||||
<Chinesesimp>(点击)提早拉开引信</Chinesesimp>
|
||||
<Portuguese>(Clique) Cozinhar</Portuguese>
|
||||
@ -313,7 +333,7 @@
|
||||
<English>Pick Up</English>
|
||||
<Spanish>Coger</Spanish>
|
||||
<Russian>Подобрать</Russian>
|
||||
<Japanese>拾い上げる</Japanese>
|
||||
<Japanese>拾う</Japanese>
|
||||
<Polish>Podnieś</Polish>
|
||||
<German>Aufheben</German>
|
||||
<Korean>줍기</Korean>
|
||||
|
@ -1,3 +1,5 @@
|
||||
PREP(assignNVG);
|
||||
PREP(assignNVGpfh);
|
||||
PREP(drawCuratorGarrisonPathing);
|
||||
PREP(garrison);
|
||||
PREP(garrisonMove);
|
||||
|
@ -16,7 +16,7 @@
|
||||
} forEach _sections;
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
[QGVAR(unGarrison), FUNC(unGarrison)] call CBA_fnc_addEventHandler;
|
||||
[QGVAR(unGarrison), LINKFUNC(unGarrison)] call CBA_fnc_addEventHandler;
|
||||
|
||||
[QGVAR(doMove), {
|
||||
params ["_unitsArray"];
|
||||
@ -68,3 +68,11 @@
|
||||
params ["_unit", "_mode"];
|
||||
_unit enableGunLights _mode;
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
|
||||
if (isServer) then {
|
||||
["CAManBase", "init", {
|
||||
// wait for HMD to be assigned so `hmd _unit` works
|
||||
[LINKFUNC(assignNVG), _this, 1] call CBA_fnc_waitAndExecute;
|
||||
}] call CBA_fnc_addClassEventHandler;
|
||||
};
|
||||
|
@ -6,4 +6,11 @@ PREP_RECOMPILE_START;
|
||||
#include "XEH_PREP.hpp"
|
||||
PREP_RECOMPILE_END;
|
||||
|
||||
if (isServer) then {
|
||||
GVAR(assignNVGthread) = false;
|
||||
GVAR(assignNVGstate) = false;
|
||||
};
|
||||
|
||||
#include "initSettings.inc.sqf"
|
||||
|
||||
ADDON = true;
|
||||
|
39
addons/ai/functions/fnc_assignNVG.sqf
Normal file
39
addons/ai/functions/fnc_assignNVG.sqf
Normal file
@ -0,0 +1,39 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Assigns AI first found NVG in their inventory during night time and unassigns it during day time.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [cursorObject] call ace_ai_fnc_assignNVG
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
if (!GVAR(assignNVG)) exitWith {};
|
||||
|
||||
params ["_unit"];
|
||||
|
||||
if (alive _unit && {!isPlayer _unit}) then {
|
||||
private _nvg = hmd _unit;
|
||||
|
||||
if (GVAR(assignNVGstate)) then {
|
||||
if (_nvg == "") then {
|
||||
private _items = [_unit, false, true, true, true, false, false] call CBA_fnc_uniqueUnitItems; // backpack, vest, uniform
|
||||
{
|
||||
if (getText (configFile >> "CfgWeapons" >> _x >> "simulation") == "NVGoggles") exitWith {
|
||||
_unit assignItem _x;
|
||||
};
|
||||
} forEach _items;
|
||||
};
|
||||
} else {
|
||||
if (_nvg != "" && {currentVisionMode _unit == 0} && {_unit canAdd _nvg}) then {
|
||||
_unit unassignItem _nvg;
|
||||
};
|
||||
};
|
||||
};
|
27
addons/ai/functions/fnc_assignNVGpfh.sqf
Normal file
27
addons/ai/functions/fnc_assignNVGpfh.sqf
Normal file
@ -0,0 +1,27 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* waitAndExecute Handler for periodic NVG assignment.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [] call ace_ai_fnc_assignNVGpfh
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
TRACE_1("assignNVGpfh",count allUnits);
|
||||
|
||||
if (!GVAR(assignNVG)) exitWith { TRACE_1("shutdown loop",_this); GVAR(assignNVGthread) = false; };
|
||||
|
||||
GVAR(assignNVGstate) = sunOrMoon < 1 || {moonIntensity > 0.8};
|
||||
|
||||
{
|
||||
_x call FUNC(assignNVG);
|
||||
} forEach allUnits;
|
||||
|
||||
[FUNC(assignNVGpfh), [], 300] call CBA_fnc_waitAndExecute;
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: alganthe
|
||||
* Draws AI garrison pathing while the Zeus display is open.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: alganthe
|
||||
* Garrison function used to garrison AI inside buildings.
|
||||
@ -7,8 +7,8 @@
|
||||
* 0: The building(s) nearest this position are used <POSITION>
|
||||
* 1: Limit the building search to those type of building <ARRAY>
|
||||
* 2: Units that will be garrisoned <ARRAY>
|
||||
* 3: Radius to fill building(s) <SCALAR> (default: 50)
|
||||
* 4: 0: even filling, 1: building by building, 2: random filling <SCALAR> (default: 0)
|
||||
* 3: Radius to fill building(s) <NUMBER> (default: 50)
|
||||
* 4: 0: even filling, 1: building by building, 2: random filling <NUMBER> (default: 0)
|
||||
* 5: True to fill building(s) from top to bottom <BOOL> (default: false) (note: only works with filling mode 0 and 1)
|
||||
* 6: Teleport units <BOOL> (default: false)
|
||||
|
||||
@ -33,7 +33,7 @@ if (_startingPos isEqualTo [0,0,0]) exitWith {
|
||||
[LSTRING(GarrisonInvalidPosition)] call EFUNC(common,displayTextStructured);
|
||||
};
|
||||
|
||||
if (count _unitsArray == 0 || {isNull (_unitsArray select 0)}) exitWith {
|
||||
if (_unitsArray isEqualTo [] || {isNull (_unitsArray select 0)}) exitWith {
|
||||
TRACE_1("fnc_garrison: Units error",_unitsArray);
|
||||
[LSTRING(GarrisonNoUnits)] call EFUNC(common,displayTextStructured);
|
||||
};
|
||||
@ -43,7 +43,7 @@ if (_fillingRadius >= 50) then {
|
||||
_buildings = [_buildings] call CBA_fnc_shuffle;
|
||||
};
|
||||
|
||||
if (count _buildings == 0) exitWith {
|
||||
if (_buildings isEqualTo []) exitWith {
|
||||
TRACE_1("fnc_garrison: Building error",_buildings);
|
||||
[LSTRING(GarrisonNoBuilding)] call EFUNC(common,displayTextStructured);
|
||||
};
|
||||
@ -128,7 +128,7 @@ switch (_fillingType) do {
|
||||
} else {
|
||||
private _pos = _building select 0;
|
||||
private _nearestUnits = (_pos nearEntities ["CAManBase", 2]);
|
||||
LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]);
|
||||
LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits,{floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]);
|
||||
|
||||
if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then {
|
||||
LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]);
|
||||
@ -177,7 +177,7 @@ switch (_fillingType) do {
|
||||
} else {
|
||||
private _pos = _building select 0;
|
||||
private _nearestUnits = (_pos nearEntities ["CAManBase", 2]);
|
||||
LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]);
|
||||
LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits,{floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]);
|
||||
|
||||
if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then {
|
||||
LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]);
|
||||
@ -224,7 +224,7 @@ switch (_fillingType) do {
|
||||
} else {
|
||||
private _pos = selectRandom _building;
|
||||
private _nearestUnits = (_pos nearEntities ["CAManBase", 2]);
|
||||
LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]);
|
||||
LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits,{floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]);
|
||||
|
||||
if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then {
|
||||
LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]);
|
||||
@ -258,7 +258,7 @@ switch (_fillingType) do {
|
||||
};
|
||||
};
|
||||
|
||||
TRACE_1(format [ARR_2("fnc_garrison: while loop ended | %1 units ready to be treated by PFH",count _unitMoveList)], _teleport);
|
||||
TRACE_1(format [ARR_2("fnc_garrison: while loop ended | %1 units ready to be treated by PFH",count _unitMoveList)],_teleport);
|
||||
|
||||
// Update the unit list and remove duplicate positions and units
|
||||
private _garrison_unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []];
|
||||
@ -279,5 +279,5 @@ if (_teleport) then {
|
||||
[_unitMoveList] call FUNC(garrisonMove);
|
||||
};
|
||||
|
||||
TRACE_1(format [ARR_3("fnc_garrison: End | %1 units left | %2 buildings left", count _unitsArray, count _buildingsIndex)], _unitsArray);
|
||||
TRACE_1(format [ARR_3("fnc_garrison: End | %1 units left | %2 buildings left",count _unitsArray,count _buildingsIndex)],_unitsArray);
|
||||
_unitsArray
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: alganthe
|
||||
* Internal function used by ace_ai_fnc_garrison to make the units move to the positions it picked.
|
||||
@ -81,13 +81,13 @@ if (isNil QGVAR(garrison_moveUnitPFH)) then {
|
||||
[QGVAR(enableAttack), [[_unit], true], _unit] call CBA_fnc_targetEvent;
|
||||
};
|
||||
|
||||
LOG(format [ARR_2("garrisonMove PFH: unit in position | %1 units left", count _unitMoveList)]);
|
||||
LOG(format [ARR_2("garrisonMove PFH: unit in position | %1 units left",count _unitMoveList)]);
|
||||
};
|
||||
|
||||
// Check if unit is alive or even existing
|
||||
if (!alive _unit || {_unit getVariable [QGVAR(garrisoned), false]}) then {
|
||||
_unitMoveList deleteAt (_unitMoveList find _x);
|
||||
LOG(format [ARR_2("garrisonMove PFH: unit dead, deleted or garrisoned via TP | %1 units left", count _unitMoveList)]);
|
||||
LOG(format [ARR_2("garrisonMove PFH: unit dead, deleted or garrisoned via TP | %1 units left",count _unitMoveList)]);
|
||||
|
||||
} else {
|
||||
private _unitPos = getPos _unit;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: mharis001
|
||||
* Initializes the Zeus display.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: alganthe
|
||||
* Used to un-garrison units.
|
||||
@ -28,7 +28,7 @@ _units = _units select {local _x};
|
||||
|
||||
private _leader = leader _unit;
|
||||
|
||||
TRACE_3("fnc_ungarrison: unit and leader",_unit , _leader, (_leader == _unit));
|
||||
TRACE_3("fnc_ungarrison: unit and leader",_unit,_leader,(_leader == _unit));
|
||||
|
||||
_unit setVariable [QGVAR(garrisonned), false, true];
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
#include "\z\ace\addons\ai\script_component.hpp"
|
19
addons/ai/initSettings.inc.sqf
Normal file
19
addons/ai/initSettings.inc.sqf
Normal file
@ -0,0 +1,19 @@
|
||||
private _category = format ["ACE %1", LLSTRING(DisplayName)];
|
||||
|
||||
[
|
||||
QGVAR(assignNVG), "CHECKBOX",
|
||||
[LSTRING(AssignNVG_DisplayName), LSTRING(AssignNVG_Description)],
|
||||
_category,
|
||||
false,
|
||||
1,
|
||||
{
|
||||
if (isServer) then {
|
||||
params ["_enabled"];
|
||||
if (_enabled && {!GVAR(assignNVGthread)}) then {
|
||||
TRACE_1("start loop",_this);
|
||||
GVAR(assignNVGthread) = true;
|
||||
[FUNC(assignNVGpfh), [], 1] call CBA_fnc_waitAndExecute;
|
||||
};
|
||||
};
|
||||
}
|
||||
] call CBA_fnc_addSetting;
|
@ -1,6 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project name="ACE">
|
||||
<Package name="AI">
|
||||
<Key ID="STR_ACE_AI_DisplayName">
|
||||
<English>AI</English>
|
||||
<Chinese>AI</Chinese>
|
||||
<French>IA</French>
|
||||
<Spanish>IA</Spanish>
|
||||
<Italian>IA</Italian>
|
||||
<Polish>SI</Polish>
|
||||
<Russian>ИИ</Russian>
|
||||
<German>KI</German>
|
||||
<Czech>UI</Czech>
|
||||
<Portuguese>IA</Portuguese>
|
||||
<Korean>AI</Korean>
|
||||
<Chinesesimp>AI</Chinesesimp>
|
||||
<Japanese>AI</Japanese>
|
||||
<Turkish>AI</Turkish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_AI_GarrisonInvalidPosition">
|
||||
<English>Invalid position provided.</English>
|
||||
<German>Ungültige Position</German>
|
||||
@ -65,5 +81,29 @@
|
||||
<Czech>Nenalezena žádná budova.</Czech>
|
||||
<Turkish>Bir yapı bulunamadı</Turkish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_AI_AssignNVG_DisplayName">
|
||||
<English>Auto-Equip NVGs</English>
|
||||
<Polish>Automatyczne zakładanie NVG</Polish>
|
||||
<German>Automatisch NVGs ausrüsten</German>
|
||||
<Italian>Equipaggia NVG in automatico</Italian>
|
||||
<Korean>야투경 자동 창착</Korean>
|
||||
<French>Equipement JVN automatique</French>
|
||||
<Portuguese>Equipar NVGs automaticamente</Portuguese>
|
||||
<Japanese>暗視装置の自動装備</Japanese>
|
||||
<Russian>Автоматическое оснащение ПНВ</Russian>
|
||||
<Spanish>Auto equipar gafas de visión nocturna</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_AI_AssignNVG_Description">
|
||||
<English>Equips NVG in inventory during night time and unequips it during day time.\nDoes not add NVGs to inventory!</English>
|
||||
<Polish>Zakłada NVG w nocy i zdejmuje je w ciągu dnia.\nNie dodaje NVG do ekwipunku!</Polish>
|
||||
<German>Rüstet NVG nachts aus dem Inventar aus und entfernt es tagsüber.\nFügt keine NVGs zum Inventar hinzu!</German>
|
||||
<Italian>Equipaggia NVG dall'inventario durante la notte, e li mette nell'inventario durante il giorno.\nNon aggiunge NVG all'inventario se non sono presenti.</Italian>
|
||||
<Korean>야간에는 야투경을 소지품에 장착하고 주간에는 장착을 해제합니다.\n주의! 소지품에 야투경을 추가하는 것이 아닙니다!</Korean>
|
||||
<French>Equipe des JVN pendant la nuit et les déséquipe le jour.\nN'ajoute pas les JVN dans l'intenvaire !</French>
|
||||
<Portuguese>Equipa o NVG do inventário durante a noite e desequipa durante o dia.\nNão adiciona NVGs ao inventário!</Portuguese>
|
||||
<Japanese>インベントリ内の暗視装置を夜間に装備し、日中は解除し収納します。\nこれはNVGをインベントリに追加しません。</Japanese>
|
||||
<Russian>Экипирует ПНВ в ночное время и отключает его в дневное время.\nНе добавляет ПНВ в инвентарь!</Russian>
|
||||
<Spanish>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!</Spanish>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
||||
|
@ -12,6 +12,6 @@ class Extended_PreInit_EventHandlers {
|
||||
|
||||
class Extended_PostInit_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_postInit));
|
||||
init = QUOTE(call COMPILE_SCRIPT(XEH_postInit));
|
||||
};
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Dystopian
|
||||
* Check if Eject action can be shown.
|
||||
@ -30,6 +30,6 @@ _vehicle == vehicle _unit
|
||||
if (_unit == _x select FULLCREW_UNIT) exitWith {
|
||||
_ejectVarName = format [QGVAR(ejectAction_%1_%2), _x select FULLCREW_ROLE, _x select FULLCREW_TURRETPATH];
|
||||
};
|
||||
} count fullCrew _vehicle;
|
||||
} forEach fullCrew _vehicle;
|
||||
_vehicle getVariable [_ejectVarName, false]
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Adds actions to a drone
|
||||
@ -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;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Get drone's target location, if aimed at infinity it will return a virtual point
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Modify the current waypoint of a drone
|
||||
@ -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];
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Set new waypoint of a drone
|
||||
@ -8,6 +8,7 @@
|
||||
* 1: Group <GROUP>
|
||||
* 2: Pos 2D <ARRAY>
|
||||
* 3: Type <STRING>
|
||||
* 4: Target to follow <OBJECT> (default: objNull)
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
@ -18,7 +19,7 @@
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_vehicle", "_group", "_pos", "_type"];
|
||||
params ["_vehicle", "_group", "_pos", "_type", ["_target", objNull]];
|
||||
TRACE_4("droneSetWaypoint",_vehicle,_group,_pos,_type);
|
||||
|
||||
private _index = (currentWaypoint _group) min count waypoints _group;
|
||||
@ -29,11 +30,39 @@ private _currentLoiterRadius = waypointLoiterRadius _waypoint;
|
||||
private _currentLoiterType = waypointLoiterType _waypoint;
|
||||
|
||||
// Set pos to ATL
|
||||
_pos set [2, if (_currentHeight >= 50) then { _currentHeight } else { 0 }];
|
||||
_pos set [
|
||||
2,
|
||||
[0, _currentHeight] select (_currentHeight >= 50)
|
||||
];
|
||||
|
||||
// [_group] call CBA_fnc_clearWaypoints;
|
||||
_waypoint = _group addWaypoint [_pos, 0];
|
||||
_waypoint setWaypointType _type;
|
||||
// The Vanilla "FOLLOW"-type waypoint is not used directly, due to 2 main issues (as of v2.16):
|
||||
// - It does not work at all for UGVs, which is a known issue https://feedback.bistudio.com/T126283;
|
||||
// - No clear scripting way was found to mimic the UAV Terminal's "Follow Distance" functionality;
|
||||
// Instead, the solution for both UAV and UGV following consists of a CBA PFH that moves a "HOLD"-type Waypoint every 3 seconds.
|
||||
// Either on the target itself, or on the Drone's current position if the target is within the desired follow distance.
|
||||
if (_type == "FOLLOW" && {["CAManBase", "LandVehicle", "Ship"] findIf {_target isKindOf _x} != -1}) then {
|
||||
_waypoint setWaypointType "HOLD";
|
||||
[{
|
||||
params ["_args", "_handle"];
|
||||
_args params ["_vehicle", "_group", "_waypoint", "_target"];
|
||||
|
||||
if ( // Abort PFH if a new waypoint is created via UAV Terminal or ACE Interaction
|
||||
_waypoint select 1 != currentWaypoint _group ||
|
||||
{!alive _vehicle} || {isNull _target}
|
||||
) exitWith {
|
||||
deleteWaypoint _waypoint;
|
||||
[_handle] call CBA_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
private _followDistance = _vehicle getVariable [QGVAR(wpFollowDistance), 0];
|
||||
if ((_vehicle distance2D _target) < _followDistance) then {
|
||||
_waypoint setWaypointPosition [getPosASL _vehicle, -1];
|
||||
} else {
|
||||
_waypoint setWaypointPosition [getPosASL _target, -1];
|
||||
};
|
||||
}, 3, [_vehicle, _group, _waypoint, _target]] call CBA_fnc_addPerFrameHandler;
|
||||
};
|
||||
|
||||
TRACE_3("",_currentHeight,_currentLoiterRadius,_currentLoiterType);
|
||||
if (_currentHeight > 1) then { _vehicle flyInHeight _currentHeight; };
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user