mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merge remote-tracking branch 'refs/remotes/acemod/master' into tracer_adjustment
This commit is contained in:
commit
d8cf117841
56
.gibot.yml
Normal file
56
.gibot.yml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
stages:
|
||||||
|
mark_for_closing:
|
||||||
|
days: 30
|
||||||
|
labels:
|
||||||
|
- status/need more info
|
||||||
|
- status/invalid
|
||||||
|
- status/can't reproduce
|
||||||
|
- status/wontfix
|
||||||
|
exclude:
|
||||||
|
- status/marked for cleanup
|
||||||
|
- status/accepting-pr
|
||||||
|
comment:
|
||||||
|
- 'Hello @{author}! There has been no activity on this ticket for over a period of {days} days. I am automatically replying to let you know we will close this ticket within 1 week due to inactivity and consider this resolved.'
|
||||||
|
- 'If you believe this is in error, please reply with the requested information.'
|
||||||
|
- 'Thank you. :robot:'
|
||||||
|
action:
|
||||||
|
close: false
|
||||||
|
comment: true
|
||||||
|
assign_label:
|
||||||
|
- status/marked for cleanup
|
||||||
|
clean_up:
|
||||||
|
days: 7
|
||||||
|
labels:
|
||||||
|
- status/marked for cleanup
|
||||||
|
comment:
|
||||||
|
- 'Hello @{author}! We have detected no activity for {days} days on this ticket. We therefore assume that the original reporter has lost interest or the issue has been resolved.'
|
||||||
|
- 'Since we have marked this ticket for deletion, we will be closing it.'
|
||||||
|
- 'If this has been closed in error, please create a comment below and we can reopen this issue. Note that you may need to provide additional information that was requested.'
|
||||||
|
- 'Thank you. :robot:'
|
||||||
|
action:
|
||||||
|
close: true
|
||||||
|
comment: true
|
||||||
|
assign_label:
|
||||||
|
- status/closed by bot
|
||||||
|
remove_label:
|
||||||
|
- status/marked for cleanup
|
||||||
|
remind_about_old_ticket:
|
||||||
|
days: 365
|
||||||
|
labels:
|
||||||
|
- kind/bug
|
||||||
|
- kind/critical bug
|
||||||
|
exclude:
|
||||||
|
- status/need more info
|
||||||
|
- status/invalid
|
||||||
|
- status/can't reproduce
|
||||||
|
- status/wontfix
|
||||||
|
- status/marked for cleanup
|
||||||
|
- status/inactive
|
||||||
|
- status/stale
|
||||||
|
- status/accepting-pr
|
||||||
|
comment:
|
||||||
|
- 'Hello @acemod/maintainers. This ticket has been open for over {days} days without any activity.'
|
||||||
|
action:
|
||||||
|
comment: true
|
||||||
|
assign_label:
|
||||||
|
- status/inactive
|
8
.github/ISSUE_TEMPLATE.md
vendored
8
.github/ISSUE_TEMPLATE.md
vendored
@ -3,8 +3,10 @@
|
|||||||
**ACE3 Version:** `3.x.x` (stable / dev + commit hash)
|
**ACE3 Version:** `3.x.x` (stable / dev + commit hash)
|
||||||
|
|
||||||
**Mods:**
|
**Mods:**
|
||||||
- `@CBA_A3`
|
```
|
||||||
- `@ace`
|
- CBA_A3
|
||||||
|
- ace
|
||||||
|
```
|
||||||
|
|
||||||
**Description:**
|
**Description:**
|
||||||
- Add a detailed description of the error. This makes it easier for us to fix the issue.
|
- Add a detailed description of the error. This makes it easier for us to fix the issue.
|
||||||
@ -20,4 +22,4 @@
|
|||||||
|
|
||||||
**RPT log file:**
|
**RPT log file:**
|
||||||
- Add a link ([gist](https://gist.github.com) or [pastebin](http://pastebin.com)) to the client and/or server RPT file. An instruction to find your RPT files can be found [here](https://community.bistudio.com/wiki/Crash_Files#Arma_3).
|
- Add a link ([gist](https://gist.github.com) or [pastebin](http://pastebin.com)) to the client and/or server RPT file. An instruction to find your RPT files can be found [here](https://community.bistudio.com/wiki/Crash_Files#Arma_3).
|
||||||
- If possible at the time the bug is encountered, go to ACE Options and select "Debug To Clipboard", this will print extensive debug information to the RPT file.
|
- If possible at the time the bug is encountered, go to Options and select "ACE Debug To Clipboard", this will print extensive debug information to the RPT file and copy it to clipboard.
|
||||||
|
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -2,4 +2,4 @@
|
|||||||
- Describe what this pull request will do
|
- Describe what this pull request will do
|
||||||
- Each change in a separate line
|
- Each change in a separate line
|
||||||
- Include documentation if applicable
|
- Include documentation if applicable
|
||||||
- Respect the [Development Guidelines](http://ace3mod.com/wiki/development/)
|
- Respect the [Development Guidelines](https://ace3mod.com/wiki/development/)
|
||||||
|
20
.github_changelog_generator
Normal file
20
.github_changelog_generator
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# No issues and PRs without labels
|
||||||
|
issues=false
|
||||||
|
pr-wo-labels=false
|
||||||
|
|
||||||
|
# Issues are disabled, don't fetch them
|
||||||
|
max-issues=0
|
||||||
|
|
||||||
|
# Label filters
|
||||||
|
exclude-labels=by design,can't reproduce,duplicate,question,invalid,wontfix,ignore changelog
|
||||||
|
|
||||||
|
# Tag is created before generating changelog for release candidates
|
||||||
|
unreleased=false
|
||||||
|
|
||||||
|
# No section labels, we only want a list of merged PRs (label separation only works for Issues)
|
||||||
|
simple-list=true
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
author=false
|
||||||
|
compare-link=false
|
||||||
|
header-label=## Change Log Summary
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,3 +7,4 @@ texHeaders.bin
|
|||||||
*.swo
|
*.swo
|
||||||
*.biprivatekey
|
*.biprivatekey
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
CHANGELOG.md
|
||||||
|
3
.lgtm
3
.lgtm
@ -1,3 +0,0 @@
|
|||||||
approvals = 1
|
|
||||||
pattern = "(?i)LGTM|(?i):\\+1:|(?i):shipit:"
|
|
||||||
self_approval_off = true
|
|
30
.travis.yml
30
.travis.yml
@ -1,30 +0,0 @@
|
|||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
- release
|
|
||||||
language: python
|
|
||||||
python:
|
|
||||||
- '3.4'
|
|
||||||
before_script:
|
|
||||||
- if [ -n "${GH_TOKEN}" ] && [ "${TRAVIS_BRANCH}" == "master" ] && [ "${TRAVIS_PULL_REQUEST}" == "false" ]; then
|
|
||||||
pip install pygithub;
|
|
||||||
pip install pygithub3;
|
|
||||||
fi
|
|
||||||
script:
|
|
||||||
- python3 tools/sqf_validator.py
|
|
||||||
- python3 tools/config_style_checker.py
|
|
||||||
- if [ -n "${GH_TOKEN}" ] && [ "${TRAVIS_BRANCH}" == "master" ] && [ "${TRAVIS_PULL_REQUEST}" == "false" ]; then
|
|
||||||
python3 tools/deploy.py;
|
|
||||||
fi
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- secure: cdxkn5cAx+s1C9Ne5m+odEhde1uuSg6XGMDgepN4DwSAJwtMnUv3ZmDebd5YJC1raZJdep+n09Cj0GoTNICQRkco50DxHKHYNad41wetY0tn0cs9gmPYzyFE5q4vuWiQ47dlGhQQ7IJDyX0nU++gG5E50/PhlZfebdedGSprN/4=
|
|
||||||
notifications:
|
|
||||||
slack:
|
|
||||||
rooms:
|
|
||||||
- secure: byZMNBl8PMlgjT9NA1WmhgCdGfX4b3g1kA0vEiwfm+IFNlx7BiM4J/5rp6zV/jV470xl/epAejx2tsa5SdTyFbO87NH63ILJSt5QnjUZjRuGKSutFs9WE671DtZkPRSJXHS4N6x802PRkyBz/84/lsc34FWvHvjwOuYAtOcJRFk=
|
|
||||||
- secure: V22TNaLWV+yUNWqR7c6HVvIxkRDz7Dyz9xqa43FY8iFgvNL4Q/X69h5DYHU/ILNFM00tx8OBjtPRbcjWQ+F6eY8Sje/A2axJAU+qNurAvoyiTahXUprdUUpPdkgXWuSRTZ9kALxOq5e11RC8XUietghoMcl8zPcqdrZCOOKgoEM=
|
|
||||||
on_success: change
|
|
||||||
email:
|
|
||||||
on_success: never
|
|
||||||
on_failure: change
|
|
20
AUTHORS.txt
20
AUTHORS.txt
@ -1,4 +1,4 @@
|
|||||||
# ACE3 CONTRIBUTOR LIST
|
# ACE3 CONTRIBUTOR LIST
|
||||||
# If you contributed, but are not listed here, contact me:
|
# If you contributed, but are not listed here, contact me:
|
||||||
# koffeinflummi@gmail.com
|
# koffeinflummi@gmail.com
|
||||||
#
|
#
|
||||||
@ -29,6 +29,7 @@ Walter Pearce <jaynus@gmail.com>
|
|||||||
# CONTRIBUTORS
|
# CONTRIBUTORS
|
||||||
[BIG]Bull
|
[BIG]Bull
|
||||||
11RDP-LoupVert <loupvert@11rdp.fr>
|
11RDP-LoupVert <loupvert@11rdp.fr>
|
||||||
|
654wak654 <ozanegitmen@gmail.com>
|
||||||
ACCtomeek <tomeek99@gmail.com>
|
ACCtomeek <tomeek99@gmail.com>
|
||||||
adam3adam <br.ada@seznam.cz>
|
adam3adam <br.ada@seznam.cz>
|
||||||
Adanteh
|
Adanteh
|
||||||
@ -37,7 +38,9 @@ Aggr094 <bastards4glory@gmail.com>
|
|||||||
alef <alefor@gmail.com>
|
alef <alefor@gmail.com>
|
||||||
Aleksey EpMAK Yermakov <epmak777@gmail.com>
|
Aleksey EpMAK Yermakov <epmak777@gmail.com>
|
||||||
Alganthe <alganthe@live.fr>
|
Alganthe <alganthe@live.fr>
|
||||||
|
Andrea "AtixNeon" Verano <veranoandrea88@gmail.com>
|
||||||
Anthariel <Contact@storm-simulation.com>
|
Anthariel <Contact@storm-simulation.com>
|
||||||
|
Anton
|
||||||
Arkhir <wonsz666@gmail.com >
|
Arkhir <wonsz666@gmail.com >
|
||||||
Asgar Serran <piechottaf@web.de>
|
Asgar Serran <piechottaf@web.de>
|
||||||
BaerMitUmlaut
|
BaerMitUmlaut
|
||||||
@ -49,6 +52,8 @@ Brakoviejo
|
|||||||
Brisse <brisse@outlook.com>
|
Brisse <brisse@outlook.com>
|
||||||
Brostrom.A | Evul <andreas.brostrom.ce@gmail.com>
|
Brostrom.A | Evul <andreas.brostrom.ce@gmail.com>
|
||||||
BullHorn <bullhorn7@gmail.com>
|
BullHorn <bullhorn7@gmail.com>
|
||||||
|
chris579 <github@klemm.one>
|
||||||
|
classicarma
|
||||||
Clon1998 <ps.patti1998@gmail.com>
|
Clon1998 <ps.patti1998@gmail.com>
|
||||||
Codingboy
|
Codingboy
|
||||||
Coren <coren4@gmail.com>
|
Coren <coren4@gmail.com>
|
||||||
@ -60,6 +65,7 @@ Drill <drill87@gmail.com>
|
|||||||
Dudakov aka [OMCB]Kaban <dudakov.s@gmail.com>
|
Dudakov aka [OMCB]Kaban <dudakov.s@gmail.com>
|
||||||
Drofseh <drofseh@gmail.com>
|
Drofseh <drofseh@gmail.com>
|
||||||
Dslyecxi <dslyecxi@gmail.com>
|
Dslyecxi <dslyecxi@gmail.com>
|
||||||
|
ElTyranos
|
||||||
eRazeri
|
eRazeri
|
||||||
evromalarkey <evromalarkey@gmail.com>
|
evromalarkey <evromalarkey@gmail.com>
|
||||||
F3 Project <alanr@ferstaberinde.com>
|
F3 Project <alanr@ferstaberinde.com>
|
||||||
@ -83,26 +89,35 @@ Harakhti <shadowdragonphd@gmail.com>
|
|||||||
havena <silveredenis@gmail.com>
|
havena <silveredenis@gmail.com>
|
||||||
Hawkins
|
Hawkins
|
||||||
Head <brobergsebastian@gmail.com>
|
Head <brobergsebastian@gmail.com>
|
||||||
|
Hybrid V
|
||||||
|
john681611 <john681611@hotmail.com>
|
||||||
Karneck <dschultz26@hotmail.com>
|
Karneck <dschultz26@hotmail.com>
|
||||||
Kavinsky <nmunozfernandez@gmail.com>
|
Kavinsky <nmunozfernandez@gmail.com>
|
||||||
|
Keithen <Keithen.Neu@gmail.com>
|
||||||
Kllrt <kllrtik@gmail.com>
|
Kllrt <kllrtik@gmail.com>
|
||||||
legman <juicemelon@msn.com>
|
legman <juicemelon@msn.com>
|
||||||
Legolasindar "Viper" <legolasindar@gmail.com>
|
Legolasindar "Viper" <legolasindar@gmail.com>
|
||||||
licht-im-Norden87 <lichtimnorden87@gmail.com>
|
licht-im-Norden87 <lichtimnorden87@gmail.com>
|
||||||
looter <looter222@gmail.com>
|
looter <looter222@gmail.com>
|
||||||
|
Lugubrious Hatchling <thunderbra@gmail.com>
|
||||||
|
Luigi "Luigium" Myrini <luigium@outlook.fr>
|
||||||
Macusercom <macusercom@gmail.com>
|
Macusercom <macusercom@gmail.com>
|
||||||
MarcBook
|
MarcBook
|
||||||
meat <p.humberdroz@gmail.com>
|
meat <p.humberdroz@gmail.com>
|
||||||
|
mharis001 <mhariszakar@gmail.com>
|
||||||
Michail Nikolaev
|
Michail Nikolaev
|
||||||
MikeMatrix <m.braun92@gmail.com>
|
MikeMatrix <m.braun92@gmail.com>
|
||||||
nic547 <nic547@outlook.com>
|
nic547 <nic547@outlook.com>
|
||||||
nikolauska <nikolauska1@gmail.com>
|
nikolauska <nikolauska1@gmail.com>
|
||||||
nomisum <nomisum@gmail.com>
|
nomisum <nomisum@gmail.com>
|
||||||
OnkelDisMaster <onkeldismaster@gmail.com>
|
OnkelDisMaster <onkeldismaster@gmail.com>
|
||||||
|
Orbis2358 <mgkid3310@naver.com>
|
||||||
oscarmolinadev
|
oscarmolinadev
|
||||||
PaxJaromeMalues <seemax1991@gmail.com>
|
PaxJaromeMalues <seemax1991@gmail.com>
|
||||||
|
Phyma <sethramstrom@gmail.com>
|
||||||
pokertour
|
pokertour
|
||||||
Professor <lukas.trneny@wo.cz>
|
Professor <lukas.trneny@wo.cz>
|
||||||
|
QuickDagger
|
||||||
rakowozz
|
rakowozz
|
||||||
ramius86 <pasini86@hotmail.com>
|
ramius86 <pasini86@hotmail.com>
|
||||||
Raspu86
|
Raspu86
|
||||||
@ -116,11 +131,14 @@ System98
|
|||||||
SzwedzikPL <szwedzikpl@gmail.com>
|
SzwedzikPL <szwedzikpl@gmail.com>
|
||||||
Tachi <zaveruha007@gmail.com>
|
Tachi <zaveruha007@gmail.com>
|
||||||
Tessa Elieff <Fastroping Sound - CreativeCommons Attributions 3.0>
|
Tessa Elieff <Fastroping Sound - CreativeCommons Attributions 3.0>
|
||||||
|
Timi007 <timi007@gmx.net>
|
||||||
Toaster <jonathan.pereira@gmail.com>
|
Toaster <jonathan.pereira@gmail.com>
|
||||||
Tonic
|
Tonic
|
||||||
Tourorist <tourorist@gmail.com>
|
Tourorist <tourorist@gmail.com>
|
||||||
|
Tuupertunut
|
||||||
Valentin Torikian <valentin.torikian@gmail.com>
|
Valentin Torikian <valentin.torikian@gmail.com>
|
||||||
voiper
|
voiper
|
||||||
VyMajoris(W-Cephei)<vycanismajoriscsa@gmail.com>
|
VyMajoris(W-Cephei)<vycanismajoriscsa@gmail.com>
|
||||||
Winter <simon@agius-muscat.net>
|
Winter <simon@agius-muscat.net>
|
||||||
|
xrufix
|
||||||
zGuba
|
zGuba
|
||||||
|
76
README.md
76
README.md
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/acemod/ACE3/releases/latest">
|
<a href="https://github.com/acemod/ACE3/releases/latest">
|
||||||
<img src="https://img.shields.io/badge/Version-3.6.2-blue.svg?style=flat-square" alt="ACE3 Version">
|
<img src="https://img.shields.io/badge/Version-3.12.3-blue.svg?style=flat-square" alt="ACE3 Version">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/acemod/ACE3/issues">
|
<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">
|
<img src="https://img.shields.io/github/issues-raw/acemod/ACE3.svg?style=flat-square&label=Issues" alt="ACE3 Issues">
|
||||||
@ -18,17 +18,17 @@
|
|||||||
<a href="https://github.com/acemod/ACE3/blob/master/LICENSE">
|
<a href="https://github.com/acemod/ACE3/blob/master/LICENSE">
|
||||||
<img src="https://img.shields.io/badge/License-GPLv2-red.svg?style=flat-square" alt="ACE3 License">
|
<img src="https://img.shields.io/badge/License-GPLv2-red.svg?style=flat-square" alt="ACE3 License">
|
||||||
</a>
|
</a>
|
||||||
<a href="http://slackin.ace3mod.com/">
|
<a href="https://slackin.ace3mod.com/">
|
||||||
<img src="http://slackin.ace3mod.com/badge.svg?style=flat-square&label=Slack" alt="ACE3 Slack">
|
<img src="https://slackin.ace3mod.com/badge.svg?style=flat-square&label=Slack" alt="ACE3 Slack">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://travis-ci.org/acemod/ACE3">
|
<a href="https://circleci.com/gh/acemod/ACE3">
|
||||||
<img src="https://img.shields.io/travis/acemod/ACE3.svg?style=flat-square&label=Build" alt="ACE3 Build Status">
|
<img src="https://circleci.com/gh/acemod/ACE3.svg?style=svg" alt="ACE3 Build Status">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<sup><strong>Requires the latest version of <a href="https://github.com/CBATeam/CBA_A3/releases">CBA A3</a>.<br/>
|
<sup><strong>Requires the latest version of <a href="https://github.com/CBATeam/CBA_A3/releases">CBA A3</a>.<br/>
|
||||||
Visit us on <a href="https://twitter.com/ACE3Mod">Twitter</a> | <a href="https://www.facebook.com/ACE3Mod">Facebook</a> | <a href="https://www.youtube.com/c/ACE3Mod">YouTube</a> | <a href="http://www.reddit.com/r/arma/search?q=ACE&restrict_sr=on&sort=new&t=all">Reddit</a></strong></sup>
|
Visit us on <a href="https://twitter.com/ACE3Mod">Twitter</a> | <a href="https://www.facebook.com/ACE3Mod">Facebook</a> | <a href="https://www.youtube.com/c/ACE3Mod">YouTube</a> | <a href="https://www.reddit.com/r/arma/search?q=ACE&restrict_sr=on&sort=new&t=all">Reddit</a></strong></sup>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
**ACE3** is a joint effort by the teams behind **ACE2**, **AGM** and **CSE** to improve the realism and authenticity of Arma 3.
|
**ACE3** is a joint effort by the teams behind **ACE2**, **AGM** and **CSE** to improve the realism and authenticity of Arma 3.
|
||||||
@ -37,7 +37,8 @@ The project is entirely **open-source** and all contributions are welcome. Feel
|
|||||||
|
|
||||||
The mod is **built modularly**, so almost any included PBO can be easily removed from the configuration. This way, a team can maintain its own tailored version of ACE3 by simply excluding any components they don't need, or those possibly in conflict with other mods. Modules themselves, e.g. the medical system, also include various customization options, allowing mission designers to tweak the overall experience.
|
The mod is **built modularly**, so almost any included PBO can be easily removed from the configuration. This way, a team can maintain its own tailored version of ACE3 by simply excluding any components they don't need, or those possibly in conflict with other mods. Modules themselves, e.g. the medical system, also include various customization options, allowing mission designers to tweak the overall experience.
|
||||||
|
|
||||||
### Core features
|
## Core features
|
||||||
|
|
||||||
- Brand new 3D interaction/action system
|
- Brand new 3D interaction/action system
|
||||||
- Performance and reliability framework
|
- Performance and reliability framework
|
||||||
- Focus on modularity and customization
|
- Focus on modularity and customization
|
||||||
@ -51,7 +52,8 @@ The mod is **built modularly**, so almost any included PBO can be easily removed
|
|||||||
- Logistics
|
- Logistics
|
||||||
- Advanced missile guidance and laser designation
|
- Advanced missile guidance and laser designation
|
||||||
|
|
||||||
#### Additional features
|
### Additional features
|
||||||
|
|
||||||
- Carrying and dragging
|
- Carrying and dragging
|
||||||
- Realistic names for vehicles and weapons
|
- Realistic names for vehicles and weapons
|
||||||
- A fire control system (FCS) for armored vehicles and helicopters
|
- A fire control system (FCS) for armored vehicles and helicopters
|
||||||
@ -72,18 +74,56 @@ The mod is **built modularly**, so almost any included PBO can be easily removed
|
|||||||
- Vector, MicroDAGR and Kestrel devices<br>
|
- Vector, MicroDAGR and Kestrel devices<br>
|
||||||
***and much more...***
|
***and much more...***
|
||||||
|
|
||||||
### Guides & how-tos
|
## Getting started
|
||||||
If you installed ACE3 but have trouble understanding how it all works, or where to start, read this first:
|
|
||||||
- [Installation guide](http://ace3mod.com/wiki/user/installation-guide.html)
|
|
||||||
- [Information center](http://ace3mod.com/wiki/user/information-center.html)
|
|
||||||
|
|
||||||
#### Contributing
|
ACE3 requires Arma 3 and the latest version of <a href="https://github.com/CBATeam/CBA_A3/releases">CBA A3</a>. See the following pages for help and information on how to get started with ACE3:
|
||||||
You can help out with the ongoing development by looking for potential bugs in our code base, or by contributing new features. To contribute something to ACE3, simply fork this repository and submit your pull requests for review by other collaborators. Remember to add yourself to the author array of any PBO you will be editing and the [`AUTHORS.txt`](https://github.com/acemod/ACE3/blob/master/AUTHORS.txt) file; including a valid email address.
|
|
||||||
|
- [Installation guide](https://ace3mod.com/wiki/user/installation-guide.html)
|
||||||
|
- [Information center](https://ace3mod.com/wiki/user/information-center.html)
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
You can help out with the ongoing development by looking for potential bugs in our code base, or by contributing new features. We are always welcoming new pull requests containing bug fixes, refactors and new features. We have a list of tasks and bugs on our issue tracker on Github. Please comment on issues if you want to contribute with, to avoid duplicating effort.
|
||||||
|
|
||||||
|
### Contribution guidelines
|
||||||
|
|
||||||
|
To contribute something to ACE3, simply fork this repository and submit your pull requests for review by other collaborators. Remember to add yourself to the author array of any PBO you will be editing and the [`AUTHORS.txt`](https://github.com/acemod/ACE3/blob/master/AUTHORS.txt) file; including a valid email address.
|
||||||
|
|
||||||
|
### Submitting issues and requesting features
|
||||||
|
|
||||||
Please, use our [Issue Tracker](https://github.com/acemod/ACE3/issues) to report a bug, propose a feature, or suggest changes to the existing ones. See also:
|
Please, use our [Issue Tracker](https://github.com/acemod/ACE3/issues) to report a bug, propose a feature, or suggest changes to the existing ones. See also:
|
||||||
- [How to report an issue](http://ace3mod.com/wiki/user/how-to-report-an-issue.html)
|
- [How to report an issue](https://ace3mod.com/wiki/user/how-to-report-an-issue.html)
|
||||||
- [How to make a feature request](http://ace3mod.com/wiki/user/how-to-make-a-feature-request.html)
|
- [How to make a feature request](https://ace3mod.com/wiki/user/how-to-make-a-feature-request.html)
|
||||||
|
|
||||||
|
### Testing & building
|
||||||
|
|
||||||
#### 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:
|
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](http://ace3mod.com/wiki/development/setting-up-the-development-environment.html) – step-by-step instructions on how to properly setup and build a version of ACE3 for testing purposes.
|
|
||||||
|
- [Setting up the development environment](https://ace3mod.com/wiki/development/setting-up-the-development-environment.html) – step-by-step instructions on how to properly setup and build a version of ACE3 for testing purposes.
|
||||||
|
|
||||||
|
### Get in touch
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://slackin.ace3mod.com/">Slack</a></td>
|
||||||
|
<td>We have a public Slack team that anyone can join. This is where all our developers and contributors hang out and where we make announcements</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://twitter.com/ACE3Mod">Twitter</a></td>
|
||||||
|
<td>You can follow our Twitter account to get updates and various links to guides</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://www.facebook.com/ACE3Mod">Facebook</a></td>
|
||||||
|
<td>You can follow our Facebook account to get updates and various links to guides</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://forums.bistudio.com/topic/181341-ace3-a-collaborative-merger-between-agm-cse-and-ace/?p=2859670">Bohemia Forum</a></td>
|
||||||
|
<td>We have a dedicated thread on the Bohemia Forums for the ACE3 project</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
ACE3 is licensed under the GNU General Public License ([GPLv2](https://github.com/acemod/ACE3/blob/master/LICENSE)).
|
||||||
|
Binary file not shown.
BIN
ace_advanced_ballistics_x64.dll
Normal file
BIN
ace_advanced_ballistics_x64.dll
Normal file
Binary file not shown.
BIN
ace_break_line_x64.dll
Normal file
BIN
ace_break_line_x64.dll
Normal file
Binary file not shown.
BIN
ace_clipboard_x64.dll
Normal file
BIN
ace_clipboard_x64.dll
Normal file
Binary file not shown.
BIN
ace_fcs_x64.dll
Normal file
BIN
ace_fcs_x64.dll
Normal file
Binary file not shown.
BIN
ace_medical_x64.dll
Normal file
BIN
ace_medical_x64.dll
Normal file
Binary file not shown.
BIN
ace_parse_imagepath_x64.dll
Normal file
BIN
ace_parse_imagepath_x64.dll
Normal file
Binary file not shown.
@ -6,43 +6,13 @@ class ACE_Settings {
|
|||||||
typeName = "BOOL";
|
typeName = "BOOL";
|
||||||
value = 0;
|
value = 0;
|
||||||
};
|
};
|
||||||
class GVAR(simulateForSnipers) {
|
class GVAR(muzzleVelocityVariationEnabled) {
|
||||||
category = CSTRING(DisplayName);
|
category = CSTRING(DisplayName);
|
||||||
displayName = CSTRING(simulateForSnipers_DisplayName);
|
displayName = CSTRING(muzzleVelocityVariationEnabled_DisplayName);
|
||||||
description = CSTRING(simulateForSnipers_Description);
|
description = CSTRING(muzzleVelocityVariationEnabled_Description);
|
||||||
typeName = "BOOL";
|
typeName = "BOOL";
|
||||||
value = 1;
|
value = 1;
|
||||||
};
|
};
|
||||||
class GVAR(simulateForGroupMembers) {
|
|
||||||
category = CSTRING(DisplayName);
|
|
||||||
displayName = CSTRING(simulateForGroupMembers_DisplayName);
|
|
||||||
description = CSTRING(simulateForGroupMembers_Description);
|
|
||||||
typeName = "BOOL";
|
|
||||||
value = 0;
|
|
||||||
};
|
|
||||||
class GVAR(simulateForEveryone) {
|
|
||||||
category = CSTRING(DisplayName);
|
|
||||||
displayName = CSTRING(simulateForEveryone_DisplayName);
|
|
||||||
description = CSTRING(simulateForEveryone_Description);
|
|
||||||
typeName = "BOOL";
|
|
||||||
value = 0;
|
|
||||||
};
|
|
||||||
class GVAR(disabledInFullAutoMode) {
|
|
||||||
category = CSTRING(DisplayName);
|
|
||||||
displayName = CSTRING(disabledInFullAutoMod_DisplayName);
|
|
||||||
description = CSTRING(disabledInFullAutoMod_Description);
|
|
||||||
typeName = "BOOL";
|
|
||||||
value = 0;
|
|
||||||
};
|
|
||||||
/* // TODO: We currently do not have firedEHs on vehicles
|
|
||||||
class GVAR(vehicleGunnerEnabled) {
|
|
||||||
category = CSTRING(DisplayName);
|
|
||||||
displayName = "Enabled For Vehicle Gunners";
|
|
||||||
description = "Enables advanced ballistics for vehicle gunners";
|
|
||||||
typeName = "BOOL";
|
|
||||||
value = 0;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
class GVAR(ammoTemperatureEnabled) {
|
class GVAR(ammoTemperatureEnabled) {
|
||||||
category = CSTRING(DisplayName);
|
category = CSTRING(DisplayName);
|
||||||
displayName = CSTRING(ammoTemperatureEnabled_DisplayName);
|
displayName = CSTRING(ammoTemperatureEnabled_DisplayName);
|
||||||
@ -69,13 +39,7 @@ class ACE_Settings {
|
|||||||
displayName = CSTRING(simulationInterval_DisplayName);
|
displayName = CSTRING(simulationInterval_DisplayName);
|
||||||
description = CSTRING(simulationInterval_Description);
|
description = CSTRING(simulationInterval_Description);
|
||||||
typeName = "SCALAR";
|
typeName = "SCALAR";
|
||||||
value = 0.0;
|
value = 0.05;
|
||||||
};
|
sliderSettings[] = {0, 0.2, 0.05, 2};
|
||||||
class GVAR(simulationRadius) {
|
|
||||||
category = CSTRING(DisplayName);
|
|
||||||
displayName = CSTRING(simulationRadius_DisplayName);
|
|
||||||
description = CSTRING(simulationRadius_Description);
|
|
||||||
typeName = "SCALAR";
|
|
||||||
value = 3000;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
class CfgVehicles {
|
class CfgVehicles {
|
||||||
class ACE_Module;
|
class ACE_Module;
|
||||||
class GVAR(ModuleSettings): ACE_Module {
|
class GVAR(ModuleSettings): ACE_Module {
|
||||||
scope = 2;
|
scope = 1;
|
||||||
displayName = CSTRING(DisplayName);
|
displayName = CSTRING(DisplayName);
|
||||||
icon = QPATHTOF(UI\Icon_Module_Wind_ca.paa);
|
icon = QPATHTOF(UI\Icon_Module_Wind_ca.paa);
|
||||||
category = "ACE";
|
category = "ACE";
|
||||||
@ -17,38 +17,12 @@ class CfgVehicles {
|
|||||||
typeName = "BOOL";
|
typeName = "BOOL";
|
||||||
defaultValue = 0;
|
defaultValue = 0;
|
||||||
};
|
};
|
||||||
class simulateForSnipers {
|
class muzzleVelocityVariationEnabled {
|
||||||
displayName = CSTRING(simulateForSnipers_DisplayName);
|
displayName = CSTRING(muzzleVelocityVariationEnabled_DisplayName);
|
||||||
description = CSTRING(simulateForSnipers_Description);
|
description = CSTRING(muzzleVelocityVariationEnabled_Description);
|
||||||
typeName = "BOOL";
|
typeName = "BOOL";
|
||||||
defaultValue = 1;
|
defaultValue = 1;
|
||||||
};
|
};
|
||||||
class simulateForGroupMembers {
|
|
||||||
displayName = CSTRING(simulateForGroupMembers_DisplayName);
|
|
||||||
description = CSTRING(simulateForGroupMembers_Description);
|
|
||||||
typeName = "BOOL";
|
|
||||||
defaultValue = 0;
|
|
||||||
};
|
|
||||||
class simulateForEveryone {
|
|
||||||
displayName = CSTRING(simulateForEveryone_DisplayName);
|
|
||||||
description = CSTRING(simulateForEveryone_Description);
|
|
||||||
typeName = "BOOL";
|
|
||||||
defaultValue = 0;
|
|
||||||
};
|
|
||||||
class disabledInFullAutoMode {
|
|
||||||
displayName = CSTRING(disabledInFullAutoMod_DisplayName);
|
|
||||||
description = CSTRING(disabledInFullAutoMod_Description);
|
|
||||||
typeName = "BOOL";
|
|
||||||
defaultValue = 0;
|
|
||||||
};
|
|
||||||
/* // TODO: We currently do not have firedEHs on vehicles
|
|
||||||
class vehicleGunnerEnabled {
|
|
||||||
displayName = "Enabled For Vehicle Gunners";
|
|
||||||
description = "Enables advanced ballistics for vehicle gunners";
|
|
||||||
typeName = "BOOL";
|
|
||||||
defaultValue = 0;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
class ammoTemperatureEnabled {
|
class ammoTemperatureEnabled {
|
||||||
displayName = CSTRING(ammoTemperatureEnabled_DisplayName);
|
displayName = CSTRING(ammoTemperatureEnabled_DisplayName);
|
||||||
description = CSTRING(ammoTemperatureEnabled_Description);
|
description = CSTRING(ammoTemperatureEnabled_Description);
|
||||||
@ -71,13 +45,7 @@ class CfgVehicles {
|
|||||||
displayName = CSTRING(simulationInterval_DisplayName);
|
displayName = CSTRING(simulationInterval_DisplayName);
|
||||||
description = CSTRING(simulationInterval_Description);
|
description = CSTRING(simulationInterval_Description);
|
||||||
typeName = "NUMBER";
|
typeName = "NUMBER";
|
||||||
defaultValue = 0.0;
|
defaultValue = 0.05;
|
||||||
};
|
|
||||||
class simulationRadius {
|
|
||||||
displayName = CSTRING(simulationRadius_DisplayName);
|
|
||||||
description = CSTRING(simulationRadius_Description);
|
|
||||||
typeName = "NUMBER";
|
|
||||||
defaultValue = 3000;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
class ModuleDescription {
|
class ModuleDescription {
|
||||||
|
@ -9,19 +9,6 @@ GVAR(ProtractorStart) = CBA_missionTime;
|
|||||||
GVAR(allBullets) = [];
|
GVAR(allBullets) = [];
|
||||||
GVAR(currentGrid) = 0;
|
GVAR(currentGrid) = 0;
|
||||||
|
|
||||||
GVAR(extensionAvailable) = true;
|
|
||||||
/* @TODO: Remove this until versioning is in sync with cmake/build versioning
|
|
||||||
GVAR(extensionVersion) = ("ace_advanced_ballistics" callExtension "version");
|
|
||||||
GVAR(extensionAvailable) = (GVAR(extensionVersion) == EXTENSION_REQUIRED_VERSION);
|
|
||||||
if (!GVAR(extensionAvailable)) exitWith {
|
|
||||||
if (GVAR(extensionVersion) == "") then {
|
|
||||||
diag_log text "[ACE] ERROR: ace_advanced_ballistics.dll is missing";
|
|
||||||
} else {
|
|
||||||
diag_log text "[ACE] ERROR: ace_advanced_ballistics.dll is incompatible";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!hasInterface) exitWith {};
|
if (!hasInterface) exitWith {};
|
||||||
|
|
||||||
["ace_settingsInitialized", {
|
["ace_settingsInitialized", {
|
||||||
@ -39,7 +26,7 @@ if (!hasInterface) exitWith {};
|
|||||||
{
|
{
|
||||||
_x params ["_modPBO", "_compatPBO"];
|
_x params ["_modPBO", "_compatPBO"];
|
||||||
if ((isClass (configFile >> "CfgPatches" >> _modPBO)) && {!isClass (configFile >> "CfgPatches" >> _compatPBO)}) then {
|
if ((isClass (configFile >> "CfgPatches" >> _modPBO)) && {!isClass (configFile >> "CfgPatches" >> _compatPBO)}) then {
|
||||||
ACE_LOGWARNING_2("Weapon Mod [%1] missing ace compat pbo [%2] (from @ace\optionals)",_modPBO,_compatPBO);
|
WARNING_2("Weapon Mod [%1] missing ace compat pbo [%2] (from @ace\optionals)",_modPBO,_compatPBO);
|
||||||
};
|
};
|
||||||
} forEach [
|
} forEach [
|
||||||
["RH_acc","ace_compat_rh_acc"],
|
["RH_acc","ace_compat_rh_acc"],
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
ADDON = false;
|
ADDON = false;
|
||||||
|
|
||||||
|
PREP_RECOMPILE_START;
|
||||||
#include "XEH_PREP.hpp"
|
#include "XEH_PREP.hpp"
|
||||||
|
PREP_RECOMPILE_END;
|
||||||
|
|
||||||
ADDON = true;
|
ADDON = true;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Ruthberg
|
* Author: Ruthberg
|
||||||
*
|
*
|
||||||
@ -10,26 +11,24 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* muzzle velocity shift - m/s <NUMBER>
|
* muzzle velocity shift - m/s <NUMBER>
|
||||||
*
|
*
|
||||||
|
* Example:
|
||||||
|
* [[], 5] call ace_advanced_ballistics_fnc_calcilateAmmoTemperatureVelocityShift
|
||||||
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_muzzleVelocityShiftTable", "_temperature"];
|
params ["_muzzleVelocityShiftTable", "_temperature"];
|
||||||
|
|
||||||
// Check if muzzleVelocityShiftTable is Less Than 11 Entrys
|
// Check if muzzleVelocityShiftTable is less than 11 Entrys
|
||||||
if ((count _muzzleVelocityShiftTable) < 11) exitWith {0};
|
if ((count _muzzleVelocityShiftTable) < 11) exitWith {0};
|
||||||
private _muzzleVelocityShiftTableUpperLimit = _muzzleVelocityShiftTable select 10;
|
private _muzzleVelocityShiftTableUpperLimit = _muzzleVelocityShiftTable select 10;
|
||||||
if (isNil "_muzzleVelocityShiftTableUpperLimit") exitWith { 0 };
|
if (isNil "_muzzleVelocityShiftTableUpperLimit") exitWith {0};
|
||||||
|
|
||||||
// Find exact data index required for given temperature
|
// Find exact data index required for given temperature
|
||||||
private _temperatureIndexFunction = (_temperature + 15) / 5;
|
private _temperatureIndexFunction = 0 max ((_temperature + 15) / 5) min 10;
|
||||||
|
|
||||||
// lower and upper data index used for interpolation
|
// Lower and upper data index used for interpolation
|
||||||
private _temperatureIndexA = (0 max (floor(_temperatureIndexFunction))) min 10;
|
private _temperatureIndexA = floor(_temperatureIndexFunction);
|
||||||
private _temperatureIndexB = (0 max (ceil(_temperatureIndexFunction))) min 10;
|
private _temperatureIndexB = ceil(_temperatureIndexFunction);
|
||||||
|
|
||||||
// Interpolation ratio
|
linearConversion [_temperatureIndexA, _temperatureIndexB, _temperatureIndexFunction, _muzzleVelocityShiftTable select _temperatureIndexA, _muzzleVelocityShiftTable select _temperatureIndexB, true] // Return
|
||||||
private _interpolationRatio = _temperatureIndexFunction - floor(_temperatureIndexFunction);
|
|
||||||
|
|
||||||
// Interpolation
|
|
||||||
(_muzzleVelocityShiftTable select _temperatureIndexA) * (1 - _interpolationRatio) + (_muzzleVelocityShiftTable select _temperatureIndexB) * _interpolationRatio // Return
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Ruthberg
|
* Author: Ruthberg
|
||||||
*
|
*
|
||||||
@ -13,9 +14,11 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* corrected ballistic coefficient <NUMBER>
|
* corrected ballistic coefficient <NUMBER>
|
||||||
*
|
*
|
||||||
|
* Example:
|
||||||
|
* [2, 5, 5, 0.5, "ASM"] call ace_advanced_ballistics_fnc_calculateAtmosphericCorrection
|
||||||
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_ballisticCoefficient", "_temperature"/*in C*/, "_pressure"/*in hPa*/, "_relativeHumidity"/*as ratio 0-1*/, "_atmosphereModel"/*"ICAO" or "ASM"*/];
|
params ["_ballisticCoefficient", "_temperature"/*in C*/, "_pressure"/*in hPa*/, "_relativeHumidity"/*as ratio 0-1*/, "_atmosphereModel"/*"ICAO" or "ASM"*/];
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Ruthberg, MikeMatrix, joko // Jonas
|
* Author: Ruthberg, MikeMatrix, joko // Jonas
|
||||||
*
|
*
|
||||||
* Calculates the muzzle velocity shift caused by different barrel lengths
|
* Calculates the muzzle velocity shift caused by different barrel lengths
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: barrel length - mm
|
* 0: barrel length - mm <NUMBER>
|
||||||
* 1: muzzle velocity lookup table - m/s <ARRAY>
|
* 1: muzzle velocity lookup table - m/s <ARRAY>
|
||||||
* 2: barrel length lookup table - mm <ARRAY>
|
* 2: barrel length lookup table - mm <ARRAY>
|
||||||
* 3: muzzle velocity - m/s <NUMBER>
|
* 3: muzzle velocity - m/s <NUMBER>
|
||||||
@ -12,26 +13,23 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* muzzle velocity shift - m/s <NUMBER>
|
* muzzle velocity shift - m/s <NUMBER>
|
||||||
*
|
*
|
||||||
|
* Example:
|
||||||
|
* [5, [0,5], [0,5], 5] call ace_advanced_ballistics_fnc_calculateBarrelLengthVelocityShift
|
||||||
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
scopeName "main";
|
|
||||||
|
|
||||||
private ["_muzzleVelocityTableCount", "_barrelLengthTableCount", "_lowerDataIndex",
|
|
||||||
"_upperDataIndex", "_lowerBarrelLength", "_upperBarrelLength", "_lowerMuzzleVelocity",
|
|
||||||
"_upperMuzzleVelocity", "_interpolationRatio"];
|
|
||||||
params ["_barrelLength", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleVelocity"];
|
params ["_barrelLength", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleVelocity"];
|
||||||
TRACE_4("params",_barrelLength,_muzzleVelocityTable,_barrelLengthTable,_muzzleVelocity);
|
TRACE_4("params",_barrelLength,_muzzleVelocityTable,_barrelLengthTable,_muzzleVelocity);
|
||||||
|
|
||||||
// If barrel length is not defined, then there is no point in calculating muzzle velocity
|
// If barrel length is not defined, then there is no point in calculating muzzle velocity
|
||||||
if (_barrelLength == 0) exitWith { 0 };
|
if (_barrelLength == 0) exitWith { 0 };
|
||||||
|
|
||||||
_muzzleVelocityTableCount = count _muzzleVelocityTable;
|
private _muzzleVelocityTableCount = count _muzzleVelocityTable;
|
||||||
_barrelLengthTableCount = count _barrelLengthTable;
|
private _barrelLengthTableCount = count _barrelLengthTable;
|
||||||
|
|
||||||
// Exit if tables are different sizes, have no elements or have only one element
|
// Exit if tables are different sizes, have no elements or have only one element
|
||||||
if (_muzzleVelocityTableCount != _barrelLengthTableCount || _muzzleVelocityTableCount == 0 || _barrelLengthTableCount == 0) exitWith { 0 };
|
if (_muzzleVelocityTableCount != _barrelLengthTableCount || _muzzleVelocityTableCount == 0) exitWith { 0 };
|
||||||
if (_muzzleVelocityTableCount == 1) exitWith { (_muzzleVelocityTable select 0) - _muzzleVelocity };
|
if (_muzzleVelocityTableCount == 1) exitWith { (_muzzleVelocityTable select 0) - _muzzleVelocity };
|
||||||
|
|
||||||
// If we have the precise barrel length value, return result immediately
|
// If we have the precise barrel length value, return result immediately
|
||||||
@ -43,29 +41,15 @@ if (_barrelLength in _barrelLengthTable) exitWith {
|
|||||||
if (_barrelLength <= (_barrelLengthTable select 0)) exitWith { (_muzzleVelocityTable select 0) - _muzzleVelocity };
|
if (_barrelLength <= (_barrelLengthTable select 0)) exitWith { (_muzzleVelocityTable select 0) - _muzzleVelocity };
|
||||||
if (_barrelLength >= (_barrelLengthTable select _barrelLengthTableCount - 1)) exitWith { (_muzzleVelocityTable select _barrelLengthTableCount - 1) - _muzzleVelocity };
|
if (_barrelLength >= (_barrelLengthTable select _barrelLengthTableCount - 1)) exitWith { (_muzzleVelocityTable select _barrelLengthTableCount - 1) - _muzzleVelocity };
|
||||||
|
|
||||||
|
private _upperDataIndex = 0;
|
||||||
|
private _lowerDataIndex = 1;
|
||||||
|
|
||||||
// Find closest bordering values for barrel length
|
// Find closest bordering values for barrel length
|
||||||
{
|
{
|
||||||
if (_barrelLength <= _x) then {
|
if (_barrelLength <= _x) exitWith {
|
||||||
_upperDataIndex = _forEachIndex;
|
_upperDataIndex = _forEachIndex;
|
||||||
_lowerDataIndex = _upperDataIndex - 1;
|
_lowerDataIndex = _upperDataIndex - 1;
|
||||||
breakTo "main";
|
|
||||||
};
|
};
|
||||||
} forEach _barrelLengthTable;
|
} forEach _barrelLengthTable;
|
||||||
|
|
||||||
// Worst case scenario
|
(linearConversion [_barrelLengthTable select _lowerDataIndex, _barrelLengthTable select _upperDataIndex, _barrelLength, _muzzleVelocityTable select _lowerDataIndex, _muzzleVelocityTable select _upperDataIndex]) - _muzzleVelocity // Return
|
||||||
if (isNil "_lowerDataIndex" || isNil "_upperDataIndex") exitWith {0};
|
|
||||||
|
|
||||||
_lowerBarrelLength = _barrelLengthTable select _lowerDataIndex;
|
|
||||||
_upperBarrelLength = _barrelLengthTable select _upperDataIndex;
|
|
||||||
_lowerMuzzleVelocity = _muzzleVelocityTable select _lowerDataIndex;
|
|
||||||
_upperMuzzleVelocity = _muzzleVelocityTable select _upperDataIndex;
|
|
||||||
|
|
||||||
// Calculate interpolation ratio
|
|
||||||
_interpolationRatio = if (abs (_lowerBarrelLength - _upperBarrelLength) > 0) then {
|
|
||||||
(_upperBarrelLength - _barrelLength) / (_upperBarrelLength - _lowerBarrelLength)
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
// Calculate interpolated muzzle velocity shift
|
|
||||||
(_lowerMuzzleVelocity + ((_upperMuzzleVelocity - _lowerMuzzleVelocity) * (1 - _interpolationRatio))) - _muzzleVelocity // Return
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Ruthberg
|
* Author: Ruthberg
|
||||||
*
|
*
|
||||||
@ -11,9 +12,11 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* retardation - m/(s^2) <NUMBER>
|
* retardation - m/(s^2) <NUMBER>
|
||||||
*
|
*
|
||||||
|
* Example:
|
||||||
|
* [5, 20, 10] call ace_advanced_ballistics_fnc_calculateRetardation
|
||||||
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
// Source: GNU Exterior Ballistics
|
// Source: GNU Exterior Ballistics
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Ruthberg
|
* Author: Ruthberg
|
||||||
*
|
*
|
||||||
@ -15,9 +16,11 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* stability factor <NUMBER>
|
* stability factor <NUMBER>
|
||||||
*
|
*
|
||||||
|
* Example:
|
||||||
|
* [1, 2, 3, 4, 5, 6, 7] call ace_advanced_ballistics_fnc_calculateStabilityFactor
|
||||||
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_caliber", "_bulletLength", "_bulletMass", "_barrelTwist", "_muzzleVelocity", "_temperature", "_barometricPressure"];
|
params ["_caliber", "_bulletLength", "_bulletMass", "_barrelTwist", "_muzzleVelocity", "_temperature", "_barometricPressure"];
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#define DEBUG_MODE_FULL
|
||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: esteldunedain
|
* Author: esteldunedain
|
||||||
*
|
*
|
||||||
@ -10,10 +12,20 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
|
* Example:
|
||||||
|
* [] call ace_advanced_ballistics_fnc_diagnoseWeapons
|
||||||
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#define DEBUG_MODE_FULL
|
|
||||||
#include "script_component.hpp"
|
private _diagnoseStartTime = diag_tickTime;
|
||||||
|
#ifdef DEBUG_INIT_SPEEDS
|
||||||
|
private _data = [];
|
||||||
|
private _weapons = [];
|
||||||
|
private _magazines = [];
|
||||||
|
private _weaponInitSpeeds = [];
|
||||||
|
private _magazineInitSpeeds = [];
|
||||||
|
#endif
|
||||||
|
|
||||||
private _cfgWeapons = configFile >> "CfgWeapons";
|
private _cfgWeapons = configFile >> "CfgWeapons";
|
||||||
for "_i" from 0 to (count _cfgWeapons)-1 do {
|
for "_i" from 0 to (count _cfgWeapons)-1 do {
|
||||||
@ -21,9 +33,7 @@ for "_i" from 0 to (count _cfgWeapons)-1 do {
|
|||||||
if (isClass _weaponConfig) then {
|
if (isClass _weaponConfig) then {
|
||||||
private _weapon = configName _weaponConfig;
|
private _weapon = configName _weaponConfig;
|
||||||
private _weaponType = getNumber (_weaponConfig >> "Type");
|
private _weaponType = getNumber (_weaponConfig >> "Type");
|
||||||
if (_weaponType == 1) then {
|
if (_weaponType in [TYPE_WEAPON_PRIMARY, TYPE_WEAPON_HANDGUN]) then {
|
||||||
// The weapon is a primary weapon
|
|
||||||
|
|
||||||
private _weaponInitSpeed = getNumber (_weaponConfig >> "initSpeed");
|
private _weaponInitSpeed = getNumber (_weaponConfig >> "initSpeed");
|
||||||
private _magazines = getArray (_weaponConfig >> "magazines");
|
private _magazines = getArray (_weaponConfig >> "magazines");
|
||||||
{
|
{
|
||||||
@ -44,16 +54,78 @@ for "_i" from 0 to (count _cfgWeapons)-1 do {
|
|||||||
|
|
||||||
// AB initial speed --------------------------------
|
// AB initial speed --------------------------------
|
||||||
// Get Weapon and Ammo Configurations
|
// Get Weapon and Ammo Configurations
|
||||||
private _AmmoCacheEntry = _ammo call FUNC(readAmmoDataFromConfig);
|
private _AmmoCacheEntry = uiNamespace getVariable format[QGVAR(%1), _ammo];
|
||||||
private _WeaponCacheEntry = _weapon call FUNC(readWeaponDataFromConfig);
|
if (isNil "_AmmoCacheEntry") then {
|
||||||
_AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable"];
|
_AmmoCacheEntry = _ammo call FUNC(readAmmoDataFromConfig);
|
||||||
|
};
|
||||||
|
private _WeaponCacheEntry = uiNamespace getVariable format[QGVAR(%1), _weapon];
|
||||||
|
if (isNil "_WeaponCacheEntry") then {
|
||||||
|
_WeaponCacheEntry = _weapon call FUNC(readWeaponDataFromConfig);
|
||||||
|
};
|
||||||
|
_AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleVelocityVariationSD"];
|
||||||
_WeaponCacheEntry params ["_barrelTwist", "_twistDirection", "_barrelLength"];
|
_WeaponCacheEntry params ["_barrelTwist", "_twistDirection", "_barrelLength"];
|
||||||
|
|
||||||
private _barrelVelocityShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _vanillaInitialSpeed] call FUNC(calculateBarrelLengthVelocityShift);
|
private _barrelVelocityShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _vanillaInitialSpeed] call FUNC(calculateBarrelLengthVelocityShift);
|
||||||
private _abInitialSpeed = _vanillaInitialSpeed + _barrelVelocityShift;
|
private _abInitialSpeed = _vanillaInitialSpeed + _barrelVelocityShift;
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
diag_log text format ["ABDiagnose,%1,%2,%3,%4,%5,%6,%7",_weapon,_magazine,_ammo,_magazineInitSpeed,_weaponInitSpeed,_vanillaInitialSpeed,_abInitialSpeed];
|
|
||||||
|
if (_weapon find "_base" == -1 && _weapon find "_Base" == -1) then {
|
||||||
|
#ifdef DEBUG_INIT_SPEEDS
|
||||||
|
_data pushBack [-_forEachIndex, _abInitialSpeed, _magazine, _weapon];
|
||||||
|
#endif
|
||||||
|
if (_barrelLength > 0 && abs(_vanillaInitialSpeed - _abInitialSpeed) > abs(_abInitialSpeed) * 0.0025) then {
|
||||||
|
diag_log text format ["AB_Diagnose_initSpeed,%1,%2,%3,%4,%5,%6,%7,%8",_weapon,_magazine,_ammo,_magazineInitSpeed,_weaponInitSpeed,_vanillaInitialSpeed,_abInitialSpeed,_abInitialSpeed/_vanillaInitialSpeed];
|
||||||
|
};
|
||||||
|
if (_barrelTwist == 0) then {
|
||||||
|
diag_log text format ["AB_Diagnose_barrelTwist,%1,%2,%3,%4,%5",_weapon,_magazine,_ammo,_twistDirection,_barrelTwist];
|
||||||
|
};
|
||||||
|
if (_barrelLength == 0) then {
|
||||||
|
diag_log text format ["AB_Diagnose_barrelLength,%1,%2,%3,%4,%5",_weapon,_magazine,_ammo,_barrelLength];
|
||||||
|
};
|
||||||
|
};
|
||||||
} forEach _magazines;
|
} forEach _magazines;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef DEBUG_INIT_SPEEDS
|
||||||
|
_data sort false;
|
||||||
|
{
|
||||||
|
_x params ["_magazineIndex", "_abInitialSpeed", "_magazine", "_weapon"];
|
||||||
|
if (_magazines find _magazine == -1) then {
|
||||||
|
private _magSpeed = _abInitialSpeed;
|
||||||
|
private _ammoRef = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo");
|
||||||
|
if (_ammoRef != "") then {
|
||||||
|
{
|
||||||
|
private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo");
|
||||||
|
if (_ammo == _ammoRef) exitWith {
|
||||||
|
_magSpeed = _magazineInitSpeeds select _forEachIndex;
|
||||||
|
};
|
||||||
|
} forEach _magazines;
|
||||||
|
};
|
||||||
|
_magazines pushBack _magazine;
|
||||||
|
_magazineInitSpeeds pushBack round(_magSpeed);
|
||||||
|
};
|
||||||
|
if (_weapons find _weapon == -1) then {
|
||||||
|
_weapons pushBack _weapon;
|
||||||
|
_magIndex = _magazines find _magazine;
|
||||||
|
_magSpeed = _magazineInitSpeeds select _magIndex;
|
||||||
|
_weaponInitSpeeds pushBack (_abInitialSpeed / _magSpeed);
|
||||||
|
};
|
||||||
|
} forEach _data;
|
||||||
|
{
|
||||||
|
_x params ["_magazineIndex", "_abInitialSpeed", "_magazine", "_weapon"];
|
||||||
|
_magIndex = _magazines find _magazine;
|
||||||
|
_magSpeed = _magazineInitSpeeds select _magIndex;
|
||||||
|
_wepIndex = _weapons find _weapon;
|
||||||
|
_wepSpeed = _weaponInitSpeeds select _wepIndex;
|
||||||
|
} forEach _data;
|
||||||
|
{
|
||||||
|
diag_log text format ["AB_WeaponInitSpeed,%1,%2", _x, _weaponInitSpeeds select _forEachIndex];
|
||||||
|
} forEach _weapons;
|
||||||
|
{
|
||||||
|
diag_log text format ["AB_MagazineInitSpeed,%1,%2", _x, _magazineInitSpeeds select _forEachIndex];
|
||||||
|
} forEach _magazines;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
diag_log format["AdvancedBallistics: Finished 'diagnoseWeapons' in %1 seconds", (diag_tickTime - _diagnoseStartTime) toFixed 2];
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Ruthberg
|
* Author: Ruthberg
|
||||||
*
|
*
|
||||||
@ -9,9 +10,11 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
|
* Example:
|
||||||
|
* [] call ace_advanced_ballistics_fnc_displayProtractor
|
||||||
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
#define __dsp (uiNamespace getVariable "RscProtractor")
|
#define __dsp (uiNamespace getVariable "RscProtractor")
|
||||||
#define __ctrl1 (__dsp displayCtrl 132950)
|
#define __ctrl1 (__dsp displayCtrl 132950)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Glowbal, Ruthberg, joko // Jonas
|
* Author: Glowbal, Ruthberg, joko // Jonas
|
||||||
* Handle the PFH for Bullets
|
* Handle the PFH for Bullets
|
||||||
@ -8,29 +9,26 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
|
* Example:
|
||||||
|
* [] call ace_advanced_ballistics_fnc_handleFirePFH
|
||||||
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
private _aceTimeSecond = floor CBA_missionTime;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
_x params ["_bullet","_caliber","_bulletTraceVisible","_index"];
|
_x params ["_bullet","_caliber","_bulletTraceVisible","_index"];
|
||||||
|
|
||||||
private _bulletVelocity = velocity _bullet;
|
if (!alive _bullet) then {
|
||||||
|
|
||||||
private _bulletSpeed = vectorMagnitude _bulletVelocity;
|
|
||||||
|
|
||||||
if (!alive _bullet || _bulletSpeed < 100) then {
|
|
||||||
GVAR(allBullets) deleteAt (GVAR(allBullets) find _x);
|
GVAR(allBullets) deleteAt (GVAR(allBullets) find _x);
|
||||||
} else {
|
} else {
|
||||||
|
private _bulletVelocity = velocity _bullet;
|
||||||
private _bulletPosition = getPosASL _bullet;
|
private _bulletPosition = getPosASL _bullet;
|
||||||
|
|
||||||
if (_bulletTraceVisible && _bulletSpeed > 500) then {
|
if (_bulletTraceVisible && {vectorMagnitude _bulletVelocity > BULLET_TRACE_MIN_VELOCITY}) then {
|
||||||
drop ["\A3\data_f\ParticleEffects\Universal\Refract","","Billboard",1,0.1,getPos _bullet,[0,0,0],0,1.275,1,0,[0.02*_caliber,0.01*_caliber],[[0,0,0,0.65],[0,0,0,0.2]],[1,0],0,0,"","",""];
|
drop ["\A3\data_f\ParticleEffects\Universal\Refract","","Billboard",1,0.1,getPos _bullet,[0,0,0],0,1.275,1,0,[0.02*_caliber,0.01*_caliber],[[0,0,0,0.65],[0,0,0,0.2]],[1,0],0,0,"","",""];
|
||||||
};
|
};
|
||||||
|
|
||||||
call compile ("ace_advanced_ballistics" callExtension format["simulate:%1:%2:%3:%4:%5:%6:%7", _index, _bulletVelocity, _bulletPosition, ACE_wind, ASLToATL(_bulletPosition) select 2, _aceTimeSecond, CBA_missionTime - _aceTimeSecond]);
|
_bullet setVelocity (_bulletVelocity vectorAdd (parseSimpleArray ("ace_advanced_ballistics" callExtension format["simulate:%1:%2:%3:%4:%5:%6", _index, _bulletVelocity, _bulletPosition, wind, ASLToATL(_bulletPosition) select 2, CBA_missionTime toFixed 6])));
|
||||||
};
|
};
|
||||||
nil
|
nil
|
||||||
} count +GVAR(allBullets);
|
} count +GVAR(allBullets);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Glowbal, Ruthberg
|
* Author: Glowbal, Ruthberg
|
||||||
*
|
*
|
||||||
@ -9,109 +10,117 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
|
* Example:
|
||||||
|
* [] call ace_advanced_ballistics_fnc_handleFired
|
||||||
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"];
|
//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);
|
||||||
|
|
||||||
// Parameterization
|
|
||||||
private ["_abort", "_AmmoCacheEntry", "_WeaponCacheEntry", "_opticsName", "_opticType", "_bulletTraceVisible", "_temperature", "_barometricPressure", "_bulletMass", "_bulletLength", "_muzzleVelocity", "_muzzleVelocityShift", "_bulletVelocity", "_bulletLength", "_barrelTwist", "_stabilityFactor", "_aceTimeSecond", "_barrelVelocityShift", "_ammoTemperatureVelocityShift"];
|
|
||||||
|
|
||||||
_abort = false;
|
|
||||||
|
|
||||||
if (!(_ammo isKindOf "BulletBase")) exitWith {};
|
if (!(_ammo isKindOf "BulletBase")) exitWith {};
|
||||||
if (!alive _projectile) exitWith {};
|
if (!alive _projectile) exitWith {};
|
||||||
if (_unit distance ACE_player > GVAR(simulationRadius)) exitWith {};
|
|
||||||
if (underwater _unit) exitWith {};
|
if (underwater _unit) exitWith {};
|
||||||
if (!GVAR(simulateForEveryone) && !(local _unit)) then {
|
|
||||||
// The shooter is non local
|
|
||||||
_abort = true;
|
|
||||||
if (GVAR(simulateForSnipers)) then {
|
|
||||||
if (currentWeapon _unit == primaryWeapon _unit && count primaryWeaponItems _unit > 2) then {
|
|
||||||
_opticsName = (primaryWeaponItems _unit) select 2;
|
|
||||||
_opticType = getNumber(configFile >> "CfgWeapons" >> _opticsName >> "ItemInfo" >> "opticType");
|
|
||||||
_abort = _opticType != 2; // We only abort if the non local shooter is not a sniper
|
|
||||||
};
|
|
||||||
};
|
|
||||||
if (GVAR(simulateForGroupMembers) && _abort) then {
|
|
||||||
_abort = (group ACE_player) != (group _unit);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
//if (!GVAR(vehicleGunnerEnabled) && !(_unit isKindOf "Man")) then { _abort = true; }; // We currently do not have firedEHs on vehicles
|
|
||||||
if (GVAR(disabledInFullAutoMode) && getNumber(configFile >> "CfgWeapons" >> _weapon >> _mode >> "autoFire") == 1) then { _abort = true; };
|
|
||||||
|
|
||||||
if (_abort || !(GVAR(extensionAvailable))) exitWith {
|
private _abort = !local _unit;
|
||||||
if (missionNamespace getVariable [QEGVAR(windDeflection,enabled), false]) then {
|
if (_abort) then {
|
||||||
EGVAR(windDeflection,trackedBullets) pushBack [_projectile, getNumber(configFile >> "CfgAmmo" >> _ammo >> "airFriction")];
|
private _bulletVelocity = velocity _projectile;
|
||||||
|
private _muzzleVelocity = vectorMagnitude _bulletVelocity;
|
||||||
|
|
||||||
|
private _maxRange = uiNamespace getVariable format[QGVAR(maxRange_%1), _ammo];
|
||||||
|
if (isNil "_maxRange") then {
|
||||||
|
private _airFriction = getNumber(configFile >> "CfgAmmo" >> _ammo >> "airFriction");
|
||||||
|
private _maxRange = if (_airFriction < 0) then {
|
||||||
|
private _maxTime = ((_vanillaInitialSpeed - BULLET_TRACE_MIN_VELOCITY) / (BULLET_TRACE_MIN_VELOCITY * -_airFriction * _vanillaInitialSpeed)) max getNumber(configFile >> "CfgAmmo" >> _ammo >> "tracerEndTime");
|
||||||
|
-ln(1 - _airFriction * _vanillaInitialSpeed * _maxTime) / _airFriction
|
||||||
|
} else {
|
||||||
|
_vanillaInitialSpeed * getNumber(configFile >> "CfgAmmo" >> _ammo >> "tracerEndTime")
|
||||||
|
};
|
||||||
|
uiNamespace setVariable [format[QGVAR(maxRange_%1), _ammo], _maxRange];
|
||||||
|
};
|
||||||
|
if (ACE_player distance _unit > _maxRange && {ACE_player distance ((getPosASL _unit) vectorAdd ((vectorNormalized _bulletVelocity) vectorMultiply _maxRange)) > _maxRange}) exitWith {};
|
||||||
|
|
||||||
|
private _ammoCount = (_unit ammo _muzzle) + 1;
|
||||||
|
private _tracersEvery = getNumber(configFile >> "CfgMagazines" >> _magazine >> "tracersEvery");
|
||||||
|
private _lastRoundsTracer = getNumber(configFile >> "CfgMagazines" >> _magazine >> "lastRoundsTracer");
|
||||||
|
if (_ammoCount <= _lastRoundsTracer || {_tracersEvery > 0 && {(_ammoCount - _lastRoundsTracer) % _tracersEvery == 0}}) exitWith { _abort = false };
|
||||||
|
|
||||||
|
if (GVAR(bulletTraceEnabled) && {_muzzleVelocity > BULLET_TRACE_MIN_VELOCITY} && {cameraView == "GUNNER"}) then {
|
||||||
|
if (currentWeapon ACE_player == binocular ACE_player) exitWith { _abort = false };
|
||||||
|
if (currentWeapon ACE_player == primaryWeapon ACE_player && {count primaryWeaponItems ACE_player > 2}) then {
|
||||||
|
private _opticsName = (primaryWeaponItems ACE_player) select 2;
|
||||||
|
private _opticType = getNumber(configFile >> "CfgWeapons" >> _opticsName >> "ItemInfo" >> "opticType");
|
||||||
|
if (_opticType == 2) exitWith { _abort = false };
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
if (_abort) exitWith {};
|
||||||
|
|
||||||
// Get Weapon and Ammo Configurations
|
// Get Weapon and Ammo Configurations
|
||||||
_AmmoCacheEntry = uiNamespace getVariable format[QGVAR(%1), _ammo];
|
private _AmmoCacheEntry = uiNamespace getVariable format[QGVAR(%1), _ammo];
|
||||||
if (isNil "_AmmoCacheEntry") then {
|
if (isNil "_AmmoCacheEntry") then {
|
||||||
_AmmoCacheEntry = _ammo call FUNC(readAmmoDataFromConfig);
|
_AmmoCacheEntry = _ammo call FUNC(readAmmoDataFromConfig);
|
||||||
};
|
};
|
||||||
_WeaponCacheEntry = uiNamespace getVariable format[QGVAR(%1), _weapon];
|
private _WeaponCacheEntry = uiNamespace getVariable format[QGVAR(%1), _weapon];
|
||||||
if (isNil "_WeaponCacheEntry") then {
|
if (isNil "_WeaponCacheEntry") then {
|
||||||
_WeaponCacheEntry = _weapon call FUNC(readWeaponDataFromConfig);
|
_WeaponCacheEntry = _weapon call FUNC(readWeaponDataFromConfig);
|
||||||
};
|
};
|
||||||
|
|
||||||
_AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable"];
|
_AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleVelocityVariationSD"];
|
||||||
_WeaponCacheEntry params ["_barrelTwist", "_twistDirection", "_barrelLength"];
|
_WeaponCacheEntry params ["_barrelTwist", "_twistDirection", "_barrelLength"];
|
||||||
|
|
||||||
|
private _temperature = nil; // We need the variable in this scope. So we need to init it here.
|
||||||
|
|
||||||
_bulletVelocity = velocity _projectile;
|
private _ammoCount = _unit ammo _muzzle;
|
||||||
_muzzleVelocity = vectorMagnitude _bulletVelocity;
|
private _bulletVelocity = velocity _projectile;
|
||||||
|
private _muzzleVelocity = vectorMagnitude _bulletVelocity;
|
||||||
|
|
||||||
_barrelVelocityShift = 0;
|
|
||||||
if (GVAR(barrelLengthInfluenceEnabled)) then {
|
if (GVAR(barrelLengthInfluenceEnabled)) then {
|
||||||
_barrelVelocityShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _muzzleVelocity] call FUNC(calculateBarrelLengthVelocityShift);
|
_muzzleVelocity = _muzzleVelocity + ([_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _muzzleVelocity] call FUNC(calculateBarrelLengthVelocityShift));
|
||||||
};
|
};
|
||||||
|
|
||||||
_ammoTemperatureVelocityShift = 0;
|
|
||||||
if (GVAR(ammoTemperatureEnabled)) then {
|
if (GVAR(ammoTemperatureEnabled)) then {
|
||||||
_temperature = ((getPosASL _unit) select 2) call EFUNC(weather,calculateTemperatureAtHeight);
|
_temperature = ((getPosASL _unit) select 2) call EFUNC(weather,calculateTemperatureAtHeight);
|
||||||
_ammoTemperatureVelocityShift = ([_ammoTempMuzzleVelocityShifts, _temperature] call FUNC(calculateAmmoTemperatureVelocityShift));
|
_muzzleVelocity = _muzzleVelocity + ([_ammoTempMuzzleVelocityShifts, _temperature] call FUNC(calculateAmmoTemperatureVelocityShift));
|
||||||
|
};
|
||||||
|
if (GVAR(muzzleVelocityVariationEnabled)) then {
|
||||||
|
private _time = round (CBA_missionTime / 2);
|
||||||
|
// Generate seed from publicly known values (via Cantor pairing function)
|
||||||
|
private _seed = 0.5 * (_time + _ammoCount) * (_time + _ammoCount + 1) + _ammoCount;
|
||||||
|
// Generate normally distributed random number (via Box–Muller transform)
|
||||||
|
private _z = sqrt(-2.0 * ln(0.00000001 max (-_seed random 1))) * cos(_seed random 360);
|
||||||
|
|
||||||
|
_muzzleVelocity = _muzzleVelocity * (_z * _muzzleVelocityVariationSD + 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (GVAR(ammoTemperatureEnabled) || GVAR(barrelLengthInfluenceEnabled)) then {
|
_bulletVelocity = (vectorNormalized _bulletVelocity) vectorMultiply _muzzleVelocity;
|
||||||
_muzzleVelocityShift = _barrelVelocityShift + _ammoTemperatureVelocityShift;
|
_projectile setVelocity _bulletVelocity;
|
||||||
TRACE_4("shift",_muzzleVelocity,_muzzleVelocityShift, _barrelVelocityShift, _ammoTemperatureVelocityShift);
|
|
||||||
if (_muzzleVelocityShift != 0) then {
|
|
||||||
_muzzleVelocity = _muzzleVelocity + _muzzleVelocityShift;
|
|
||||||
_bulletVelocity = _bulletVelocity vectorAdd ((vectorNormalized _bulletVelocity) vectorMultiply (_muzzleVelocityShift));
|
|
||||||
_projectile setVelocity _bulletVelocity;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
_bulletTraceVisible = false;
|
private _bulletTraceVisible = false;
|
||||||
if (GVAR(bulletTraceEnabled) && cameraView == "GUNNER") then {
|
if (GVAR(bulletTraceEnabled) && {_muzzleVelocity > BULLET_TRACE_MIN_VELOCITY} && {cameraView == "GUNNER"}) then {
|
||||||
if (currentWeapon ACE_player == binocular ACE_player) then {
|
if (currentWeapon ACE_player == binocular ACE_player) then {
|
||||||
_bulletTraceVisible = true;
|
_bulletTraceVisible = true;
|
||||||
} else {
|
} else {
|
||||||
if (currentWeapon ACE_player == primaryWeapon ACE_player && count primaryWeaponItems ACE_player > 2) then {
|
if (currentWeapon ACE_player == primaryWeapon ACE_player && count primaryWeaponItems ACE_player > 2) then {
|
||||||
_opticsName = (primaryWeaponItems ACE_player) select 2;
|
private _opticsName = (primaryWeaponItems ACE_player) select 2;
|
||||||
_opticType = getNumber(configFile >> "CfgWeapons" >> _opticsName >> "ItemInfo" >> "opticType");
|
private _opticType = getNumber(configFile >> "CfgWeapons" >> _opticsName >> "ItemInfo" >> "opticType");
|
||||||
_bulletTraceVisible = _opticType == 2;
|
_bulletTraceVisible = _opticType == 2;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
_stabilityFactor = 1.5;
|
private _stabilityFactor = 1.5;
|
||||||
if (_caliber > 0 && _bulletLength > 0 && _bulletMass > 0 && _barrelTwist > 0) then {
|
if (_caliber * _bulletLength * _bulletMass * _barrelTwist > 0) then {
|
||||||
if (isNil "_temperature") then {
|
if (isNil "_temperature") then {
|
||||||
_temperature = ((getPosASL _unit) select 2) call EFUNC(weather,calculateTemperatureAtHeight);
|
_temperature = ((getPosASL _unit) select 2) call EFUNC(weather,calculateTemperatureAtHeight);
|
||||||
};
|
};
|
||||||
_barometricPressure = ((getPosASL _projectile) select 2) call EFUNC(weather,calculateBarometricPressure);
|
private _barometricPressure = ((getPosASL _projectile) select 2) call EFUNC(weather,calculateBarometricPressure);
|
||||||
_stabilityFactor = [_caliber, _bulletLength, _bulletMass, _barrelTwist, _muzzleVelocity, _temperature, _barometricPressure] call FUNC(calculateStabilityFactor);
|
_stabilityFactor = [_caliber, _bulletLength, _bulletMass, _barrelTwist, _muzzleVelocity, _temperature, _barometricPressure] call FUNC(calculateStabilityFactor);
|
||||||
};
|
};
|
||||||
|
|
||||||
GVAR(currentbulletID) = (GVAR(currentbulletID) + 1) % 10000;
|
GVAR(currentbulletID) = (GVAR(currentbulletID) + 1) % 10000;
|
||||||
|
|
||||||
_aceTimeSecond = floor CBA_missionTime;
|
"ace_advanced_ballistics" callExtension format["new:%1:%2:%3:%4:%5:%6:%7:%8:%9:%10:%11:%12:%13:%14:%15:%16:%17:%18", GVAR(currentbulletID), _ammoCount, _airFriction, _ballisticCoefficients, _velocityBoundaries, _atmosphereModel, _dragModel, _stabilityFactor, _twistDirection, _transonicStabilityCoef, getPosASL _projectile, _bulletVelocity, EGVAR(common,mapLatitude), EGVAR(weather,currentTemperature), EGVAR(common,mapAltitude), EGVAR(weather,currentHumidity), EGVAR(weather,currentOvercast), CBA_missionTime toFixed 6];
|
||||||
"ace_advanced_ballistics" callExtension format["new:%1:%2:%3:%4:%5:%6:%7:%8:%9:%10:%11:%12:%13:%14:%15:%16:%17:%18", GVAR(currentbulletID), _airFriction, _ballisticCoefficients, _velocityBoundaries, _atmosphereModel, _dragModel, _stabilityFactor, _twistDirection, _muzzleVelocity, _transonicStabilityCoef, getPosASL _projectile, EGVAR(common,mapLatitude), EGVAR(weather,currentTemperature), EGVAR(common,mapAltitude), EGVAR(weather,currentHumidity), overcast, _aceTimeSecond, CBA_missionTime - _aceTimeSecond];
|
|
||||||
|
|
||||||
GVAR(allBullets) pushBack [_projectile, _caliber, _bulletTraceVisible, GVAR(currentbulletID)];
|
GVAR(allBullets) pushBack [_projectile, _caliber, _bulletTraceVisible, GVAR(currentbulletID)];
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Glowbal, Ruthberg
|
* Author: Glowbal, Ruthberg
|
||||||
* Module for adjusting the advanced ballistics settings
|
* Module for adjusting the advanced ballistics settings
|
||||||
@ -10,23 +11,21 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
|
* Example:
|
||||||
|
* [LOGIC, [bob, kevin], true] call ace_advanced_ballistics_fnc_initModuleSettings
|
||||||
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_logic","_units", "_activated"];
|
params ["_logic","_units", "_activated"];
|
||||||
|
|
||||||
if !(_activated) exitWith {};
|
if !(_activated) exitWith {};
|
||||||
|
|
||||||
[_logic, QGVAR(enabled), "enabled"] call EFUNC(common,readSettingFromModule);
|
[_logic, QGVAR(enabled), "enabled"] call EFUNC(common,readSettingFromModule);
|
||||||
|
[_logic, QGVAR(muzzleVelocityVariationEnabled), "muzzleVelocityVariationEnabled"] call EFUNC(common,readSettingFromModule);
|
||||||
[_logic, QGVAR(ammoTemperatureEnabled), "ammoTemperatureEnabled"] call EFUNC(common,readSettingFromModule);
|
[_logic, QGVAR(ammoTemperatureEnabled), "ammoTemperatureEnabled"] call EFUNC(common,readSettingFromModule);
|
||||||
[_logic, QGVAR(barrelLengthInfluenceEnabled), "barrelLengthInfluenceEnabled"] call EFUNC(common,readSettingFromModule);
|
[_logic, QGVAR(barrelLengthInfluenceEnabled), "barrelLengthInfluenceEnabled"] call EFUNC(common,readSettingFromModule);
|
||||||
[_logic, QGVAR(bulletTraceEnabled), "bulletTraceEnabled"] call EFUNC(common,readSettingFromModule);
|
[_logic, QGVAR(bulletTraceEnabled), "bulletTraceEnabled"] call EFUNC(common,readSettingFromModule);
|
||||||
[_logic, QGVAR(simulateForEveryone), "simulateForEveryone"] call EFUNC(common,readSettingFromModule);
|
|
||||||
[_logic, QGVAR(disabledInFullAutoMode), "disabledInFullAutoMode"] call EFUNC(common,readSettingFromModule);
|
|
||||||
[_logic, QGVAR(simulateForSnipers), "simulateForSnipers"] call EFUNC(common,readSettingFromModule);
|
|
||||||
[_logic, QGVAR(simulateForGroupMembers), "simulateForGroupMembers"] call EFUNC(common,readSettingFromModule);
|
|
||||||
[_logic, QGVAR(simulationInterval), "simulationInterval"] call EFUNC(common,readSettingFromModule);
|
[_logic, QGVAR(simulationInterval), "simulationInterval"] call EFUNC(common,readSettingFromModule);
|
||||||
[_logic, QGVAR(simulationRadius), "simulationRadius"] call EFUNC(common,readSettingFromModule);
|
|
||||||
|
|
||||||
GVAR(simulationInterval) = 0 max GVAR(simulationInterval) min 0.2;
|
GVAR(simulationInterval) = 0 max GVAR(simulationInterval) min 0.2;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Ruthberg
|
* Author: Ruthberg
|
||||||
* Initializes the advanced ballistics dll extension with terrain data
|
* Initializes the advanced ballistics dll extension with terrain data
|
||||||
@ -8,48 +9,51 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
|
* Example:
|
||||||
|
* [] call ace_advanced_ballistics_fnc_initializeTerrainExtension
|
||||||
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
if (!hasInterface) exitWith {};
|
if (!hasInterface) exitWith {};
|
||||||
if (!GVAR(enabled)) exitWith {};
|
if (!GVAR(enabled)) exitWith {};
|
||||||
if (!GVAR(extensionAvailable)) exitWith {};
|
|
||||||
|
|
||||||
private ["_initStartTime", "_mapSize", "_mapGrids", "_gridCells", "_x", "_y", "_gridCenter", "_gridHeight", "_gridNumObjects", "_gridSurfaceIsWater"];
|
private _initStartTime = diag_tickTime;
|
||||||
|
private _mapSize = getNumber (configFile >> "CfgWorlds" >> worldName >> "MapSize");
|
||||||
_initStartTime = CBA_missionTime;
|
|
||||||
_mapSize = getNumber (configFile >> "CfgWorlds" >> worldName >> "MapSize");
|
|
||||||
|
|
||||||
if (("ace_advanced_ballistics" callExtension format["init:%1:%2", worldName, _mapSize]) == "Terrain already initialized") exitWith {
|
if (("ace_advanced_ballistics" callExtension format["init:%1:%2", worldName, _mapSize]) == "Terrain already initialized") exitWith {
|
||||||
|
INFO_1("Terrain already initialized [world: %1]", worldName);
|
||||||
#ifdef DEBUG_MODE_FULL
|
#ifdef DEBUG_MODE_FULL
|
||||||
systemChat "AdvancedBallistics: Terrain already initialized";
|
systemChat "AdvancedBallistics: Terrain already initialized";
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
_mapGrids = ceil(_mapSize / 50) + 1;
|
private _mapGrids = ceil(_mapSize / 50) + 1;
|
||||||
_gridCells = _mapGrids * _mapGrids;
|
private _gridCells = _mapGrids * _mapGrids;
|
||||||
|
|
||||||
GVAR(currentGrid) = 0;
|
GVAR(currentGrid) = 0;
|
||||||
|
|
||||||
|
INFO_2("Starting Terrain Extension [cells: %1] [world: %2]", _gridCells, worldName);
|
||||||
|
|
||||||
[{
|
[{
|
||||||
params ["_args","_idPFH"];
|
params ["_args","_idPFH"];
|
||||||
_args params ["_mapGrids", "_gridCells", "_initStartTime"];
|
_args params ["_mapGrids", "_gridCells", "_initStartTime"];
|
||||||
|
|
||||||
if (GVAR(currentGrid) >= _gridCells) exitWith {
|
if (GVAR(currentGrid) >= _gridCells) exitWith {
|
||||||
|
INFO_2("Finished terrain initialization in %1 seconds [world: %2]", (diag_tickTime - _initStartTime) toFixed 2, worldName);
|
||||||
#ifdef DEBUG_MODE_FULL
|
#ifdef DEBUG_MODE_FULL
|
||||||
systemChat format["AdvancedBallistics: Finished terrain initialization in %1 seconds", ceil(CBA_missionTime - _initStartTime)];
|
systemChat format["AdvancedBallistics: Finished terrain initialization in %1 seconds", (diag_tickTime - _initStartTime) toFixed 2];
|
||||||
#endif
|
#endif
|
||||||
[_idPFH] call CBA_fnc_removePerFrameHandler;
|
[_idPFH] call CBA_fnc_removePerFrameHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
for "_i" from 1 to 50 do {
|
for "_i" from 1 to 50 do {
|
||||||
_x = floor(GVAR(currentGrid) / _mapGrids) * 50;
|
private _x = floor(GVAR(currentGrid) / _mapGrids) * 50;
|
||||||
_y = (GVAR(currentGrid) - floor(GVAR(currentGrid) / _mapGrids) * _mapGrids) * 50;
|
private _y = (GVAR(currentGrid) - floor(GVAR(currentGrid) / _mapGrids) * _mapGrids) * 50;
|
||||||
_gridCenter = [_x + 25, _y + 25];
|
private _gridCenter = [_x + 25, _y + 25];
|
||||||
_gridHeight = round(getTerrainHeightASL _gridCenter);
|
private _gridHeight = round(getTerrainHeightASL _gridCenter);
|
||||||
_gridNumObjects = count (_gridCenter nearObjects ["Building", 50]);
|
private _gridNumObjects = count (_gridCenter nearObjects ["Building", 50]);
|
||||||
_gridSurfaceIsWater = if (surfaceIsWater _gridCenter) then {1} else {0};
|
private _gridSurfaceIsWater = if (surfaceIsWater _gridCenter) then {1} else {0};
|
||||||
"ace_advanced_ballistics" callExtension format["set:%1:%2:%3", _gridHeight, _gridNumObjects, _gridSurfaceIsWater];
|
"ace_advanced_ballistics" callExtension format["set:%1:%2:%3", _gridHeight, _gridNumObjects, _gridSurfaceIsWater];
|
||||||
GVAR(currentGrid) = GVAR(currentGrid) + 1;
|
GVAR(currentGrid) = GVAR(currentGrid) + 1;
|
||||||
if (GVAR(currentGrid) >= _gridCells) exitWith {};
|
if (GVAR(currentGrid) >= _gridCells) exitWith {};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Ruthberg
|
* Author: Ruthberg
|
||||||
*
|
*
|
||||||
@ -7,48 +8,54 @@
|
|||||||
* ammo - classname <STRING>
|
* ammo - classname <STRING>
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* 0: _airFriction
|
* 0: _airFriction <NUMBER>
|
||||||
* 1: _caliber
|
* 1: _caliber <NUMBER>
|
||||||
* 2: _bulletLength
|
* 2: _bulletLength <NUMBER>
|
||||||
* 3: _bulletMass
|
* 3: _bulletMass <NUMBER>
|
||||||
* 4: _transonicStabilityCoef
|
* 4: _transonicStabilityCoef <NUMBER>
|
||||||
* 5: _dragModel
|
* 5: _dragModel <NUMBER>
|
||||||
* 6: _ballisticCoefficients
|
* 6: _ballisticCoefficients <NUMBER>
|
||||||
* 7: _velocityBoundaries
|
* 7: _velocityBoundaries <NUMBER>
|
||||||
* 8: _atmosphereModel
|
* 8: _atmosphereModel <NUMBER>
|
||||||
* 9: _ammoTempMuzzleVelocityShifts
|
* 9: _ammoTempMuzzleVelocityShifts <NUMBER>
|
||||||
* 10: _muzzleVelocityTable
|
* 10: _muzzleVelocityTable <NUMBER>
|
||||||
* 11: _barrelLengthTable
|
* 11: _barrelLengthTable <NUMBER>
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* ["ammo"] call ace_advanced_ballistics_fnc_readAmmoDataFromConfig
|
||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
TRACE_1("Reading Ammo Config",_this);
|
TRACE_1("Reading Ammo Config",_this);
|
||||||
private ["_ammo", "_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable", "_result"];
|
|
||||||
_ammoConfig = configFile >> "CfgAmmo" >> _this;
|
|
||||||
|
|
||||||
_airFriction = getNumber(_ammoConfig >> "airFriction");
|
private _ammoConfig = configFile >> "CfgAmmo" >> _this;
|
||||||
_caliber = getNumber(_ammoConfig >> "ACE_caliber");
|
|
||||||
_bulletLength = getNumber(_ammoConfig >> "ACE_bulletLength");
|
private _airFriction = getNumber(_ammoConfig >> "airFriction");
|
||||||
_bulletMass = getNumber(_ammoConfig >> "ACE_bulletMass");
|
private _caliber = 0 max getNumber(_ammoConfig >> "ACE_caliber");
|
||||||
_transonicStabilityCoef = getNumber(_ammoConfig >> "ACE_transonicStabilityCoef");
|
private _bulletLength = 0 max getNumber(_ammoConfig >> "ACE_bulletLength");
|
||||||
|
private _bulletMass = 0 max getNumber(_ammoConfig >> "ACE_bulletMass");
|
||||||
|
private _transonicStabilityCoef = 0 max getNumber(_ammoConfig >> "ACE_transonicStabilityCoef") min 1;
|
||||||
if (_transonicStabilityCoef == 0) then {
|
if (_transonicStabilityCoef == 0) then {
|
||||||
_transonicStabilityCoef = 0.5;
|
_transonicStabilityCoef = 0.5;
|
||||||
};
|
};
|
||||||
_dragModel = getNumber(_ammoConfig >> "ACE_dragModel");
|
private _dragModel = getNumber(_ammoConfig >> "ACE_dragModel");
|
||||||
if (_dragModel == 0 || !(_dragModel in [1, 2, 5, 6, 7, 8])) then {
|
if (!(_dragModel in [1, 2, 5, 6, 7, 8])) then {
|
||||||
_dragModel = 1;
|
_dragModel = 1;
|
||||||
};
|
};
|
||||||
_ballisticCoefficients = getArray(_ammoConfig >> "ACE_ballisticCoefficients");
|
private _ballisticCoefficients = getArray(_ammoConfig >> "ACE_ballisticCoefficients");
|
||||||
_velocityBoundaries = getArray(_ammoConfig >> "ACE_velocityBoundaries");
|
private _velocityBoundaries = getArray(_ammoConfig >> "ACE_velocityBoundaries");
|
||||||
_atmosphereModel = getText(_ammoConfig >> "ACE_standardAtmosphere");
|
private _atmosphereModel = getText(_ammoConfig >> "ACE_standardAtmosphere");
|
||||||
if (_atmosphereModel isEqualTo "") then {
|
if (_atmosphereModel isEqualTo "") then {
|
||||||
_atmosphereModel = "ICAO";
|
_atmosphereModel = "ICAO";
|
||||||
};
|
};
|
||||||
_ammoTempMuzzleVelocityShifts = getArray(_ammoConfig >> "ACE_ammoTempMuzzleVelocityShifts");
|
private _muzzleVelocityVariationSD = DEFAULT_MUZZLE_VELOCITY_VARIATION_SD;
|
||||||
_muzzleVelocityTable = getArray(_ammoConfig >> "ACE_muzzleVelocities");
|
if (isNumber (_ammoConfig >> "ACE_muzzleVelocityVariationSD")) then {
|
||||||
_barrelLengthTable = getArray(_ammoConfig >> "ACE_barrelLengths");
|
_muzzleVelocityVariationSD = getNumber(_ammoConfig >> "ACE_muzzleVelocityVariationSD") / 100;
|
||||||
|
};
|
||||||
|
private _ammoTempMuzzleVelocityShifts = getArray(_ammoConfig >> "ACE_ammoTempMuzzleVelocityShifts");
|
||||||
|
private _muzzleVelocityTable = getArray(_ammoConfig >> "ACE_muzzleVelocities");
|
||||||
|
private _barrelLengthTable = getArray(_ammoConfig >> "ACE_barrelLengths");
|
||||||
|
|
||||||
//Handle subsonic ammo that would have a huge muzzle velocity shift (when ballistic configs not explicitly defined)
|
//Handle subsonic ammo that would have a huge muzzle velocity shift (when ballistic configs not explicitly defined)
|
||||||
private _typicalSpeed = getNumber (_ammoConfig >> "typicalSpeed");
|
private _typicalSpeed = getNumber (_ammoConfig >> "typicalSpeed");
|
||||||
@ -59,7 +66,7 @@ if ((_typicalSpeed > 0) && {_typicalSpeed < 360}) then {
|
|||||||
if (_inheritedBarrelConfig || _inheritedTempConfig) then {
|
if (_inheritedBarrelConfig || _inheritedTempConfig) then {
|
||||||
private _parentConfig = inheritsFrom _ammoConfig;
|
private _parentConfig = inheritsFrom _ammoConfig;
|
||||||
private _parentSpeed = getNumber (_parentConfig >> "typicalSpeed");
|
private _parentSpeed = getNumber (_parentConfig >> "typicalSpeed");
|
||||||
ACE_LOGWARNING_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
|
if (_parentSpeed <= 0) exitWith {//Handle weird or null parent
|
||||||
_muzzleVelocityTable = [];
|
_muzzleVelocityTable = [];
|
||||||
_ammoTempMuzzleVelocityShifts = [];
|
_ammoTempMuzzleVelocityShifts = [];
|
||||||
@ -86,7 +93,7 @@ if ((_typicalSpeed > 0) && {_typicalSpeed < 360}) then {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
_result = [_airFriction, _caliber, _bulletLength, _bulletMass, _transonicStabilityCoef, _dragModel, _ballisticCoefficients, _velocityBoundaries, _atmosphereModel, _ammoTempMuzzleVelocityShifts, _muzzleVelocityTable, _barrelLengthTable];
|
private _result = [_airFriction, _caliber, _bulletLength, _bulletMass, _transonicStabilityCoef, _dragModel, _ballisticCoefficients, _velocityBoundaries, _atmosphereModel, _ammoTempMuzzleVelocityShifts, _muzzleVelocityTable, _barrelLengthTable, _muzzleVelocityVariationSD];
|
||||||
|
|
||||||
uiNamespace setVariable [format[QGVAR(%1), _this], _result];
|
uiNamespace setVariable [format[QGVAR(%1), _this], _result];
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Ruthberg
|
* Author: Ruthberg
|
||||||
*
|
*
|
||||||
@ -7,18 +8,20 @@
|
|||||||
* weapon - classname <STRING>
|
* weapon - classname <STRING>
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* 0: _barrelTwist
|
* 0: _barrelTwist <NUMBER>
|
||||||
* 1: _twistDirection
|
* 1: _twistDirection <NUMBER>
|
||||||
* 2: _barrelLength
|
* 2: _barrelLength <NUMBER>
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* ["weapon"] call ace_advanced_ballistics_fnc_readWeaponDataFromConfig
|
||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
private _weaponConfig = (configFile >> "CfgWeapons" >> _this);
|
private _weaponConfig = (configFile >> "CfgWeapons" >> _this);
|
||||||
|
|
||||||
private _barrelTwist = getNumber(_weaponConfig >> "ACE_barrelTwist");
|
private _barrelTwist = 0 max getNumber(_weaponConfig >> "ACE_barrelTwist");
|
||||||
private _twistDirection = 1;
|
private _twistDirection = [0, 1] select (_barrelTwist != 0);
|
||||||
if (isNumber (_weaponConfig >> "ACE_twistDirection")) then {
|
if (isNumber (_weaponConfig >> "ACE_twistDirection")) then {
|
||||||
_twistDirection = getNumber (_weaponConfig >> "ACE_twistDirection");
|
_twistDirection = getNumber (_weaponConfig >> "ACE_twistDirection");
|
||||||
if !(_twistDirection in [-1, 0, 1]) then {
|
if !(_twistDirection in [-1, 0, 1]) then {
|
||||||
@ -26,10 +29,10 @@ if (isNumber (_weaponConfig >> "ACE_twistDirection")) then {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
private _barrelLength = getNumber(_weaponConfig >> "ACE_barrelLength");
|
private _barrelLength = 0 max getNumber(_weaponConfig >> "ACE_barrelLength");
|
||||||
|
|
||||||
private _result = [_barrelTwist, _twistDirection, _barrelLength];
|
private _result = [_barrelTwist, _twistDirection, _barrelLength];
|
||||||
|
|
||||||
uiNamespace setVariable [format[QGVAR(%1), _weapon], _result];
|
uiNamespace setVariable [format[QGVAR(%1), _this], _result];
|
||||||
|
|
||||||
_result
|
_result
|
||||||
|
@ -4,9 +4,10 @@
|
|||||||
|
|
||||||
// #define DEBUG_MODE_FULL
|
// #define DEBUG_MODE_FULL
|
||||||
// #define DISABLE_COMPILE_CACHE
|
// #define DISABLE_COMPILE_CACHE
|
||||||
// #define CBA_DEBUG_SYNCHRONOUS
|
|
||||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||||
|
|
||||||
|
#define DEBUG_INIT_SPEEDS
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED_ADVANCEDBALLISTICS
|
#ifdef DEBUG_ENABLED_ADVANCEDBALLISTICS
|
||||||
#define DEBUG_MODE_FULL
|
#define DEBUG_MODE_FULL
|
||||||
#endif
|
#endif
|
||||||
@ -17,7 +18,6 @@
|
|||||||
|
|
||||||
#include "\z\ace\addons\main\script_macros.hpp"
|
#include "\z\ace\addons\main\script_macros.hpp"
|
||||||
|
|
||||||
#define GRAVITY 9.80665
|
|
||||||
#define ABSOLUTE_ZERO_IN_CELSIUS -273.15
|
#define ABSOLUTE_ZERO_IN_CELSIUS -273.15
|
||||||
#define KELVIN(t) (t - ABSOLUTE_ZERO_IN_CELSIUS)
|
#define KELVIN(t) (t - ABSOLUTE_ZERO_IN_CELSIUS)
|
||||||
#define CELSIUS(t) (t + ABSOLUTE_ZERO_IN_CELSIUS)
|
#define CELSIUS(t) (t + ABSOLUTE_ZERO_IN_CELSIUS)
|
||||||
@ -28,4 +28,9 @@
|
|||||||
#define STD_AIR_DENSITY_ICAO 1.22498
|
#define STD_AIR_DENSITY_ICAO 1.22498
|
||||||
#define STD_AIR_DENSITY_ASM 1.20885
|
#define STD_AIR_DENSITY_ASM 1.20885
|
||||||
|
|
||||||
|
// Standard deviation of the default muzzle velocity variation (0.3%)
|
||||||
|
#define DEFAULT_MUZZLE_VELOCITY_VARIATION_SD 0.003
|
||||||
|
|
||||||
|
#define BULLET_TRACE_MIN_VELOCITY 500
|
||||||
|
|
||||||
#define EXTENSION_REQUIRED_VERSION "1.0"
|
#define EXTENSION_REQUIRED_VERSION "1.0"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project name="ACE">
|
<Project name="ACE">
|
||||||
<Package name="Advanced_Ballistics">
|
<Package name="Advanced_Ballistics">
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_WindInfoKey">
|
<Key ID="STR_ACE_Advanced_Ballistics_WindInfoKey">
|
||||||
@ -12,6 +12,10 @@
|
|||||||
<Hungarian>Széladatok mutatása</Hungarian>
|
<Hungarian>Széladatok mutatása</Hungarian>
|
||||||
<Czech>Zobrazit údaje o větru</Czech>
|
<Czech>Zobrazit údaje o větru</Czech>
|
||||||
<Portuguese>Mostrar Informação do Vento</Portuguese>
|
<Portuguese>Mostrar Informação do Vento</Portuguese>
|
||||||
|
<Japanese>風の情報を表示する</Japanese>
|
||||||
|
<Korean>바람의 정보를 표시</Korean>
|
||||||
|
<Chinese>顯示風況</Chinese>
|
||||||
|
<Chinesesimp>显示风况</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_ProtractorKey">
|
<Key ID="STR_ACE_Advanced_Ballistics_ProtractorKey">
|
||||||
<English>Show Protractor</English>
|
<English>Show Protractor</English>
|
||||||
@ -24,6 +28,10 @@
|
|||||||
<Hungarian>Szögmérő mutatása</Hungarian>
|
<Hungarian>Szögmérő mutatása</Hungarian>
|
||||||
<Czech>Zobrazit úhloměr</Czech>
|
<Czech>Zobrazit úhloměr</Czech>
|
||||||
<Portuguese>Mostrar Transferidor</Portuguese>
|
<Portuguese>Mostrar Transferidor</Portuguese>
|
||||||
|
<Japanese>分度器を表示する</Japanese>
|
||||||
|
<Korean>각도기 표시</Korean>
|
||||||
|
<Chinese>顯示量角器</Chinese>
|
||||||
|
<Chinesesimp>显示量角器</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_DisplayName">
|
<Key ID="STR_ACE_Advanced_Ballistics_DisplayName">
|
||||||
<English>Advanced Ballistics</English>
|
<English>Advanced Ballistics</English>
|
||||||
@ -36,6 +44,10 @@
|
|||||||
<Hungarian>Fejlett ballisztika</Hungarian>
|
<Hungarian>Fejlett ballisztika</Hungarian>
|
||||||
<Russian>Продвинутая баллистика</Russian>
|
<Russian>Продвинутая баллистика</Russian>
|
||||||
<Italian>Balistica Avanzata</Italian>
|
<Italian>Balistica Avanzata</Italian>
|
||||||
|
<Japanese>アドバンスド バリスティックス</Japanese>
|
||||||
|
<Korean>고급 탄도학</Korean>
|
||||||
|
<Chinese>先進彈道系統</Chinese>
|
||||||
|
<Chinesesimp>先进弹道系统</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_enabled_DisplayName">
|
<Key ID="STR_ACE_Advanced_Ballistics_enabled_DisplayName">
|
||||||
<English>Advanced Ballistics</English>
|
<English>Advanced Ballistics</English>
|
||||||
@ -48,6 +60,10 @@
|
|||||||
<Hungarian>Fejlett ballisztika</Hungarian>
|
<Hungarian>Fejlett ballisztika</Hungarian>
|
||||||
<Russian>Продвинутая баллистика</Russian>
|
<Russian>Продвинутая баллистика</Russian>
|
||||||
<Italian>Balistica Avanzata</Italian>
|
<Italian>Balistica Avanzata</Italian>
|
||||||
|
<Japanese>アドバンスド バリスティックス</Japanese>
|
||||||
|
<Korean>고급 탄도학</Korean>
|
||||||
|
<Chinese>先進彈道系統</Chinese>
|
||||||
|
<Chinesesimp>先进弹道系统</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_enabled_Description">
|
<Key ID="STR_ACE_Advanced_Ballistics_enabled_Description">
|
||||||
<English>Enables advanced ballistics</English>
|
<English>Enables advanced ballistics</English>
|
||||||
@ -60,126 +76,30 @@
|
|||||||
<Hungarian>Engedélyezi a fejlett ballisztikát</Hungarian>
|
<Hungarian>Engedélyezi a fejlett ballisztikát</Hungarian>
|
||||||
<Russian>Включает продвинутую баллистику</Russian>
|
<Russian>Включает продвинутую баллистику</Russian>
|
||||||
<Italian>Abilita Balistica Avanzata</Italian>
|
<Italian>Abilita Balistica Avanzata</Italian>
|
||||||
|
<Japanese>アドバンスド バリスティックスを有効化します。</Japanese>
|
||||||
|
<Korean>고급 탄도학을 적용합니다</Korean>
|
||||||
|
<Chinese>啟用先進彈道系統</Chinese>
|
||||||
|
<Chinesesimp>启用先进弹道系统</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_simulateForSnipers_DisplayName">
|
<Key ID="STR_ACE_Advanced_Ballistics_muzzleVelocityVariationEnabled_DisplayName">
|
||||||
<English>Enabled For Snipers</English>
|
<English>Enable Muzzle Velocity Variation</English>
|
||||||
<Spanish>Activada para francotiradores</Spanish>
|
<German>Variation der Mündungsgeschwindigkeit aktivieren</German>
|
||||||
<Polish>Akt. dla snajperów</Polish>
|
<Japanese>銃口初速の変動を有効化する</Japanese>
|
||||||
<German>Für Scharfschützen aktiviert</German>
|
<Italian>Abilita Variazione Velocità Volata</Italian>
|
||||||
<Czech>Povoleno pro odstřelovače</Czech>
|
<Korean>총구속도 변화적용</Korean>
|
||||||
<Portuguese>Ativar para caçadores</Portuguese>
|
<Chinese>啟用槍口初速變化</Chinese>
|
||||||
<French>Activé pour les snipers</French>
|
<Chinesesimp>启用枪口初速变化</Chinesesimp>
|
||||||
<Hungarian>Mesterlövészeknek engedélyezve</Hungarian>
|
<French>Activer les variations de la vitesse initiale</French>
|
||||||
<Russian>Включена для снайперов</Russian>
|
|
||||||
<Italian>Abilita per Tiratori Scelti</Italian>
|
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_simulateForSnipers_Description">
|
<Key ID="STR_ACE_Advanced_Ballistics_muzzleVelocityVariationEnabled_Description">
|
||||||
<English>Enables advanced ballistics for non local snipers (when using high power optics)</English>
|
<English>Simulates slight variations in muzzle velocity between each shot</English>
|
||||||
<Spanish>Activa la balística avanzada para francotiradores no locales (cuando se usa una mira telescópica)</Spanish>
|
<German>Simuliert leichte Variationen der Mündungsgeschwindigkeit zwischen jedem Schuss.</German>
|
||||||
<Polish>Aktywuje zaawansowaną balistykę dla nielokalnych snajperów (kiedy używają optyki)</Polish>
|
<Japanese>発射毎の銃口初速の変動をシミュレートします。</Japanese>
|
||||||
<German>Aktiviert die erweiterte Ballistik für nicht lokale Scharfschützen (bei Benutzung von Optiken mit starker Vergrößerung)</German>
|
<Italian>Simula lievi variazioni della velocità della volata tra un colpo e l'altro</Italian>
|
||||||
<Czech>Aktivuje pokročilou balistiku pro nelokální odstřelovače (při použití optiky)</Czech>
|
<Korean>각 사격 사이에 총구속도 변화를 시뮬레이션 합니다.</Korean>
|
||||||
<Portuguese>Ativa balística avançada para caçadores não locais (quando usando miras telescópicas)</Portuguese>
|
<Chinese>模擬每發子彈的槍口初速都略有不同</Chinese>
|
||||||
<French>Active la balistique avancée pour les snipers non locaux (en utilisant les optiques avancées)</French>
|
<Chinesesimp>模拟每发子弹的枪口初速都略有不同</Chinesesimp>
|
||||||
<Hungarian>Engedélyezi a fejlett ballisztikát nem-helyi mesterlövészeknek (nagy-teljesítményű optika használatakor)</Hungarian>
|
<French>Simule les légères variations</French>
|
||||||
<Russian>Включает продвинутую баллистику для нелокальных снайперов (при использовании мощной оптики)</Russian>
|
|
||||||
<Italian>Abilita Balistica Avanzata per Tiratori Scelti non locali (con ottiche ad alto potenziale)</Italian>
|
|
||||||
</Key>
|
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_simulateForGroupMembers_DisplayName">
|
|
||||||
<English>Enabled For Group Members</English>
|
|
||||||
<Spanish>Activada para miembros de grupo</Spanish>
|
|
||||||
<Polish>Akt. dla czł. grupy</Polish>
|
|
||||||
<German>Für Gruppenmitglieder aktiviert</German>
|
|
||||||
<Czech>Povoleno pro členy skupiny</Czech>
|
|
||||||
<Portuguese>Ativada para membros do grupo</Portuguese>
|
|
||||||
<French>Activé pour les membres groupés</French>
|
|
||||||
<Hungarian>Csoporttagoknak engedélyezve</Hungarian>
|
|
||||||
<Russian>Включена для группы</Russian>
|
|
||||||
<Italian>Abilita per Membri del Gruppo</Italian>
|
|
||||||
</Key>
|
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_simulateForGroupMembers_Description">
|
|
||||||
<English>Enables advanced ballistics for non local group members</English>
|
|
||||||
<Spanish>Activada la balística avanzada para miembros de grupo no locales</Spanish>
|
|
||||||
<Polish>Aktywuje zaawansowaną balistykę dla nielokalnych członków grupy</Polish>
|
|
||||||
<German>Aktiviert die erweiterte Ballistik für nicht lokale Gruppenmitglieder</German>
|
|
||||||
<Czech>Aktivuje pokročilou balistiku pro nelokální členy skupiny</Czech>
|
|
||||||
<Portuguese>Ativa balística avançada para membros de grupo não locais</Portuguese>
|
|
||||||
<French>Active la balistique avancée pour les membres du groupe non locaux</French>
|
|
||||||
<Hungarian>Engedélyezi a fejlett ballisztikát nem-helyi csoporttagoknak</Hungarian>
|
|
||||||
<Russian>Включает продвинутую баллистику для нелокальных членов группы</Russian>
|
|
||||||
<Italian>Abilita Balistica Avanzata per Membri non locali del Gruppo</Italian>
|
|
||||||
</Key>
|
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_simulateForEveryone_DisplayName">
|
|
||||||
<English>Enabled For Everyone</English>
|
|
||||||
<Spanish>Activada para todos</Spanish>
|
|
||||||
<Polish>Akt. dla wszystkich</Polish>
|
|
||||||
<German>Für jeden aktiviert</German>
|
|
||||||
<Czech>Povoleno pro všechny</Czech>
|
|
||||||
<Portuguese>Ativada para todos</Portuguese>
|
|
||||||
<French>Activé pour tout le monde</French>
|
|
||||||
<Hungarian>Mindenkinek engedélyezve</Hungarian>
|
|
||||||
<Russian>Включена для всех</Russian>
|
|
||||||
<Italian>Abilita per tutti</Italian>
|
|
||||||
</Key>
|
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_simulateForEveryone_Description">
|
|
||||||
<English>Enables advanced ballistics for all non local players (enabling this may degrade performance during heavy firefights in multiplayer)</English>
|
|
||||||
<Spanish>Activada la balística avanzada para todos los jugadores no locales (activarlo puede degradar el rendimiento durante grandes tiroteos en multijugador).</Spanish>
|
|
||||||
<Polish>Aktywuje zaawansowaną balistykę dla wszystkich nielokalnych graczy (aktywacja tej opcji może spodowować spory spadek wydajności podczas ciężkiej wymiany ognia)</Polish>
|
|
||||||
<German>Aktiviert die erweiterte Ballistik für alle nicht lokalen Spieler (das Aktivieren dieser Funktion kann zur Beeinträchtigung des Spielerlebnisses im Multiplayer führen)</German>
|
|
||||||
<Czech>Aktivuje pokročilou balistiku pro všechny nelokální hráče (aktivace této možnosti způsobuje pokles FPS během velké přestřelky v multiplayeru)</Czech>
|
|
||||||
<Portuguese>Ativa balística avançada para todos os jogadores não locais (ativando isso pode degradar a performance durante troca de tiros intensas no multiplayer)</Portuguese>
|
|
||||||
<French>Active la balistique avancée pour tous les joueurs non locaux (activer cette option peut avoir un impact sur les performance en multi durant les grands échanges de tirs)</French>
|
|
||||||
<Hungarian>Engedélyezi a fejlett ballisztikát az összes nem-helyi játékosnak (ez a funkció leronthatja a teljesítményt intenzív többjátékos tűzharcok alatt)</Hungarian>
|
|
||||||
<Russian>Включает продвинутую баллистику для всех нелокальных игроков (включение этой опции может снизить производительность при массовых перестрелках в мультиплеере)</Russian>
|
|
||||||
<Italian>Abilita Balistica Avanzata per tutti i giocatori non locali (abilitare questo parametro potrebbe degradare le prestazioni durante scontri intensi in multiplayer)</Italian>
|
|
||||||
</Key>
|
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_alwaysSimulateForGroupMembers_DisplayName">
|
|
||||||
<English>Always Enabled For Group Members</English>
|
|
||||||
<Polish>Zawsze akt. dla czł. grupy</Polish>
|
|
||||||
<Spanish>Siempre activada para miembros de grupo</Spanish>
|
|
||||||
<German>Für Gruppenmitglieder immer aktiviert</German>
|
|
||||||
<Czech>Vždy povoleno pro členy skupiny</Czech>
|
|
||||||
<Portuguese>Sempre ativada para membros do grupo</Portuguese>
|
|
||||||
<French>Toujours activer pour les membres du groupe</French>
|
|
||||||
<Hungarian>Mindig engedélyezve csoporttagoknak</Hungarian>
|
|
||||||
<Russian>Всегда включена для членов группы</Russian>
|
|
||||||
<Italian>Sempre abilitato per Membri del Gruppo</Italian>
|
|
||||||
</Key>
|
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_alwaysSimulateForGroupMembers_Description">
|
|
||||||
<English>Always enables advanced ballistics when a group member fires</English>
|
|
||||||
<Polish>Aktywuje zaawansowaną balistykę dla wszystkich członków grupy</Polish>
|
|
||||||
<Spanish>Activada la balística avanzada siempre cuando miembros de grupo disparan</Spanish>
|
|
||||||
<German>Aktiviert die erweiterte Ballistik immer, wenn ein Gruppenmitglied schießt</German>
|
|
||||||
<Czech>Aktivuje pokročilou balistiku pro členy skupiny</Czech>
|
|
||||||
<Portuguese>Sempre ative balística avançada quando um membro do grupo disparar</Portuguese>
|
|
||||||
<French>Active tout le temps la balistique avancée quand un membre du groupe ouvre le feu</French>
|
|
||||||
<Hungarian>Mindig engedélyezi a fejlett ballisztikát, ha egy csoporttag tüzel</Hungarian>
|
|
||||||
<Russian>Всегда включает продвинутую баллистику когда стреляет член группы</Russian>
|
|
||||||
<Italian>Abilita sempre Balistica Avanzata quando un Membro del Gruppo spara</Italian>
|
|
||||||
</Key>
|
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_disabledInFullAutoMod_DisplayName">
|
|
||||||
<English>Disabled In FullAuto Mode</English>
|
|
||||||
<Polish>Wył. podczas ognia auto.</Polish>
|
|
||||||
<Spanish>Desactivada en modo automático</Spanish>
|
|
||||||
<German>Beim vollautomatischen Feuern deaktiviert</German>
|
|
||||||
<Czech>Zakázáno v automatickém režimu střelby</Czech>
|
|
||||||
<Portuguese>Desabilitar no modo automático</Portuguese>
|
|
||||||
<French>Désactiver en mode automatique</French>
|
|
||||||
<Hungarian>Automata módban letiltva</Hungarian>
|
|
||||||
<Russian>Выкл. для автомат. режима</Russian>
|
|
||||||
<Italian>Disabilita in modalità di fuoco automatico</Italian>
|
|
||||||
</Key>
|
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_disabledInFullAutoMod_Description">
|
|
||||||
<English>Disables the advanced ballistics during full auto fire</English>
|
|
||||||
<Polish>Dezaktywuje zaawansowaną balistykę podczas ognia automatycznego</Polish>
|
|
||||||
<Spanish>Desactivada la balística avanzada durante el fuego automático</Spanish>
|
|
||||||
<German>Deaktiviert die erweiterte Ballistik beim vollautomatischen Feuern</German>
|
|
||||||
<Czech>Zákáže pokročilou balistiku během střelby v režimu automat</Czech>
|
|
||||||
<Portuguese>Desabilitar a balística avançada durante fogo automático</Portuguese>
|
|
||||||
<French>Désactive la balistique avancée pour les tirs en automatique</French>
|
|
||||||
<Hungarian>Letiltja a fejlett ballisztikát automata tüzelés folyamán</Hungarian>
|
|
||||||
<Russian>Выключает продвинутую баллистику при стрельбе в полностью автоматическом режиме</Russian>
|
|
||||||
<Italian>Disabilita Balistica Avanzata durante fuoco automatico</Italian>
|
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_ammoTemperatureEnabled_DisplayName">
|
<Key ID="STR_ACE_Advanced_Ballistics_ammoTemperatureEnabled_DisplayName">
|
||||||
<English>Enable Ammo Temperature Simulation</English>
|
<English>Enable Ammo Temperature Simulation</English>
|
||||||
@ -192,6 +112,10 @@
|
|||||||
<Hungarian>Lőszer-hő szimuláció engedélyezése</Hungarian>
|
<Hungarian>Lőszer-hő szimuláció engedélyezése</Hungarian>
|
||||||
<Russian>Симуляция температуры для боеприпасов</Russian>
|
<Russian>Симуляция температуры для боеприпасов</Russian>
|
||||||
<Italian>Abilita simulazione della temperatura delle munizioni</Italian>
|
<Italian>Abilita simulazione della temperatura delle munizioni</Italian>
|
||||||
|
<Japanese>弾薬温度のシミュレーションを有効化する</Japanese>
|
||||||
|
<Korean>탄약 온도 구현 적용</Korean>
|
||||||
|
<Chinese>啟用彈藥溫度模擬系統</Chinese>
|
||||||
|
<Chinesesimp>启用弹药温度模拟系统</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_ammoTemperatureEnabled_Description">
|
<Key ID="STR_ACE_Advanced_Ballistics_ammoTemperatureEnabled_Description">
|
||||||
<English>Muzzle velocity varies with ammo temperature</English>
|
<English>Muzzle velocity varies with ammo temperature</English>
|
||||||
@ -203,7 +127,11 @@
|
|||||||
<French>La température de la munition influe sur la vélocité intiale</French>
|
<French>La température de la munition influe sur la vélocité intiale</French>
|
||||||
<Hungarian>A kezdősebesség a lőszer hőmérsékletétől függően változó</Hungarian>
|
<Hungarian>A kezdősebesség a lőszer hőmérsékletétől függően változó</Hungarian>
|
||||||
<Russian>Начальная скорость пули зависит от температуры</Russian>
|
<Russian>Начальная скорость пули зависит от температуры</Russian>
|
||||||
<Italian>Velocità alla volata varia con la temperatura delle munizioni</Italian>
|
<Italian>La velocità dello sparo varia a seconda della temperatura delle munizioni</Italian>
|
||||||
|
<Japanese>弾薬の温度により銃口初速を変動させます。</Japanese>
|
||||||
|
<Korean>탄약 온도에 비례해 총구 속도가 달라집니다</Korean>
|
||||||
|
<Chinese>子彈初速將隨彈藥溫度而有所變化</Chinese>
|
||||||
|
<Chinesesimp>子弹初速将随弹药温度而有所变化</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_barrelLengthInfluenceEnabled_DisplayName">
|
<Key ID="STR_ACE_Advanced_Ballistics_barrelLengthInfluenceEnabled_DisplayName">
|
||||||
<English>Enable Barrel Length Simulation</English>
|
<English>Enable Barrel Length Simulation</English>
|
||||||
@ -216,6 +144,10 @@
|
|||||||
<Hungarian>Csőhossz-szimuláció engedélyezése</Hungarian>
|
<Hungarian>Csőhossz-szimuláció engedélyezése</Hungarian>
|
||||||
<Russian>Симуляция длины ствола</Russian>
|
<Russian>Симуляция длины ствола</Russian>
|
||||||
<Italian>Abilita simulazione della lunghezza della canna</Italian>
|
<Italian>Abilita simulazione della lunghezza della canna</Italian>
|
||||||
|
<Japanese>銃身長のシミュレーションを有効化する</Japanese>
|
||||||
|
<Korean>총열 길이 구현 적용</Korean>
|
||||||
|
<Chinese>啟用槍管長度模擬系統</Chinese>
|
||||||
|
<Chinesesimp>启用枪管长度模拟系统</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_barrelLengthInfluenceEnabled_Description">
|
<Key ID="STR_ACE_Advanced_Ballistics_barrelLengthInfluenceEnabled_Description">
|
||||||
<English>Muzzle velocity varies with barrel length</English>
|
<English>Muzzle velocity varies with barrel length</English>
|
||||||
@ -227,7 +159,11 @@
|
|||||||
<French>La longueur du canon influe sur la vélocité initale</French>
|
<French>La longueur du canon influe sur la vélocité initale</French>
|
||||||
<Hungarian>A kezdősebesség a cső hosszától függően változó</Hungarian>
|
<Hungarian>A kezdősebesség a cső hosszától függően változó</Hungarian>
|
||||||
<Russian>Начальная скорость пули зависит от длины ствола</Russian>
|
<Russian>Начальная скорость пули зависит от длины ствола</Russian>
|
||||||
<Italian>Velocità alla volata varia con la lunghezza della canna</Italian>
|
<Italian>La velocità di sparo varia a seconda della lunghezza della canna</Italian>
|
||||||
|
<Japanese>銃身長により銃口初速を変動させます。</Japanese>
|
||||||
|
<Korean>총구 속도가 총열에 비례해 달라집니다</Korean>
|
||||||
|
<Chinese>子彈初速將隨槍管長度而有所變化</Chinese>
|
||||||
|
<Chinesesimp>子弹初速将随枪管长度而有所变化</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_bulletTraceEnabled_DisplayName">
|
<Key ID="STR_ACE_Advanced_Ballistics_bulletTraceEnabled_DisplayName">
|
||||||
<English>Enable Bullet Trace Effect</English>
|
<English>Enable Bullet Trace Effect</English>
|
||||||
@ -239,7 +175,11 @@
|
|||||||
<French>Activer l'effet balle traçante</French>
|
<French>Activer l'effet balle traçante</French>
|
||||||
<Hungarian>Nyomkövető-effekt engedélyezése</Hungarian>
|
<Hungarian>Nyomkövető-effekt engedélyezése</Hungarian>
|
||||||
<Russian>Следы пуль</Russian>
|
<Russian>Следы пуль</Russian>
|
||||||
<Italian>Abilita effetto di tracciatura dei proiettili</Italian>
|
<Italian>Abilita effetto dei Proiettili Traccianti</Italian>
|
||||||
|
<Japanese>弾丸の軌跡エフェクトを有効化する</Japanese>
|
||||||
|
<Korean>예광탄 효과 적용</Korean>
|
||||||
|
<Chinese>啟用曳光彈效果</Chinese>
|
||||||
|
<Chinesesimp>启用曳光弹效果</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_bulletTraceEnabled_Description">
|
<Key ID="STR_ACE_Advanced_Ballistics_bulletTraceEnabled_Description">
|
||||||
<English>Enables a bullet trace effect to high caliber bullets (only visible when looking through high power optics)</English>
|
<English>Enables a bullet trace effect to high caliber bullets (only visible when looking through high power optics)</English>
|
||||||
@ -251,7 +191,11 @@
|
|||||||
<French>Active une tracante pour les munitions de gros calibre (seulement visible en utilisant des optiques avancées)</French>
|
<French>Active une tracante pour les munitions de gros calibre (seulement visible en utilisant des optiques avancées)</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>
|
<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>
|
<Russian>Включает эффект следов пуль для больших калибров (видны только через мощную оптику)</Russian>
|
||||||
<Italian>Abilita effetto di tracciatura per proiettili di alto calibro (visibile solo attraverso ottiche ad alto potenziale)</Italian>
|
<Italian>Abilita effetto dei proiettili traccianti di alto calibro (visibile solo attraverso ottiche ad alto potenziale)</Italian>
|
||||||
|
<Japanese>大口径弾の軌跡エフェクトを有効化します。 (高性能光学機器を介してのみ見ることができます)</Japanese>
|
||||||
|
<Korean>대구경 탄환에 예광탄 효과를 적용합니다(오직 고성능 조준경 사용시에만 보입니다)</Korean>
|
||||||
|
<Chinese>啟用曳光彈效果給大口徑子彈 (只有透過高倍率光學瞄鏡才能看到)</Chinese>
|
||||||
|
<Chinesesimp>启用曳光弹效果给大口径子弹 (只有透过高倍率光学瞄镜才能看到)</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_simulationInterval_DisplayName">
|
<Key ID="STR_ACE_Advanced_Ballistics_simulationInterval_DisplayName">
|
||||||
<English>Simulation Interval</English>
|
<English>Simulation Interval</English>
|
||||||
@ -264,18 +208,26 @@
|
|||||||
<Hungarian>Szimuláció intervalluma</Hungarian>
|
<Hungarian>Szimuláció intervalluma</Hungarian>
|
||||||
<Russian>Интервал симуляции</Russian>
|
<Russian>Интервал симуляции</Russian>
|
||||||
<Italian>Intervallo Simulazione</Italian>
|
<Italian>Intervallo Simulazione</Italian>
|
||||||
|
<Japanese>シミュレーションの間隔</Japanese>
|
||||||
|
<Korean>구현 간격</Korean>
|
||||||
|
<Chinese>模擬間隔</Chinese>
|
||||||
|
<Chinesesimp>模拟间隔</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_simulationInterval_Description">
|
<Key ID="STR_ACE_Advanced_Ballistics_simulationInterval_Description">
|
||||||
<English>Defines the interval between every calculation step</English>
|
<English>Defines the interval between each calculation step</English>
|
||||||
<Polish>Określa interwał pomiędzy każdym krokiem kalkulacji</Polish>
|
<Polish>Określa interwał pomiędzy każdym krokiem kalkulacji</Polish>
|
||||||
<Spanish>Define el intervalo entre cada cálculo</Spanish>
|
<Spanish>Define el intervalo entre cada cálculo</Spanish>
|
||||||
<German>Legt das Intervall zwischen den Berechnungsschritten fest</German>
|
<German>Definiert das Intervall zwischen den einzelnen Simulationsschritten</German>
|
||||||
<Czech>Určuje interval mezi každým výpočtem</Czech>
|
<Czech>Určuje interval mezi každým výpočtem</Czech>
|
||||||
<Portuguese>Define o intervalo entre cada cálculo</Portuguese>
|
<Portuguese>Define o intervalo entre cada cálculo</Portuguese>
|
||||||
<French>Définit un intervalle de calcul entre deux simulations</French>
|
<French>Définit un intervalle de calcul entre deux simulations</French>
|
||||||
<Hungarian>Meghatározza a számítási lépések közötti időintervallumot</Hungarian>
|
<Hungarian>Meghatározza a számítási lépések közötti időintervallumot</Hungarian>
|
||||||
<Russian>Определяет временной интервал между вычислениями</Russian>
|
<Russian>Определяет временной интервал между вычислениями</Russian>
|
||||||
<Italian>Definisce l'intervallo tra ogni step di calcolo</Italian>
|
<Italian>Definisce l'intervallo tra ogni step di calcolo</Italian>
|
||||||
|
<Japanese>各計算毎の間隔を定義します。</Japanese>
|
||||||
|
<Korean>각 계산 단위의 간격을 정의합니다</Korean>
|
||||||
|
<Chinese>定義每個模擬計算之間的時間間隔</Chinese>
|
||||||
|
<Chinesesimp>定义每个模拟计算之间的时间间隔</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_simulationRadius_DisplayName">
|
<Key ID="STR_ACE_Advanced_Ballistics_simulationRadius_DisplayName">
|
||||||
<English>Simulation Radius</English>
|
<English>Simulation Radius</English>
|
||||||
@ -288,6 +240,10 @@
|
|||||||
<Hungarian>Szimuláció hatóköre</Hungarian>
|
<Hungarian>Szimuláció hatóköre</Hungarian>
|
||||||
<Russian>Радиус симуляции</Russian>
|
<Russian>Радиус симуляции</Russian>
|
||||||
<Italian>Raggio Simulazione</Italian>
|
<Italian>Raggio Simulazione</Italian>
|
||||||
|
<Japanese>シミュレーションの範囲</Japanese>
|
||||||
|
<Korean>구현 범위</Korean>
|
||||||
|
<Chinese>模擬半徑</Chinese>
|
||||||
|
<Chinesesimp>模拟半径</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_simulationRadius_Description">
|
<Key ID="STR_ACE_Advanced_Ballistics_simulationRadius_Description">
|
||||||
<English>Defines the radius around the player (in meters) at which advanced ballistics are applied to projectiles</English>
|
<English>Defines the radius around the player (in meters) at which advanced ballistics are applied to projectiles</English>
|
||||||
@ -300,6 +256,10 @@
|
|||||||
<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>
|
<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>
|
<Russian>Определяет радиус вокруг игрока (в метрах), в котором продвинутая баллистика применяется к снарядам</Russian>
|
||||||
<Italian>Definisce il raggio attorno al giocatore (in metri) per cui la Balistica Avanzata è applicata ai proiettili</Italian>
|
<Italian>Definisce il raggio attorno al giocatore (in metri) per cui la Balistica Avanzata è applicata ai proiettili</Italian>
|
||||||
|
<Japanese>アドバンスド バリスティックスの適用半径範囲 (プレイヤー中心、メートル単位) を定義します。</Japanese>
|
||||||
|
<Korean>플레이어 주위의 발사체를 고급 탄도학으로 정의하는 범위를 정합니다(미터)</Korean>
|
||||||
|
<Chinese>以玩家的半徑距離(公尺)定義先進彈道系統啟用範圍</Chinese>
|
||||||
|
<Chinesesimp>以玩家的半径距离(公尺)定义先进弹道系统启用范围</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Ballistics_Description">
|
<Key ID="STR_ACE_Advanced_Ballistics_Description">
|
||||||
<English>This module enables advanced ballistics simulation - meaning the trajectory of projectiles is influenced by variables like air temperature, atmospheric pressure, humidity, gravity, the type of ammunition and the weapon from which it was fired.</English>
|
<English>This module enables advanced ballistics simulation - meaning the trajectory of projectiles is influenced by variables like air temperature, atmospheric pressure, humidity, gravity, the type of ammunition and the weapon from which it was fired.</English>
|
||||||
@ -312,6 +272,10 @@
|
|||||||
<Russian>Этот модуль включает симуляцию продвинутой баллистики - при этом на траекторию полета снаряда влияют различные параметры, такие как температура воздуха, атмосферное давление, влажность, гравитация, тип боеприпаса и оружия, из которого произвели выстрел.</Russian>
|
<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>
|
<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>
|
<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>
|
||||||
|
<Korean>이 모듈은 고급 탄도학을 적용시킵니다 - 이는 발사체의 궤적이 기온, 대기압, 습도, 중력, 탄환의 종류와 어느 무기에서 발사되는지에 따라 영향을 받습니다.</Korean>
|
||||||
|
<Chinese>該模塊實現先進的彈道仿真 - 這意味著子彈的軌跡是由空氣溫度、大氣壓力、濕度、重力、彈藥類型以及射擊的武器所影響</Chinese>
|
||||||
|
<Chinesesimp>该模块实现先进的弹道仿真 - 这意味着子弹的轨迹是由空气温度、大气压力、湿度、重力、弹药类型以及射击的武器所影响</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
</Package>
|
</Package>
|
||||||
</Project>
|
</Project>
|
@ -1,45 +1,20 @@
|
|||||||
class ACE_Settings {
|
class ACE_Settings {
|
||||||
class GVAR(enabled) {
|
class GVAR(enabled) {
|
||||||
category = "Advanced Fatigue";
|
movedToSQF = 1;
|
||||||
displayName = CSTRING(Enabled);
|
|
||||||
description = CSTRING(Enabled_Description);
|
|
||||||
typeName = "BOOL";
|
|
||||||
value = 1;
|
|
||||||
};
|
};
|
||||||
class GVAR(enableStaminaBar) {
|
class GVAR(enableStaminaBar) {
|
||||||
category = "Advanced Fatigue";
|
movedToSQF = 1;
|
||||||
displayName = CSTRING(EnableStaminaBar);
|
|
||||||
description = CSTRING(EnableStaminaBar_Description);
|
|
||||||
typeName = "BOOL";
|
|
||||||
value = 1;
|
|
||||||
isClientSettable = 1;
|
|
||||||
};
|
};
|
||||||
class GVAR(performanceFactor) {
|
class GVAR(performanceFactor) {
|
||||||
category = "Advanced Fatigue";
|
movedToSQF = 1;
|
||||||
displayName = CSTRING(PerformanceFactor);
|
|
||||||
description = CSTRING(PerformanceFactor_Description);
|
|
||||||
typeName = "SCALAR";
|
|
||||||
value = 1;
|
|
||||||
};
|
};
|
||||||
class GVAR(recoveryFactor) {
|
class GVAR(recoveryFactor) {
|
||||||
category = "Advanced Fatigue";
|
movedToSQF = 1;
|
||||||
displayName = CSTRING(RecoveryFactor);
|
|
||||||
description = CSTRING(RecoveryFactor_Description);
|
|
||||||
typeName = "SCALAR";
|
|
||||||
value = 1;
|
|
||||||
};
|
};
|
||||||
class GVAR(loadFactor) {
|
class GVAR(loadFactor) {
|
||||||
category = "Advanced Fatigue";
|
movedToSQF = 1;
|
||||||
displayName = CSTRING(LoadFactor);
|
|
||||||
description = CSTRING(LoadFactor_Description);
|
|
||||||
typeName = "SCALAR";
|
|
||||||
value = 1;
|
|
||||||
};
|
};
|
||||||
class GVAR(terrainGradientFactor) {
|
class GVAR(terrainGradientFactor) {
|
||||||
category = "Advanced Fatigue";
|
movedToSQF = 1;
|
||||||
displayName = CSTRING(TerrainGradientFactor);
|
|
||||||
description = CSTRING(TerrainGradientFactor_Description);
|
|
||||||
typeName = "SCALAR";
|
|
||||||
value = 1;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -3,9 +3,9 @@ class CfgVehicles {
|
|||||||
class GVAR(moduleSettings): ACE_Module {
|
class GVAR(moduleSettings): ACE_Module {
|
||||||
author = ECSTRING(common,ACETeam);
|
author = ECSTRING(common,ACETeam);
|
||||||
category = "ACE";
|
category = "ACE";
|
||||||
displayName = "Advanced Fatigue";
|
displayName = CSTRING(DisplayName);
|
||||||
function = QFUNC(moduleSettings);
|
function = QFUNC(moduleSettings);
|
||||||
scope = 2;
|
scope = 1;
|
||||||
isGlobal = 1;
|
isGlobal = 1;
|
||||||
isTriggerActivated = 0;
|
isTriggerActivated = 0;
|
||||||
icon = QPATHTOF(UI\Icon_Module.paa);
|
icon = QPATHTOF(UI\Icon_Module.paa);
|
||||||
|
@ -5,6 +5,6 @@ PREP(getMetabolicCosts);
|
|||||||
PREP(handleEffects);
|
PREP(handleEffects);
|
||||||
PREP(handlePlayerChanged);
|
PREP(handlePlayerChanged);
|
||||||
PREP(handleStaminaBar);
|
PREP(handleStaminaBar);
|
||||||
|
PREP(mainLoop);
|
||||||
PREP(moduleSettings);
|
PREP(moduleSettings);
|
||||||
PREP(pfhMain);
|
|
||||||
PREP(removeDutyFactor);
|
PREP(removeDutyFactor);
|
||||||
|
@ -12,39 +12,38 @@ if (!hasInterface) exitWith {};
|
|||||||
GVAR(ppeBlackout) ppEffectCommit 0.4;
|
GVAR(ppeBlackout) ppEffectCommit 0.4;
|
||||||
|
|
||||||
// - GVAR updating and initialization -----------------------------------------
|
// - GVAR updating and initialization -----------------------------------------
|
||||||
if !(isNull ACE_player) then {
|
["unit", FUNC(handlePlayerChanged), true] call CBA_fnc_addPlayerEventHandler;
|
||||||
[ACE_player, objNull] call FUNC(handlePlayerChanged);
|
|
||||||
};
|
["visibleMap", {
|
||||||
["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler;
|
params ["", "_visibleMap"]; // command visibleMap is updated one frame later
|
||||||
|
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||||
|
_staminaBarContainer ctrlShow ((!_visibleMap) && {(vehicle ACE_player) == ACE_player});
|
||||||
|
}, true] call CBA_fnc_addPlayerEventHandler;
|
||||||
|
["vehicle", {
|
||||||
|
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||||
|
_staminaBarContainer ctrlShow ((!visibleMap) && {(vehicle ACE_player) == ACE_player});
|
||||||
|
}, true] call CBA_fnc_addPlayerEventHandler;
|
||||||
|
|
||||||
// - Duty factors -------------------------------------------------------------
|
// - Duty factors -------------------------------------------------------------
|
||||||
[QEGVAR(medical,pain), {
|
if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then {
|
||||||
1 + (((_this getVariable [QEGVAR(medical,pain), 0]) min 1) / 10)
|
[QEGVAR(medical,pain), { // 0->1.0, 0.5->1.05, 1->1.1
|
||||||
|
linearConversion [0, 1, (_this getVariable [QEGVAR(medical,pain), 0]), 1, 1.1, true];
|
||||||
}] call FUNC(addDutyFactor);
|
}] call FUNC(addDutyFactor);
|
||||||
[QEGVAR(medical,bloodVolume), {
|
[QEGVAR(medical,bloodVolume), { // 100->1.0, 90->1.1, 80->1.2
|
||||||
2 - (((_this getVariable [QEGVAR(medical,bloodVolume), 100]) min 100) / 100)
|
linearConversion [100, 0, (_this getVariable [QEGVAR(medical,bloodVolume), 100]), 1, 2, true];
|
||||||
}] call FUNC(addDutyFactor);
|
}] call FUNC(addDutyFactor);
|
||||||
|
};
|
||||||
|
if (["ACE_Dragging"] call EFUNC(common,isModLoaded)) then {
|
||||||
[QEGVAR(dragging,isCarrying), {
|
[QEGVAR(dragging,isCarrying), {
|
||||||
if (_this getVariable [QEGVAR(dragging,isCarrying), false]) then {
|
[1, 3] select (_this getVariable [QEGVAR(dragging,isCarrying), false]);
|
||||||
3
|
|
||||||
} else {
|
|
||||||
1
|
|
||||||
};
|
|
||||||
}] call FUNC(addDutyFactor);
|
}] call FUNC(addDutyFactor);
|
||||||
[QEGVAR(weather,temperature), {
|
|
||||||
(((missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25]) - 35) / 10) max 2 min 1
|
|
||||||
}] call FUNC(addDutyFactor);
|
|
||||||
|
|
||||||
// - Add main PFH -------------------------------------------------------------
|
|
||||||
[FUNC(pfhMain), 1, []] call CBA_fnc_addPerFrameHandler;
|
|
||||||
}] call CBA_fnc_addEventHandler;
|
|
||||||
|
|
||||||
["ace_settingChanged", {
|
|
||||||
params ["_name", "_value"];
|
|
||||||
|
|
||||||
if (_name == QGVAR(enableStaminaBar) && {!_value}) then {
|
|
||||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
|
||||||
_staminaBarContainer ctrlSetFade 1;
|
|
||||||
_staminaBarContainer ctrlCommit 0;
|
|
||||||
};
|
};
|
||||||
|
if (["ACE_Weather"] call EFUNC(common,isModLoaded)) then {
|
||||||
|
[QEGVAR(weather,temperature), { // 35->1, 45->2
|
||||||
|
linearConversion [35, 45, (missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25]), 1, 2, true];
|
||||||
|
}] call FUNC(addDutyFactor);
|
||||||
|
};
|
||||||
|
|
||||||
|
// - Add main loop at 1 second interval -------------------------------------------------------------
|
||||||
|
[FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute;
|
||||||
}] call CBA_fnc_addEventHandler;
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
ADDON = false;
|
ADDON = false;
|
||||||
|
|
||||||
|
PREP_RECOMPILE_START;
|
||||||
#include "XEH_PREP.hpp"
|
#include "XEH_PREP.hpp"
|
||||||
//#include "initSettings.sqf"
|
PREP_RECOMPILE_END;
|
||||||
|
|
||||||
|
#include "initSettings.sqf"
|
||||||
|
|
||||||
GVAR(staminaBarWidth) = 10 * (((safezoneW / safezoneH) min 1.2) / 40);
|
GVAR(staminaBarWidth) = 10 * (((safezoneW / safezoneH) min 1.2) / 40);
|
||||||
GVAR(dutyList) = [[], []];
|
GVAR(dutyList) = [[], []];
|
||||||
|
@ -7,7 +7,7 @@ class CfgPatches {
|
|||||||
weapons[] = {};
|
weapons[] = {};
|
||||||
requiredVersion = REQUIRED_VERSION;
|
requiredVersion = REQUIRED_VERSION;
|
||||||
requiredAddons[] = {"ace_common"};
|
requiredAddons[] = {"ace_common"};
|
||||||
author = CSTRING(ACETeam);
|
author = ECSTRING(common,ACETeam);
|
||||||
authors[] = {"BaerMitUmlaut"};
|
authors[] = {"BaerMitUmlaut"};
|
||||||
url = ECSTRING(main,URL);
|
url = ECSTRING(main,URL);
|
||||||
VERSION_CONFIG;
|
VERSION_CONFIG;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: BaerMitUmlaut
|
* Author: BaerMitUmlaut
|
||||||
* Adds a duty factor.
|
* Adds a duty factor.
|
||||||
@ -8,8 +9,12 @@
|
|||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* ["ID", 5] call ace_advanced_fatigue_fnc_addDutyFactor
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
params [["_id", "", [""]], ["_factor", 1, [0, {}]]];
|
params [["_id", "", [""]], ["_factor", 1, [0, {}]]];
|
||||||
if (_id == "" || {_factor isEqualTo 1}) exitWith {};
|
if (_id == "" || {_factor isEqualTo 1}) exitWith {};
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: BaerMitUmlaut
|
* Author: BaerMitUmlaut
|
||||||
* Creates the stamina bar.
|
* Creates the stamina bar.
|
||||||
@ -7,8 +8,12 @@
|
|||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [DISPLAY] call ace_advanced_fatigue_fnc_createStaminaBar
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
params ["_display"];
|
params ["_display"];
|
||||||
|
|
||||||
private _staminaBar = _display ctrlCreate [QGVAR(StaminaBarContainer), -1];
|
private _staminaBar = _display ctrlCreate [QGVAR(StaminaBarContainer), -1];
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: BaerMitUmlaut
|
* Author: BaerMitUmlaut
|
||||||
* Calculates the duty of the current animation.
|
* Calculates the duty of the current animation.
|
||||||
@ -14,21 +15,22 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
params ["_unit", "_animName"];
|
params ["_unit", "_animName"];
|
||||||
|
|
||||||
private _duty = 1;
|
private _duty = 1;
|
||||||
private _animType = _animName select [1, 3];
|
private _animType = _animName select [1, 3];
|
||||||
|
|
||||||
GVAR(isSwimming) = false;
|
GVAR(isSwimming) = false;
|
||||||
|
GVAR(isProne) = (stance _unit) == "PRONE";
|
||||||
|
|
||||||
if (_animType in ["idl", "mov"]) then {
|
if (_animType in ["idl", "mov", "adj"]) then {
|
||||||
switch (_animName select [5, 3]) do {
|
switch (_animName select [5, 3]) do {
|
||||||
case ("knl"): {
|
case ("knl"): {
|
||||||
_duty = 1.5;
|
_duty = 1.5;
|
||||||
};
|
};
|
||||||
case ("pne"): {
|
case ("pne"): {
|
||||||
_duty = 12;
|
_duty = 10;
|
||||||
|
GVAR(isProne) = true; // #4880 - Unarmed sprint->prone has wrong `stance`
|
||||||
};
|
};
|
||||||
default {
|
default {
|
||||||
_duty = 1;
|
_duty = 1;
|
||||||
@ -47,10 +49,16 @@ if (_animType in ["idl", "mov"]) then {
|
|||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// swimming and diving
|
// swimming and diving
|
||||||
if (_animType in ["swm", "ssw", "bsw", "dve", "sdv", "bdv"]) then {
|
switch (true) do {
|
||||||
_duty = 5;
|
case (_animType in ["swm", "ssw", "bsw"]): {
|
||||||
|
_duty = 6.5;
|
||||||
GVAR(isSwimming) = true;
|
GVAR(isSwimming) = true;
|
||||||
};
|
};
|
||||||
|
case (_animType in ["dve", "sdv", "bdv"]): {
|
||||||
|
_duty = 2.5;
|
||||||
|
GVAR(isSwimming) = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
_duty
|
_duty
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: BaerMitUmlaut
|
* Author: BaerMitUmlaut
|
||||||
* Calculates the current metabolic costs for a unit.
|
* Calculates the current metabolic costs for a unit.
|
||||||
@ -15,21 +16,10 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
params ["_unit", "_velocity"];
|
params ["_unit", "_velocity"];
|
||||||
|
|
||||||
private _virtualLoad = 0;
|
private _gearMass = ((_unit getVariable [QEGVAR(movement,totalLoad), loadAbs _unit]) / 22.046) * GVAR(loadFactor);
|
||||||
{
|
|
||||||
_virtualLoad = _virtualLoad + (_x getVariable [QEGVAR(movement,vLoad), 0]);
|
|
||||||
} forEach [
|
|
||||||
_unit,
|
|
||||||
uniformContainer _unit,
|
|
||||||
vestContainer _unit,
|
|
||||||
backpackContainer _unit
|
|
||||||
];
|
|
||||||
|
|
||||||
private _gearMass = ((loadAbs _unit + _virtualLoad) * 0.1 / 2.2046) * GVAR(loadFactor);
|
|
||||||
private _terrainFactor = 1;
|
|
||||||
private _terrainAngle = asin (1 - ((surfaceNormal getPosASL _unit) select 2));
|
private _terrainAngle = asin (1 - ((surfaceNormal getPosASL _unit) select 2));
|
||||||
private _terrainGradient = (_terrainAngle / 45 min 1) * 5 * GVAR(terrainGradientFactor);
|
private _terrainGradient = (_terrainAngle / 45 min 1) * 5 * GVAR(terrainGradientFactor);
|
||||||
private _duty = GVAR(animDuty);
|
private _duty = GVAR(animDuty);
|
||||||
@ -50,12 +40,12 @@ if (_velocity > 2) then {
|
|||||||
(
|
(
|
||||||
2.10 * SIM_BODYMASS
|
2.10 * SIM_BODYMASS
|
||||||
+ 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2)
|
+ 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2)
|
||||||
+ _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.90 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient)
|
+ (SIM_BODYMASS + _gearMass) * (0.90 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient)
|
||||||
) * 0.23 * _duty
|
) * 0.23 * _duty
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
1.05 * SIM_BODYMASS
|
1.05 * SIM_BODYMASS
|
||||||
+ 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2)
|
+ 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2)
|
||||||
+ _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient)
|
+ (SIM_BODYMASS + _gearMass) * (1.15 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient)
|
||||||
) * 0.23 * _duty
|
) * 0.23 * _duty
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: BaerMitUmlaut
|
* Author: BaerMitUmlaut
|
||||||
* Handles any audible, visual and physical effects of fatigue.
|
* Handles any audible, visual and physical effects of fatigue.
|
||||||
@ -16,7 +17,6 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
params ["_unit", "_fatigue", "_speed", "_overexhausted"];
|
params ["_unit", "_fatigue", "_speed", "_overexhausted"];
|
||||||
|
|
||||||
#ifdef DEBUG_MODE_FULL
|
#ifdef DEBUG_MODE_FULL
|
||||||
@ -58,7 +58,18 @@ if (GVAR(ppeBlackoutLast) == 1) then {
|
|||||||
|
|
||||||
// - Physical effects ---------------------------------------------------------
|
// - Physical effects ---------------------------------------------------------
|
||||||
if (GVAR(isSwimming)) exitWith {
|
if (GVAR(isSwimming)) exitWith {
|
||||||
_unit setAnimSpeedCoef (1 - _fatigue / 3);
|
_unit setAnimSpeedCoef linearConversion [0.7, 0.9, _fatigue, 1, 0.5, true];
|
||||||
|
|
||||||
|
if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then {
|
||||||
|
[_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
|
||||||
|
} else {
|
||||||
|
if ((!isSprintAllowed _unit) && {_fatigue < 0.7}) then {
|
||||||
|
[_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if ((getAnimSpeedCoef _unit) != 1) then {
|
||||||
|
_unit setAnimSpeedCoef 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_overexhausted) then {
|
if (_overexhausted) then {
|
||||||
@ -79,12 +90,12 @@ if (_overexhausted) then {
|
|||||||
|
|
||||||
switch (stance _unit) do {
|
switch (stance _unit) do {
|
||||||
case ("CROUCH"): {
|
case ("CROUCH"): {
|
||||||
_unit setCustomAimCoef (1.0 + _fatigue ^ 2 * 0.1);
|
[_unit, QUOTE(ADDON), (1.0 + _fatigue ^ 2 * 0.1) * GVAR(swayFactor)] call EFUNC(common,setAimCoef);
|
||||||
};
|
};
|
||||||
case ("PRONE"): {
|
case ("PRONE"): {
|
||||||
_unit setCustomAimCoef (1.0 + _fatigue ^ 2 * 2.0);
|
[_unit, QUOTE(ADDON), (1.0 + _fatigue ^ 2 * 2.0) * GVAR(swayFactor)] call EFUNC(common,setAimCoef);
|
||||||
};
|
};
|
||||||
default {
|
default {
|
||||||
_unit setCustomAimCoef (1.5 + _fatigue ^ 2 * 3.0);
|
[_unit, QUOTE(ADDON), (1.5 + _fatigue ^ 2 * 3.0) * GVAR(swayFactor)] call EFUNC(common,setAimCoef);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: BaerMitUmlaut
|
* Author: BaerMitUmlaut
|
||||||
* Handles switching units (once on init and afterwards via Zeus).
|
* Handles switching units (once on init and afterwards via Zeus).
|
||||||
@ -8,13 +9,20 @@
|
|||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [newbob, oldbob] call ace_advanced_fatigue_fnc_handlePlayerChanged
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
params ["_newUnit", "_oldUnit"];
|
params ["_newUnit", "_oldUnit"];
|
||||||
|
TRACE_2("unit changed",_newUnit,_oldUnit);
|
||||||
|
|
||||||
if !(isNull _oldUnit) then {
|
if !(isNull _oldUnit) then {
|
||||||
_oldUnit enableStamina true;
|
_oldUnit enableStamina true;
|
||||||
_oldUnit removeEventHandler ["AnimChanged", _oldUnit getVariable [QGVAR(animHandler), -1]];
|
_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(ae1Reserve), GVAR(ae1Reserve)];
|
||||||
_oldUnit setVariable [QGVAR(ae2Reserve), GVAR(ae2Reserve)];
|
_oldUnit setVariable [QGVAR(ae2Reserve), GVAR(ae2Reserve)];
|
||||||
@ -30,6 +38,7 @@ if (_newUnit getVariable [QGVAR(animHandler), -1] == -1) then {
|
|||||||
private _animHandler = _newUnit addEventHandler ["AnimChanged", {
|
private _animHandler = _newUnit addEventHandler ["AnimChanged", {
|
||||||
GVAR(animDuty) = _this call FUNC(getAnimDuty);
|
GVAR(animDuty) = _this call FUNC(getAnimDuty);
|
||||||
}];
|
}];
|
||||||
|
TRACE_1("add new",_animHandler);
|
||||||
_newUnit setVariable [QGVAR(animHandler), _animHandler];
|
_newUnit setVariable [QGVAR(animHandler), _animHandler];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -50,7 +59,6 @@ GVAR(peakPower) = VO2MAX_STRENGTH * GVAR(VO2MaxPower);
|
|||||||
|
|
||||||
GVAR(ae1PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 13.3 * ANTPERCENT ^ 1.28 * 1.362;
|
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(ae2PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 16.7 * ANTPERCENT ^ 1.28 * 1.362;
|
||||||
GVAR(anPathwayPower) = GVAR(peakPower) - _ae1PathwayPower - _ae2PathwayPower;
|
|
||||||
|
|
||||||
GVAR(ppeBlackoutLast) = 100;
|
GVAR(ppeBlackoutLast) = 100;
|
||||||
GVAR(lastBreath) = 0;
|
GVAR(lastBreath) = 0;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: BaerMitUmlaut
|
* Author: BaerMitUmlaut
|
||||||
* Handles visual changes of the stamina bar.
|
* Handles visual changes of the stamina bar.
|
||||||
@ -7,8 +8,12 @@
|
|||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [0.5] call ace_advanced_fatigue_fnc_handleStaminaBar
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
params ["_stamina"];
|
params ["_stamina"];
|
||||||
|
|
||||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||||
|
81
addons/advanced_fatigue/functions/fnc_mainLoop.sqf
Normal file
81
addons/advanced_fatigue/functions/fnc_mainLoop.sqf
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
/*
|
||||||
|
* Author: BaerMitUmlaut
|
||||||
|
* Main looping function that updates fatigue values.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [] call ace_advanced_fatigue_fnc_mainLoop
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
if (!alive ACE_player) exitWith { // Dead people don't breath, Will also handle null (Map intros)
|
||||||
|
[FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute;
|
||||||
|
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||||
|
_staminaBarContainer ctrlSetFade 1;
|
||||||
|
_staminaBarContainer ctrlCommit 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
private _currentWork = REE;
|
||||||
|
private _currentSpeed = (vectorMagnitude (velocity ACE_player)) 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);
|
||||||
|
_currentWork = _currentWork max REE;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
GVAR(anFatigue) = ((GVAR(anFatigue)
|
||||||
|
- (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) * (0.057 / GVAR(peakPower)) * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor)
|
||||||
|
) min 1) max 0;
|
||||||
|
|
||||||
|
private _aeReservePercentage = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2;
|
||||||
|
private _anReservePercentage = GVAR(anReserve) / AN_MAXRESERVE;
|
||||||
|
private _perceivedFatigue = 1 - (_anReservePercentage min _aeReservePercentage);
|
||||||
|
|
||||||
|
[ACE_player, _perceivedFatigue, _currentSpeed, GVAR(anReserve) == 0] call FUNC(handleEffects);
|
||||||
|
|
||||||
|
if (GVAR(enableStaminaBar)) then {
|
||||||
|
[GVAR(anReserve) / AN_MAXRESERVE] call FUNC(handleStaminaBar);
|
||||||
|
};
|
||||||
|
|
||||||
|
[FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute;
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: BaerMitUmlaut
|
* Author: BaerMitUmlaut
|
||||||
* Initializes the module settings.
|
* Initializes the module settings.
|
||||||
@ -7,8 +8,12 @@
|
|||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [MODULE] call ace_advanced_fatigue_fnc_moduleSettings
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
params ["_logic"];
|
params ["_logic"];
|
||||||
|
|
||||||
[_logic, QGVAR(enabled), "Enabled"] call EFUNC(common,readSettingFromModule);
|
[_logic, QGVAR(enabled), "Enabled"] call EFUNC(common,readSettingFromModule);
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* Author: BaerMitUmlaut
|
|
||||||
* Main perFrameHandler that updates fatigue values.
|
|
||||||
*
|
|
||||||
* Arguments:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Return Value:
|
|
||||||
* None
|
|
||||||
*/
|
|
||||||
#include "script_component.hpp"
|
|
||||||
if (isNull ACE_player) exitWith {}; // Map intros
|
|
||||||
|
|
||||||
private _currentWork = REE;
|
|
||||||
private _currentSpeed = (vectorMagnitude (velocity ACE_player)) min 6;
|
|
||||||
if ((vehicle ACE_player == ACE_player) && {_currentSpeed > 0.1} && {isTouchingGround ACE_player || {underwater ACE_player}}) then {
|
|
||||||
_currentWork = [ACE_player, _currentSpeed] call FUNC(getMetabolicCosts);
|
|
||||||
_currentWork = _currentWork max REE;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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 _muscleIntegrity = 1 - GVAR(muscleDamage);
|
|
||||||
|
|
||||||
// Calculate available power
|
|
||||||
private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * OXYGEN * sqrt _muscleIntegrity;
|
|
||||||
private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * OXYGEN * sqrt _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;
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
GVAR(anFatigue) = ((GVAR(anFatigue)
|
|
||||||
- (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) * (0.057 / GVAR(peakPower)) * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor)
|
|
||||||
) min 1) max 0;
|
|
||||||
|
|
||||||
private _aeReservePercentage = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2;
|
|
||||||
private _anReservePercentage = GVAR(anReserve) / AN_MAXRESERVE;
|
|
||||||
private _perceivedFatigue = 1 - (_anReservePercentage min _aeReservePercentage);
|
|
||||||
|
|
||||||
[ACE_player, _perceivedFatigue, _currentSpeed, GVAR(anReserve) == 0] call FUNC(handleEffects);
|
|
||||||
|
|
||||||
if (GVAR(enableStaminaBar)) then {
|
|
||||||
[GVAR(anReserve) / AN_MAXRESERVE] call FUNC(handleStaminaBar);
|
|
||||||
};
|
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: BaerMitUmlaut
|
* Author: BaerMitUmlaut
|
||||||
* Removes a duty factor.
|
* Removes a duty factor.
|
||||||
@ -7,8 +8,12 @@
|
|||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* ["ID"] call ace_advanced_fatigue_fnc_removeDutyFactor
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
params [["_id", "", [""]]];
|
params [["_id", "", [""]]];
|
||||||
|
|
||||||
GVAR(dutyList) params ["_idList", "_factorList"];
|
GVAR(dutyList) params ["_idList", "_factorList"];
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
QGVAR(enabled),
|
QGVAR(enabled),
|
||||||
"CHECKBOX",
|
"CHECKBOX",
|
||||||
[LSTRING(Enabled), LSTRING(Enabled_Description)],
|
[LSTRING(Enabled), LSTRING(Enabled_Description)],
|
||||||
"ACE3 Advanced Fatigue",
|
LSTRING(DisplayName),
|
||||||
true,
|
true,
|
||||||
true
|
true
|
||||||
] call CBA_Settings_fnc_init;
|
] call CBA_Settings_fnc_init;
|
||||||
@ -11,7 +11,7 @@
|
|||||||
QGVAR(enableStaminaBar),
|
QGVAR(enableStaminaBar),
|
||||||
"CHECKBOX",
|
"CHECKBOX",
|
||||||
[LSTRING(EnableStaminaBar), LSTRING(EnableStaminaBar_Description)],
|
[LSTRING(EnableStaminaBar), LSTRING(EnableStaminaBar_Description)],
|
||||||
"ACE3 Advanced Fatigue",
|
LSTRING(DisplayName),
|
||||||
true,
|
true,
|
||||||
true, {
|
true, {
|
||||||
if (!_this) then {
|
if (!_this) then {
|
||||||
@ -26,8 +26,8 @@
|
|||||||
QGVAR(performanceFactor),
|
QGVAR(performanceFactor),
|
||||||
"SLIDER",
|
"SLIDER",
|
||||||
[LSTRING(PerformanceFactor), LSTRING(PerformanceFactor_Description)],
|
[LSTRING(PerformanceFactor), LSTRING(PerformanceFactor_Description)],
|
||||||
"ACE3 Advanced Fatigue",
|
LSTRING(DisplayName),
|
||||||
[0, 2, 1, 1],
|
[0, 5, 1, 1],
|
||||||
true
|
true
|
||||||
] call CBA_Settings_fnc_init;
|
] call CBA_Settings_fnc_init;
|
||||||
|
|
||||||
@ -35,8 +35,8 @@
|
|||||||
QGVAR(recoveryFactor),
|
QGVAR(recoveryFactor),
|
||||||
"SLIDER",
|
"SLIDER",
|
||||||
[LSTRING(RecoveryFactor), LSTRING(RecoveryFactor_Description)],
|
[LSTRING(RecoveryFactor), LSTRING(RecoveryFactor_Description)],
|
||||||
"ACE3 Advanced Fatigue",
|
LSTRING(DisplayName),
|
||||||
[0, 2, 1, 1],
|
[0, 5, 1, 1],
|
||||||
true
|
true
|
||||||
] call CBA_Settings_fnc_init;
|
] call CBA_Settings_fnc_init;
|
||||||
|
|
||||||
@ -44,8 +44,8 @@
|
|||||||
QGVAR(loadFactor),
|
QGVAR(loadFactor),
|
||||||
"SLIDER",
|
"SLIDER",
|
||||||
[LSTRING(LoadFactor), LSTRING(LoadFactor_Description)],
|
[LSTRING(LoadFactor), LSTRING(LoadFactor_Description)],
|
||||||
"ACE3 Advanced Fatigue",
|
LSTRING(DisplayName),
|
||||||
[0, 2, 1, 1],
|
[0, 5, 1, 1],
|
||||||
true
|
true
|
||||||
] call CBA_Settings_fnc_init;
|
] call CBA_Settings_fnc_init;
|
||||||
|
|
||||||
@ -53,7 +53,16 @@
|
|||||||
QGVAR(terrainGradientFactor),
|
QGVAR(terrainGradientFactor),
|
||||||
"SLIDER",
|
"SLIDER",
|
||||||
[LSTRING(TerrainGradientFactor), LSTRING(TerrainGradientFactor_Description)],
|
[LSTRING(TerrainGradientFactor), LSTRING(TerrainGradientFactor_Description)],
|
||||||
"ACE3 Advanced Fatigue",
|
LSTRING(DisplayName),
|
||||||
[0, 2, 1, 1],
|
[0, 5, 1, 1],
|
||||||
|
true
|
||||||
|
] call CBA_Settings_fnc_init;
|
||||||
|
|
||||||
|
[
|
||||||
|
QGVAR(swayFactor),
|
||||||
|
"SLIDER",
|
||||||
|
[LSTRING(SwayFactor), LSTRING(SwayFactor_Description)],
|
||||||
|
LSTRING(DisplayName),
|
||||||
|
[0, 5, 1, 1],
|
||||||
true
|
true
|
||||||
] call CBA_Settings_fnc_init;
|
] call CBA_Settings_fnc_init;
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
// #define DEBUG_MODE_FULL
|
// #define DEBUG_MODE_FULL
|
||||||
// #define DISABLE_COMPILE_CACHE
|
// #define DISABLE_COMPILE_CACHE
|
||||||
// #define CBA_DEBUG_SYNCHRONOUS
|
|
||||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED_ADVANCED_FATIGUE
|
#ifdef DEBUG_ENABLED_ADVANCED_FATIGUE
|
||||||
|
@ -1,57 +1,171 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project name="ACE">
|
<Project name="ACE">
|
||||||
<Package name="Advanced_Fatigue">
|
<Package name="Advanced_Fatigue">
|
||||||
|
<Key ID="STR_ACE_Advanced_Fatigue_DisplayName">
|
||||||
|
<English>ACE Advanced Fatigue</English>
|
||||||
|
<German>ACE Erweiterte Ausdauer</German>
|
||||||
|
<Chinese>ACE 進階疲勞</Chinese>
|
||||||
|
<Chinesesimp>ACE 进阶疲劳</Chinesesimp>
|
||||||
|
<Japanese>ACE アドバンスド ファティーグ</Japanese>
|
||||||
|
<Italian>ACE Fatica Avanzata</Italian>
|
||||||
|
<Korean>ACE 고급 피로도</Korean>
|
||||||
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Fatigue_PerformanceFactor">
|
<Key ID="STR_ACE_Advanced_Fatigue_PerformanceFactor">
|
||||||
<English>Performance Factor</English>
|
<English>Performance Factor</English>
|
||||||
<German>Leistungsfaktor</German>
|
<German>Leistungsfaktor</German>
|
||||||
|
<Japanese>パフォーマンス因数</Japanese>
|
||||||
|
<Polish>Współczynnik wydolności</Polish>
|
||||||
|
<Korean>성능 요인</Korean>
|
||||||
|
<French>Facteur de performance</French>
|
||||||
|
<Italian>Fattore Prestazione</Italian>
|
||||||
|
<Chinese>體力值</Chinese>
|
||||||
|
<Chinesesimp>体力值</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Fatigue_PerformanceFactor_Description">
|
<Key ID="STR_ACE_Advanced_Fatigue_PerformanceFactor_Description">
|
||||||
<English>Influences the overall performance of all players with no custom factor. Higher means better.</English>
|
<English>Influences the overall performance of all players with no custom factor. Higher means better.</English>
|
||||||
<German>Beinflusst die Leistungsfähigkeit aller Spieler ohne eigenen Leistungsfaktor. Ein höherer Wert bedeutet bessere Leistung.</German>
|
<German>Beinflusst die Leistungsfähigkeit aller Spieler ohne eigenen Leistungsfaktor. Ein höherer Wert bedeutet bessere Leistung.</German>
|
||||||
|
<Japanese>個別の因数を設定されていない、全てのプレイヤーのあらゆるパフォーマンスに影響を与えます。 値が高ければ高いほど、良い効果が得られます。</Japanese>
|
||||||
|
<Polish>Wpływa na ogólną wydolność organizmu u wszystkich graczy bez ustawionego niestandardowego współczynnika. Więcej znaczy lepiej.</Polish>
|
||||||
|
<Korean>모든 성능이 임의로 설정된 값 없이 영향받습니다. 값이 클수록 더 나은 성능을 발휘합니다</Korean>
|
||||||
|
<French>Influence les performances générales de tous les joueurs sans facteurs personalisés. Une valeur plus élevée implique de meilleures performances.</French>
|
||||||
|
<Italian>Influenza qualsiasi prestazione di tutti i giocatori smuniti di un fattore personalizzato. Maggiore significa migliore.</Italian>
|
||||||
|
<Chinese>影響所有玩家的體力表現,值越高代表體力越好</Chinese>
|
||||||
|
<Chinesesimp>影响所有玩家的体力表现,值越高代表体力越好</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Fatigue_PerformanceFactor_EdenDescription">
|
<Key ID="STR_ACE_Advanced_Fatigue_PerformanceFactor_EdenDescription">
|
||||||
<English>Influences the overall performance of this unit. Higher means better.</English>
|
<English>Influences the overall performance of this unit. Higher means better.</English>
|
||||||
<German>Beinflusst die Leistungsfähigkeit dieser Einheit. Ein höherer Wert bedeutet bessere Leistung.</German>
|
<German>Beinflusst die Leistungsfähigkeit dieser Einheit. Ein höherer Wert bedeutet bessere Leistung.</German>
|
||||||
|
<Japanese>このユニットのあらゆるパフォーマンスに影響を与えます。 値が高ければ高いほど、良い効果が得られます。</Japanese>
|
||||||
|
<Polish>Wpływa na ogólną wydolność tej jednostki. Więcej znaczy lepiej.</Polish>
|
||||||
|
<Korean>모든 성능이 이 단위로 영향을 받습니다. 값이 클수록 더 나은 성능을 발휘합니다</Korean>
|
||||||
|
<French>Influence les performances générales de cette unité. Une valeur plus élevée implique de meilleures performances.</French>
|
||||||
|
<Italian>Influenza qualsiasi prestazione di questa unità. Maggiore significa migliore.</Italian>
|
||||||
|
<Chinese>影響這個單位的體力表現,值越高代表體力越好</Chinese>
|
||||||
|
<Chinesesimp>影响这个单位的体力表现,值越高代表体力越好</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Fatigue_RecoveryFactor">
|
<Key ID="STR_ACE_Advanced_Fatigue_RecoveryFactor">
|
||||||
<English>Recovery Factor</English>
|
<English>Recovery Factor</English>
|
||||||
<German>Erholungsfaktor</German>
|
<German>Erholungsfaktor</German>
|
||||||
|
<Japanese>回復因数</Japanese>
|
||||||
|
<Polish>Współczynnik regeneracji</Polish>
|
||||||
|
<Korean>회복 요인</Korean>
|
||||||
|
<French>Facteur de récupération</French>
|
||||||
|
<Italian>Fattore Recupero</Italian>
|
||||||
|
<Chinese>回復值</Chinese>
|
||||||
|
<Chinesesimp>回复值</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Fatigue_RecoveryFactor_Description">
|
<Key ID="STR_ACE_Advanced_Fatigue_RecoveryFactor_Description">
|
||||||
<English>Changes how fast the player recovers when resting. Higher is faster.</English>
|
<English>Changes how fast the player recovers when resting. Higher is faster.</English>
|
||||||
<German>Ändert, wie schnell ein Spieler Ausdauer regeneriert. Ein höherer Wert bedeutet eine schnellere Regeneration.</German>
|
<German>Ändert, wie schnell ein Spieler Ausdauer regeneriert. Ein höherer Wert bedeutet eine schnellere Regeneration.</German>
|
||||||
|
<Japanese>プレイヤーが休憩をとる際に、どのくらいの速度でスタミナ回復するかを設定します。 値が高ければ高いほど、早くなります。</Japanese>
|
||||||
|
<Polish>Wpływa na czas regeneracji podczas postoju. Więcej znaczy szybciej.</Polish>
|
||||||
|
<Korean>얼마나 빨리 회복하는지를 바꿉니다. 값이 클수록 더 나은 성능을 발휘합니다</Korean>
|
||||||
|
<French>Change la vitesse à laquelle les joueurs récupèrent leur endurance lorsqu'ils se reposent. Une valeur plus élevée implique une récupération plus rapide.</French>
|
||||||
|
<Italian>Determina in quanto tempo il giocatore recupera quando rilassato. Maggiore significa migliore.</Italian>
|
||||||
|
<Chinese>決定玩家休息多久就能回復體力,值越高恢復越快</Chinese>
|
||||||
|
<Chinesesimp>决定玩家休息多久就能回复体力,值越高恢复越快</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Fatigue_LoadFactor">
|
<Key ID="STR_ACE_Advanced_Fatigue_LoadFactor">
|
||||||
<English>Load Factor</English>
|
<English>Load Factor</English>
|
||||||
<German>Gewichtsfaktor</German>
|
<German>Gewichtsfaktor</German>
|
||||||
|
<Japanese>重量因数</Japanese>
|
||||||
|
<Polish>Współczynnik masy ekwipunku</Polish>
|
||||||
|
<Korean>부담 요인</Korean>
|
||||||
|
<French>Facteur d'encombrement</French>
|
||||||
|
<Italian>Fattore Caricamento</Italian>
|
||||||
|
<Chinese>負重量</Chinese>
|
||||||
|
<Chinesesimp>负重量</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Fatigue_LoadFactor_Description">
|
<Key ID="STR_ACE_Advanced_Fatigue_LoadFactor_Description">
|
||||||
<English>Increases or decreases how much weight influences the players performance. Zero means equipment weight has no performance influence.</English>
|
<English>Increases or decreases how much weight influences the players performance. Zero means equipment weight has no performance influence.</English>
|
||||||
<German>Erhöht oder verringert, wie viel Einfluss das Ausrüstungsgewicht auf die Leistung hat. Null heißt, dass es keinen Einfluss hat.</German>
|
<German>Erhöht oder verringert, wie viel Einfluss das Ausrüstungsgewicht auf die Leistung hat. Null heißt, dass es keinen Einfluss hat.</German>
|
||||||
|
<Japanese>装備重量がプレイヤーのパフォーマンスにもたらす影響を増減させます。 値をゼロに設定した場合、装備重量はパフォーマンスに影響を与えません。</Japanese>
|
||||||
|
<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 réduit l'influence que le poids à sur les performances des joueurs. Zéro implique que le poids de l'équipement n'a pas d'influence sur les performances.</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>
|
||||||
|
<Chinese>增加或降低玩家所能承受的負重量. 如設定值為0, 代表裝備的重量將不會影響到玩家的體力表現</Chinese>
|
||||||
|
<Chinesesimp>增加或降低玩家所能承受的负重量. 如设定值为0, 代表装备的重量将不会影响到玩家的体力表现</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Fatigue_TerrainGradientFactor">
|
<Key ID="STR_ACE_Advanced_Fatigue_TerrainGradientFactor">
|
||||||
<English>Terrain Gradient Factor</English>
|
<English>Terrain Gradient Factor</English>
|
||||||
<German>Terrainsteigungsfaktor</German>
|
<German>Terrainsteigungsfaktor</German>
|
||||||
|
<Japanese>地形勾配因数</Japanese>
|
||||||
|
<Polish>Współczynnik terenu</Polish>
|
||||||
|
<Korean>지형 경사도 요인</Korean>
|
||||||
|
<French>Facteur d'inclinaison du terrain</French>
|
||||||
|
<Italian>Fattore Pendenza Terreno</Italian>
|
||||||
|
<Chinese>地形陡峭影響值</Chinese>
|
||||||
|
<Chinesesimp>地形陡峭影响值</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Fatigue_TerrainGradientFactor_Description">
|
<Key ID="STR_ACE_Advanced_Fatigue_TerrainGradientFactor_Description">
|
||||||
<English>Sets how much steep terrain increases stamina loss. Higher means higher stamina loss.</English>
|
<English>Sets how much steep terrain increases stamina loss. Higher means higher stamina loss.</English>
|
||||||
<German>Beeinflusst, wie stark Steigungen den Ausdauerverbrauch erhöhen. Ein höherer Wert erhöht den Ausdauerverbrauch.</German>
|
<German>Beeinflusst, wie stark Steigungen den Ausdauerverbrauch erhöhen. Ein höherer Wert erhöht den Ausdauerverbrauch.</German>
|
||||||
|
<Japanese>急勾配の地形がどれだけスタミナ消費を増大させるかを設定します。 値が高ければ高いほど、スタミナ消費が大きくなります。</Japanese>
|
||||||
|
<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>Configure l'influence de l'inclinaison du terrain sur la perte d'endurance. Une valeur plus élevée implique une perte d'endurance plus importante.</French>
|
||||||
|
<Italian>Stabilisce quanto la pendenza del terreno incrementa la perdita della stamina. Maggiore significa più stamina persa.</Italian>
|
||||||
|
<Chinese>設定陡峭的地形將會影響多少體力的流失,值越高代表體力流失越快</Chinese>
|
||||||
|
<Chinesesimp>设定陡峭的地形将会影响多少体力的流,失值越高代表体力流失越快</Chinesesimp>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Advanced_Fatigue_SwayFactor">
|
||||||
|
<English>Sway factor</English>
|
||||||
|
<Japanese>手ぶれ因数</Japanese>
|
||||||
|
<Chinesesimp>抖动因数</Chinesesimp>
|
||||||
|
<Chinese>抖動因素</Chinese>
|
||||||
|
<Italian>Fattore di oscillazione</Italian>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Advanced_Fatigue_SwayFactor_Description">
|
||||||
|
<English>Influences the amount of weapon sway. Higher means more sway.</English>
|
||||||
|
<Japanese>武器を持つ手のぶれ度合いを設定します。 値が高ければ高いほど、手ぶれが強くなります。</Japanese>
|
||||||
|
<Chinesesimp>影响手持武器的晃动程度,数值越高,抖动的越厉害.</Chinesesimp>
|
||||||
|
<Chinese>影響手持武器晃動程度,數值越高抖動越厲害</Chinese>
|
||||||
|
<Italian>Influenza l'ammontare di oscillazione dell'arma. Maggiore significa più oscillazione.</Italian>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Fatigue_Enabled">
|
<Key ID="STR_ACE_Advanced_Fatigue_Enabled">
|
||||||
<English>Enabled</English>
|
<English>Enabled</English>
|
||||||
<German>Aktiv</German>
|
<German>Aktiv</German>
|
||||||
|
<Japanese>アドバンスド ファティーグを有効化する</Japanese>
|
||||||
|
<Polish>Włączone</Polish>
|
||||||
|
<Korean>활성화</Korean>
|
||||||
|
<French>Activé</French>
|
||||||
|
<Italian>Abilitato</Italian>
|
||||||
|
<Chinese>啟用</Chinese>
|
||||||
|
<Chinesesimp>启用</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Fatigue_Enabled_Description">
|
<Key ID="STR_ACE_Advanced_Fatigue_Enabled_Description">
|
||||||
<English>Enables/disables Advanced Fatigue.</English>
|
<English>Enables/disables Advanced Fatigue.</English>
|
||||||
<German>Aktiviert/deaktiviert Advanced Fatigue.</German>
|
<German>Aktiviert/deaktiviert Advanced Fatigue.</German>
|
||||||
|
<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>
|
||||||
|
<Chinese>啟用/關閉進階體力.</Chinese>
|
||||||
|
<Chinesesimp>启用/关闭进阶体力.</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Fatigue_EnableStaminaBar">
|
<Key ID="STR_ACE_Advanced_Fatigue_EnableStaminaBar">
|
||||||
<English>Show stamina bar</English>
|
<English>Show stamina bar</English>
|
||||||
<German>Zeige Ausdauerleiste</German>
|
<German>Zeige Ausdauerleiste</German>
|
||||||
|
<Japanese>スタミナバーを表示する</Japanese>
|
||||||
|
<Polish>Pokaż pasek wytrzymałości</Polish>
|
||||||
|
<Korean>피로도 막대</Korean>
|
||||||
|
<French>Afficher la barre d'endurance</French>
|
||||||
|
<Italian>Mostra barra stamina</Italian>
|
||||||
|
<Chinese>顯示體力條</Chinese>
|
||||||
|
<Chinesesimp>显示体力条</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Fatigue_EnableStaminaBar_Description">
|
<Key ID="STR_ACE_Advanced_Fatigue_EnableStaminaBar_Description">
|
||||||
<English>Shows the stamina bar.</English>
|
<English>Shows the stamina bar.</English>
|
||||||
<German>Zeigt die Ausdauerleiste an.</German>
|
<German>Zeigt die Ausdauerleiste an.</German>
|
||||||
|
<Japanese>スタミナバーを表示します。</Japanese>
|
||||||
|
<Polish>Pokazuje pasek wytrzymałości.</Polish>
|
||||||
|
<Korean>피로도 막대를 보여줍니다.</Korean>
|
||||||
|
<French>Affiche la barre d'endurance.</French>
|
||||||
|
<Italian>Mostra la barra della stamina.</Italian>
|
||||||
|
<Chinese>顯示體力條</Chinese>
|
||||||
|
<Chinesesimp>显示体力条</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
</Package>
|
</Package>
|
||||||
</Project>
|
</Project>
|
||||||
|
11
addons/advanced_throwing/CfgAmmo.hpp
Normal file
11
addons/advanced_throwing/CfgAmmo.hpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
class CfgAmmo {
|
||||||
|
class Default;
|
||||||
|
class Grenade: Default {
|
||||||
|
GVAR(torqueDirection)[] = {1, 1, 0};
|
||||||
|
GVAR(torqueMagnitude) = "(50 + random 100) * selectRandom [1, -1]";
|
||||||
|
};
|
||||||
|
class GrenadeCore: Default {
|
||||||
|
GVAR(torqueDirection)[] = {1, 1, 0};
|
||||||
|
GVAR(torqueMagnitude) = "(50 + random 100) * selectRandom [1, -1]";
|
||||||
|
};
|
||||||
|
};
|
@ -12,6 +12,6 @@ class Extended_PreInit_EventHandlers {
|
|||||||
|
|
||||||
class Extended_PostInit_EventHandlers {
|
class Extended_PostInit_EventHandlers {
|
||||||
class ADDON {
|
class ADDON {
|
||||||
clientInit = QUOTE(call COMPILE_FILE(XEH_postInitClient));
|
init = QUOTE(call COMPILE_FILE(XEH_postInit));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -7,7 +7,7 @@ class CfgVehicles {
|
|||||||
category = "ACE";
|
category = "ACE";
|
||||||
displayName = CSTRING(Category);
|
displayName = CSTRING(Category);
|
||||||
function = QFUNC(moduleInit);
|
function = QFUNC(moduleInit);
|
||||||
scope = 2;
|
scope = 1;
|
||||||
isGlobal = 1;
|
isGlobal = 1;
|
||||||
icon = QPATHTOF(UI\Icon_Module_AdvancedThrowing_ca.paa);
|
icon = QPATHTOF(UI\Icon_Module_AdvancedThrowing_ca.paa);
|
||||||
class Arguments {
|
class Arguments {
|
||||||
@ -58,8 +58,9 @@ class CfgVehicles {
|
|||||||
class ACE_Actions {
|
class ACE_Actions {
|
||||||
class GVAR(pickUp) {
|
class GVAR(pickUp) {
|
||||||
displayName = CSTRING(PickUp);
|
displayName = CSTRING(PickUp);
|
||||||
condition = QUOTE(_player call FUNC(canPrepare));
|
condition = QUOTE([ARR_2(_player,true)] call FUNC(canPrepare));
|
||||||
statement = QUOTE(_this call FUNC(pickUp));
|
statement = QUOTE(_this call FUNC(pickUp));
|
||||||
|
exceptions[] = {"isNotSwimming"};
|
||||||
distance = 1.8; // Requires >1.7 to work when standing with weapon on back
|
distance = 1.8; // Requires >1.7 to work when standing with weapon on back
|
||||||
icon = "\a3\ui_f\data\igui\cfg\actions\obsolete\ui_action_takemine_ca.paa";
|
icon = "\a3\ui_f\data\igui\cfg\actions\obsolete\ui_action_takemine_ca.paa";
|
||||||
};
|
};
|
||||||
|
125
addons/advanced_throwing/XEH_postInit.sqf
Normal file
125
addons/advanced_throwing/XEH_postInit.sqf
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
// Fired XEH
|
||||||
|
[QGVAR(throwFiredXEH), FUNC(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");
|
||||||
|
|
||||||
|
|
||||||
|
// Add keybinds
|
||||||
|
["ACE3 Weapons", QGVAR(prepare), localize LSTRING(Prepare), {
|
||||||
|
// Condition
|
||||||
|
if (!([ACE_player] call FUNC(canPrepare))) exitWith {false};
|
||||||
|
if (EGVAR(common,isReloading)) exitWith {true};
|
||||||
|
|
||||||
|
// Statement
|
||||||
|
[ACE_player] call FUNC(prepare);
|
||||||
|
|
||||||
|
true
|
||||||
|
}, {false}, [34, [true, false, false]], false] call CBA_fnc_addKeybind; // Shift + G
|
||||||
|
|
||||||
|
["ACE3 Weapons", QGVAR(dropModeToggle), localize LSTRING(DropModeToggle), {
|
||||||
|
// Condition
|
||||||
|
if (!(ACE_player getVariable [QGVAR(inHand), false]) || {underwater ACE_player}) exitWith {false};
|
||||||
|
|
||||||
|
// Statement
|
||||||
|
private _currentDropMode = ACE_player getVariable [QGVAR(dropMode), false];
|
||||||
|
ACE_player setVariable [QGVAR(dropMode), !_currentDropMode];
|
||||||
|
|
||||||
|
ACE_player setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT]; // Reset for consistency when opening
|
||||||
|
call FUNC(updateControlsHint); // Change controls hint for MMB
|
||||||
|
true
|
||||||
|
}, {false}, [34, [false, true, false]], false] call CBA_fnc_addKeybind; // Ctrl + G
|
||||||
|
|
||||||
|
["ACE3 Weapons", QGVAR(dropModeHold), localize LSTRING(DropModeHold), {
|
||||||
|
// Condition
|
||||||
|
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false};
|
||||||
|
|
||||||
|
// Statement
|
||||||
|
ACE_player setVariable [QGVAR(dropMode), true];
|
||||||
|
ACE_player setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT]; // Reset for consistency when opening
|
||||||
|
call FUNC(updateControlsHint); // Change controls hint for MMB
|
||||||
|
true
|
||||||
|
}, {
|
||||||
|
// Condition
|
||||||
|
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false};
|
||||||
|
|
||||||
|
// Statement
|
||||||
|
ACE_player setVariable [QGVAR(dropMode), false];
|
||||||
|
call FUNC(updateControlsHint); // Change controls hint for MMB
|
||||||
|
true
|
||||||
|
}, [0, [false, false, false]], false] call CBA_fnc_addKeybind; // Empty
|
||||||
|
|
||||||
|
|
||||||
|
// Event handlers
|
||||||
|
["unit", {
|
||||||
|
[_this select 1, "Player changed"] call FUNC(exitThrowMode);
|
||||||
|
}] call CBA_fnc_addPlayerEventhandler;
|
||||||
|
|
||||||
|
["visibleMap", {
|
||||||
|
params ["", "_visibleMap"]; // command visibleMap is updated one frame later
|
||||||
|
if (_visibleMap && {ACE_player getVariable [QGVAR(inHand), false]}) then {
|
||||||
|
[ACE_player, "Opened Map"] call FUNC(exitThrowMode);
|
||||||
|
};
|
||||||
|
}] call CBA_fnc_addPlayerEventhandler;
|
||||||
|
|
||||||
|
|
||||||
|
["ace_interactMenuOpened", {
|
||||||
|
// Exit if advanced throwing is disabled (pick up only supports advanced throwing)
|
||||||
|
if (!GVAR(enabled)) exitWith {};
|
||||||
|
|
||||||
|
if (ACE_player getVariable [QGVAR(inHand), false]) then {
|
||||||
|
[ACE_player, "Interact menu opened"] call FUNC(exitThrowMode);
|
||||||
|
} else {
|
||||||
|
params ["_interactionType"];
|
||||||
|
// Ignore self-interaction menu, when in vehicle and when pick up is disabled
|
||||||
|
if (GVAR(enablePickUp) && {_interactionType == 0} && {vehicle ACE_player == ACE_player}) then {
|
||||||
|
// Show pick up actions on CfgAmmo's
|
||||||
|
call FUNC(renderPickUpInteraction);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
|
||||||
|
// Set last thrown time on Vanilla Throwing and Advanced Throwing
|
||||||
|
["ace_firedPlayer", {
|
||||||
|
//IGNORE_PRIVATE_WARNING ["_unit", "_weapon"];
|
||||||
|
if (_weapon == "Throw") then {
|
||||||
|
_unit setVariable [QGVAR(lastThrownTime), CBA_missionTime];
|
||||||
|
};
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
|
||||||
|
// Display handlers
|
||||||
|
["KeyDown", {_this call FUNC(onKeyDown)}] call CBA_fnc_addDisplayHandler;
|
||||||
|
["MouseButtonDown", {_this call FUNC(onMouseButtonDown)}] call CBA_fnc_addDisplayHandler;
|
||||||
|
["MouseZChanged", {_this call FUNC(onMouseScroll)}] call CBA_fnc_addDisplayHandler;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DRAW_THROW_PATH
|
||||||
|
GVAR(predictedPath) = [];
|
||||||
|
GVAR(flightPath) = [];
|
||||||
|
|
||||||
|
addMissionEventHandler ["Draw3D", { // Blue is predicted before throw, red is real
|
||||||
|
{
|
||||||
|
_x params ["", "_newTrajAGL"];
|
||||||
|
drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [0,0,1,1], _newTrajAGL, 1, 1, 0, "", 2];
|
||||||
|
} forEach GVAR(predictedPath);
|
||||||
|
{
|
||||||
|
_x params ["_pos", "_vectorUp"];
|
||||||
|
drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,0,0,1], _pos, 1, 1, 0, "", 2];
|
||||||
|
drawLine3D [_pos, _pos vectorAdd _vectorUp, [1,0,1,1]];
|
||||||
|
} forEach GVAR(flightPath);
|
||||||
|
}];
|
||||||
|
#endif
|
@ -1,107 +0,0 @@
|
|||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
// 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");
|
|
||||||
GVAR(ammoMagLookup) setVariable [_ammo, _x];
|
|
||||||
} count (getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines"));
|
|
||||||
nil
|
|
||||||
} count getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles");
|
|
||||||
|
|
||||||
|
|
||||||
// Add keybinds
|
|
||||||
["ACE3 Weapons", QGVAR(prepare), localize LSTRING(Prepare), {
|
|
||||||
// Condition
|
|
||||||
if (!([ACE_player] call FUNC(canPrepare))) exitWith {false};
|
|
||||||
|
|
||||||
// Statement
|
|
||||||
[ACE_player] call FUNC(prepare);
|
|
||||||
|
|
||||||
true
|
|
||||||
}, {false}, [34, [true, false, false]], false] call CBA_fnc_addKeybind; // Shift + G
|
|
||||||
|
|
||||||
["ACE3 Weapons", QGVAR(dropModeToggle), localize LSTRING(DropModeToggle), {
|
|
||||||
// Condition
|
|
||||||
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false};
|
|
||||||
|
|
||||||
// Statement
|
|
||||||
private _currentDropMode = ACE_player getVariable [QGVAR(dropMode), false];
|
|
||||||
ACE_player setVariable [QGVAR(dropMode), !_currentDropMode];
|
|
||||||
|
|
||||||
ACE_player setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT]; // Reset for consistency when opening
|
|
||||||
call FUNC(updateControlsHint); // Change controls hint for MMB
|
|
||||||
true
|
|
||||||
}, {false}, [34, [false, true, false]], false] call CBA_fnc_addKeybind; // Ctrl + G
|
|
||||||
|
|
||||||
["ACE3 Weapons", QGVAR(dropModeHold), localize LSTRING(DropModeHold), {
|
|
||||||
// Condition
|
|
||||||
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false};
|
|
||||||
|
|
||||||
// Statement
|
|
||||||
ACE_player setVariable [QGVAR(dropMode), true];
|
|
||||||
ACE_player setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT]; // Reset for consistency when opening
|
|
||||||
call FUNC(updateControlsHint); // Change controls hint for MMB
|
|
||||||
true
|
|
||||||
}, {
|
|
||||||
// Condition
|
|
||||||
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false};
|
|
||||||
|
|
||||||
// Statement
|
|
||||||
ACE_player setVariable [QGVAR(dropMode), false];
|
|
||||||
call FUNC(updateControlsHint); // Change controls hint for MMB
|
|
||||||
true
|
|
||||||
}, [0, [false, false, false]], false] call CBA_fnc_addKeybind; // Empty
|
|
||||||
|
|
||||||
|
|
||||||
// Event handlers
|
|
||||||
["unit", {
|
|
||||||
[_this select 1, "Player changed"] call FUNC(exitThrowMode);
|
|
||||||
}] call CBA_fnc_addPlayerEventhandler;
|
|
||||||
|
|
||||||
["ace_interactMenuOpened", {
|
|
||||||
// Exit if advanced throwing is disabled (pick up only supports advanced throwing)
|
|
||||||
if (!GVAR(enabled)) exitWith {};
|
|
||||||
|
|
||||||
if (ACE_player getVariable [QGVAR(inHand), false]) then {
|
|
||||||
[ACE_player, "Interact menu opened"] call FUNC(exitThrowMode);
|
|
||||||
} else {
|
|
||||||
params ["_interactionType"];
|
|
||||||
// Ignore self-interaction menu, when in vehicle and when pick up is disabled
|
|
||||||
if (GVAR(enablePickUp) && {_interactionType == 0} && {vehicle ACE_player == ACE_player}) then {
|
|
||||||
// Show pick up actions on CfgAmmo's
|
|
||||||
call FUNC(renderPickUpInteraction);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}] call CBA_fnc_addEventHandler;
|
|
||||||
|
|
||||||
|
|
||||||
// Fired XEH
|
|
||||||
[QGVAR(throwFiredXEH), FUNC(throwFiredXEH)] call CBA_fnc_addEventHandler;
|
|
||||||
|
|
||||||
|
|
||||||
// Display handlers
|
|
||||||
["KeyDown", {_this call FUNC(onKeyDown)}] call CBA_fnc_addDisplayHandler;
|
|
||||||
["MouseButtonDown", {_this call FUNC(onMouseButtonDown)}] call CBA_fnc_addDisplayHandler;
|
|
||||||
["MouseZChanged", {_this call FUNC(onMouseScroll)}] call CBA_fnc_addDisplayHandler;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DRAW_THROW_PATH
|
|
||||||
GVAR(predictedPath) = [];
|
|
||||||
GVAR(flightPath) = [];
|
|
||||||
|
|
||||||
addMissionEventHandler ["Draw3D", { // Blue is predicted before throw, red is real
|
|
||||||
{
|
|
||||||
_x params ["", "_newTrajAGL"];
|
|
||||||
drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [0,0,1,1], _newTrajAGL, 1, 1, 0, "", 2];
|
|
||||||
} forEach GVAR(predictedPath);
|
|
||||||
{
|
|
||||||
_newTrajAGL = _x;
|
|
||||||
drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,0,0,1], _newTrajAGL, 1, 1, 0, "", 2];
|
|
||||||
} forEach GVAR(flightPath)
|
|
||||||
}];
|
|
||||||
#endif
|
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
ADDON = false;
|
ADDON = false;
|
||||||
|
|
||||||
|
PREP_RECOMPILE_START;
|
||||||
#include "XEH_PREP.hpp"
|
#include "XEH_PREP.hpp"
|
||||||
|
PREP_RECOMPILE_END;
|
||||||
|
|
||||||
ADDON = true;
|
ADDON = true;
|
||||||
|
@ -15,5 +15,6 @@ class CfgPatches {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#include "ACE_Settings.hpp"
|
#include "ACE_Settings.hpp"
|
||||||
|
#include "CfgAmmo.hpp"
|
||||||
#include "CfgEventHandlers.hpp"
|
#include "CfgEventHandlers.hpp"
|
||||||
#include "CfgVehicles.hpp"
|
#include "CfgVehicles.hpp"
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Jonpas
|
* Author: Jonpas
|
||||||
* Checks if a throwable can be prepared.
|
* Checks if a throwable can be prepared.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Unit <OBJECT>
|
* 0: Unit <OBJECT>
|
||||||
|
* 1: Ignore Last Thrown Time <BOOL> (default: false)
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* Can Prepare <BOOL>
|
* Can Prepare <BOOL>
|
||||||
@ -13,19 +15,25 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_unit"];
|
params ["_unit", ["_ignoreLastThrownTime", false]];
|
||||||
|
|
||||||
|
// Don't delay when picking up
|
||||||
|
if (_ignoreLastThrownTime) then {
|
||||||
|
_unit setVariable [QGVAR(lastThrownTime), -1];
|
||||||
|
};
|
||||||
|
|
||||||
GVAR(enabled) &&
|
GVAR(enabled) &&
|
||||||
|
|
||||||
#ifndef DEBUG_MODE_FULL
|
#ifdef ALLOW_QUICK_THROW
|
||||||
{_unit getVariable [QGVAR(lastThrownTime), CBA_missionTime - 3] < CBA_missionTime - 2} && // Prevent throwing in quick succession
|
|
||||||
#else
|
|
||||||
{true} &&
|
{true} &&
|
||||||
|
#else
|
||||||
|
{_unit getVariable [QGVAR(lastThrownTime), CBA_missionTime - 3] < CBA_missionTime - 2} && // Prevent throwing in quick succession
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{!(call EFUNC(common,isFeatureCameraActive))} &&
|
{!(call EFUNC(common,isFeatureCameraActive))} &&
|
||||||
{!EGVAR(common,isReloading)} &&
|
{[_unit, objNull, ["isNotInside", "isNotSwimming", "isNotSitting"/*, "isNotOnLadder"*/]] call EFUNC(common,canInteractWith)} && // Ladder needs positioning fixes on throw
|
||||||
{[_unit, objNull, ["isNotInside", "isNotSitting"/*, "isNotOnLadder"*/]] call EFUNC(common,canInteractWith)} && // Ladder needs positioning fixes on throw
|
{_unit call CBA_fnc_canUseWeapon} && // Disable in non-FFV seats due to surface detection issues
|
||||||
{_unit call CBA_fnc_canUseWeapon} // Disable in non-FFV seats due to surface detection issues
|
{"" == currentWeapon _unit || {currentWeapon _unit != secondaryWeapon _unit}} &&
|
||||||
|
{0 >= _unit getVariable [QEGVAR(common,effect_blockThrow), 0]} &&
|
||||||
|
{isNull (ACE_controlledUAV select 0)}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Jonpas
|
* Author: Jonpas
|
||||||
* Checks if a throwable can be thrown.
|
* Checks if a throwable can be thrown.
|
||||||
@ -13,7 +14,6 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_unit"];
|
params ["_unit"];
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Zapat, Dslyecxi, Jonpas
|
* Author: Zapat, Dslyecxi, Jonpas
|
||||||
* Draws throw arc.
|
* Draws throw arc.
|
||||||
@ -13,7 +14,6 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
// Disable drawing when intersecting with the vehicle
|
// Disable drawing when intersecting with the vehicle
|
||||||
if !([ACE_player] call FUNC(canThrow)) exitWith {
|
if !([ACE_player] call FUNC(canThrow)) exitWith {
|
||||||
@ -47,11 +47,15 @@ for "_i" from 0.05 to 1.45 step 0.1 do {
|
|||||||
|
|
||||||
if (_newTrajASL distance (getPosASLVisual ACE_player) <= 20) then {
|
if (_newTrajASL distance (getPosASLVisual ACE_player) <= 20) then {
|
||||||
if ((ASLToATL _newTrajASL) select 2 <= 0) then {
|
if ((ASLToATL _newTrajASL) select 2 <= 0) then {
|
||||||
_cross = 1
|
_cross = 1; // 1: Distance Limit (Green)
|
||||||
} else {
|
} else {
|
||||||
// Even vanilla throwables go through glass, only "GEOM" LOD will stop it but that will also stop it when there is glass in a window
|
// Even vanilla throwables go through glass, only "GEOM" LOD will stop it but that will also stop it when there is glass in a window
|
||||||
if (lineIntersects [_prevTrajASL, _newTrajASL]) then {
|
if (lineIntersects [_prevTrajASL, _newTrajASL]) then { // Checks the "VIEW" LOD
|
||||||
_cross = 2;
|
_cross = 2; // 2: View LOD Block (Red)
|
||||||
|
} else {
|
||||||
|
if (!((lineIntersectsSurfaces [_prevTrajASL, _newTrajASL, _activeThrowable, ACE_player, true, 1, "GEOM", "FIRE"]) isEqualTo [])) then {
|
||||||
|
_cross = 3; // 3: GEOM/FIRE LOD Block (Yellow) - pass a3 bulding glass, but blocked on some CUP glass
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,10 +64,10 @@ for "_i" from 0.05 to 1.45 step 0.1 do {
|
|||||||
private _movePerc = linearConversion [3, 0, vectorMagnitude (velocity ACE_player), 0, 1, true];
|
private _movePerc = linearConversion [3, 0, vectorMagnitude (velocity ACE_player), 0, 1, true];
|
||||||
_alpha = _alpha * _movePerc;
|
_alpha = _alpha * _movePerc;
|
||||||
|
|
||||||
private _col = [ [1, 1, 1, _alpha], [0, 1, 0, _alpha], [1, 0, 0, _alpha] ] select _cross;
|
private _col = [ [1, 1, 1, _alpha], [0, 1, 0, _alpha], [1, 0, 0, _alpha], [1, 1, 0, _alpha] ] select _cross;
|
||||||
|
|
||||||
if (_cross != 2 && {lineIntersects [eyePos ACE_player, _newTrajASL]}) then {
|
if (_cross != 2 && {lineIntersects [eyePos ACE_player, _newTrajASL]}) then {
|
||||||
_col set [3, 0.1]
|
_col set [3, 0.1];
|
||||||
};
|
};
|
||||||
|
|
||||||
_pathData pushBack [_col, ASLToAGL _newTrajASL, _iDim];
|
_pathData pushBack [_col, ASLToAGL _newTrajASL, _iDim];
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Dslyecxi, Jonpas, SilentSpike
|
* Author: Dslyecxi, Jonpas, SilentSpike
|
||||||
* Handles drawing the currently selected or cooked throwable.
|
* Handles drawing the currently selected or cooked throwable.
|
||||||
@ -13,9 +14,8 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
if (dialog || {!(ACE_player getVariable [QGVAR(inHand), false])} || {!([ACE_player] call FUNC(canPrepare))}) exitWith {
|
if (dialog || {!(ACE_player getVariable [QGVAR(inHand), false])} || {!([ACE_player, true] call FUNC(canPrepare))}) exitWith {
|
||||||
[ACE_player, "In dialog or no throwable in hand or cannot prepare throwable"] call FUNC(exitThrowMode);
|
[ACE_player, "In dialog or no throwable in hand or cannot prepare throwable"] call FUNC(exitThrowMode);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -36,6 +36,11 @@ if (_throwable isEqualTo [] && {!_primed}) exitWith {
|
|||||||
|
|
||||||
private _throwableMag = _throwable param [0, "#none"];
|
private _throwableMag = _throwable param [0, "#none"];
|
||||||
|
|
||||||
|
// If not primed, double check we actually have the magazine in inventory
|
||||||
|
if ((!_primed) && {!((_throwableMag in (uniformItems ACE_player)) || {_throwableMag in (vestItems ACE_player)} || {_throwableMag in (backpackItems ACE_player)})}) exitWith {
|
||||||
|
[ACE_player, "No valid throwable (glitched currentThrowable)"] call FUNC(exitThrowMode);
|
||||||
|
};
|
||||||
|
|
||||||
// Get correct throw power for primed grenade
|
// Get correct throw power for primed grenade
|
||||||
if (_primed) then {
|
if (_primed) then {
|
||||||
private _ammoType = typeOf _activeThrowable;
|
private _ammoType = typeOf _activeThrowable;
|
||||||
@ -63,7 +68,7 @@ private _power = linearConversion [0, 180, _phi - 30, 1, 0.3, true];
|
|||||||
ACE_player setVariable [QGVAR(throwSpeed), _throwSpeed * _power];
|
ACE_player setVariable [QGVAR(throwSpeed), _throwSpeed * _power];
|
||||||
|
|
||||||
#ifdef DEBUG_MODE_FULL
|
#ifdef DEBUG_MODE_FULL
|
||||||
hintSilent format ["Heading: %1\nPower: %2\nSpeed: %3\nThrowMag: %4", _phi, _power, _throwSpeed * _power, _throwableMag];
|
hintSilent format ["Heading: %1\nPower: %2\nSpeed: %3\nThrowMag: %4\nMuzzle: %5", _phi, _power, _throwSpeed * _power, _throwableMag, ACE_player getVariable [QGVAR(activeMuzzle), ""]];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private _throwableType = getText (configFile >> "CfgMagazines" >> _throwableMag >> "ammo");
|
private _throwableType = getText (configFile >> "CfgMagazines" >> _throwableMag >> "ammo");
|
||||||
@ -71,16 +76,25 @@ private _throwableType = getText (configFile >> "CfgMagazines" >> _throwableMag
|
|||||||
if (!([ACE_player] call FUNC(canThrow)) && {!_primed}) exitWith {
|
if (!([ACE_player] call FUNC(canThrow)) && {!_primed}) exitWith {
|
||||||
if (!isNull _activeThrowable) then {
|
if (!isNull _activeThrowable) then {
|
||||||
deleteVehicle _activeThrowable;
|
deleteVehicle _activeThrowable;
|
||||||
|
// Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory)
|
||||||
|
ACE_player setAmmo [ACE_player getVariable [QGVAR(activeMuzzle), ""], 1];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isNull _activeThrowable || {(_throwableType != typeOf _activeThrowable) && {!_primed}}) then {
|
if (isNull _activeThrowable || {(_throwableType != typeOf _activeThrowable) && {!_primed}}) then {
|
||||||
if (!isNull _activeThrowable) then {
|
if (!isNull _activeThrowable) then {
|
||||||
deleteVehicle _activeThrowable;
|
deleteVehicle _activeThrowable;
|
||||||
|
// Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory)
|
||||||
|
ACE_player setAmmo [ACE_player getVariable [QGVAR(activeMuzzle), ""], 1];
|
||||||
};
|
};
|
||||||
_activeThrowable = _throwableType createVehicleLocal [0, 0, 0];
|
_activeThrowable = _throwableType createVehicleLocal [0, 0, 0];
|
||||||
_activeThrowable enableSimulation false;
|
_activeThrowable enableSimulation false;
|
||||||
ACE_player setVariable [QGVAR(activeThrowable), _activeThrowable];
|
ACE_player setVariable [QGVAR(activeThrowable), _activeThrowable];
|
||||||
|
|
||||||
|
// Set muzzle ammo to 0 to block vanilla throwing (can only be 0 or 1)
|
||||||
|
private _muzzle = _throwableMag call FUNC(getMuzzle);
|
||||||
|
ACE_player setAmmo [_muzzle, 0];
|
||||||
|
ACE_player setVariable [QGVAR(activeMuzzle), _muzzle];
|
||||||
};
|
};
|
||||||
|
|
||||||
// Exit in case of explosion in hand
|
// Exit in case of explosion in hand
|
||||||
@ -114,6 +128,10 @@ _activeThrowable setDir (_unitDirVisual + 90);
|
|||||||
private _pitch = [-30, -90] select (_throwType == "high");
|
private _pitch = [-30, -90] select (_throwType == "high");
|
||||||
[_activeThrowable, _pitch, 0] call BIS_fnc_setPitchBank;
|
[_activeThrowable, _pitch, 0] call BIS_fnc_setPitchBank;
|
||||||
|
|
||||||
|
// Force drop mode if underwater
|
||||||
|
if (underwater player) then {
|
||||||
|
ACE_player setVariable [QGVAR(dropMode), true];
|
||||||
|
};
|
||||||
|
|
||||||
if (ACE_player getVariable [QGVAR(dropMode), false]) then {
|
if (ACE_player getVariable [QGVAR(dropMode), false]) then {
|
||||||
_posFin = _posFin vectorAdd (AGLToASL (positionCameraToWorld [_leanCoef, 0, ACE_player getVariable [QGVAR(dropDistance), DROP_DISTANCE_DEFAULT]]));
|
_posFin = _posFin vectorAdd (AGLToASL (positionCameraToWorld [_leanCoef, 0, ACE_player getVariable [QGVAR(dropDistance), DROP_DISTANCE_DEFAULT]]));
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Dslyecxi, Jonpas
|
* Author: Dslyecxi, Jonpas
|
||||||
* Exits throw mode.
|
* Exits throw mode.
|
||||||
@ -14,7 +15,6 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_unit", "_reason"];
|
params ["_unit", "_reason"];
|
||||||
TRACE_2("params",_unit,_reason);
|
TRACE_2("params",_unit,_reason);
|
||||||
@ -25,13 +25,26 @@ if !(_unit getVariable [QGVAR(inHand), false]) exitWith {};
|
|||||||
systemChat format ["Exit Throw Mode: %1", _reason];
|
systemChat format ["Exit Throw Mode: %1", _reason];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
private _activeThrowable = _unit getVariable [QGVAR(activeThrowable), objNull];
|
||||||
if !(_unit getVariable [QGVAR(primed), false]) then {
|
if !(_unit getVariable [QGVAR(primed), false]) then {
|
||||||
deleteVehicle (_unit getVariable [QGVAR(activeThrowable), objNull]);
|
deleteVehicle _activeThrowable;
|
||||||
|
} else {
|
||||||
|
_unit setVariable [QGVAR(lastThrownTime), CBA_missionTime];
|
||||||
|
// Fix floating for throwables without proper physics (eg. IR Grenade)
|
||||||
|
_activeThrowable setVelocity [0, 0, -0.1];
|
||||||
|
|
||||||
|
// Set thrower
|
||||||
|
private _instigator = (getShotParents _activeThrowable) param [1, _unit]; // getShotParents could be [] on replaced grenades (like IR chemlight)
|
||||||
|
[QEGVAR(common,setShotParents), [_activeThrowable, _unit, _instigator]] call CBA_fnc_serverEvent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory)
|
||||||
|
_unit setAmmo [_unit getVariable [QGVAR(activeMuzzle), ""], 1];
|
||||||
|
|
||||||
_unit setVariable [QGVAR(inHand), false];
|
_unit setVariable [QGVAR(inHand), false];
|
||||||
_unit setVariable [QGVAR(primed), false];
|
_unit setVariable [QGVAR(primed), false];
|
||||||
_unit setVariable [QGVAR(activeThrowable), objNull];
|
_unit setVariable [QGVAR(activeThrowable), objNull];
|
||||||
|
_unit setVariable [QGVAR(activeMuzzle), ""];
|
||||||
_unit setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT];
|
_unit setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT];
|
||||||
_unit setVariable [QGVAR(throwSpeed), THROW_SPEED_DEFAULT];
|
_unit setVariable [QGVAR(throwSpeed), THROW_SPEED_DEFAULT];
|
||||||
_unit setVariable [QGVAR(dropMode), false];
|
_unit setVariable [QGVAR(dropMode), false];
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: PabstMirror
|
* Author: PabstMirror
|
||||||
* Retrieve muzzle name from config.
|
* Retrieve muzzle name from config.
|
||||||
@ -13,7 +14,6 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_magazineClassname"];
|
params ["_magazineClassname"];
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Jonpas
|
* Author: Jonpas
|
||||||
* Initializes the Advanced Throwing module.
|
* Initializes the Advanced Throwing module.
|
||||||
@ -13,12 +14,8 @@
|
|||||||
* Example:
|
* Example:
|
||||||
* [logic, [unit1, unit2], true] call ace_advanced_throwing_fnc_moduleInit
|
* [logic, [unit1, unit2], true] call ace_advanced_throwing_fnc_moduleInit
|
||||||
*
|
*
|
||||||
* Public:
|
* Public: No
|
||||||
* No
|
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
if (!isServer) exitWith {};
|
|
||||||
|
|
||||||
params ["_logic", "_units", "_activated"];
|
params ["_logic", "_units", "_activated"];
|
||||||
|
|
||||||
@ -30,4 +27,4 @@ if (!_activated) exitWith {};
|
|||||||
[_logic, QGVAR(enablePickUp), "enablePickUp"] call EFUNC(common,readSettingFromModule);
|
[_logic, QGVAR(enablePickUp), "enablePickUp"] call EFUNC(common,readSettingFromModule);
|
||||||
[_logic, QGVAR(enablePickUpAttached), "enablePickUpAttached"] call EFUNC(common,readSettingFromModule);
|
[_logic, QGVAR(enablePickUpAttached), "enablePickUpAttached"] call EFUNC(common,readSettingFromModule);
|
||||||
|
|
||||||
ACE_LOGINFO_1("Advanced Throwing Module Initialized. Enabled: %1",GVAR(enabled));
|
INFO_1("Advanced Throwing Module Initialized. Enabled: %1",GVAR(enabled));
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Dslyecxi, Jonpas
|
* Author: Dslyecxi, Jonpas
|
||||||
* Key down event.
|
* Key down event.
|
||||||
@ -17,7 +18,6 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false};
|
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false};
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Dslyecxi, Jonpas
|
* Author: Dslyecxi, Jonpas
|
||||||
* Mouse button down event.
|
* Mouse button down event.
|
||||||
@ -13,7 +14,6 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {};
|
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {};
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Dslyecxi, Jonpas
|
* Author: Dslyecxi, Jonpas
|
||||||
* Mouse scroll wheel changed event.
|
* Mouse scroll wheel changed event.
|
||||||
@ -13,7 +14,6 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {};
|
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {};
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Jonpas
|
* Author: Jonpas
|
||||||
* Picks up a throwable from the ground.
|
* Picks up a throwable from the ground.
|
||||||
@ -14,7 +15,6 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_helper", "_unit"];
|
params ["_helper", "_unit"];
|
||||||
TRACE_2("params",_helper,_unit);
|
TRACE_2("params",_helper,_unit);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Dslyecxi, Jonpas
|
* Author: Dslyecxi, Jonpas
|
||||||
* Prepares throwable or selects the next.
|
* Prepares throwable or selects the next.
|
||||||
@ -13,7 +14,6 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_unit"];
|
params ["_unit"];
|
||||||
TRACE_1("params",_unit);
|
TRACE_1("params",_unit);
|
||||||
@ -23,12 +23,15 @@ if (_unit getVariable [QGVAR(inHand), false]) exitWith {
|
|||||||
TRACE_1("inHand",_unit);
|
TRACE_1("inHand",_unit);
|
||||||
if (!(_unit getVariable [QGVAR(primed), false])) then {
|
if (!(_unit getVariable [QGVAR(primed), false])) then {
|
||||||
TRACE_1("not primed",_unit);
|
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)
|
||||||
|
ACE_player setAmmo [ACE_player getVariable [QGVAR(activeMuzzle), ""], 1];
|
||||||
[_unit] call EFUNC(weaponselect,selectNextGrenade);
|
[_unit] call EFUNC(weaponselect,selectNextGrenade);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Try selecting next throwable if none currently selected
|
// Try selecting next throwable if none currently selected
|
||||||
if ((isNull (_unit getVariable [QGVAR(activeThrowable), objNull])) && {(currentThrowable _unit) isEqualTo []} && {!([_unit] call EFUNC(weaponselect,selectNextGrenade))}) exitWith {
|
if (isNull (_unit getVariable [QGVAR(activeThrowable), objNull]) && {(currentThrowable _unit) isEqualTo []} && {!([_unit] call EFUNC(weaponselect,selectNextGrenade))}) exitWith {
|
||||||
TRACE_1("no throwables",_unit);
|
TRACE_1("no throwables",_unit);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Dslyecxi, Jonpas
|
* Author: Dslyecxi, Jonpas
|
||||||
* Primes the throwable, creates global throwable vehicle and throws Fired XEH.
|
* Primes the throwable, creates global throwable vehicle and throws Fired XEH.
|
||||||
@ -14,7 +15,6 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_unit", ["_showHint", false]];
|
params ["_unit", ["_showHint", false]];
|
||||||
TRACE_2("params",_unit,_showHint);
|
TRACE_2("params",_unit,_showHint);
|
||||||
@ -26,7 +26,16 @@ private _throwableMag = (currentThrowable _unit) select 0;
|
|||||||
_unit removeItem _throwableMag;
|
_unit removeItem _throwableMag;
|
||||||
|
|
||||||
private _throwableType = getText (configFile >> "CfgMagazines" >> _throwableMag >> "ammo");
|
private _throwableType = getText (configFile >> "CfgMagazines" >> _throwableMag >> "ammo");
|
||||||
private _muzzle = _throwableMag call FUNC(getMuzzle);
|
private _muzzle = _unit getVariable [QGVAR(activeMuzzle), ""];
|
||||||
|
|
||||||
|
// Set muzzle ammo to 0 to block vanilla throwing (can only be 0 or 1), removeItem above resets it
|
||||||
|
_unit setAmmo [_muzzle, 0];
|
||||||
|
|
||||||
|
// Handle weird scripted grenades (RHS) which could cause unexpected behaviour
|
||||||
|
private _nonInheritedCfg = configProperties [configFile >> "CfgAmmo" >> _throwableType, 'configName _x == QGVAR(replaceWith)', false];
|
||||||
|
if ((count _nonInheritedCfg) == 1) then {
|
||||||
|
_throwableType = getText (_nonInheritedCfg select 0);
|
||||||
|
};
|
||||||
|
|
||||||
// Create actual throwable globally
|
// Create actual throwable globally
|
||||||
private _activeThrowableOld = _unit getVariable [QGVAR(activeThrowable), objNull];
|
private _activeThrowableOld = _unit getVariable [QGVAR(activeThrowable), objNull];
|
||||||
@ -45,6 +54,9 @@ deleteVehicle _activeThrowableOld;
|
|||||||
_activeThrowable // projectile
|
_activeThrowable // projectile
|
||||||
]] call CBA_fnc_globalEvent;
|
]] call CBA_fnc_globalEvent;
|
||||||
|
|
||||||
|
// Set prime instigator
|
||||||
|
[QEGVAR(common,setShotParents), [_activeThrowable, _unit, _unit]] call CBA_fnc_serverEvent;
|
||||||
|
|
||||||
if (_showHint) then {
|
if (_showHint) then {
|
||||||
// Show primed hint
|
// Show primed hint
|
||||||
private _displayNameShort = getText (configFile >> "CfgMagazines" >> _throwableMag >> "displayNameShort");
|
private _displayNameShort = getText (configFile >> "CfgMagazines" >> _throwableMag >> "displayNameShort");
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: PabstMirror, Jonpas
|
* Author: PabstMirror, Jonpas
|
||||||
* When interact_menu starts rendering (from "interact_keyDown" event).
|
* When interact_menu starts rendering (from "interact_keyDown" event).
|
||||||
@ -7,14 +8,13 @@
|
|||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* Nothing
|
* None
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* call ace_advanced_throwing_fnc_renderPickUpInteraction
|
* call ace_advanced_throwing_fnc_renderPickUpInteraction
|
||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
[{
|
[{
|
||||||
params ["_args", "_idPFH"];
|
params ["_args", "_idPFH"];
|
||||||
@ -22,15 +22,19 @@
|
|||||||
|
|
||||||
// isNull is necessarry to prevent rare error when ending mission with interact key down
|
// isNull is necessarry to prevent rare error when ending mission with interact key down
|
||||||
if (EGVAR(interact_menu,keyDown) && {!isNull ACE_player}) then {
|
if (EGVAR(interact_menu,keyDown) && {!isNull ACE_player}) then {
|
||||||
// Rescan when player moved >5 meters from last pos, nearObjects is costly
|
// Rescan when player moved >5 meters from last pos, nearObjects can be costly with a lot of objects around
|
||||||
if ((getPosASL ACE_player) distance _setPosition > 5) then {
|
if ((getPosASL ACE_player) distance _setPosition > 5) then {
|
||||||
// IR throwbles inherit from GrenadeCore, others from GrenadeHand, IR Chemlights are special snowflakes
|
// Grenades inherit from GrenadeHand, IR throwbles from IRStrobeBase, IR Chemlights are special snowflakes
|
||||||
|
// nearEntities does not see throwables
|
||||||
_nearThrowables = ACE_player nearObjects ["GrenadeHand", PICK_UP_DISTANCE];
|
_nearThrowables = ACE_player nearObjects ["GrenadeHand", PICK_UP_DISTANCE];
|
||||||
_nearThrowables append (ACE_player nearObjects ["GrenadeCore", PICK_UP_DISTANCE]);
|
_nearThrowables append (ACE_player nearObjects ["IRStrobeBase", PICK_UP_DISTANCE]);
|
||||||
_nearThrowables append (ACE_player nearObjects ["ACE_Chemlight_IR_Dummy", PICK_UP_DISTANCE]);
|
_nearThrowables append (ACE_player nearObjects ["ACE_Chemlight_IR_Dummy", PICK_UP_DISTANCE]);
|
||||||
|
|
||||||
{
|
{
|
||||||
if (!(_x in _throwablesHelped) && {GVAR(enablePickUpAttached) || {!GVAR(enablePickUpAttached) && {isNull (attachedTo _x)}}}) then {
|
if (!(_x in _throwablesHelped) &&
|
||||||
|
{!(_x isKindOf "SmokeShellArty")} && {!(_x isKindOf "G_40mm_Smoke")} && // All smokes inherit from "GrenadeHand" >> "SmokeShell"
|
||||||
|
{GVAR(enablePickUpAttached) || {!GVAR(enablePickUpAttached) && {isNull (attachedTo _x)}}}
|
||||||
|
) then {
|
||||||
TRACE_2("Making PickUp Helper",_x,typeOf _x);
|
TRACE_2("Making PickUp Helper",_x,typeOf _x);
|
||||||
private _pickUpHelper = QGVAR(pickUpHelper) createVehicleLocal [0, 0, 0];
|
private _pickUpHelper = QGVAR(pickUpHelper) createVehicleLocal [0, 0, 0];
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Dslyecxi, Jonpas
|
* Author: Dslyecxi, Jonpas
|
||||||
* Throw selected throwable.
|
* Throw selected throwable.
|
||||||
@ -13,7 +14,6 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_unit"];
|
params ["_unit"];
|
||||||
TRACE_1("params",_unit);
|
TRACE_1("params",_unit);
|
||||||
@ -49,13 +49,28 @@ if (!(_unit getVariable [QGVAR(primed), false])) then {
|
|||||||
_newVelocity = _newVelocity vectorAdd (velocity (vehicle _unit));
|
_newVelocity = _newVelocity vectorAdd (velocity (vehicle _unit));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Calculate torque of thrown grenade
|
||||||
|
private _config = configFile >> "CfgAmmo" >> typeOf _activeThrowable;
|
||||||
|
private _torqueDir = getArray (_config >> QGVAR(torqueDirection));
|
||||||
|
_torqueDir = if (_torqueDir isEqualTypeArray [0,0,0]) then { vectorNormalized _torqueDir } else { [0,0,0] };
|
||||||
|
private _torqueMag = getNumber (_config >> QGVAR(torqueMagnitude));
|
||||||
|
|
||||||
|
if (_dropMode) then {
|
||||||
|
_torqueMag = _torqueMag * THROWSTYLE_DROP_TORQUE_COEF;
|
||||||
|
} else {
|
||||||
|
if (_throwType == "high") then {
|
||||||
|
_torqueMag = _torqueMag * THROWSTYLE_HIGH_TORQUE_COEF;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
private _torque = _torqueDir vectorMultiply _torqueMag;
|
||||||
|
|
||||||
// Drop if unit dies during throw process
|
// Drop if unit dies during throw process
|
||||||
if (alive _unit) then {
|
if (alive _unit) then {
|
||||||
_activeThrowable setVelocity _newVelocity;
|
_activeThrowable setVelocity _newVelocity;
|
||||||
|
_activeThrowable addTorque (_unit vectorModelToWorld _torque);
|
||||||
};
|
};
|
||||||
|
|
||||||
_unit setVariable [QGVAR(lastThrownTime), CBA_missionTime];
|
|
||||||
|
|
||||||
// Invoke listenable event
|
// Invoke listenable event
|
||||||
["ace_throwableThrown", [_unit, _activeThrowable]] call CBA_fnc_localEvent;
|
["ace_throwableThrown", [_unit, _activeThrowable]] call CBA_fnc_localEvent;
|
||||||
}, [
|
}, [
|
||||||
@ -69,12 +84,12 @@ if (!(_unit getVariable [QGVAR(primed), false])) then {
|
|||||||
|
|
||||||
|
|
||||||
#ifdef DRAW_THROW_PATH
|
#ifdef DRAW_THROW_PATH
|
||||||
GVAR(predictedPath) = call FUNC(drawArc); // save the current throw arc
|
GVAR(predictedPath) = call FUNC(drawArc); // Save the current throw arc
|
||||||
GVAR(flightPath) = [];
|
GVAR(flightPath) = [];
|
||||||
[_unit getVariable QGVAR(activeThrowable)] spawn {
|
GVAR(flightRotation) = [];
|
||||||
params ["_grenade"];
|
(_unit getVariable QGVAR(activeThrowable)) spawn {
|
||||||
while {!isNull _grenade} do {
|
while {!isNull _this && {(getPosATL _this) select 2 > 0.05}} do {
|
||||||
GVAR(flightPath) pushBack ASLtoAGL getPosASL _grenade;
|
GVAR(flightPath) pushBack [ASLtoAGL (getPosASL _this), vectorUp _this];
|
||||||
sleep 0.05;
|
sleep 0.05;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: CBA Team
|
* Author: CBA Team
|
||||||
* Throws Fired XEH.
|
* Throws Fired XEH.
|
||||||
@ -19,7 +20,6 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
TRACE_1("Fired",_this);
|
TRACE_1("Fired",_this);
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Jonpas
|
* Author: Jonpas
|
||||||
* Updates controls hints based on current state.
|
* Updates controls hints based on current state.
|
||||||
@ -13,7 +14,6 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
if (!GVAR(showMouseControls)) exitWith {};
|
if (!GVAR(showMouseControls)) exitWith {};
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
#include "\z\ace\addons\main\script_mod.hpp"
|
#include "\z\ace\addons\main\script_mod.hpp"
|
||||||
|
|
||||||
// #define DRAW_THROW_PATH
|
// #define DRAW_THROW_PATH
|
||||||
|
// #define ALLOW_QUICK_THROW
|
||||||
// #define DEBUG_MODE_FULL
|
// #define DEBUG_MODE_FULL
|
||||||
// #define DISABLE_COMPILE_CACHE
|
// #define DISABLE_COMPILE_CACHE
|
||||||
// #define CBA_DEBUG_SYNCHRONOUS
|
|
||||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED_ADVANCED_THROWING
|
#ifdef DEBUG_ENABLED_ADVANCED_THROWING
|
||||||
@ -23,6 +23,8 @@
|
|||||||
#define THROWSTYLE_HIGH_DIR [0, 200, 500]
|
#define THROWSTYLE_HIGH_DIR [0, 200, 500]
|
||||||
#define THROWSTYLE_HIGH_VEL_COEF 2
|
#define THROWSTYLE_HIGH_VEL_COEF 2
|
||||||
#define THROWSTYLE_DROP_VEL 2
|
#define THROWSTYLE_DROP_VEL 2
|
||||||
|
#define THROWSTYLE_HIGH_TORQUE_COEF .6
|
||||||
|
#define THROWSTYLE_DROP_TORQUE_COEF .2
|
||||||
|
|
||||||
#define THROW_TYPE_DEFAULT "normal"
|
#define THROW_TYPE_DEFAULT "normal"
|
||||||
#define THROW_SPEED_DEFAULT 18
|
#define THROW_SPEED_DEFAULT 18
|
||||||
|
@ -1,89 +1,257 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project name="ACE">
|
<Project name="ACE">
|
||||||
<Package name="Advanced_Throwing">
|
<Package name="Advanced_Throwing">
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_Category">
|
<Key ID="STR_ACE_Advanced_Throwing_Category">
|
||||||
<English>Advanced Throwing</English>
|
<English>Advanced Throwing</English>
|
||||||
<Russian>Улучшенный бросок гранат</Russian>
|
<Russian>Улучшенный бросок гранат</Russian>
|
||||||
|
<Japanese>アドバンスド スローイング</Japanese>
|
||||||
|
<Polish>Zaawansowane rzucanie</Polish>
|
||||||
|
<German>Erweitertes Wurfsystem</German>
|
||||||
|
<Korean>고급 투척</Korean>
|
||||||
|
<French>Lancé amélioré</French>
|
||||||
|
<Italian>Lancio Avanzato</Italian>
|
||||||
|
<Chinese>進階投擲</Chinese>
|
||||||
|
<Chinesesimp>进阶投掷</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_Module_Description">
|
<Key ID="STR_ACE_Advanced_Throwing_Module_Description">
|
||||||
<English>Allows changing advanced throwing behaviour.</English>
|
<English>Allows changing advanced throwing behaviour.</English>
|
||||||
<Russian>Позволяет настраивать поведение улучшенного броска гранат.</Russian>
|
<Russian>Позволяет настраивать поведение улучшенного броска гранат.</Russian>
|
||||||
|
<Japanese>アドバンスド スローイングの動作挙動を変更します。</Japanese>
|
||||||
|
<Polish>Zezwala na zmianę zachowania zaawansowanego trybu rzucania.</Polish>
|
||||||
|
<German>Erlaubt es, das Verhalten des erweiterten Wurfsystems zu ändern.</German>
|
||||||
|
<Korean>고급 투척 행위를 허가합니다</Korean>
|
||||||
|
<French>Permet de changer la configuration du lancé amélioré.</French>
|
||||||
|
<Italian>Permette il cambiamento della modalità di tiro.</Italian>
|
||||||
|
<Chinese>允許使用更多不同的投擲方式</Chinese>
|
||||||
|
<Chinesesimp>允许使用更多不同的投掷方式</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_Enable_DisplayName">
|
<Key ID="STR_ACE_Advanced_Throwing_Enable_DisplayName">
|
||||||
<English>Enable Advanced Throwing</English>
|
<English>Enable Advanced Throwing</English>
|
||||||
<Russian>Включить улучшенный бросок</Russian>
|
<Russian>Включить улучшенный бросок</Russian>
|
||||||
|
<Japanese>アドバンスド スローイングを有効化する</Japanese>
|
||||||
|
<Polish>Aktywuj zaawansowane rzucanie</Polish>
|
||||||
|
<German>Aktiviere erweitertes Wurfsystem</German>
|
||||||
|
<Korean>고급 투척 활성화 </Korean>
|
||||||
|
<French>Active le lancé amélioré</French>
|
||||||
|
<Italian>Abilita Lancio Avanzato</Italian>
|
||||||
|
<Chinese>啟用進階投擲</Chinese>
|
||||||
|
<Chinesesimp>启用进阶投掷</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_Enable_Description">
|
<Key ID="STR_ACE_Advanced_Throwing_Enable_Description">
|
||||||
<English>Enables advanced throwing system.</English>
|
<English>Enables advanced throwing system.</English>
|
||||||
<Russian>Включает систему улучшенного броска.</Russian>
|
<Russian>Включает систему улучшенного броска.</Russian>
|
||||||
|
<Japanese>アドバンスド スローイングを有効化します。</Japanese>
|
||||||
|
<Polish>Aktywuje system zaawansowanego rzucania.</Polish>
|
||||||
|
<German>Aktiviert das erweiterte Wurfsystem.</German>
|
||||||
|
<Korean>고급 투척을 활성화 합니다</Korean>
|
||||||
|
<French>Active le système de lancé amélioré.</French>
|
||||||
|
<Italian>Abilita il sistema di lancio avanzato.</Italian>
|
||||||
|
<Chinese>啟用進階投擲系統</Chinese>
|
||||||
|
<Chinesesimp>启用进阶投掷系统</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_ShowThrowArc_DisplayName">
|
<Key ID="STR_ACE_Advanced_Throwing_ShowThrowArc_DisplayName">
|
||||||
<English>Show Throw Arc</English>
|
<English>Show Throw Arc</English>
|
||||||
<Russian>Показать траекторию броска</Russian>
|
<Russian>Показать траекторию броска</Russian>
|
||||||
|
<Japanese>投てき軌道を表示する</Japanese>
|
||||||
|
<Polish>Pokaż trasę lotu</Polish>
|
||||||
|
<German>Zeige Wurfbogen</German>
|
||||||
|
<Korean>투척 궤적 표시</Korean>
|
||||||
|
<French>Afficher l'arc de lancé</French>
|
||||||
|
<Italian>Mostra Arco di Tiro</Italian>
|
||||||
|
<Chinese>顯示投擲軌道</Chinese>
|
||||||
|
<Chinesesimp>显示投掷轨道</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_ShowThrowArc_Description">
|
<Key ID="STR_ACE_Advanced_Throwing_ShowThrowArc_Description">
|
||||||
<English>Enables visualization of the throw arc (where throwable will fly).</English>
|
<English>Enables visualization of the throw arc (where throwable will fly).</English>
|
||||||
<Russian>Включает визуализацию траектории броска (как полетит граната).</Russian>
|
<Russian>Включает визуализацию траектории броска (как полетит граната).</Russian>
|
||||||
|
<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>
|
||||||
|
<French>Active la visualisation de l'arc de lancé (où l'objet lancé va atterrir).</French>
|
||||||
|
<Italian>Abilita la visualizzazione dell'arco del tiro (dove l'oggetto lanciabile volerà).</Italian>
|
||||||
|
<Chinese>顯示投擲軌道幫助投擲</Chinese>
|
||||||
|
<Chinesesimp>显示投掷轨道帮助投掷</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_ShowMouseControls_DisplayName">
|
<Key ID="STR_ACE_Advanced_Throwing_ShowMouseControls_DisplayName">
|
||||||
<English>Show Throwing Mouse Controls</English>
|
<English>Show Throwing Mouse Controls</English>
|
||||||
<Russian>Показывать управление мышью</Russian>
|
<Russian>Показывать управление мышью</Russian>
|
||||||
|
<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>
|
||||||
|
<Chinese>顯示滑鼠投擲控制提示</Chinese>
|
||||||
|
<Chinesesimp>显示滑鼠投掷控制提示</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_ShowMouseControls_Description">
|
<Key ID="STR_ACE_Advanced_Throwing_ShowMouseControls_Description">
|
||||||
<English>Enables visual cues for mouse controls when throwable is prepared.</English>
|
<English>Enables visual cues for mouse controls when throwable is prepared.</English>
|
||||||
<Russian>Включает отображение подсказок по управлению мышью, когда граната подготовлена.</Russian>
|
<Russian>Включает отображение подсказок по управлению мышью, когда граната подготовлена.</Russian>
|
||||||
|
<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>
|
||||||
|
<French>Active les aides visuels pour les controles à la souris lorsqu'un lancé est préparé.</French>
|
||||||
|
<Italian>Abilita la visualizzazione dei controlli del mouse quando l'oggetto lanciabile è pronto.</Italian>
|
||||||
|
<Chinese>開啟後會在準備投擲時, 顯示滑鼠相關操作</Chinese>
|
||||||
|
<Chinesesimp>开启后会在准备投掷时, 显示滑鼠相关操作</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_EnablePickUp_DisplayName">
|
<Key ID="STR_ACE_Advanced_Throwing_EnablePickUp_DisplayName">
|
||||||
<English>Enable Throwables Pick Up</English>
|
<English>Enable Throwables Pick Up</English>
|
||||||
<Russian>Включить подбор гранат</Russian>
|
<Russian>Включить подбор гранат</Russian>
|
||||||
|
<Japanese>投てき物の拾い上げを有効化する</Japanese>
|
||||||
|
<Polish>Zezwól na podnoszenie obiektów miotanych</Polish>
|
||||||
|
<German>Aktiviere Aufheben von Wurfobjekten</German>
|
||||||
|
<Korean>투척물 줍기 활성화</Korean>
|
||||||
|
<French>Active la récupération des objets lancés</French>
|
||||||
|
<Italian>Abilita Raccogli Oggetti</Italian>
|
||||||
|
<Chinese>啟用可撿取地面投擲物</Chinese>
|
||||||
|
<Chinesesimp>启用可捡取地面投掷物</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_EnablePickUp_Description">
|
<Key ID="STR_ACE_Advanced_Throwing_EnablePickUp_Description">
|
||||||
<English>Enables ability to pick up throwables from the ground.</English>
|
<English>Enables ability to pick up throwables from the ground.</English>
|
||||||
<Russian>Включает возможность подбирать гранаты с земли.</Russian>
|
<Russian>Включает возможность подбирать гранаты с земли.</Russian>
|
||||||
|
<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 capacité de récupérer les objets lancés sur le sol.</French>
|
||||||
|
<Italian>Abilita la possibilità di raccogliere un oggetto lanciabile da terra.</Italian>
|
||||||
|
<Chinese>啟用後, 可撿取地面上的投擲物</Chinese>
|
||||||
|
<Chinesesimp>启用后, 可捡取地面上的投掷物</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_EnablePickUpAttached_DisplayName">
|
<Key ID="STR_ACE_Advanced_Throwing_EnablePickUpAttached_DisplayName">
|
||||||
<English>Enable Attached Throwables Pick Up</English>
|
<English>Enable Attached Throwables Pick Up</English>
|
||||||
<Russian>Включить подбор прикрепленных гранат</Russian>
|
<Russian>Включить подбор прикрепленных гранат</Russian>
|
||||||
|
<Japanese>取り付けられた投てき物の拾い上げを有効化する</Japanese>
|
||||||
|
<Polish>Zezwól na podnoszenie przyczepionych obiektów miotanych</Polish>
|
||||||
|
<German>Aktiviere erneute Aufnahme befestigter Wurfobjekte</German>
|
||||||
|
<Korean>부착 투척물 줍기 활성화</Korean>
|
||||||
|
<French>Active le ramassage d'objets lançables attachés</French>
|
||||||
|
<Italian>Abilita Raccogli Oggetti Lanciabili da altri Oggetti</Italian>
|
||||||
|
<Chinese>啟用可撿取附著投擲物</Chinese>
|
||||||
|
<Chinesesimp>启用可捡取附着投掷物</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_EnablePickUpAttached_Description">
|
<Key ID="STR_ACE_Advanced_Throwing_EnablePickUpAttached_Description">
|
||||||
<English>Enables ability to pick up throwables from attached objects.</English>
|
<English>Enables ability to pick up throwables from attached objects.</English>
|
||||||
<Russian>Включает возможность подбирать гранаты, прикрепленные к объектам.</Russian>
|
<Russian>Включает возможность подбирать гранаты, прикрепленные к объектам.</Russian>
|
||||||
|
<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 capacité à ramasser les objets lançables attaché à d'autres objets.</French>
|
||||||
|
<Italian>Abilita la possibilità di raccogliere gli oggetti lanciabili dagli altri oggetti. </Italian>
|
||||||
|
<Chinese>啟用後, 可撿取附著在物件上的投擲物</Chinese>
|
||||||
|
<Chinesesimp>启用后, 可捡取附着在物件上的投掷物</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_Prepare">
|
<Key ID="STR_ACE_Advanced_Throwing_Prepare">
|
||||||
<English>Prepare/Change Throwable</English>
|
<English>Prepare/Change Throwable</English>
|
||||||
<Russian>Подготовить/заменить гранату</Russian>
|
<Russian>Подготовить/заменить гранату</Russian>
|
||||||
|
<Japanese>投てき物の準備/変更</Japanese>
|
||||||
|
<Polish>Przygotuj/zmień ob. miotany</Polish>
|
||||||
|
<German>Wurfobjekt vorbereiten/wechseln</German>
|
||||||
|
<Korean>투척물 준비/변경</Korean>
|
||||||
|
<French>Préparer/changer d'objet</French>
|
||||||
|
<Italian>Prepara/Cambia Oggetto lanciabile</Italian>
|
||||||
|
<Chinese>準備/變更投擲物</Chinese>
|
||||||
|
<Chinesesimp>准备/变更投掷物</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_dropModeHold">
|
<Key ID="STR_ACE_Advanced_Throwing_dropModeHold">
|
||||||
<English>Throwable Drop Mode (Hold)</English>
|
<English>Throwable Drop Mode (Hold)</English>
|
||||||
<Russian>Режим броска гранаты (удерживать)</Russian>
|
<Russian>Режим броска гранаты (удерживать)</Russian>
|
||||||
|
<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>
|
||||||
|
<Chinese>投擲模式 (按住)</Chinese>
|
||||||
|
<Chinesesimp>投掷模式 (按住)</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_DropModeToggle">
|
<Key ID="STR_ACE_Advanced_Throwing_DropModeToggle">
|
||||||
<English>Throwable Drop Mode (Toggle)</English>
|
<English>Throwable Drop Mode (Toggle)</English>
|
||||||
<Russian>Режим броска гранаты (переключить)</Russian>
|
<Russian>Режим броска гранаты (переключить)</Russian>
|
||||||
|
<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>
|
||||||
|
<Chinese>投擲模式 (切換)</Chinese>
|
||||||
|
<Chinesesimp>投掷模式 (切换)</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_Primed">
|
<Key ID="STR_ACE_Advanced_Throwing_Primed">
|
||||||
<English>Primed</English>
|
<English>Primed</English>
|
||||||
<Russian>Подготовлена</Russian>
|
<Russian>Подготовлена</Russian>
|
||||||
|
<Japanese>点火</Japanese>
|
||||||
|
<Polish>Odbezpieczony</Polish>
|
||||||
|
<German>Scharf gemacht</German>
|
||||||
|
<Korean>뇌관 작동</Korean>
|
||||||
|
<French>Amorcer</French>
|
||||||
|
<Italian>Armato</Italian>
|
||||||
|
<Chinese>引信開始燃燒</Chinese>
|
||||||
|
<Chinesesimp>引信开始燃烧</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_Throw">
|
<Key ID="STR_ACE_Advanced_Throwing_Throw">
|
||||||
<English>Throw</English>
|
<English>Throw</English>
|
||||||
<Russian>Бросить</Russian>
|
<Russian>Бросить</Russian>
|
||||||
|
<Japanese>投げる</Japanese>
|
||||||
|
<Polish>Rzuć</Polish>
|
||||||
|
<German>Werfen</German>
|
||||||
|
<Korean>던지기</Korean>
|
||||||
|
<French>Lancer</French>
|
||||||
|
<Italian>Lanciare</Italian>
|
||||||
|
<Chinese>投擲</Chinese>
|
||||||
|
<Chinesesimp>投掷</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_ChangeMode">
|
<Key ID="STR_ACE_Advanced_Throwing_ChangeMode">
|
||||||
<English>(Scroll) Change Mode</English>
|
<English>(Scroll) Change Mode</English>
|
||||||
<Russian>(Скролл) Изменить режим</Russian>
|
<Russian>(Скролл) Изменить режим</Russian>
|
||||||
|
<Japanese>(スクロール) モード変更</Japanese>
|
||||||
|
<Polish>(Kółko m.) zmień tryb</Polish>
|
||||||
|
<German>(Scrollen) Modus wechseln</German>
|
||||||
|
<Korean>(마우스 휠) 모드 변경</Korean>
|
||||||
|
<French>(Molette souris) Changer de mode</French>
|
||||||
|
<Italian>(Scorrere) Cambio Modalità</Italian>
|
||||||
|
<Chinese>(滾輪) 變更模式</Chinese>
|
||||||
|
<Chinesesimp>(滚轮) 变更模式</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_Extend">
|
<Key ID="STR_ACE_Advanced_Throwing_Extend">
|
||||||
<English>(Scroll) Extend</English>
|
<English>(Scroll) Extend</English>
|
||||||
<Russian>(Скролл) Увеличить</Russian>
|
<Russian>(Скролл) Увеличить</Russian>
|
||||||
|
<Japanese>(スクロール) 腕を伸ばす</Japanese>
|
||||||
|
<Polish>(Kółko m.) przedłuż</Polish>
|
||||||
|
<German>(Scrollen) Erweitern</German>
|
||||||
|
<Korean>(마우스 휠) 연장</Korean>
|
||||||
|
<French>(Molette souris) Etendre</French>
|
||||||
|
<Italian>(Scorrere) Estendere</Italian>
|
||||||
|
<Chinese>(滾輪) 延長</Chinese>
|
||||||
|
<Chinesesimp>(滚轮) 延长</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_Cook">
|
<Key ID="STR_ACE_Advanced_Throwing_Cook">
|
||||||
<English>(Click) Cook</English>
|
<English>(Click) Cook</English>
|
||||||
<Russian>(Клик) Подготовить</Russian>
|
<Russian>(Клик) Подготовить</Russian>
|
||||||
|
<Japanese>(クリック) 点火する</Japanese>
|
||||||
|
<Polish>(Kliknięcie) Odbezpiecz</Polish>
|
||||||
|
<German>(Klicken) Abkochen</German>
|
||||||
|
<Korean>(클릭) 예열</Korean>
|
||||||
|
<French>(Clique) Dégoupiller</French>
|
||||||
|
<Italian>(Click) Arma</Italian>
|
||||||
|
<Chinese>(點擊) 提早拉開引信</Chinese>
|
||||||
|
<Chinesesimp>(点击) 提早拉开引信</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_ACE_Advanced_Throwing_PickUp">
|
<Key ID="STR_ACE_Advanced_Throwing_PickUp">
|
||||||
<English>Pick Up</English>
|
<English>Pick Up</English>
|
||||||
<Russian>Подобрать</Russian>
|
<Russian>Подобрать</Russian>
|
||||||
|
<Japanese>拾い上げる</Japanese>
|
||||||
|
<Polish>Podnieś</Polish>
|
||||||
|
<German>Aufheben</German>
|
||||||
|
<Korean>줍기</Korean>
|
||||||
|
<French>Ramasser</French>
|
||||||
|
<Italian>Raccogli</Italian>
|
||||||
|
<Chinese>撿取</Chinese>
|
||||||
|
<Chinesesimp>捡取</Chinesesimp>
|
||||||
</Key>
|
</Key>
|
||||||
</Package>
|
</Package>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
|
|
||||||
/*
|
|
||||||
* Documentation:
|
|
||||||
* https://community.bistudio.com/wiki/AI_Sub-skills
|
|
||||||
*
|
|
||||||
* The idea here is to reduce the AI's godlike aiming
|
|
||||||
* capabilties while retaining it's high intelligence.
|
|
||||||
* The AI should be smart enough to move through a town,
|
|
||||||
* but also be 'human' in their reaction time and aim.
|
|
||||||
*
|
|
||||||
* Note: All these values can still be adjusted via
|
|
||||||
* scripts, these arrays just change what 0 & 1
|
|
||||||
* are for setSkill.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class CfgAISkill {
|
|
||||||
aimingAccuracy[] = {0,0, 1,0.8}; // {0,0,1,1}; v1.26 defaults
|
|
||||||
aimingShake[] = {0,0, 1,0.6}; // {0,0,1,1};
|
|
||||||
aimingSpeed[] = {0,0, 1,0.7}; // {0,0.5,1,1};
|
|
||||||
commanding[] = {0,0, 1,0.8}; // {0,0,1,1};
|
|
||||||
courage[] = {0,0, 1,0.7}; // {0,0,1,1};
|
|
||||||
endurance[] = {0,0, 1,0.7}; // {0,0,1,1};
|
|
||||||
general[] = {0,0, 1,0.9}; // {0,0,1,1};
|
|
||||||
// apparently breaks rapid firing in single fire mode for players
|
|
||||||
//reloadSpeed[] = {0,0, 1,0.8}; // {0,0,1,1};
|
|
||||||
spotDistance[] = {0,0, 1,0.9}; // {0,0.2,1,0.4};
|
|
||||||
spotTime[] = {0,0, 1,0.7}; // {0,0,1,0.7};
|
|
||||||
};
|
|
18
addons/ai/CfgEventHandlers.hpp
Normal file
18
addons/ai/CfgEventHandlers.hpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
class Extended_PreStart_EventHandlers {
|
||||||
|
class ADDON {
|
||||||
|
init = QUOTE(call COMPILE_FILE(XEH_preStart));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Extended_PreInit_EventHandlers {
|
||||||
|
class ADDON {
|
||||||
|
init = QUOTE(call COMPILE_FILE(XEH_preInit));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Extended_PostInit_EventHandlers {
|
||||||
|
class ADDON {
|
||||||
|
init = QUOTE(call COMPILE_FILE(XEH_postInit));
|
||||||
|
};
|
||||||
|
};
|
@ -2,8 +2,6 @@
|
|||||||
// weapon config changes, by commy2
|
// weapon config changes, by commy2
|
||||||
|
|
||||||
/* documentation:
|
/* documentation:
|
||||||
aiDispersionCoefX = 1.0 Dispersion multiplier for AI units (axis X - left to right).
|
|
||||||
aiDispersionCoefY = 1.0 Dispersion multiplier for AI units (axis Y - top-down).
|
|
||||||
aiRateOfFire = 5.0 Delay between shots at given aiRateOfFireDistance.
|
aiRateOfFire = 5.0 Delay between shots at given aiRateOfFireDistance.
|
||||||
aiRateOfFireDistance = 500 At shorter distance delay (aiRateOfFire) goes linearly to zero.
|
aiRateOfFireDistance = 500 At shorter distance delay (aiRateOfFire) goes linearly to zero.
|
||||||
*/
|
*/
|
||||||
@ -15,19 +13,12 @@ class Mode_FullAuto;
|
|||||||
class CfgWeapons {
|
class CfgWeapons {
|
||||||
|
|
||||||
// rifles
|
// rifles
|
||||||
class RifleCore;
|
class Rifle_Base_F;
|
||||||
class Rifle: RifleCore {
|
class Rifle_Short_Base_F;
|
||||||
aiDispersionCoefX = 6;
|
class Rifle_Long_Base_F;
|
||||||
aiDispersionCoefY = 6;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Rifle_Base_F: Rifle {};
|
|
||||||
class Rifle_Long_Base_F: Rifle_Base_F {};
|
|
||||||
|
|
||||||
// MX
|
// MX
|
||||||
class arifle_MX_Base_F: Rifle_Base_F {
|
class arifle_MX_Base_F: Rifle_Base_F {
|
||||||
aiDispersionCoefY = 18.0;
|
|
||||||
aiDispersionCoefX = 12.0;
|
|
||||||
modes[] += {"ACE_Burst_far"};
|
modes[] += {"ACE_Burst_far"};
|
||||||
|
|
||||||
class Single: Mode_SemiAuto {
|
class Single: Mode_SemiAuto {
|
||||||
@ -70,8 +61,6 @@ class CfgWeapons {
|
|||||||
|
|
||||||
// MX carbine
|
// MX carbine
|
||||||
class arifle_MXC_F: arifle_MX_Base_F {
|
class arifle_MXC_F: arifle_MX_Base_F {
|
||||||
aiDispersionCoefY = 18.0;
|
|
||||||
aiDispersionCoefX = 12.0;
|
|
||||||
|
|
||||||
class Single: Single {
|
class Single: Single {
|
||||||
minRange = 120; // 2;
|
minRange = 120; // 2;
|
||||||
@ -143,8 +132,6 @@ class CfgWeapons {
|
|||||||
|
|
||||||
// MX machine gun
|
// MX machine gun
|
||||||
class arifle_MX_SW_F: arifle_MX_Base_F {
|
class arifle_MX_SW_F: arifle_MX_Base_F {
|
||||||
aiDispersionCoefY = 24.0;
|
|
||||||
aiDispersionCoefX = 21.0;
|
|
||||||
// Shit is still broken
|
// Shit is still broken
|
||||||
//modes[] += {"ACE_Burst_far"};
|
//modes[] += {"ACE_Burst_far"};
|
||||||
modes[] = {"Single","manual","close","short","medium","far_optic1","far_optic2","ACE_Burst_far"};
|
modes[] = {"Single","manual","close","short","medium","far_optic1","far_optic2","ACE_Burst_far"};
|
||||||
@ -180,8 +167,6 @@ class CfgWeapons {
|
|||||||
|
|
||||||
// Katiba
|
// Katiba
|
||||||
class arifle_Katiba_Base_F: Rifle_Base_F {
|
class arifle_Katiba_Base_F: Rifle_Base_F {
|
||||||
aiDispersionCoefY = 18.0;
|
|
||||||
aiDispersionCoefX = 12.0;
|
|
||||||
modes[] += {"ACE_Burst_far"};
|
modes[] += {"ACE_Burst_far"};
|
||||||
|
|
||||||
class Single: Mode_SemiAuto {
|
class Single: Mode_SemiAuto {
|
||||||
@ -224,8 +209,6 @@ class CfgWeapons {
|
|||||||
|
|
||||||
// Katiba carbine
|
// Katiba carbine
|
||||||
class arifle_Katiba_C_F: arifle_Katiba_Base_F {
|
class arifle_Katiba_C_F: arifle_Katiba_Base_F {
|
||||||
aiDispersionCoefY = 18.0;
|
|
||||||
aiDispersionCoefX = 12.0;
|
|
||||||
|
|
||||||
class Single: Single {
|
class Single: Single {
|
||||||
minRange = 120; // 2;
|
minRange = 120; // 2;
|
||||||
@ -268,8 +251,6 @@ class CfgWeapons {
|
|||||||
|
|
||||||
// F2002
|
// F2002
|
||||||
class mk20_base_F: Rifle_Base_F {
|
class mk20_base_F: Rifle_Base_F {
|
||||||
aiDispersionCoefY = 18.0;
|
|
||||||
aiDispersionCoefX = 12.0;
|
|
||||||
modes[] += {"ACE_Burst_far"};
|
modes[] += {"ACE_Burst_far"};
|
||||||
|
|
||||||
class Single: Mode_SemiAuto {
|
class Single: Mode_SemiAuto {
|
||||||
@ -316,8 +297,6 @@ class CfgWeapons {
|
|||||||
|
|
||||||
// F2002 carbine
|
// F2002 carbine
|
||||||
class arifle_Mk20C_F: mk20_base_F {
|
class arifle_Mk20C_F: mk20_base_F {
|
||||||
aiDispersionCoefY = 18.0;
|
|
||||||
aiDispersionCoefX = 12.0;
|
|
||||||
|
|
||||||
class Single: Single {
|
class Single: Single {
|
||||||
minRange = 120; // 2;
|
minRange = 120; // 2;
|
||||||
@ -358,8 +337,6 @@ class CfgWeapons {
|
|||||||
|
|
||||||
// TAR-20
|
// TAR-20
|
||||||
class Tavor_base_F: Rifle_Base_F {
|
class Tavor_base_F: Rifle_Base_F {
|
||||||
aiDispersionCoefY = 18.0;
|
|
||||||
aiDispersionCoefX = 12.0;
|
|
||||||
modes[] += {"ACE_Burst_far"};
|
modes[] += {"ACE_Burst_far"};
|
||||||
|
|
||||||
class Single: Mode_SemiAuto {
|
class Single: Mode_SemiAuto {
|
||||||
@ -407,8 +384,6 @@ class CfgWeapons {
|
|||||||
|
|
||||||
// TAR-21
|
// TAR-21
|
||||||
class arifle_TRG21_F: Tavor_base_F {
|
class arifle_TRG21_F: Tavor_base_F {
|
||||||
aiDispersionCoefY = 18.0;
|
|
||||||
aiDispersionCoefX = 12.0;
|
|
||||||
|
|
||||||
class Single: Single {
|
class Single: Single {
|
||||||
minRange = 120; // 2;
|
minRange = 120; // 2;
|
||||||
@ -457,8 +432,6 @@ class CfgWeapons {
|
|||||||
|
|
||||||
// SDAR
|
// SDAR
|
||||||
class SDAR_base_F: Rifle_Base_F {
|
class SDAR_base_F: Rifle_Base_F {
|
||||||
aiDispersionCoefY = 28.0;
|
|
||||||
aiDispersionCoefX = 20.0;
|
|
||||||
|
|
||||||
class Single: Mode_SemiAuto {
|
class Single: Mode_SemiAuto {
|
||||||
minRange = 10; //2;
|
minRange = 10; //2;
|
||||||
@ -470,9 +443,7 @@ class CfgWeapons {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// PD2000
|
// PD2000
|
||||||
class pdw2000_base_F: Rifle_Base_F {
|
class pdw2000_base_F: Rifle_Short_Base_F {
|
||||||
aiDispersionCoefY = 18.0;
|
|
||||||
aiDispersionCoefX = 12.0;
|
|
||||||
|
|
||||||
class Single: Mode_SemiAuto {
|
class Single: Mode_SemiAuto {
|
||||||
minRange = 100; //2;
|
minRange = 100; //2;
|
||||||
@ -484,9 +455,7 @@ class CfgWeapons {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Vector
|
// Vector
|
||||||
class SMG_01_Base: Rifle_Base_F {
|
class SMG_01_Base: Rifle_Short_Base_F {
|
||||||
aiDispersionCoefY = 18.0;
|
|
||||||
aiDispersionCoefX = 12.0;
|
|
||||||
|
|
||||||
class Single: Mode_SemiAuto {
|
class Single: Mode_SemiAuto {
|
||||||
minRange = 50; //2;
|
minRange = 50; //2;
|
||||||
@ -498,9 +467,7 @@ class CfgWeapons {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Scorpion EVO
|
// Scorpion EVO
|
||||||
class SMG_02_base_F: Rifle_Base_F {
|
class SMG_02_base_F: Rifle_Short_Base_F {
|
||||||
aiDispersionCoefY = 18.0;
|
|
||||||
aiDispersionCoefX = 12.0;
|
|
||||||
|
|
||||||
class Single: Mode_SemiAuto {
|
class Single: Mode_SemiAuto {
|
||||||
minRange = 50; //2;
|
minRange = 50; //2;
|
||||||
@ -515,8 +482,6 @@ class CfgWeapons {
|
|||||||
|
|
||||||
// Stoner
|
// Stoner
|
||||||
class LMG_Mk200_F: Rifle_Long_Base_F {
|
class LMG_Mk200_F: Rifle_Long_Base_F {
|
||||||
aiDispersionCoefY = 24.0;
|
|
||||||
aiDispersionCoefX = 21.0;
|
|
||||||
modes[] += {"ACE_Burst_far"};
|
modes[] += {"ACE_Burst_far"};
|
||||||
|
|
||||||
class medium;
|
class medium;
|
||||||
@ -544,8 +509,6 @@ class CfgWeapons {
|
|||||||
|
|
||||||
// Negev
|
// Negev
|
||||||
class LMG_Zafir_F: Rifle_Long_Base_F {
|
class LMG_Zafir_F: Rifle_Long_Base_F {
|
||||||
aiDispersionCoefY = 23.0;
|
|
||||||
aiDispersionCoefX = 19.0;
|
|
||||||
modes[] += {"ACE_Burst_far"};
|
modes[] += {"ACE_Burst_far"};
|
||||||
|
|
||||||
class Single: Mode_SemiAuto {
|
class Single: Mode_SemiAuto {
|
||||||
@ -719,8 +682,6 @@ class CfgWeapons {
|
|||||||
|
|
||||||
// marksmen medium mg
|
// marksmen medium mg
|
||||||
class MMG_01_base_F: Rifle_Long_Base_F {
|
class MMG_01_base_F: Rifle_Long_Base_F {
|
||||||
aiDispersionCoefY = 25.0;
|
|
||||||
aiDispersionCoefX = 20.0;
|
|
||||||
modes[] += {"ACE_Burst_far"};
|
modes[] += {"ACE_Burst_far"};
|
||||||
|
|
||||||
class manual;
|
class manual;
|
||||||
@ -745,8 +706,6 @@ class CfgWeapons {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class MMG_02_base_F: Rifle_Long_Base_F {
|
class MMG_02_base_F: Rifle_Long_Base_F {
|
||||||
aiDispersionCoefY = 20.0;
|
|
||||||
aiDispersionCoefX = 15.0;
|
|
||||||
modes[] += {"ACE_Burst_far"};
|
modes[] += {"ACE_Burst_far"};
|
||||||
|
|
||||||
class manual;
|
class manual;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
ace_ai
|
ace_ai
|
||||||
======
|
======
|
||||||
|
|
||||||
Minor changes of AI skill and overhaul of AI firing modes of vanilla weapons, encouraging the AI to use full-auto and bursts more often.
|
Overhaul of AI firing modes of vanilla weapons, encouraging the AI to use full-auto and bursts more often.
|
||||||
|
|
||||||
|
|
||||||
## Maintainers
|
## Maintainers
|
||||||
|
3
addons/ai/XEH_PREP.hpp
Normal file
3
addons/ai/XEH_PREP.hpp
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
PREP(garrison);
|
||||||
|
PREP(unGarrison);
|
||||||
|
PREP(garrisonMove);
|
109
addons/ai/XEH_postInit.sqf
Normal file
109
addons/ai/XEH_postInit.sqf
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
[QGVAR(AISection), {
|
||||||
|
params [["_units", [], [[]]], ["_sections", [], [[]]], ["_bool", true, [true]]];
|
||||||
|
{
|
||||||
|
private _section = _x;
|
||||||
|
{
|
||||||
|
if (_bool) then {
|
||||||
|
_x enableAI _section;
|
||||||
|
LOG_3("%1 enableAI %2 | ID: %3",_x,_section,clientOwner);
|
||||||
|
} else {
|
||||||
|
_x disableAI _section;
|
||||||
|
LOG_3("%1 disableAI %2 | ID: %3",_x,_section,clientOwner);
|
||||||
|
};
|
||||||
|
} forEach (_units select {local _x});
|
||||||
|
} forEach _sections;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
[QGVAR(unGarrison), FUNC(unGarrison)] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
[QGVAR(doMove), {
|
||||||
|
params ["_unitsArray"];
|
||||||
|
{
|
||||||
|
_x params ["_unit", "_pos"];
|
||||||
|
_unit setDestination [_pos, "LEADER PLANNED", true];
|
||||||
|
_unit doMove _pos;
|
||||||
|
LOG_3("%1 doMove %2 | ID: %3",_unit,_pos,clientOwner);
|
||||||
|
} forEach _unitsArray;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
[QGVAR(setBehaviour), {
|
||||||
|
params ["_groupsArray", "_behaviour"];
|
||||||
|
{
|
||||||
|
_x setBehaviour _behaviour;
|
||||||
|
LOG_3("%1 setBehaviour %2 | ID: %3",_x,_behaviour,clientOwner);
|
||||||
|
} forEach _groupsArray;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
[QGVAR(enableAttack), {
|
||||||
|
params ["_unitsArray", "_mode"];
|
||||||
|
{
|
||||||
|
_x enableAttack _mode;
|
||||||
|
LOG_3("%1 enableAttack %2 | ID: %3",_x,_mode,clientOwner);
|
||||||
|
} forEach _unitsArray;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
[QGVAR(setUnitPos), {
|
||||||
|
params ["_unit", "_mode"];
|
||||||
|
_unit setUnitPos _mode;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
[QGVAR(setSpeedMode), {
|
||||||
|
params ["_unit", "_mode"];
|
||||||
|
_unit setSpeedMode _mode;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
[QGVAR(setCombatMode), {
|
||||||
|
params ["_unit", "_mode"];
|
||||||
|
_unit setCombatMode _mode;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
[QGVAR(allowFleeing), {
|
||||||
|
params ["_unit", "_cowardice"];
|
||||||
|
_unit allowFleeing _cowardice;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
[QGVAR(enableGunLights), {
|
||||||
|
params ["_unit", "_mode"];
|
||||||
|
_unit enableGunLights _mode;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
#ifdef DEBUG_MODE_FULL
|
||||||
|
addMissionEventHandler ["Draw3D", {
|
||||||
|
private _unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []];
|
||||||
|
{
|
||||||
|
_x params ["_unit", "_pos"];
|
||||||
|
|
||||||
|
switch (true) do {
|
||||||
|
case (surfaceIsWater (getPos _unit) && {surfaceIsWater _pos}) : {
|
||||||
|
for "_i" from 0 to 3 do {
|
||||||
|
drawLine3D [_unit modelToWorldVisualWorld [0,0,1], (AGLtoASL _pos), [1,0,0,1]];
|
||||||
|
};
|
||||||
|
drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], (AGLtoASL _pos), 0.75, 0.75, 0.75];
|
||||||
|
};
|
||||||
|
|
||||||
|
case (!surfaceIsWater (getPos _unit) && {!surfaceIsWater _pos}) : {
|
||||||
|
for "_i" from 0 to 3 do {
|
||||||
|
drawLine3D [_unit modelToWorldVisual [0,0,1], _pos, [1,0,0,1]];
|
||||||
|
};
|
||||||
|
drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], _pos, 0.75, 0.75, 0.75];
|
||||||
|
};
|
||||||
|
|
||||||
|
case (!surfaceIsWater (getPos _unit) && {surfaceIsWater _pos}) : {
|
||||||
|
for "_i" from 0 to 3 do {
|
||||||
|
drawLine3D [_unit modelToWorldVisual [0,0,1], (AGLToASL _pos), [1,0,0,1]];
|
||||||
|
};
|
||||||
|
drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], (AGLtoASL _pos), 0.75, 0.75, 0.75];
|
||||||
|
};
|
||||||
|
|
||||||
|
case (surfaceIsWater (getPos _unit) && {!surfaceIsWater _pos}) : {
|
||||||
|
for "_i" from 0 to 3 do {
|
||||||
|
drawLine3D [_unit modelToWorldVisualWorld [0,0,1], _pos, [1,0,0,1]];
|
||||||
|
};
|
||||||
|
drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], _pos, 0.75, 0.75, 0.75];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} forEach _unitMoveList;
|
||||||
|
}];
|
||||||
|
#endif
|
9
addons/ai/XEH_preInit.sqf
Normal file
9
addons/ai/XEH_preInit.sqf
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
ADDON = false;
|
||||||
|
|
||||||
|
PREP_RECOMPILE_START;
|
||||||
|
#include "XEH_PREP.hpp"
|
||||||
|
PREP_RECOMPILE_END;
|
||||||
|
|
||||||
|
ADDON = true;
|
@ -14,5 +14,5 @@ class CfgPatches {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "CfgAISkill.hpp"
|
|
||||||
#include "CfgWeapons.hpp"
|
#include "CfgWeapons.hpp"
|
||||||
|
#include "CfgEventHandlers.hpp"
|
||||||
|
278
addons/ai/functions/fnc_garrison.sqf
Normal file
278
addons/ai/functions/fnc_garrison.sqf
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
/*
|
||||||
|
* Author: alganthe
|
||||||
|
* Garrison function used to garrison AI inside buildings.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 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)
|
||||||
|
* 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)
|
||||||
|
|
||||||
|
* Return Value:
|
||||||
|
* Units not garrisoned <ARRAY>
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [position, nil, [unit1, unit2, unit3, unitN], 200, 1, false, false] call ace_ai_fnc_garrison
|
||||||
|
*
|
||||||
|
* Public: Yes
|
||||||
|
*/
|
||||||
|
|
||||||
|
params [["_startingPos",[0,0,0], [[]], 3], ["_buildingTypes", ["Building"], [[]]], ["_unitsArray", [], [[]]], ["_fillingRadius", 50, [0]], ["_fillingType", 0, [0]], ["_topDownFilling", false, [true]], ["_teleport", false, [true]]];
|
||||||
|
|
||||||
|
TRACE_6("fnc_garrison: Start",_startingPos,_buldingTypes,count _unitsArray,_fillingRadius,_fillingTYpe,_topDownFilling);
|
||||||
|
|
||||||
|
_unitsArray = _unitsArray select {alive _x && {!isPlayer _x}};
|
||||||
|
|
||||||
|
if (_startingPos isEqualTo [0,0,0]) exitWith {
|
||||||
|
TRACE_1("fnc_garrison: StartingPos error",_startingPos);
|
||||||
|
[LSTRING(GarrisonInvalidPosition)] call EFUNC(common,displayTextStructured);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (count _unitsArray == 0 || {isNull (_unitsArray select 0)}) exitWith {
|
||||||
|
TRACE_1("fnc_garrison: Units error",_unitsArray);
|
||||||
|
[LSTRING(GarrisonNoUnits)] call EFUNC(common,displayTextStructured);
|
||||||
|
};
|
||||||
|
|
||||||
|
private _buildings = nearestObjects [_startingPos, _buildingTypes, ([_fillingRadius, 50] select (_fillingRadius < 50))];
|
||||||
|
if (_fillingRadius >= 50) then {
|
||||||
|
_buildings = [_buildings] call CBA_fnc_shuffle;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (count _buildings == 0) exitWith {
|
||||||
|
TRACE_1("fnc_garrison: Building error",_buildings);
|
||||||
|
[LSTRING(GarrisonNoBuilding)] call EFUNC(common,displayTextStructured);
|
||||||
|
};
|
||||||
|
|
||||||
|
private _buildingsIndex = [];
|
||||||
|
|
||||||
|
if (_topDownFilling) then {
|
||||||
|
{
|
||||||
|
private _buildingPos = _x buildingPos -1;
|
||||||
|
|
||||||
|
// Those reverse are necessary, as dumb as it is there's no better way to sort those subarrays in sqf
|
||||||
|
{
|
||||||
|
reverse _x;
|
||||||
|
} foreach _buildingPos;
|
||||||
|
|
||||||
|
_buildingPos sort false;
|
||||||
|
|
||||||
|
{
|
||||||
|
reverse _x;
|
||||||
|
} foreach _buildingPos;
|
||||||
|
|
||||||
|
_buildingsIndex pushBack _buildingPos;
|
||||||
|
} foreach _buildings;
|
||||||
|
} else {
|
||||||
|
{
|
||||||
|
_buildingsIndex pushBack (_x buildingPos -1);
|
||||||
|
} foreach _buildings;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Remove buildings without positions
|
||||||
|
{
|
||||||
|
_buildingsIndex deleteAt (_buildingsIndex find _x);
|
||||||
|
} foreach (_buildingsIndex select {count _x == 0});
|
||||||
|
|
||||||
|
//Remove positions units are already pathing to
|
||||||
|
_buildingsIndex = _buildingsIndex apply {
|
||||||
|
private _testedBuilding = _x;
|
||||||
|
|
||||||
|
_testedBuilding select {
|
||||||
|
private _testedPos = _x;
|
||||||
|
(({(_x select 1) isEqualTo _testedPos} count (missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []])) == 0)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Warn the user that there's not enough positions to place all units
|
||||||
|
private _count = 0;
|
||||||
|
{_count = _count + count _x} foreach _buildingsIndex;
|
||||||
|
if ( (count _unitsArray) - _count > 0) then {
|
||||||
|
TRACE_4("fnc_garrison: Not enough spots to place all units",_unitsArray,count _unitsArray,_count,((count _unitsArray) - _count > 0));
|
||||||
|
[LSTRING(GarrisonNotEnoughPos)] call EFUNC(common,displayTextStructured);
|
||||||
|
};
|
||||||
|
|
||||||
|
private _placedUnits = [];
|
||||||
|
private _unitMoveList = [];
|
||||||
|
|
||||||
|
// Force all units to un-garrison
|
||||||
|
[QGVAR(unGarrison), [_unitsArray], _unitsArray] call CBA_fnc_targetEvent;
|
||||||
|
|
||||||
|
private _fnc_comparePos = {
|
||||||
|
params ["_nearestUnits", "_pos"];
|
||||||
|
({
|
||||||
|
if (surfaceIsWater getPos _x) then {
|
||||||
|
floor ((getPosASL _x) select 2) == floor ((AGLtoASL _pos) select 2)
|
||||||
|
} else {
|
||||||
|
floor ((getPosATL _x) select 2) == floor (_pos select 2)
|
||||||
|
};
|
||||||
|
} count _nearestUnits) > 0
|
||||||
|
};
|
||||||
|
|
||||||
|
// Do the placement
|
||||||
|
switch (_fillingType) do {
|
||||||
|
|
||||||
|
// Even filling
|
||||||
|
case 0: {
|
||||||
|
|
||||||
|
while {count _unitsArray > 0} do {
|
||||||
|
if (count _buildingsIndex == 0) exitWith {};
|
||||||
|
private _building = _buildingsIndex select 0;
|
||||||
|
|
||||||
|
if (_building isEqualTo []) then {
|
||||||
|
LOG(format [ARR_2("fnc_garrison: Empty building array | removing building from buildingsIndex | %1 buildings remaining",count _buildingsIndex)]);
|
||||||
|
_buildingsIndex deleteAt 0;
|
||||||
|
|
||||||
|
} 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)]);
|
||||||
|
|
||||||
|
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)]);
|
||||||
|
_buildingsIndex set [0, _building - [_pos]];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
private _unit = _unitsArray select 0;
|
||||||
|
private _posSurface = surfaceIsWater _pos;
|
||||||
|
|
||||||
|
if (_teleport) then {
|
||||||
|
doStop _unit;
|
||||||
|
if (_posSurface) then {
|
||||||
|
_unit setPosASL (AGLtoASL _pos);
|
||||||
|
} else {
|
||||||
|
_unit setPosATL _pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_unitMoveList pushBack [_unit,[_pos, AGLToASL _pos] select (_posSurface)];
|
||||||
|
};
|
||||||
|
|
||||||
|
_placedUnits pushBack _unit;
|
||||||
|
_unitsArray deleteAt (_unitsArray find _unit);
|
||||||
|
_building deleteAt 0;
|
||||||
|
_buildingsIndex deleteAt 0;
|
||||||
|
_buildingsIndex pushBackUnique _building;
|
||||||
|
_unit setVariable [QGVAR(garrisonned), true, true];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Building by building
|
||||||
|
case 1: {
|
||||||
|
|
||||||
|
while {count _unitsArray > 0} do {
|
||||||
|
if (count _buildingsIndex == 0) exitWith {};
|
||||||
|
private _building = _buildingsIndex select 0;
|
||||||
|
|
||||||
|
if (_building isEqualTo []) then {
|
||||||
|
LOG(format [ARR_2("fnc_garrison: empty building array | removing building from buildingsIndex | %1 buildings remaining",count _buildingsIndex)]);
|
||||||
|
_buildingsIndex deleteAt 0;
|
||||||
|
|
||||||
|
} 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)]);
|
||||||
|
|
||||||
|
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)]);
|
||||||
|
_buildingsIndex set [0, _building - [_pos]];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
private _unit = _unitsArray select 0;
|
||||||
|
private _posSurface = surfaceIsWater _pos;
|
||||||
|
|
||||||
|
if (_teleport) then {
|
||||||
|
doStop _unit;
|
||||||
|
if (_posSurface) then {
|
||||||
|
_unit setPosASL (AGLtoASL _pos);
|
||||||
|
} else {
|
||||||
|
_unit setPosATL _pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_unitMoveList pushBack [_unit,[_pos, AGLToASL _pos] select (_posSurface)];
|
||||||
|
};
|
||||||
|
|
||||||
|
_placedUnits pushBack _unit;
|
||||||
|
_unitsArray deleteAt (_unitsArray find _unit);
|
||||||
|
_buildingsIndex set [0, _building - [_pos]];
|
||||||
|
_unit setVariable [QGVAR(garrisonned), true, true];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Random
|
||||||
|
case 2: {
|
||||||
|
|
||||||
|
while {count _unitsArray > 0} do {
|
||||||
|
if (count _buildingsIndex == 0) exitWith {};
|
||||||
|
private _building = selectRandom _buildingsIndex;
|
||||||
|
|
||||||
|
if (_building isEqualTo []) then {
|
||||||
|
LOG(format [ARR_2("fnc_garrison: empty building array | removing building from buildingsIndex | %1 buildings remaining",count _buildingsIndex)]);
|
||||||
|
_buildingsIndex deleteAt (_buildingsIndex find _building);
|
||||||
|
|
||||||
|
} 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)]);
|
||||||
|
|
||||||
|
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)]);
|
||||||
|
_buildingsIndex set [(_buildingsIndex find _building), _building - [_pos]];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
private _unit = _unitsArray select 0;
|
||||||
|
private _posSurface = surfaceIsWater _pos;
|
||||||
|
|
||||||
|
if (_teleport) then {
|
||||||
|
doStop _unit;
|
||||||
|
if (_posSurface) then {
|
||||||
|
_unit setPosASL (AGLtoASL _pos);
|
||||||
|
} else {
|
||||||
|
_unit setPosATL _pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_unitMoveList pushBack [_unit,[_pos, AGLToASL _pos] select (_posSurface)];
|
||||||
|
};
|
||||||
|
|
||||||
|
_placedUnits pushBack _unit;
|
||||||
|
_unitsArray deleteAt (_unitsArray find _unit);
|
||||||
|
_buildingsIndex set [(_buildingsIndex find _building), _building - [_pos]];
|
||||||
|
_unit setVariable [QGVAR(garrisonned), true, true];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
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), []];
|
||||||
|
|
||||||
|
_garrison_unitMoveList = _garrison_unitMoveList select {
|
||||||
|
_x params ["_testedUnit", "_testedPos"];
|
||||||
|
({(_x select 0) isEqualTo _testedUnit} count _unitMoveList == 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
_garrison_unitMoveList append _unitMoveList;
|
||||||
|
|
||||||
|
missionNameSpace setVariable [QGVAR(garrison_unitMoveList), _garrison_unitMoveList, true];
|
||||||
|
|
||||||
|
if (_teleport) then {
|
||||||
|
[QGVAR(AISection), [_placedUnits, ["PATH"], false], _placedUnits] call CBA_fnc_targetEvent;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
[_unitMoveList] call FUNC(garrisonMove);
|
||||||
|
};
|
||||||
|
|
||||||
|
TRACE_1(format [ARR_3("fnc_garrison: End | %1 units left | %2 buildings left", count _unitsArray, count _buildingsIndex)], _unitsArray);
|
||||||
|
_unitsArray
|
149
addons/ai/functions/fnc_garrisonMove.sqf
Normal file
149
addons/ai/functions/fnc_garrisonMove.sqf
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
/*
|
||||||
|
* Author: alganthe
|
||||||
|
* Internal function used by ace_ai_fnc_garrison to make the units move to the positions it picked.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Array of arrays <ARRAY>
|
||||||
|
* 0: Unit needing to be placed <UNIT>
|
||||||
|
* 1: Position the unit need to be placed at <POSITION>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* Nothing
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [ [unit1, [10, 10, 10]], [unit2, [30, 30, 30]], [unitN, getPos player] ] call ace_ai_fnc_garrisonMove
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
|
||||||
|
params [ ["_unitMoveList", nil, [[]]] ];
|
||||||
|
|
||||||
|
if (isNil "_unitMoveList") exitWith {};
|
||||||
|
|
||||||
|
// Start initial movement
|
||||||
|
private _unitMoveListUnits = (_unitMoveList apply {_x select 0});
|
||||||
|
[QGVAR(setBehaviour), [(_unitMoveListUnits select {leader _x == _x}), "AWARE"], _unitMoveListUnits] call CBA_fnc_targetEvent;
|
||||||
|
[QGVAR(AISection), [_unitMoveListUnits, ["FSM"], false], _unitMoveListUnits] call CBA_fnc_targetEvent;
|
||||||
|
[QGVAR(doMove), [_unitMoveList], _unitMoveListUnits] call CBA_fnc_targetEvent;
|
||||||
|
[QGVAR(enableAttack), [_unitMoveListUnits select {leader _x == _x}, false], _unitMoveListUnits] call CBA_fnc_targetEvent;
|
||||||
|
|
||||||
|
{
|
||||||
|
_x setVariable [QGVAR(garrisonMove_failSafe), nil, true];
|
||||||
|
_x setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true];
|
||||||
|
} foreach _unitMoveListUnits;
|
||||||
|
|
||||||
|
// Avoid duplicate PFHs
|
||||||
|
if (isNil QGVAR(garrison_moveUnitPFH)) then {
|
||||||
|
missionNameSpace setVariable [QGVAR(garrison_moveUnitPFH), true, true];
|
||||||
|
|
||||||
|
// PFH checking if the units have reached their destination
|
||||||
|
[{
|
||||||
|
params ["_args", "_pfhID"];
|
||||||
|
|
||||||
|
private _unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []];
|
||||||
|
|
||||||
|
// End PFH if all units are placed / unable to reach position
|
||||||
|
if (_unitMoveList isEqualTo []) then {
|
||||||
|
missionNameSpace setVariable [QGVAR(garrison_moveUnitPFH), nil, true];
|
||||||
|
LOG("garrisonMove PFH: PFH finished it's job | deleting PFH");
|
||||||
|
_pfhID call CBA_fnc_removePerFrameHandler;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
{
|
||||||
|
_x params ["_unit", "_pos"];
|
||||||
|
|
||||||
|
// Check if unit is alive or even existing
|
||||||
|
if (!alive _unit) then {
|
||||||
|
_unitMoveList deleteAt (_unitMoveList find _x);
|
||||||
|
LOG(format [ARR_2("garrisonMove PFH: unit dead or deleted | %1 units left", count _unitMoveList)]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
private _unitPos = getPos _unit;
|
||||||
|
if (surfaceisWater _unitPos) then {
|
||||||
|
_unitPos = getPosASL _unit;
|
||||||
|
} else {
|
||||||
|
_unitPos = getPosATL _unit;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (unitReady _unit) then {
|
||||||
|
// Check for distance, doMove and AI are moody and may stop for no reason, within 6 meters and ready should be fine
|
||||||
|
if (_unitPos distance _pos < 3) then {
|
||||||
|
_unit setVariable [QGVAR(garrisonMove_failSafe), nil, true];
|
||||||
|
_unit setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true];
|
||||||
|
_unit setVariable [QGVAR(garrisonned), true, true];
|
||||||
|
_unitMoveList deleteAt (_unitMoveList find _x);
|
||||||
|
|
||||||
|
[QGVAR(AISection), [[_unit], ["PATH"], false], _unit] call CBA_fnc_targetEvent;
|
||||||
|
[QGVAR(AISection), [[_unit], ["FSM"], true], _unit] call CBA_fnc_targetEvent;
|
||||||
|
|
||||||
|
if ({(_x select 0) in units _unit && {!isPlayer (_x select 0)}} count _unitMoveList == 0) then {
|
||||||
|
[QGVAR(enableAttack), [[_unit], true], _unit] call CBA_fnc_targetEvent;
|
||||||
|
};
|
||||||
|
|
||||||
|
LOG(format [ARR_2("garrisonMove PFH: unit in position | %1 units left", count _unitMoveList)]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Tell the unit to move if an order wasn't given within 30s, avoid doMove spam
|
||||||
|
(_unit getVariable [QGVAR(garrisonMove_failSafe), [CBA_missionTime, 5]]) params ["_failSafeTimer", "_failSafeRemainingAttemps"];
|
||||||
|
|
||||||
|
if (_failSafeTimer <= CBA_missionTime) then {
|
||||||
|
if (_failSafeRemainingAttemps == 0 ) then {
|
||||||
|
_unit setVariable [QGVAR(garrisonMove_failSafe), nil, true];
|
||||||
|
_unit setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true];
|
||||||
|
[QGVAR(unGarrison), [[_unit]], _unit] call CBA_fnc_targetEvent;
|
||||||
|
_unitMoveList deleteAt (_unitMoveList find _x);
|
||||||
|
LOG("garrisonMove PFH unitReady: all moving commands failed | restoring AI capabilities");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_unit setVariable [QGVAR(garrisonMove_failSafe), [_failSafeTimer + 15, _failSafeRemainingAttemps - 1]];
|
||||||
|
[QGVAR(doMove), [[[_unit, _pos]]], _unit] call CBA_fnc_targetEvent;
|
||||||
|
LOG("garrisonMove PFH unitReady: unit not close enough | Sending another doMove command");
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
(_unit getVariable [QGVAR(garrisonMove_unitPosMemory), [CBA_missionTime, [0,0,0]]]) params ["_unitPosTimer", "_unitOldPos"];
|
||||||
|
|
||||||
|
// AI may sometimes not be able to report unitReady, this is to avoid the PFH running forever
|
||||||
|
switch true do {
|
||||||
|
case ((_unitPosTimer + 15) < CBA_missionTime && {(_unitPos distance _pos) < 3}) : {
|
||||||
|
TRACE_1("case 1",_unit);
|
||||||
|
_unit setVariable [QGVAR(garrisonMove_failSafe), nil, true];
|
||||||
|
_unit setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true];
|
||||||
|
_unit setVariable [QGVAR(garrisonned), true, true];
|
||||||
|
_unitMoveList deleteAt (_unitMoveList find _x);
|
||||||
|
|
||||||
|
[QGVAR(AISection), [[_unit], ["PATH"], false], _unit] call CBA_fnc_targetEvent;
|
||||||
|
[QGVAR(AISection), [[_unit], ["FSM"], true], _unit] call CBA_fnc_targetEvent;
|
||||||
|
|
||||||
|
if ({(_x select 0) in units _unit && {!isPlayer (_x select 0)}} count _unitMoveList == 0) then {
|
||||||
|
[QGVAR(enableAttack), [[_unit], true], _unit] call CBA_fnc_targetEvent;
|
||||||
|
};
|
||||||
|
|
||||||
|
LOG(format [ARR_2("garrisonMove PFH unitNotReady: unit in position | %1 units left", count _unitMoveList)]);
|
||||||
|
};
|
||||||
|
|
||||||
|
case ((_unitPosTimer + 15) < CBA_missionTime && {_unitOldPos distance _unitPos < 0.5}) : {
|
||||||
|
TRACE_3("case 2",_unit, ((_unitPosTimer + 15) < CBA_missionTime), (_unitOldPos distance _unitPos < 0.5));
|
||||||
|
_unit setVariable [QGVAR(garrisonMove_failSafe), nil, true];
|
||||||
|
_unit setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true];
|
||||||
|
[QGVAR(unGarrison), [[_unit]], _unit] call CBA_fnc_targetEvent;
|
||||||
|
_unitMoveList deleteAt (_unitMoveList find _x);
|
||||||
|
LOG("garrisonMove PFH unitNotReady: all moving commands failed | restoring AI capabilities");
|
||||||
|
};
|
||||||
|
|
||||||
|
case (_unitOldPos distance _unitPos < 0.5) : {};
|
||||||
|
|
||||||
|
default {
|
||||||
|
_unit setVariable [QGVAR(garrisonMove_unitPosMemory), [CBA_missionTime, _unitPos]];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} foreach _unitMoveList;
|
||||||
|
|
||||||
|
missionNameSpace setVariable [QGVAR(garrison_unitMoveList), _unitMoveList, true];
|
||||||
|
};
|
||||||
|
}, 0.5, []] call CBA_fnc_addPerFrameHandler;
|
||||||
|
};
|
57
addons/ai/functions/fnc_unGarrison.sqf
Normal file
57
addons/ai/functions/fnc_unGarrison.sqf
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
/*
|
||||||
|
* Author: alganthe
|
||||||
|
* Used to un-garrison units.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Units to un-garrison <ARRAY>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [unit1, unit2, unit3] call ace_ai_fnc_unGarrison
|
||||||
|
*
|
||||||
|
* Public: Yes
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
params [["_units", [], [[]]]];
|
||||||
|
|
||||||
|
_units = _units select {local _x};
|
||||||
|
|
||||||
|
{
|
||||||
|
if (!isPlayer _x && {local _x}) then {
|
||||||
|
_x enableAI "PATH";
|
||||||
|
_x enableAI "FSM";
|
||||||
|
|
||||||
|
private _leader = leader _x;
|
||||||
|
|
||||||
|
TRACE_3("fnc_ungarrison: unit and leader",_x , _leader, (_leader == _x));
|
||||||
|
|
||||||
|
_x setVariable [QGVAR(garrisonned), false, true];
|
||||||
|
|
||||||
|
if (_leader != _x) then {
|
||||||
|
doStop _x;
|
||||||
|
_x doFollow _leader;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_x doMove ((nearestBuilding (getPos _x)) buildingExit 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
private _fnc_countGarrisonnedUnits = {
|
||||||
|
params ["_unit", "_bool"];
|
||||||
|
if (_bool) then {
|
||||||
|
({(_x getVariable [QGVAR(garrisonned), false]) && {!isPlayer _x}} count units _unit)
|
||||||
|
} else {
|
||||||
|
({!(_x getVariable [QGVAR(garrisonned), false]) && {!isPlayer _x}} count units _unit)
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
if ([_x, true] call _fnc_countGarrisonnedUnits == ({!isPlayer _x} count (units _x)) - 1 || {[_x, false] call _fnc_countGarrisonnedUnits == {!isPlayer _x} count (units _x)}) then {
|
||||||
|
LOG("fnc_ungarrison: enableAttack true");
|
||||||
|
(group _x) enableAttack true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} foreach _units;
|
1
addons/ai/functions/script_component.hpp
Normal file
1
addons/ai/functions/script_component.hpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "\z\ace\addons\ai\script_component.hpp"
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
// #define DEBUG_MODE_FULL
|
// #define DEBUG_MODE_FULL
|
||||||
// #define DISABLE_COMPILE_CACHE
|
// #define DISABLE_COMPILE_CACHE
|
||||||
// #define CBA_DEBUG_SYNCHRONOUS
|
|
||||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED_AI
|
#ifdef DEBUG_ENABLED_AI
|
||||||
|
41
addons/ai/stringtable.xml
Normal file
41
addons/ai/stringtable.xml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project name="ACE">
|
||||||
|
<Package name="ai">
|
||||||
|
<Key ID="STR_ACE_ai_GarrisonInvalidPosition">
|
||||||
|
<English>Invalid position provided.</English>
|
||||||
|
<French>Position invalide fourni</French>
|
||||||
|
<Japanese>位置が無効です。</Japanese>
|
||||||
|
<Italian>Posizione invalida fornita.</Italian>
|
||||||
|
<Chinese>提供的位置無效</Chinese>
|
||||||
|
<Chinesesimp>提供的位置无效。</Chinesesimp>
|
||||||
|
<Korean>위치가 잘못되었습니다.</Korean>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_ai_GarrisonNoUnits">
|
||||||
|
<English>No units provided.</English>
|
||||||
|
<French>Aucune unité fourni</French>
|
||||||
|
<Japanese>ユニットがありません。</Japanese>
|
||||||
|
<Italian>Nessuna unità fornita.</Italian>
|
||||||
|
<Chinese>找不到可用的單位</Chinese>
|
||||||
|
<Chinesesimp>找不到可用的单位。</Chinesesimp>
|
||||||
|
<Korean>병력이 없습니다.</Korean>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_ai_GarrisonNotEnoughPos">
|
||||||
|
<English>There aren't enough positions to place all units.</English>
|
||||||
|
<French>Il n'y a pas assez de positions pour placer toutes les unités</French>
|
||||||
|
<Japanese>全ユニットを置くために十分な位置がありません。</Japanese>
|
||||||
|
<Italian>Non ci sono abbastanza posizioni per piazzare tutte le unità.</Italian>
|
||||||
|
<Chinese>沒有足夠的位置能擺放所有單位</Chinese>
|
||||||
|
<Chinesesimp>没有足够的位置能摆放所有单位。</Chinesesimp>
|
||||||
|
<Korean>모든 병력을 배치 할 공간이 없습니다.</Korean>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_ai_GarrisonNoBuilding">
|
||||||
|
<English>No building found.</English>
|
||||||
|
<French>Aucun bâtiment trouvé</French>
|
||||||
|
<Japanese>建物がありません。</Japanese>
|
||||||
|
<Italian>Nessun edificio trovato.</Italian>
|
||||||
|
<Chinese>沒找到建築物</Chinese>
|
||||||
|
<Chinesesimp>没找到建筑物。</Chinesesimp>
|
||||||
|
<Korean>건물이 없습니다.</Korean>
|
||||||
|
</Key>
|
||||||
|
</Package>
|
||||||
|
</Project>
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
class CfgAmmo {
|
class CfgAmmo {
|
||||||
class BulletBase;
|
class BulletBase;
|
||||||
class B_20mm : BulletBase {
|
class B_20mm : BulletBase {
|
||||||
@ -11,11 +10,11 @@ class CfgAmmo {
|
|||||||
explosive = 1.8;
|
explosive = 1.8;
|
||||||
tracersEvery = 3;
|
tracersEvery = 3;
|
||||||
tracerEndTime = 3.5;
|
tracerEndTime = 3.5;
|
||||||
|
|
||||||
CraterEffects = "ExploAmmoCrater";
|
CraterEffects = "ExploAmmoCrater";
|
||||||
explosionEffects = "ExploAmmoExplosion";
|
explosionEffects = "ExploAmmoExplosion";
|
||||||
model = "\A3\Weapons_f\Data\bullettracer\tracer_red";
|
model = "\A3\Weapons_f\Data\bullettracer\tracer_red";
|
||||||
};
|
};
|
||||||
|
|
||||||
class ACE_20mm_HE : B_20mm {};
|
class ACE_20mm_HE : B_20mm {};
|
||||||
class ACE_20mm_AP : B_20mm {
|
class ACE_20mm_AP : B_20mm {
|
||||||
hit = 50;
|
hit = 50;
|
||||||
@ -40,30 +39,20 @@ class CfgAmmo {
|
|||||||
|
|
||||||
// also adjust tracer, "muh lightshow"; also adjust splash damage radius
|
// also adjust tracer, "muh lightshow"; also adjust splash damage radius
|
||||||
class Gatling_30mm_HE_Plane_CAS_01_F: BulletBase {
|
class Gatling_30mm_HE_Plane_CAS_01_F: BulletBase {
|
||||||
hit = 80;
|
hit = 80; // default: 180
|
||||||
indirectHit = 12;
|
indirectHit = 12; // default: 4
|
||||||
indirectHitRange = 3; //2;
|
indirectHitRange = 3; // default: 3
|
||||||
caliber = 1.4;
|
caliber = 1.4; // default: 5
|
||||||
deflecting = 3;
|
deflecting = 3; // default: 5
|
||||||
fuseDistance = 3;
|
fuseDistance = 3; // default: 10
|
||||||
tracerStartTime = 0.02;
|
tracerStartTime = 0.02; // default: 0.1
|
||||||
timeToLive = 40;
|
timeToLive = 40; // default: 6
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper projectiles to simulate a rof > fps
|
|
||||||
class ACE_Gatling_30mm_HE_Plane_CAS_01_Deploy: Gatling_30mm_HE_Plane_CAS_01_F {
|
|
||||||
simulation = "shotSubmunitions";
|
|
||||||
triggerTime = 0;
|
|
||||||
submunitionAmmo = "ACE_Gatling_30mm_HE_Plane_CAS_01_Sub";
|
|
||||||
submunitionConeType[] = {"custom", {{0,0}, {0,0}, {0,0}} };
|
|
||||||
};
|
|
||||||
|
|
||||||
class ACE_Gatling_30mm_HE_Plane_CAS_01_Sub: Gatling_30mm_HE_Plane_CAS_01_F {};
|
|
||||||
|
|
||||||
// adjust damage and splash damage, closer to bluefor gatling with same caliber
|
// adjust damage and splash damage, closer to bluefor gatling with same caliber
|
||||||
class Cannon_30mm_HE_Plane_CAS_02_F: Gatling_30mm_HE_Plane_CAS_01_F {
|
class Cannon_30mm_HE_Plane_CAS_02_F: Gatling_30mm_HE_Plane_CAS_01_F {
|
||||||
hit = 70; //40;
|
hit = 70; // default: 150
|
||||||
indirectHit = 11; //14;
|
indirectHit = 11; // default: 4
|
||||||
indirectHitRange = 3;
|
indirectHitRange = 3; // default: 3
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
17
addons/aircraft/CfgEventHandlers.hpp
Normal file
17
addons/aircraft/CfgEventHandlers.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
class Extended_PreStart_EventHandlers {
|
||||||
|
class ADDON {
|
||||||
|
init = QUOTE(call COMPILE_FILE(XEH_preStart));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Extended_PreInit_EventHandlers {
|
||||||
|
class ADDON {
|
||||||
|
init = QUOTE(call COMPILE_FILE(XEH_preInit));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Extended_PostInit_EventHandlers {
|
||||||
|
class ADDON {
|
||||||
|
clientInit = QUOTE(call COMPILE_FILE(XEH_postInitClient));
|
||||||
|
};
|
||||||
|
};
|
@ -1,9 +1,7 @@
|
|||||||
|
|
||||||
class CfgMagazines {
|
class CfgMagazines {
|
||||||
// shoot helper object to tripple rof
|
// shoot helper object to tripple rof
|
||||||
class VehicleMagazine;
|
class VehicleMagazine;
|
||||||
class 1000Rnd_Gatling_30mm_Plane_CAS_01_F: VehicleMagazine {
|
class 1000Rnd_Gatling_30mm_Plane_CAS_01_F: VehicleMagazine {
|
||||||
ammo = "ACE_Gatling_30mm_HE_Plane_CAS_01_Deploy";
|
|
||||||
count = 1170;
|
count = 1170;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
class CfgVehicles {
|
class CfgVehicles {
|
||||||
class All {
|
class All {
|
||||||
class Turrets;
|
class Turrets;
|
||||||
@ -11,7 +10,6 @@ class CfgVehicles {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class Air: AllVehicles {};
|
class Air: AllVehicles {};
|
||||||
|
|
||||||
class Helicopter: Air {
|
class Helicopter: Air {
|
||||||
class Turrets {
|
class Turrets {
|
||||||
class MainTurret;
|
class MainTurret;
|
||||||
@ -19,13 +17,11 @@ class CfgVehicles {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class Plane: Air {};
|
class Plane: Air {};
|
||||||
|
|
||||||
class ParachuteBase: Helicopter {
|
class ParachuteBase: Helicopter {
|
||||||
class Turrets;
|
class Turrets;
|
||||||
};
|
};
|
||||||
|
|
||||||
class UAV: Plane {};
|
class UAV: Plane {};
|
||||||
|
|
||||||
class Helicopter_Base_F: Helicopter {
|
class Helicopter_Base_F: Helicopter {
|
||||||
class Turrets: Turrets {
|
class Turrets: Turrets {
|
||||||
class CopilotTurret;
|
class CopilotTurret;
|
||||||
@ -37,53 +33,27 @@ class CfgVehicles {
|
|||||||
class Turrets: Turrets {
|
class Turrets: Turrets {
|
||||||
class CopilotTurret;
|
class CopilotTurret;
|
||||||
};
|
};
|
||||||
//class UserActions;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Heli_Light_01_base_F: Helicopter_Base_H {
|
class Heli_Light_01_base_F: Helicopter_Base_H {
|
||||||
lockDetectionSystem = 0;
|
incomingMissileDetectionSystem = 16; // Vanilla: 0
|
||||||
incomingMissileDetectionSystem = 16;
|
|
||||||
driverCanEject = 1;
|
|
||||||
|
|
||||||
class Turrets: Turrets {
|
class Turrets: Turrets {
|
||||||
class CopilotTurret: CopilotTurret {
|
class CopilotTurret: CopilotTurret {
|
||||||
canEject = 1;
|
|
||||||
showHMD = 1;
|
showHMD = 1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class Heli_Light_01_unarmed_base_F: Heli_Light_01_base_F {};
|
|
||||||
|
|
||||||
class B_Heli_Light_01_F: Heli_Light_01_unarmed_base_F {
|
|
||||||
/*class Turrets: Turrets {
|
|
||||||
class CopilotTurret: CopilotTurret {};
|
|
||||||
};*/
|
|
||||||
};
|
|
||||||
|
|
||||||
class Heli_Light_01_armed_base_F: Heli_Light_01_base_F {
|
class Heli_Light_01_armed_base_F: Heli_Light_01_base_F {
|
||||||
lockDetectionSystem = 0;
|
incomingMissileDetectionSystem = 16; // Vanilla: 0
|
||||||
incomingMissileDetectionSystem = 16;
|
|
||||||
driverCanEject = 1;
|
|
||||||
|
|
||||||
class Turrets: Turrets {
|
|
||||||
class CopilotTurret: CopilotTurret {
|
|
||||||
canEject = 1;
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class B_Heli_Light_01_armed_F: Heli_Light_01_armed_base_F {};
|
|
||||||
|
|
||||||
class Heli_Light_02_base_F: Helicopter_Base_H {
|
class Heli_Light_02_base_F: Helicopter_Base_H {
|
||||||
driverCanEject = 1;
|
incomingMissileDetectionSystem = 16; // Vanilla: 24
|
||||||
lockDetectionSystem = 12;
|
magazines[] = {"2000Rnd_762x51_Belt_T_Green", "12Rnd_PG_missiles", "168Rnd_CMFlare_Chaff_Magazine"}; // Switch gun magazine to 7.62mm from 6.5mm
|
||||||
incomingMissileDetectionSystem = 16;
|
|
||||||
magazines[] = {"2000Rnd_762x51_Belt_T_Green","12Rnd_PG_missiles","168Rnd_CMFlare_Chaff_Magazine"};
|
|
||||||
|
|
||||||
class Turrets: Turrets {
|
class Turrets: Turrets {
|
||||||
class CopilotTurret: CopilotTurret {
|
class CopilotTurret: CopilotTurret {
|
||||||
canEject = 1;
|
|
||||||
showHMD = 1;
|
showHMD = 1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -97,248 +67,81 @@ class CfgVehicles {
|
|||||||
|
|
||||||
#include "Heli_Attack_01_base_F.hpp"
|
#include "Heli_Attack_01_base_F.hpp"
|
||||||
|
|
||||||
class B_Heli_Attack_01_F: Heli_Attack_01_base_F {};
|
|
||||||
|
|
||||||
class Heli_Attack_02_base_F: Helicopter_Base_F {
|
class Heli_Attack_02_base_F: Helicopter_Base_F {
|
||||||
lockDetectionSystem = 12;
|
incomingMissileDetectionSystem = 16; // Vanilla: 24
|
||||||
incomingMissileDetectionSystem = 16;
|
|
||||||
driverCanEject = 1;
|
|
||||||
|
|
||||||
class Turrets: Turrets {
|
|
||||||
class MainTurret: MainTurret {
|
|
||||||
canEject = 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Heli_Transport_01_base_F: Helicopter_Base_H {
|
class Heli_Transport_01_base_F: Helicopter_Base_H {
|
||||||
lockDetectionSystem = 12;
|
incomingMissileDetectionSystem = 16; // Vanilla: 24
|
||||||
incomingMissileDetectionSystem = 16;
|
|
||||||
driverCanEject = 1;
|
|
||||||
|
|
||||||
class Turrets: Turrets {
|
class Turrets: Turrets {
|
||||||
class CopilotTurret: CopilotTurret {
|
class CopilotTurret: CopilotTurret {
|
||||||
canEject = 1;
|
|
||||||
showHMD = 1;
|
showHMD = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MainTurret: MainTurret {
|
class MainTurret: MainTurret {
|
||||||
magazines[] = {"2000Rnd_762x51_Belt_T_Red"};
|
magazines[] = {"2000Rnd_762x51_Belt_T_Red"}; // Switch gun magazine to 7.62mm from 6.5mm
|
||||||
canEject = 1;
|
|
||||||
};
|
|
||||||
class RightDoorGun: MainTurret {
|
|
||||||
magazines[] = {"2000Rnd_762x51_Belt_T_Red"};
|
|
||||||
canEject = 1;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*class UserActions {
|
class RightDoorGun: MainTurret {
|
||||||
class DoorL1_Open {
|
magazines[] = {"2000Rnd_762x51_Belt_T_Red"}; // Switch gun magazine to 7.62mm from 6.5mm
|
||||||
available = 1;
|
|
||||||
condition = "((this doorPhase 'door_L') == 0) AND Alive(this) AND driver this != player AND gunner this != player";
|
|
||||||
};
|
};
|
||||||
class DoorR1_Open: DoorL1_Open {
|
|
||||||
condition = "((this doorPhase 'door_R') == 0) AND Alive(this) AND driver this != player AND gunner this != player";
|
|
||||||
};
|
};
|
||||||
class DoorL1_Close: DoorL1_Open {
|
|
||||||
condition = "((this doorPhase 'door_L') > 0) AND Alive(this) AND driver this != player AND gunner this != player";
|
|
||||||
};
|
|
||||||
class DoorR1_Close: DoorL1_Close {
|
|
||||||
condition = "((this doorPhase 'door_R') > 0) AND Alive(this) AND driver this != player AND gunner this != player";
|
|
||||||
};
|
|
||||||
};*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Heli_Transport_02_base_F: Helicopter_Base_H {
|
class Heli_Transport_02_base_F: Helicopter_Base_H {
|
||||||
lockDetectionSystem = 12;
|
incomingMissileDetectionSystem = 16; // Vanilla: 24
|
||||||
incomingMissileDetectionSystem = 16;
|
|
||||||
driverCanEject = 1;
|
|
||||||
|
|
||||||
class Turrets: Turrets {
|
class Turrets: Turrets {
|
||||||
class CopilotTurret: CopilotTurret {
|
class CopilotTurret: CopilotTurret {
|
||||||
canEject = 1;
|
|
||||||
showHMD = 1;
|
showHMD = 1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/*class UserActions: UserActions {
|
|
||||||
class DoorL1_Open {
|
|
||||||
available = 1;
|
|
||||||
condition = "this animationPhase ""door_back_L"" < 0.5 AND Alive(this)";
|
|
||||||
};
|
|
||||||
class DoorR1_Open: DoorL1_Open {
|
|
||||||
condition = "this animationPhase ""door_back_R"" < 0.5 AND Alive(this)";
|
|
||||||
};
|
|
||||||
class DoorL1_Close: DoorL1_Open {
|
|
||||||
condition = "this animationPhase ""door_back_L"" > 0.5 AND Alive(this)";
|
|
||||||
};
|
|
||||||
class DoorR1_Close: DoorL1_Close {
|
|
||||||
condition = "this animationPhase ""door_back_R"" > 0.5 AND Alive(this)";
|
|
||||||
};
|
|
||||||
class CargoRamp_Open: DoorL1_Open {
|
|
||||||
userActionID = 52;
|
|
||||||
displayName = CSTRING(OpenCargoRamp);
|
|
||||||
textToolTip = CSTRING(OpenCargoRamp);
|
|
||||||
position = "action_cargoramp";
|
|
||||||
radius = 3.0;
|
|
||||||
condition = "this animationPhase ""cargoramp_open"" < 0.5 AND Alive(this)";
|
|
||||||
statement = "this animateDoor ['cargoramp_open', 1]";
|
|
||||||
};
|
|
||||||
class CargoRamp_Close: DoorL1_Close {
|
|
||||||
userActionID = 55;
|
|
||||||
displayName = CSTRING(CloseCargoRamp);
|
|
||||||
textToolTip = CSTRING(CloseCargoRamp);
|
|
||||||
position = "action_cargoramp";
|
|
||||||
radius = 3.0;
|
|
||||||
condition = "this animationPhase ""cargoramp_open"" > 0.5 AND Alive(this)";
|
|
||||||
statement = "this animateDoor ['cargoramp_open', 0]";
|
|
||||||
};
|
|
||||||
};*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Heli_light_03_base_F: Helicopter_Base_F {};
|
class Heli_light_03_base_F: Helicopter_Base_F {
|
||||||
class I_Heli_light_03_base_F: Heli_light_03_base_F {
|
lockDetectionSystem = 0; // Vanilla: 12
|
||||||
lockDetectionSystem = 0;
|
incomingMissileDetectionSystem = 16; // Vanilla: 24
|
||||||
incomingMissileDetectionSystem = 16;
|
|
||||||
driverCanEject = 1;
|
|
||||||
weapons[] = {"M134_minigun","missiles_DAR","CMFlareLauncher", "ACE_AIR_SAFETY" };
|
|
||||||
magazines[] = {"5000Rnd_762x51_Yellow_Belt","24Rnd_missiles","168Rnd_CMFlare_Chaff_Magazine"};
|
|
||||||
|
|
||||||
class Turrets: Turrets {
|
class Turrets: Turrets {
|
||||||
class MainTurret: MainTurret {
|
class MainTurret: MainTurret {
|
||||||
canEject = 1;
|
|
||||||
showHMD = 1;
|
showHMD = 1;
|
||||||
gunBeg = "commanderview";
|
weapons[] = {"Laserdesignator_mounted"}; // Add Laser Designator
|
||||||
gunEnd = "laserstart";
|
|
||||||
memoryPointGun = "laserstart";
|
|
||||||
stabilizedInAxes = 3;
|
|
||||||
weapons[] = {"Laserdesignator_mounted"};
|
|
||||||
soundServo[] = {"",0.01,1,30};
|
|
||||||
magazines[] = {"Laserbatteries"};
|
magazines[] = {"Laserbatteries"};
|
||||||
inGunnerMayFire = 1;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class I_Heli_light_03_F: Heli_light_03_base_F {
|
|
||||||
class Turrets: Turrets {
|
|
||||||
class MainTurret: MainTurret {};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Heli_light_03_unarmed_base_F: Heli_light_03_base_F {};
|
|
||||||
|
|
||||||
class I_Heli_light_03_unarmed_F: Heli_light_03_unarmed_base_F {};
|
|
||||||
|
|
||||||
class Plane_CAS_01_base_F: Plane_Base_F {
|
class Plane_CAS_01_base_F: Plane_Base_F {
|
||||||
lockDetectionSystem = 12;
|
lockDetectionSystem = 12; // Vanilla: 8
|
||||||
incomingMissileDetectionSystem = 16;
|
incomingMissileDetectionSystem = 16; // Vanilla: 24
|
||||||
|
|
||||||
class Turrets;
|
|
||||||
|
|
||||||
#include <flightmodel_thunderbolt.hpp>
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Plane_CAS_02_base_F: Plane_Base_F {
|
class Plane_CAS_02_base_F: Plane_Base_F {
|
||||||
lockDetectionSystem = 12;
|
lockDetectionSystem = 12; // Vanilla: 8
|
||||||
incomingMissileDetectionSystem = 16;
|
incomingMissileDetectionSystem = 16; // Vanilla: 24
|
||||||
|
|
||||||
class Turrets;
|
|
||||||
|
|
||||||
#include <flightmodel_yak.hpp>
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Plane_Fighter_03_base_F: Plane_Base_F {
|
class Plane_Fighter_03_base_F: Plane_Base_F {
|
||||||
lockDetectionSystem = 12;
|
lockDetectionSystem = 12; // Vanilla: 8
|
||||||
incomingMissileDetectionSystem = 16;
|
incomingMissileDetectionSystem = 16; // Vanilla: 24
|
||||||
|
|
||||||
class Turrets;
|
|
||||||
|
|
||||||
#include <flightmodel_alca.hpp>
|
|
||||||
};
|
|
||||||
|
|
||||||
class UAV_01_base_F: Helicopter_Base_F {
|
|
||||||
/*class Turrets: Turrets {
|
|
||||||
class MainTurret: MainTurret {};
|
|
||||||
};*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class UAV_02_base_F: UAV {
|
class UAV_02_base_F: UAV {
|
||||||
weapons[] = {};
|
weapons[] = {}; // Remove flare launcher
|
||||||
magazines[] = {};
|
magazines[] = {};
|
||||||
|
|
||||||
class Turrets {
|
|
||||||
class MainTurret;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class UAV_02_CAS_base_F: UAV_02_base_F {
|
class UAV_02_CAS_base_F: UAV_02_base_F {
|
||||||
weapons[] = {};
|
weapons[] = {}; // Remove flare launcher
|
||||||
magazines[] = {};
|
magazines[] = {};
|
||||||
|
|
||||||
/*class Turrets: Turrets {
|
|
||||||
class MainTurret: MainTurret {};
|
|
||||||
};*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Heli_Transport_03_base_F: Helicopter_Base_H {};
|
class Heli_Transport_03_base_F: Helicopter_Base_H {
|
||||||
class B_Heli_Transport_03_base_F: Heli_Transport_03_base_F {
|
incomingMissileDetectionSystem = 16; // Vanilla: 24
|
||||||
lockDetectionSystem = 12;
|
|
||||||
incomingMissileDetectionSystem = 16;
|
|
||||||
driverCanEject = 1;
|
|
||||||
|
|
||||||
class Turrets: Turrets {
|
|
||||||
class CopilotTurret: CopilotTurret {
|
|
||||||
canEject = 1;
|
|
||||||
};
|
};
|
||||||
//class MainTurret: MainTurret {};
|
|
||||||
class RightDoorGun: MainTurret {};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class B_Heli_Transport_03_unarmed_base_F: Heli_Transport_03_base_F {
|
|
||||||
class Turrets: Turrets {
|
|
||||||
class CopilotTurret: CopilotTurret {
|
|
||||||
canEject = 1;
|
|
||||||
};
|
|
||||||
//class MainTurret: MainTurret {};
|
|
||||||
//class RightDoorGun: MainTurret {};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Heli_Transport_04_base_F: Helicopter_Base_H {
|
class Heli_Transport_04_base_F: Helicopter_Base_H {
|
||||||
lockDetectionSystem = 12;
|
incomingMissileDetectionSystem = 16; // Vanilla: 24
|
||||||
incomingMissileDetectionSystem = 16;
|
|
||||||
driverCanEject = 1;
|
|
||||||
|
|
||||||
class Turrets: Turrets {
|
|
||||||
class CopilotTurret: CopilotTurret {
|
|
||||||
canEject = 1;
|
|
||||||
};
|
|
||||||
class LoadmasterTurret: MainTurret {
|
|
||||||
canEject = 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class O_Heli_Transport_04_bench_F: Heli_Transport_04_base_F {
|
|
||||||
class Turrets: Turrets {
|
|
||||||
class CopilotTurret: CopilotTurret {
|
|
||||||
canEject = 1;
|
|
||||||
};
|
|
||||||
class LoadmasterTurret: LoadmasterTurret {
|
|
||||||
canEject = 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class O_Heli_Transport_04_covered_F: Heli_Transport_04_base_F {
|
|
||||||
class Turrets: Turrets {
|
|
||||||
class CopilotTurret: CopilotTurret {
|
|
||||||
canEject = 1;
|
|
||||||
};
|
|
||||||
class LoadmasterTurret: LoadmasterTurret {
|
|
||||||
canEject = 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user