mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'FF/Ops' into FF/OpsDev
This commit is contained in:
@@ -1,87 +0,0 @@
|
||||
version: 2.4.a.{build}
|
||||
shallow_clone: true
|
||||
skip_branch_with_pr: false
|
||||
skip_commits:
|
||||
message: /!nobuild/
|
||||
skip_tags: false
|
||||
|
||||
environment:
|
||||
access_token_documentation:
|
||||
secure: JVBVVL8uJUcLXN+48eRdELEeCGOGCCaMzCqutsUqNuaZ/KblG5ZTt7+LV4UKv/0f
|
||||
LUAROCKS_VER: 2.4.1
|
||||
LUA_VER: 5.1.5
|
||||
LUA: lua5.3
|
||||
matrix:
|
||||
- LUA_VER: 5.1.5
|
||||
|
||||
platform:
|
||||
- x64
|
||||
|
||||
|
||||
init:
|
||||
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
|
||||
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
|
||||
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
|
||||
throw "There are newer queued builds for this pull request, failing early." }
|
||||
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
|
||||
install:
|
||||
- cmd:
|
||||
# Outcomment if lua environment invalidates and needs to be reinstalled, otherwise all will run from the cache.
|
||||
call choco install 7zip.commandline
|
||||
call choco install lua51
|
||||
call choco install luarocks
|
||||
call refreshenv
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
|
||||
cmd: PATH = %PATH%;C:\ProgramData\chocolatey\lib\luarocks\luarocks-2.4.3-win32\systree\bin
|
||||
cmd: set LUA_PATH = %LUA_PATH%;C:\ProgramData\chocolatey\lib\luarocks\luarocks-2.4.3-win32\systree\share\lua\5.1\?.lua;C:\ProgramData\chocolatey\lib\luarocks\luarocks-2.4.3-win32\systree\share\lua\5.1\?\init.lua
|
||||
cmd: set LUA_CPATH = %LUA_CPATH%;C:\ProgramData\chocolatey\lib\luarocks\luarocks-2.4.3-win32\systree\lib\lua\5.1\?.dll
|
||||
call luarocks install luasrcdiet
|
||||
call luarocks install checks
|
||||
call luarocks install luadocumentor
|
||||
call luarocks install luacheck
|
||||
|
||||
|
||||
cache:
|
||||
C:\ProgramData\chocolatey\lib
|
||||
C:\ProgramData\chocolatey\bin
|
||||
|
||||
|
||||
|
||||
build_script:
|
||||
- ps: |
|
||||
if( $env:appveyor_repo_branch -eq 'master' -or $env:appveyor_repo_branch -eq 'develop' )
|
||||
{
|
||||
echo "Hello World!"
|
||||
$apiUrl = 'https://ci.appveyor.com/api'
|
||||
$token = 'v2.6hcv3ige78kg3yvg4ge8'
|
||||
$headers = @{
|
||||
"Authorization" = "Bearer $token"
|
||||
"Content-type" = "application/json"
|
||||
}
|
||||
$RequestBody = @{ accountName = 'FlightControl-Master'; projectSlug = 'moose-include'; branch = "$env:appveyor_repo_branch"; environmentVariables = @{} } | ConvertTo-Json
|
||||
# Generate the new version ...
|
||||
$project = Invoke-RestMethod -method Post -Uri "$apiUrl/builds" -Headers $headers -Body $RequestBody
|
||||
}
|
||||
- ps: |
|
||||
if( $env:appveyor_repo_branch -eq 'master' -or $env:appveyor_repo_branch -eq 'develop' )
|
||||
{
|
||||
$apiUrl = 'https://ci.appveyor.com/api'
|
||||
$token = 'v2.6hcv3ige78kg3yvg4ge8'
|
||||
$headers = @{
|
||||
"Authorization" = "Bearer $token"
|
||||
"Content-type" = "application/json"
|
||||
}
|
||||
$RequestBody = @{ accountName = 'FlightControl-Master'; projectSlug = 'moose-docs'; branch = "$env:appveyor_repo_branch"; environmentVariables = @{} } | ConvertTo-Json
|
||||
# get project with last build details
|
||||
$project = Invoke-RestMethod -method Post -Uri "$apiUrl/builds" -Headers $headers -Body $RequestBody
|
||||
}
|
||||
|
||||
|
||||
test: off
|
||||
# test_script:
|
||||
# - cmd: luacheck "Moose Development\Moose\moose.lua" "Moose Mission Setup\moose.lua"
|
||||
|
||||
|
||||
on_finish:
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
4
.gitattributes
vendored
4
.gitattributes
vendored
@@ -15,3 +15,7 @@
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
|
||||
# Avoid Windows line endings on shell scripts
|
||||
# Needed for dockerfile builds
|
||||
*.sh text eol=lf
|
||||
|
||||
168
.github/workflows/build-docs.yml
vendored
Normal file
168
.github/workflows/build-docs.yml
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
name: Moose-Docs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
paths:
|
||||
- 'Moose Setup/**/*.lua'
|
||||
- 'Moose Development/**/*.lua'
|
||||
- 'Moose Development/**/*.py'
|
||||
- 'Moose Development/**/*.html'
|
||||
- '.github/workflows/build-docs.yml'
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
Build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Extract branch name
|
||||
shell: bash
|
||||
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
|
||||
id: extract_branch
|
||||
|
||||
- name: Build informations
|
||||
run: |
|
||||
echo "Triggered by: ${{ github.event_name }}"
|
||||
echo "Running on: ${{ runner.os }}"
|
||||
echo "Ref: ${{ github.ref }}"
|
||||
echo "Branch name: ${{ steps.extract_branch.outputs.branch }}"
|
||||
echo "Repository: ${{ github.repository }}"
|
||||
echo "Commit-Id: ${{ github.sha }}"
|
||||
echo "Owner: ${{ github.repository_owner }}"
|
||||
echo "FORCE_PUSH: ${{ vars.FORCE_PUSH }}"
|
||||
|
||||
#########################################################################
|
||||
# Prepare build environment
|
||||
#########################################################################
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Prepare build output folders
|
||||
run: |
|
||||
mkdir -p build/tools
|
||||
mkdir -p build/doc
|
||||
|
||||
- name: Checkout FlightControls modified luadocumentor
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: Applevangelist/luadocumentor
|
||||
path: './build/tools/luadocumentor'
|
||||
ref: 'patch-1'
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
|
||||
- name: Update apt-get (needed for act docker image)
|
||||
run: |
|
||||
sudo apt-get -qq update
|
||||
|
||||
- name: Install tree
|
||||
run: |
|
||||
sudo apt-get -qq install tree
|
||||
|
||||
#########################################################################
|
||||
# Install all prerequisites for LuaDocumentor
|
||||
#########################################################################
|
||||
- name: Install Lua
|
||||
run: |
|
||||
sudo apt-get -qq install lua5.1
|
||||
|
||||
- name: Install LuaRocks
|
||||
run: |
|
||||
sudo apt-get -qq install luarocks -y
|
||||
|
||||
- name: Install markdown (prereq for LuaDocumentor)
|
||||
run: |
|
||||
sudo luarocks install markdown 0.32-2
|
||||
|
||||
- name: Install penlight (prereq for LuaDocumentor)
|
||||
run: |
|
||||
sudo luarocks install penlight 1.11.0-1
|
||||
|
||||
- name: Install metalua-compiler (prereq for LuaDocumentor)
|
||||
run: |
|
||||
sudo luarocks install metalua-compiler 0.7.3-1
|
||||
|
||||
- name: Install metalua-parser (prereq for LuaDocumentor)
|
||||
run: |
|
||||
sudo luarocks install metalua-parser 0.7.3-2
|
||||
|
||||
- name: Install checks (prereq for LuaDocumentor)
|
||||
run: |
|
||||
sudo luarocks install checks
|
||||
|
||||
#########################################################################
|
||||
# Run LuaDocumentor
|
||||
#########################################################################
|
||||
- name: Run LuaDocumentor
|
||||
run: |
|
||||
lua luadocumentor.lua -d ${{ github.workspace }}/build/doc "${{ github.workspace }}/Moose Development/Moose"
|
||||
working-directory: ${{ github.workspace }}/build/tools/luadocumentor
|
||||
|
||||
#########################################################################
|
||||
# Replace <head> tag
|
||||
#########################################################################
|
||||
- name: Replace head tag
|
||||
run: |
|
||||
python3 "${{ github.workspace }}/Moose Development/docs-header.py"
|
||||
working-directory: ${{ github.workspace }}/build/doc
|
||||
|
||||
- name: Check replacement of head tag
|
||||
run: |
|
||||
head -10 ${{ github.workspace }}/build/doc/AI.AI_A2A_Cap.html
|
||||
|
||||
#########################################################################
|
||||
# Push to MOOSE_DOCS
|
||||
#########################################################################
|
||||
- name: Set docs repo for branch
|
||||
shell: bash
|
||||
id: set_doc_repo
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/heads/master' ]]; then
|
||||
echo "docrepo=MOOSE_DOCS" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "docrepo=MOOSE_DOCS_DEVELOP" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Checkout ${{ steps.set_doc_repo.outputs.docrepo }} to folder MOOSE_DOCS
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ github.repository_owner }}/${{ steps.set_doc_repo.outputs.docrepo }}
|
||||
path: './build/MOOSE_DOCS'
|
||||
fetch-depth: 0
|
||||
ref: 'master'
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
|
||||
- name: Delete folder to remove deleted files
|
||||
run: |
|
||||
rm -rf ./build/MOOSE_DOCS/Documentation/
|
||||
|
||||
- name: Create target folder
|
||||
run: mkdir -p build/MOOSE_DOCS/Documentation
|
||||
|
||||
- name: Copy build result to MOOSE_DOCS
|
||||
run: |
|
||||
cp ./build/doc/*.* ./build/MOOSE_DOCS/Documentation/
|
||||
|
||||
- name: Push result to docs repository
|
||||
if: ${{ vars.FORCE_PUSH == 'true' }}
|
||||
run: |
|
||||
git config user.name "MooseBotter"
|
||||
git config user.email "MooseBotter@users.noreply.github.com"
|
||||
git add .
|
||||
git commit --allow-empty -m "Auto commit by GitHub Actions Workflow"
|
||||
git push --set-upstream origin master
|
||||
|
||||
working-directory: ${{ github.workspace }}/build/MOOSE_DOCS
|
||||
|
||||
#########################################################################
|
||||
# Show the results
|
||||
#########################################################################
|
||||
- name: List files in the repository
|
||||
run: |
|
||||
tree ${{ github.workspace }}/build
|
||||
|
||||
- run: echo "This job's status is ${{ job.status }}."
|
||||
148
.github/workflows/build-includes.yml
vendored
Normal file
148
.github/workflows/build-includes.yml
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
name: Moose-Includes
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
paths:
|
||||
- 'Moose Setup/**/*.lua'
|
||||
- 'Moose Development/**/*.lua'
|
||||
- '.github/workflows/build-includes.yml'
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
Build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Extract branch name
|
||||
shell: bash
|
||||
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
|
||||
id: extract_branch
|
||||
|
||||
- name: Build informations
|
||||
run: |
|
||||
echo "Triggered by: ${{ github.event_name }}"
|
||||
echo "Running on: ${{ runner.os }}"
|
||||
echo "Ref: ${{ github.ref }}"
|
||||
echo "Branch name: ${{ steps.extract_branch.outputs.branch }}"
|
||||
echo "Repository: ${{ github.repository }}"
|
||||
echo "Commit-Id: ${{ github.sha }}"
|
||||
echo "Owner: ${{ github.repository_owner }}"
|
||||
echo "FORCE_PUSH: ${{ vars.FORCE_PUSH }}"
|
||||
|
||||
#########################################################################
|
||||
# Prepare build environment
|
||||
#########################################################################
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Prepare build output folders
|
||||
run: |
|
||||
mkdir -p build/result/Moose_Include_Dynamic
|
||||
mkdir -p build/result/Moose_Include_Static
|
||||
|
||||
- name: Update apt-get (needed for act docker image)
|
||||
run: |
|
||||
sudo apt-get -qq update
|
||||
|
||||
- name: Install tree
|
||||
run: |
|
||||
sudo apt-get -qq install tree
|
||||
|
||||
#########################################################################
|
||||
# Install all prerequisites
|
||||
#########################################################################
|
||||
- name: Install Lua 5.3
|
||||
run: |
|
||||
sudo apt-get -qq install lua5.3 -y
|
||||
- name: Check Lua version
|
||||
run: |
|
||||
lua -v
|
||||
|
||||
- name: Install LuaRocks
|
||||
run: |
|
||||
sudo apt-get -qq install luarocks -y
|
||||
- name: Check LuaRocks version
|
||||
run: |
|
||||
luarocks --version
|
||||
|
||||
- name: Install Lua 5.3 Dev for prerequisites for LuaSrcDiet
|
||||
run: |
|
||||
sudo apt-get -qq install liblua5.3-dev -y
|
||||
|
||||
- name: Install LuaSrcDiet
|
||||
run: |
|
||||
sudo luarocks install luasrcdiet
|
||||
|
||||
- name: Install LuaCheck
|
||||
run: |
|
||||
sudo luarocks install luacheck
|
||||
|
||||
#########################################################################
|
||||
# Build Include files
|
||||
#########################################################################
|
||||
- name: Build Include Static
|
||||
run: |
|
||||
export COMMIT_TIME=$(git show -s --format=%cd ${{ github.sha }} --date=iso-strict)
|
||||
lua5.3 "./Moose Setup/Moose_Create.lua" S "$COMMIT_TIME-${{ github.sha }}" "./Moose Development/Moose" "./Moose Setup" "./build/result/Moose_Include_Static"
|
||||
|
||||
- name: Build Includes Dynamic
|
||||
run: |
|
||||
export COMMIT_TIME=$(git show -s --format=%cd ${{ github.sha }} --date=iso-strict)
|
||||
lua5.3 "./Moose Setup/Moose_Create.lua" D "$COMMIT_TIME-${{ github.sha }}" "./Moose Development/Moose" "./Moose Setup" "./build/result/Moose_Include_Dynamic"
|
||||
|
||||
- name: Run LuaSrcDiet
|
||||
run: |
|
||||
luasrcdiet --basic --opt-emptylines ./build/result/Moose_Include_Static/Moose.lua -o ./build/result/Moose_Include_Static/Moose_.lua
|
||||
|
||||
#########################################################################
|
||||
# Run LuaCheck
|
||||
#########################################################################
|
||||
- name: Run LuaCheck
|
||||
if: ${{ vars.SKIP_LUACHECK != true }}
|
||||
continue-on-error: true
|
||||
run: |
|
||||
luacheck --std=lua51c --config=.luacheckrc -gurasqq "Moose Development/Moose"
|
||||
|
||||
#########################################################################
|
||||
# Push to MOOSE_INCLUDE
|
||||
#########################################################################
|
||||
- name: Checkout MOOSE_INCLUDE
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ github.repository_owner }}/MOOSE_INCLUDE
|
||||
path: './build/MOOSE_INCLUDE'
|
||||
fetch-depth: 0
|
||||
ref: ${{ steps.extract_branch.outputs.branch }}
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
|
||||
- name: Create target folder (needed if checkout is deactivated)
|
||||
run: mkdir -p build/MOOSE_INCLUDE
|
||||
|
||||
- name: Copy build reseult to MOOSE_INCLUDE
|
||||
run: |
|
||||
cp -r ./build/result/* ./build/MOOSE_INCLUDE/
|
||||
|
||||
- name: Push result to MOOSE_INCLUDE repository
|
||||
if: ${{ vars.FORCE_PUSH == 'true' }}
|
||||
run: |
|
||||
git config user.name "MooseBotter"
|
||||
git config user.email "MooseBotter@users.noreply.github.com"
|
||||
git add .
|
||||
git commit --allow-empty -m "Auto commit by GitHub Actions Workflow"
|
||||
git push --set-upstream origin ${{ steps.extract_branch.outputs.branch }}
|
||||
|
||||
working-directory: ${{ github.workspace }}/build/MOOSE_INCLUDE
|
||||
|
||||
#########################################################################
|
||||
# Show the results
|
||||
#########################################################################
|
||||
- name: List files in the repository
|
||||
run: |
|
||||
tree ${{ github.workspace }}/build
|
||||
|
||||
- run: echo "This job's status is ${{ job.status }}."
|
||||
78
.github/workflows/gh-pages.yml
vendored
Normal file
78
.github/workflows/gh-pages.yml
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
|
||||
# Sample workflow for building and deploying a Jekyll site to GitHub Pages
|
||||
name: Deploy Jekyll site to Pages
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["master"]
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- '.github/workflows/pages.yml'
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow one concurrent deployment
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# Build job
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: '3.1' # Not needed with a .ruby-version file
|
||||
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
||||
cache-version: 0 # Increment this number if you need to re-download cached gems
|
||||
working-directory: docs/
|
||||
- name: Setup Pages
|
||||
id: pages
|
||||
uses: actions/configure-pages@v3
|
||||
- name: Build with Jekyll
|
||||
# Outputs to the './_site' directory by default
|
||||
run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}"
|
||||
env:
|
||||
JEKYLL_ENV: production
|
||||
working-directory: docs/
|
||||
- name: Upload artifact
|
||||
# Automatically uploads an artifact from the './_site' directory by default
|
||||
uses: actions/upload-pages-artifact@v1
|
||||
with:
|
||||
path: docs/_site/
|
||||
|
||||
# Deployment job
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v1
|
||||
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
needs: deploy
|
||||
steps:
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
- run: npm install linkinator
|
||||
- run: npx linkinator https://flightcontrol-master.github.io/MOOSE/ --recurse
|
||||
11
.gitignore
vendored
11
.gitignore
vendored
@@ -227,11 +227,12 @@ pip-log.txt
|
||||
_gsdata_/
|
||||
|
||||
#GITHUB
|
||||
.gitattributes
|
||||
.gitignore
|
||||
Moose Test Missions/MOOSE_Test_Template.miz
|
||||
Moose Development/Moose/.vscode/launch.json
|
||||
MooseCodeWS.code-workspace
|
||||
.gitignore
|
||||
.gitignore
|
||||
/.gitignore
|
||||
|
||||
# Excludes for act (https://github.com/nektos/act)
|
||||
.secrets
|
||||
.env
|
||||
.actrc
|
||||
.vars
|
||||
|
||||
@@ -91,12 +91,12 @@
|
||||
-- An optional @{Core.Zone} can be set,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- Use the method @{#AI_A2A_CAP.SetEngageZone}() to define that Zone.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_A2A_CAP
|
||||
@@ -123,7 +123,7 @@ function AI_A2A_CAP:New2( AICap, EngageMinSpeed, EngageMaxSpeed, EngageFloorAlti
|
||||
|
||||
-- Multiple inheritance ... :-)
|
||||
local AI_Air = AI_AIR:New( AICap )
|
||||
local AI_Air_Patrol = AI_AIR_PATROL:New( AI_Air, AICap, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) -- #AI_AIR_PATROL
|
||||
local AI_Air_Patrol = AI_AIR_PATROL:New( AI_Air, AICap, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||
local AI_Air_Engage = AI_AIR_ENGAGE:New( AI_Air_Patrol, AICap, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, EngageAltType )
|
||||
local self = BASE:Inherit( self, AI_Air_Engage ) --#AI_A2A_CAP
|
||||
|
||||
|
||||
@@ -176,12 +176,12 @@
|
||||
-- Per one, two, three, four?
|
||||
--
|
||||
-- **The default grouping is 1. That means, that each spawned defender will act individually.**
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Authors: **FlightControl** rework of GCICAP + introduction of new concepts (squadrons).
|
||||
@@ -310,7 +310,7 @@ do -- AI_A2A_DISPATCHER
|
||||
-- Use the method @{#AI_A2A_DISPATCHER.SetEngageRadius}() to set a specific Engage Radius.
|
||||
-- **The Engage Radius is defined for ALL squadrons which are operational.**
|
||||
--
|
||||
-- Demonstration Mission: [AID-019 - AI_A2A - Engage Range Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/release-2-2-pre/AID%20-%20AI%20Dispatching/AID-019%20-%20AI_A2A%20-%20Engage%20Range%20Test)
|
||||
-- Demonstration Mission: [AID-019 - AI_A2A - Engage Range Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-A2A%20-%20AI%20A2A%20Dispatching/AID-A2A-019%20-%20Engage%20Range%20Test)
|
||||
--
|
||||
-- In this example an Engage Radius is set to various values.
|
||||
--
|
||||
@@ -333,7 +333,7 @@ do -- AI_A2A_DISPATCHER
|
||||
-- Use the method @{#AI_A2A_DISPATCHER.SetGciRadius}() to set a specific controlled ground intercept radius.
|
||||
-- **The Ground Controlled Intercept radius is defined for ALL squadrons which are operational.**
|
||||
--
|
||||
-- Demonstration Mission: [AID-013 - AI_A2A - Intercept Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/release-2-2-pre/AID%20-%20AI%20Dispatching/AID-013%20-%20AI_A2A%20-%20Intercept%20Test)
|
||||
-- Demonstration Mission: [AID-013 - AI_A2A - Intercept Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-A2A%20-%20AI%20A2A%20Dispatching/AID-A2A-013%20-%20Intercept%20Test)
|
||||
--
|
||||
-- In these examples, the Gci Radius is set to various values:
|
||||
--
|
||||
@@ -366,7 +366,7 @@ do -- AI_A2A_DISPATCHER
|
||||
-- it makes it easier sometimes for the mission maker to envisage where the red and blue territories roughly are.
|
||||
-- In a hot war the borders are effectively defined by the ground based radar coverage of a coalition.
|
||||
--
|
||||
-- Demonstration Mission: [AID-009 - AI_A2A - Border Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/release-2-2-pre/AID%20-%20AI%20Dispatching/AID-009 - AI_A2A - Border Test)
|
||||
-- Demonstration Mission: [AID-009 - AI_A2A - Border Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-A2A%20-%20AI%20A2A%20Dispatching/AID-A2A-009%20-%20Border%20Test)
|
||||
--
|
||||
-- In this example a border is set for the CCCP A2A dispatcher:
|
||||
--
|
||||
@@ -1233,7 +1233,7 @@ do -- AI_A2A_DISPATCHER
|
||||
--
|
||||
-- **Use the method @{#AI_A2A_DISPATCHER.SetEngageRadius}() to modify the default Engage Radius for ALL squadrons.**
|
||||
--
|
||||
-- Demonstration Mission: [AID-019 - AI_A2A - Engage Range Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/release-2-2-pre/AID%20-%20AI%20Dispatching/AID-019%20-%20AI_A2A%20-%20Engage%20Range%20Test)
|
||||
-- Demonstration Mission: [AID-019 - AI_A2A - Engage Range Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-A2A%20-%20AI%20A2A%20Dispatching/AID-A2A-019%20-%20Engage%20Range%20Test)
|
||||
--
|
||||
-- @param #AI_A2A_DISPATCHER self
|
||||
-- @param #number EngageRadius (Optional, Default = 100000) The radius to report friendlies near the target.
|
||||
@@ -1283,7 +1283,7 @@ do -- AI_A2A_DISPATCHER
|
||||
-- Use the method @{#AI_A2A_DISPATCHER.SetGciRadius}() to set a specific controlled ground intercept radius.
|
||||
-- **The Ground Controlled Intercept radius is defined for ALL squadrons which are operational.**
|
||||
--
|
||||
-- Demonstration Mission: [AID-013 - AI_A2A - Intercept Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/release-2-2-pre/AID%20-%20AI%20Dispatching/AID-013%20-%20AI_A2A%20-%20Intercept%20Test)
|
||||
-- Demonstration Mission: [AID-013 - AI_A2A - Intercept Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-A2A%20-%20AI%20A2A%20Dispatching/AID-A2A-013%20-%20Intercept%20Test)
|
||||
--
|
||||
-- @param #AI_A2A_DISPATCHER self
|
||||
-- @param #number GciRadius (Optional, Default = 200000) The radius to ground control intercept detected targets from the nearest airbase.
|
||||
|
||||
@@ -14,47 +14,31 @@
|
||||
|
||||
|
||||
--- @type AI_A2A_GCI
|
||||
-- @extends AI.AI_A2A#AI_A2A
|
||||
-- @extends AI.AI_Air_Engage#AI_AIR_ENGAGE
|
||||
|
||||
|
||||
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI_A2A_GCI is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_GCI process can be started using the **Start** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||
-- Upon arrival at the 3D point, a new random 3D point will be selected within the patrol zone using the given limits.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- This cycle will continue.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- During the patrol, the AI will detect enemy targets, which are reported through the **Detected** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- When enemies are detected, the AI will automatically engage the enemy.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- Until a fuel or damage threshold has been reached by the AI, or when the AI is commanded to RTB.
|
||||
-- When the fuel threshold has been reached, the airplane will fly towards the nearest friendly airbase and will land.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ## 1. AI_A2A_GCI constructor
|
||||
--
|
||||
-- * @{#AI_A2A_GCI.New}(): Creates a new AI_A2A_GCI object.
|
||||
--
|
||||
-- ## 2. AI_A2A_GCI is a FSM
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ### 2.1 AI_A2A_GCI States
|
||||
--
|
||||
-- * **None** ( Group ): The process is not started yet.
|
||||
@@ -77,27 +61,16 @@
|
||||
--
|
||||
-- ## 3. Set the Range of Engagement
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- An optional range can be set in meters,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- The range can be beyond or smaller than the range of the Patrol Zone.
|
||||
-- The range is applied at the position of the AI.
|
||||
-- Use the method @{AI.AI_GCI#AI_A2A_GCI.SetEngageRange}() to define that range.
|
||||
--
|
||||
-- ## 4. Set the Zone of Engagement
|
||||
-- # Developer Note
|
||||
--
|
||||
-- 
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- An optional @{Core.Zone} can be set,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- Use the method @{AI.AI_CAP#AI_CAP_ZONE.SetEngageZone}() to define that Zone.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_A2A_GCI
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
|
||||
--- @type AI_A2A_PATROL
|
||||
-- @extends AI.AI_A2A#AI_A2A
|
||||
-- @extends AI.AI_Air_Patrol#AI_AIR_PATROL
|
||||
|
||||
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group} or @{Wrapper.Group}.
|
||||
--
|
||||
@@ -111,12 +111,12 @@
|
||||
-- When the AI is damaged, it is required that a new Patrol is started. However, damage cannon be foreseen early on.
|
||||
-- Therefore, when the damage threshold is reached, the AI will return immediately to the home base (RTB).
|
||||
-- Use the method @{#AI_A2A_PATROL.ManageDamage}() to have this proces in place.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_A2A_PATROL
|
||||
|
||||
@@ -12,15 +12,16 @@
|
||||
-- @image AI_Air_To_Ground_Engage.JPG
|
||||
|
||||
--- @type AI_A2G_BAI
|
||||
-- @extends AI.AI_A2A_Engage#AI_A2A_Engage -- TODO: Documentation. This class does not exist, unable to determine what it extends.
|
||||
-- @extends AI.AI_Air_Patrol#AI_AIR_PATROL
|
||||
-- @extends AI.AI_Air_Engage#AI_AIR_ENGAGE
|
||||
|
||||
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_A2G_BAI
|
||||
@@ -46,7 +47,7 @@ AI_A2G_BAI = {
|
||||
function AI_A2G_BAI:New2( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, EngageAltType, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||
|
||||
local AI_Air = AI_AIR:New( AIGroup )
|
||||
local AI_Air_Patrol = AI_AIR_PATROL:New( AI_Air, AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) -- #AI_AIR_PATROL
|
||||
local AI_Air_Patrol = AI_AIR_PATROL:New( AI_Air, AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||
local AI_Air_Engage = AI_AIR_ENGAGE:New( AI_Air_Patrol, AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, EngageAltType )
|
||||
local self = BASE:Inherit( self, AI_Air_Engage )
|
||||
|
||||
|
||||
@@ -12,15 +12,16 @@
|
||||
-- @image AI_Air_To_Ground_Engage.JPG
|
||||
|
||||
--- @type AI_A2G_CAS
|
||||
-- @extends AI.AI_A2G_Patrol#AI_AIR_PATROL TODO: Documentation. This class does not exist, unable to determine what it extends.
|
||||
-- @extends AI.AI_Air_Patrol#AI_AIR_PATROL
|
||||
-- @extends AI.AI_Air_Engage#AI_AIR_ENGAGE
|
||||
|
||||
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_A2G_CAS
|
||||
@@ -46,7 +47,7 @@ AI_A2G_CAS = {
|
||||
function AI_A2G_CAS:New2( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, EngageAltType, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||
|
||||
local AI_Air = AI_AIR:New( AIGroup )
|
||||
local AI_Air_Patrol = AI_AIR_PATROL:New( AI_Air, AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) -- #AI_AIR_PATROL
|
||||
local AI_Air_Patrol = AI_AIR_PATROL:New( AI_Air, AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||
local AI_Air_Engage = AI_AIR_ENGAGE:New( AI_Air_Patrol, AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, EngageAltType )
|
||||
local self = BASE:Inherit( self, AI_Air_Engage )
|
||||
|
||||
|
||||
@@ -253,12 +253,12 @@
|
||||
--
|
||||
-- **The default grouping is 1. That means, that each spawned defender will act individually.**
|
||||
-- But you can specify a number between 1 and 4, so that the defenders will act as a group.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **FlightControl** rework of GCICAP + introduction of new concepts (squadrons).
|
||||
@@ -296,8 +296,6 @@ do -- AI_A2G_DISPATCHER
|
||||
--
|
||||
-- ## 1. AI\_A2G\_DISPATCHER constructor:
|
||||
--
|
||||
-- 
|
||||
--
|
||||
--
|
||||
-- The @{#AI_A2G_DISPATCHER.New}() method creates a new AI_A2G_DISPATCHER instance.
|
||||
--
|
||||
@@ -311,8 +309,6 @@ do -- AI_A2G_DISPATCHER
|
||||
-- A reconnaissance network, is used to detect enemy ground targets,
|
||||
-- potentially group them into areas, and to understand the position, level of threat of the enemy.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- As explained in the introduction, depending on the type of mission you want to achieve, different types of units can be applied to detect ground enemy targets.
|
||||
-- Ground based units are very useful to act as a reconnaissance, but they lack sometimes the visibility to detect targets at greater range.
|
||||
-- Recce are very useful to acquire the position of enemy ground targets when spread out over the battlefield at strategic positions.
|
||||
@@ -686,8 +682,6 @@ do -- AI_A2G_DISPATCHER
|
||||
--
|
||||
-- Use the method @{#AI_A2G_DISPATCHER.SetSquadronGrouping}() to set the grouping of aircraft when spawned in.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- In the case of **on call** engagement, the @{#AI_A2G_DISPATCHER.SetSquadronGrouping}() method has additional behaviour.
|
||||
-- When there aren't enough patrol flights airborne, a on call will be initiated for the remaining
|
||||
-- targets to be engaged. Depending on the grouping parameter, the spawned flights for on call aircraft are grouped into this setting.
|
||||
@@ -701,8 +695,6 @@ do -- AI_A2G_DISPATCHER
|
||||
-- The effectiveness can be set with the **overhead parameter**. This is a number that is used to calculate the amount of Units that dispatching command will allocate to GCI in surplus of detected amount of units.
|
||||
-- The **default value** of the overhead parameter is 1.0, which means **equal balance**.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- However, depending on the (type of) aircraft (strength and payload) in the squadron and the amount of resources available, this parameter can be changed.
|
||||
--
|
||||
-- The @{#AI_A2G_DISPATCHER.SetSquadronOverhead}() method can be used to tweak the defense strength,
|
||||
@@ -848,8 +840,6 @@ do -- AI_A2G_DISPATCHER
|
||||
--
|
||||
-- For example, the following setup will set the default refuel tanker to "Tanker":
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- -- Set the default tanker for refuelling to "Tanker", when the default fuel threshold has reached 90% fuel left.
|
||||
-- A2GDispatcher:SetDefaultFuelThreshold( 0.9 )
|
||||
-- A2GDispatcher:SetDefaultTanker( "Tanker" )
|
||||
|
||||
@@ -14,66 +14,42 @@
|
||||
|
||||
|
||||
--- @type AI_A2G_SEAD
|
||||
-- @extends AI.AI_A2G_Patrol#AI_AIR_PATROL
|
||||
-- @extends AI.AI_Air_Patrol#AI_AIR_PATROL
|
||||
-- @extends AI.AI_Air_Engage#AI_AIR_ENGAGE
|
||||
|
||||
|
||||
--- Implements the core functions to SEAD intruders. Use the Engage trigger to intercept intruders.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI_A2G_SEAD is assigned a @{Wrapper.Group} and this must be done before the AI_A2G_SEAD process can be started using the **Start** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||
-- Upon arrival at the 3D point, a new random 3D point will be selected within the patrol zone using the given limits.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- This cycle will continue.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- During the patrol, the AI will detect enemy targets, which are reported through the **Detected** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- When enemies are detected, the AI will automatically engage the enemy.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- Until a fuel or damage threshold has been reached by the AI, or when the AI is commanded to RTB.
|
||||
-- When the fuel threshold has been reached, the airplane will fly towards the nearest friendly airbase and will land.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ## 1. AI_A2G_SEAD constructor
|
||||
--
|
||||
-- * @{#AI_A2G_SEAD.New}(): Creates a new AI_A2G_SEAD object.
|
||||
--
|
||||
-- ## 3. Set the Range of Engagement
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- An optional range can be set in meters,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- The range can be beyond or smaller than the range of the Patrol Zone.
|
||||
-- The range is applied at the position of the AI.
|
||||
-- Use the method @{AI.AI_GCI#AI_A2G_SEAD.SetEngageRange}() to define that range.
|
||||
--
|
||||
-- ## 4. Set the Zone of Engagement
|
||||
-- # Developer Note
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- An optional @{Core.Zone} can be set,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- Use the method @{AI.AI_CAP#AI_CAP_ZONE.SetEngageZone}() to define that Zone. -- TODO: Documentation. Check that this is actually correct. The originally referenced class does not exist.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_A2G_SEAD
|
||||
@@ -99,7 +75,7 @@ AI_A2G_SEAD = {
|
||||
function AI_A2G_SEAD:New2( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, EngageAltType, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||
|
||||
local AI_Air = AI_AIR:New( AIGroup )
|
||||
local AI_Air_Patrol = AI_AIR_PATROL:New( AI_Air, AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) -- #AI_AIR_PATROL
|
||||
local AI_Air_Patrol = AI_AIR_PATROL:New( AI_Air, AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||
local AI_Air_Engage = AI_AIR_ENGAGE:New( AI_Air_Patrol, AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, EngageAltType )
|
||||
local self = BASE:Inherit( self, AI_Air_Engage )
|
||||
|
||||
|
||||
@@ -45,12 +45,12 @@
|
||||
-- * **Start**: Start the transport process.
|
||||
-- * **Stop**: Stop the transport process.
|
||||
-- * **Monitor**: Monitor and take action.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- @field #AI_AIR
|
||||
AI_AIR = {
|
||||
ClassName = "AI_AIR",
|
||||
|
||||
@@ -292,8 +292,6 @@ do -- AI_AIR_DISPATCHER
|
||||
--
|
||||
-- ## 1. AI\_AIR\_DISPATCHER constructor:
|
||||
--
|
||||
-- 
|
||||
--
|
||||
--
|
||||
-- The @{#AI_AIR_DISPATCHER.New}() method creates a new AI_AIR_DISPATCHER instance.
|
||||
--
|
||||
@@ -306,8 +304,6 @@ do -- AI_AIR_DISPATCHER
|
||||
-- A reconnaissance network, is used to detect enemy ground targets,
|
||||
-- potentially group them into areas, and to understand the position, level of threat of the enemy.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- As explained in the introduction, depending on the type of mission you want to achieve, different types of units can be applied to detect ground enemy targets.
|
||||
-- Ground based units are very useful to act as a reconnaissance, but they lack sometimes the visibility to detect targets at greater range.
|
||||
-- Recce are very useful to acquire the position of enemy ground targets when spread out over the battlefield at strategic positions.
|
||||
@@ -673,8 +669,6 @@ do -- AI_AIR_DISPATCHER
|
||||
--
|
||||
-- Use the method @{#AI_AIR_DISPATCHER.SetSquadronGrouping}() to set the grouping of aircraft when spawned in.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- In the case of **on call** engagement, the @{#AI_AIR_DISPATCHER.SetSquadronGrouping}() method has additional behaviour.
|
||||
-- When there aren't enough patrol flights airborne, a on call will be initiated for the remaining
|
||||
-- targets to be engaged. Depending on the grouping parameter, the spawned flights for on call aircraft are grouped into this setting.
|
||||
@@ -688,8 +682,6 @@ do -- AI_AIR_DISPATCHER
|
||||
-- The effectiveness can be set with the **overhead parameter**. This is a number that is used to calculate the amount of Units that dispatching command will allocate to GCI in surplus of detected amount of units.
|
||||
-- The **default value** of the overhead parameter is 1.0, which means **equal balance**.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- However, depending on the (type of) aircraft (strength and payload) in the squadron and the amount of resources available, this parameter can be changed.
|
||||
--
|
||||
-- The @{#AI_AIR_DISPATCHER.SetSquadronOverhead}() method can be used to tweak the defense strength,
|
||||
@@ -835,8 +827,6 @@ do -- AI_AIR_DISPATCHER
|
||||
--
|
||||
-- For example, the following setup will set the default refuel tanker to "Tanker":
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- -- Define the CAP
|
||||
-- A2ADispatcher:SetSquadron( "Sochi", AIRBASE.Caucasus.Sochi_Adler, { "SQ CCCP SU-34" }, 20 )
|
||||
-- A2ADispatcher:SetSquadronCap( "Sochi", ZONE:New( "PatrolZone" ), 4000, 8000, 600, 800, 1000, 1300 )
|
||||
|
||||
@@ -14,58 +14,39 @@
|
||||
|
||||
|
||||
--- @type AI_AIR_ENGAGE
|
||||
-- @extends AI.AI_AIR#AI_AIR
|
||||
-- @extends AI.AI_Air#AI_AIR
|
||||
|
||||
|
||||
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI_AIR_ENGAGE is assigned a @{Wrapper.Group} and this must be done before the AI_AIR_ENGAGE process can be started using the **Start** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||
-- Upon arrival at the 3D point, a new random 3D point will be selected within the patrol zone using the given limits.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- This cycle will continue.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- During the patrol, the AI will detect enemy targets, which are reported through the **Detected** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- When enemies are detected, the AI will automatically engage the enemy.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- Until a fuel or damage threshold has been reached by the AI, or when the AI is commanded to RTB.
|
||||
-- When the fuel threshold has been reached, the airplane will fly towards the nearest friendly airbase and will land.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ## 1. AI_AIR_ENGAGE constructor
|
||||
--
|
||||
-- * @{#AI_AIR_ENGAGE.New}(): Creates a new AI_AIR_ENGAGE object.
|
||||
--
|
||||
-- ## 3. Set the Range of Engagement
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- An optional range can be set in meters,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- The range can be beyond or smaller than the range of the Patrol Zone.
|
||||
-- The range is applied at the position of the AI.
|
||||
-- Use the method @{AI.AI_GCI#AI_AIR_ENGAGE.SetEngageRange}() to define that range.
|
||||
--
|
||||
-- ## 4. Set the Zone of Engagement
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- An optional @{Core.Zone} can be set,
|
||||
--
|
||||
-- An optional @{Core.Zone} can be set,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- Use the method @{AI.AI_CAP#AI_AIR_ENGAGE.SetEngageZone}() to define that Zone.
|
||||
--
|
||||
@@ -74,6 +55,11 @@
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_AIR_ENGAGE
|
||||
@@ -456,12 +442,12 @@ function AI_AIR_ENGAGE:onafterEngageRoute( DefenderGroup, From, Event, To, Attac
|
||||
-- TODO: A factor of * 3 is way too close. This causes the AI not to engange until merged sometimes!
|
||||
if TargetDistance <= EngageDistance * 9 then
|
||||
|
||||
self:I(string.format("AI_AIR_ENGAGE onafterEngageRoute ==> __Engage - target distance = %.1f km", TargetDistance/1000))
|
||||
--self:I(string.format("AI_AIR_ENGAGE onafterEngageRoute ==> __Engage - target distance = %.1f km", TargetDistance/1000))
|
||||
self:__Engage( 0.1, AttackSetUnit )
|
||||
|
||||
else
|
||||
|
||||
self:I(string.format("FF AI_AIR_ENGAGE onafterEngageRoute ==> Routing - target distance = %.1f km", TargetDistance/1000))
|
||||
--self:I(string.format("FF AI_AIR_ENGAGE onafterEngageRoute ==> Routing - target distance = %.1f km", TargetDistance/1000))
|
||||
|
||||
local EngageRoute = {}
|
||||
local AttackTasks = {}
|
||||
|
||||
@@ -81,19 +81,11 @@
|
||||
-- The range is applied at the position of the AI.
|
||||
-- Use the method @{AI.AI_CAP#AI_AIR_PATROL.SetEngageRange}() to define that range.
|
||||
--
|
||||
-- ## 4. Set the Zone of Engagement
|
||||
-- # Developer Note
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- An optional @{Core.Zone} can be set,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- Use the method @{AI.AI_CAP#AI_AIR_PATROL.SetEngageZone}() to define that Zone.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_AIR_PATROL
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
|
||||
|
||||
--- Implements the core functions modeling squadrons for airplanes and helicopters.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_AIR_SQUADRON
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
-- ### Author: **FlightControl**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Gunterlund](http://forums.eagle.ru:8080/member.php?u=75036)**: Test case revision.
|
||||
-- * **Gunterlund**: Test case revision.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@@ -130,12 +130,12 @@
|
||||
-- AIBAIZone:SearchOff()
|
||||
--
|
||||
-- Searching can be switched back on with the method @{#AI_BAI_ZONE.SearchOn}(). Use the method @{#AI_BAI_ZONE.SearchOnOff}() to flexibily switch searching on or off.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_BAI_ZONE
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
-- ### Author: **FlightControl**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Dutch_Baron](https://forums.eagle.ru/member.php?u=112075)**: Working together with James has resulted in the creation of the AI_BALANCER class. James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)
|
||||
-- * **Dutch_Baron**: Working together with James has resulted in the creation of the AI_BALANCER class. James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@@ -40,7 +40,7 @@
|
||||
--
|
||||
-- The parent class @{Core.Fsm#FSM_SET} manages the functionality to control the Finite State Machine (FSM).
|
||||
-- The mission designer can tailor the behaviour of the AI_BALANCER, by defining event and state transition methods.
|
||||
-- An explanation about state and event transition methods can be found in the @{FSM} module documentation.
|
||||
-- An explanation about state and event transition methods can be found in the @{Core.Fsm} module documentation.
|
||||
--
|
||||
-- The mission designer can tailor the AI_BALANCER behaviour, by implementing a state or event handling method for the following:
|
||||
--
|
||||
@@ -52,7 +52,7 @@
|
||||
--
|
||||
-- ## 2. AI_BALANCER is a FSM
|
||||
--
|
||||
-- 
|
||||
-- 
|
||||
--
|
||||
-- ### 2.1. AI_BALANCER States
|
||||
--
|
||||
@@ -85,12 +85,12 @@
|
||||
--
|
||||
-- Note that when AI returns to an airbase, the AI_BALANCER will trigger the **Return** event and the AI will return,
|
||||
-- otherwise the AI_BALANCER will trigger a **Destroy** event, and the AI will be destroyed.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- @field #AI_BALANCER
|
||||
AI_BALANCER = {
|
||||
ClassName = "AI_BALANCER",
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
-- ### Author: **FlightControl**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Quax](https://forums.eagle.ru/member.php?u=90530)**: Concept, Advice & Testing.
|
||||
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Concept, Advice & Testing.
|
||||
-- * **[Gunterlund](http://forums.eagle.ru:8080/member.php?u=75036)**: Test case revision.
|
||||
-- * **[Whisper](http://forums.eagle.ru/member.php?u=3829): Testing.
|
||||
-- * **[Delta99](https://forums.eagle.ru/member.php?u=125166): Testing.
|
||||
-- * **Quax**: Concept, Advice & Testing.
|
||||
-- * **Pikey**: Concept, Advice & Testing.
|
||||
-- * **Gunterlund**: Test case revision.
|
||||
-- * **Whisper**: Testing.
|
||||
-- * **Delta99**: Testing.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@@ -112,12 +112,12 @@
|
||||
-- An optional @{Core.Zone} can be set,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- Use the method @{#AI_CAP_ZONE.SetEngageZone}() to define that Zone.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_CAP_ZONE
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
-- ### Author: **FlightControl**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Quax](https://forums.eagle.ru/member.php?u=90530)**: Concept, Advice & Testing.
|
||||
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Concept, Advice & Testing.
|
||||
-- * **[Gunterlund](http://forums.eagle.ru:8080/member.php?u=75036)**: Test case revision.
|
||||
-- * **Quax**: Concept, Advice & Testing.
|
||||
-- * **Pikey**: Concept, Advice & Testing.
|
||||
-- * **Gunterlund**: Test case revision.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@@ -118,12 +118,12 @@
|
||||
-- * **@{#AI_CAS_ZONE.Destroy}**: The AI has destroyed a target @{Wrapper.Unit}.
|
||||
-- * **@{#AI_CAS_ZONE.Destroyed}**: The AI has destroyed all target @{Wrapper.Unit}s assigned in the CAS task.
|
||||
-- * **Status**: The AI is checking status (fuel and damage). When the thresholds have been reached, the AI will RTB.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_CAS_ZONE
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
-- * @{AI.AI_Cargo_APC} - Cargo transportation using APCs and other vehicles between zones.
|
||||
-- * @{AI.AI_Cargo_Helicopter} - Cargo transportation using helicopters between zones.
|
||||
-- * @{AI.AI_Cargo_Airplane} - Cargo transportation using airplanes to and from airbases.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- @field #AI_CARGO
|
||||
AI_CARGO = {
|
||||
ClassName = "AI_CARGO",
|
||||
|
||||
@@ -75,12 +75,12 @@
|
||||
-- Using the @{#AI_CARGO_APC.Pickup}() method, you are able to direct the APCs towards a point on the battlefield to board/load the cargo at the specific coordinate.
|
||||
-- The APCs will follow nearby roads as much as possible, to ensure fast and clean cargo transportation between the objects and villages in the simulation environment.
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- @field #AI_CARGO_APC
|
||||
AI_CARGO_APC = {
|
||||
|
||||
@@ -41,12 +41,12 @@
|
||||
-- marginal impact on the overall battlefield simulation. Fortunately, the firing strength of infantry is limited, and thus, respacing healthy infantry every
|
||||
-- time is not so much of an issue ...
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- @field #AI_CARGO_AIRPLANE
|
||||
AI_CARGO_AIRPLANE = {
|
||||
ClassName = "AI_CARGO_AIRPLANE",
|
||||
|
||||
@@ -100,12 +100,12 @@
|
||||
--
|
||||
-- Yes, please ensure that the zones are declared using the @{Core.Zone} classes.
|
||||
-- Possible zones that function at the moment are ZONE, ZONE_GROUP, ZONE_UNIT, ZONE_POLYGON.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **FlightControl**
|
||||
|
||||
@@ -137,12 +137,12 @@
|
||||
-- Use @{#AI_CARGO_DISPATCHER_APC.SetHomeZone}() to specify the home zone.
|
||||
--
|
||||
-- If no home zone is specified, the APCs will wait near the deploy zone for a new pickup command.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_CARGO_DISPATCHER_APC
|
||||
|
||||
@@ -108,12 +108,12 @@
|
||||
--
|
||||
-- **There are a lot of templates available that allows you to quickly setup an event handler for a specific event type!**
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- @field #AI_CARGO_DISPATCHER_AIRPLANE
|
||||
AI_CARGO_DISPATCHER_AIRPLANE = {
|
||||
|
||||
@@ -140,12 +140,12 @@
|
||||
-- Use @{#AI_CARGO_DISPATCHER_HELICOPTER.SetHomeZone}() to specify the home zone.
|
||||
--
|
||||
-- If no home zone is specified, the helicopters will wait near the deploy zone for a new pickup command.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_CARGO_DISPATCHER_HELICOPTER
|
||||
|
||||
@@ -130,12 +130,12 @@
|
||||
-- Use @{#AI_CARGO_DISPATCHER_SHIP.SetHomeZone}() to specify the home zone.
|
||||
--
|
||||
-- If no home zone is specified, the Ship will wait near the deploy zone for a new pickup command.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_CARGO_DISPATCHER_SHIP
|
||||
|
||||
@@ -41,12 +41,12 @@
|
||||
-- marginal impact on the overall battlefield simulation. Fortunately, the firing strength of infantry is limited, and thus, respacing healthy infantry every
|
||||
-- time is not so much of an issue ...
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_CARGO_HELICOPTER
|
||||
|
||||
@@ -54,12 +54,12 @@
|
||||
-- Using the @{#AI_CARGO_SHIP.Pickup}() method, you are able to direct the Ship towards a Pickup zone to board/load the cargo at the specified
|
||||
-- coordinate. The Ship will follow the Shipping Lane to ensure consistent cargo transportation within the simulation environment.
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- @field #AI_CARGO_SHIP
|
||||
AI_CARGO_SHIP = {
|
||||
ClassName = "AI_CARGO_SHIP",
|
||||
|
||||
@@ -174,12 +174,12 @@
|
||||
-- EscortPlanes = AI_ESCORT:New( EscortUnit, EscortGroup, "Desert", "Welcome to the mission. You are escorted by a plane with code name 'Desert', which can be instructed through the F10 radio menu." )
|
||||
-- EscortPlanes:MenusAirplanes() -- create menus for airplanes
|
||||
-- EscortPlanes:__Start(2)
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- @field #AI_ESCORT
|
||||
AI_ESCORT = {
|
||||
ClassName = "AI_ESCORT",
|
||||
@@ -199,13 +199,6 @@ AI_ESCORT = {
|
||||
-- @field Functional.Detection#DETECTION_AREAS
|
||||
AI_ESCORT.Detection = nil
|
||||
|
||||
--- MENUPARAM type
|
||||
-- @type MENUPARAM
|
||||
-- @field #AI_ESCORT ParamSelf
|
||||
-- @field #Distance ParamDistance
|
||||
-- @field #function ParamFunction
|
||||
-- @field #string ParamMessage
|
||||
|
||||
--- AI_ESCORT class constructor for an AI group
|
||||
-- @param #AI_ESCORT self
|
||||
-- @param Wrapper.Client#CLIENT EscortUnit The client escorted by the EscortGroup.
|
||||
@@ -268,7 +261,7 @@ function AI_ESCORT:New( EscortUnit, EscortGroupSet, EscortName, EscortBriefing )
|
||||
|
||||
|
||||
EscortGroupSet:ForEachGroup(
|
||||
-- @param Core.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup )
|
||||
-- Set EscortGroup known at EscortUnit.
|
||||
if not self.PlayerUnit._EscortGroups then
|
||||
@@ -350,7 +343,7 @@ function AI_ESCORT:onafterStart( EscortGroupSet )
|
||||
self:F()
|
||||
|
||||
EscortGroupSet:ForEachGroup(
|
||||
-- @param Core.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup )
|
||||
EscortGroup:WayPointInitialize()
|
||||
|
||||
@@ -388,7 +381,7 @@ function AI_ESCORT:onafterStart( EscortGroupSet )
|
||||
self:_InitFlightMenus()
|
||||
|
||||
self.EscortGroupSet:ForSomeGroupAlive(
|
||||
-- @param Core.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup )
|
||||
|
||||
self:_InitEscortMenus( EscortGroup )
|
||||
@@ -419,7 +412,7 @@ function AI_ESCORT:onafterStop( EscortGroupSet )
|
||||
self:F()
|
||||
|
||||
EscortGroupSet:ForEachGroup(
|
||||
-- @param Core.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup )
|
||||
EscortGroup:WayPointInitialize()
|
||||
|
||||
@@ -568,7 +561,7 @@ function AI_ESCORT:SetFlightMenuFormation( Formation )
|
||||
local MenuFlightFormationID = MENU_GROUP_COMMAND:New( self.PlayerGroup, Formation, FlightMenuFormation,
|
||||
function ( self, Formation, ... )
|
||||
self.EscortGroupSet:ForSomeGroupAlive(
|
||||
-- @param Core.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup, self, Formation, Arguments )
|
||||
if EscortGroup:IsAir() then
|
||||
self:E({FormationID=FormationID})
|
||||
@@ -1249,7 +1242,7 @@ function AI_ESCORT:MenuAssistedAttack()
|
||||
self:F()
|
||||
|
||||
self.EscortGroupSet:ForSomeGroupAlive(
|
||||
-- @param Core.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup )
|
||||
if not EscortGroup:IsAir() then
|
||||
-- Request assistance from other escorts.
|
||||
@@ -1446,7 +1439,7 @@ function AI_ESCORT:_FlightHoldPosition( OrbitGroup, OrbitHeight, OrbitSeconds )
|
||||
local EscortUnit = self.PlayerUnit
|
||||
|
||||
self.EscortGroupSet:ForEachGroupAlive(
|
||||
-- @param Core.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup, OrbitGroup )
|
||||
if EscortGroup:IsAir() then
|
||||
if OrbitGroup == nil then
|
||||
@@ -1474,7 +1467,7 @@ end
|
||||
function AI_ESCORT:_FlightJoinUp()
|
||||
|
||||
self.EscortGroupSet:ForEachGroupAlive(
|
||||
-- @param Core.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup )
|
||||
if EscortGroup:IsAir() then
|
||||
self:_JoinUp( EscortGroup )
|
||||
@@ -1501,7 +1494,7 @@ end
|
||||
function AI_ESCORT:_FlightFormationTrail( XStart, XSpace, YStart )
|
||||
|
||||
self.EscortGroupSet:ForEachGroupAlive(
|
||||
-- @param Core.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup )
|
||||
if EscortGroup:IsAir() then
|
||||
self:_EscortFormationTrail( EscortGroup, XStart, XSpace, YStart )
|
||||
@@ -1528,7 +1521,7 @@ end
|
||||
function AI_ESCORT:_FlightFormationStack( XStart, XSpace, YStart, YSpace )
|
||||
|
||||
self.EscortGroupSet:ForEachGroupAlive(
|
||||
-- @param Core.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup )
|
||||
if EscortGroup:IsAir() then
|
||||
self:_EscortFormationStack( EscortGroup, XStart, XSpace, YStart, YSpace )
|
||||
@@ -1551,7 +1544,7 @@ end
|
||||
function AI_ESCORT:_FlightFlare( Color, Message )
|
||||
|
||||
self.EscortGroupSet:ForEachGroupAlive(
|
||||
-- @param Core.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup )
|
||||
if EscortGroup:IsAir() then
|
||||
self:_Flare( EscortGroup, Color, Message )
|
||||
@@ -1574,7 +1567,7 @@ end
|
||||
function AI_ESCORT:_FlightSmoke( Color, Message )
|
||||
|
||||
self.EscortGroupSet:ForEachGroupAlive(
|
||||
-- @param Core.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup )
|
||||
if EscortGroup:IsAir() then
|
||||
self:_Smoke( EscortGroup, Color, Message )
|
||||
@@ -1605,7 +1598,7 @@ end
|
||||
function AI_ESCORT:_FlightSwitchReportNearbyTargets( ReportTargets )
|
||||
|
||||
self.EscortGroupSet:ForEachGroupAlive(
|
||||
-- @param Core.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup )
|
||||
if EscortGroup:IsAir() then
|
||||
self:_EscortSwitchReportNearbyTargets( EscortGroup, ReportTargets )
|
||||
@@ -1813,7 +1806,7 @@ end
|
||||
function AI_ESCORT:_FlightAttackTarget( DetectedItem )
|
||||
|
||||
self.EscortGroupSet:ForEachGroupAlive(
|
||||
-- @param Core.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup, DetectedItem )
|
||||
if EscortGroup:IsAir() then
|
||||
self:_AttackTarget( EscortGroup, DetectedItem )
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
|
||||
|
||||
--- Models the automatic assignment of AI escorts to player flights.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_ESCORT_DISPATCHER
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
|
||||
|
||||
--- Models the assignment of AI escorts to player flights upon request using the radio menu.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_ESCORT_DISPATCHER_REQUEST
|
||||
|
||||
@@ -136,12 +136,12 @@
|
||||
--
|
||||
-- Escort groups can have their own mission. This menu item will allow the escort group to resume their Mission from a given waypoint.
|
||||
-- Note that this is really fantastic, as you now have the dynamic of taking control of the escort groups, and allowing them to resume their path or mission.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Authors: **FlightControl**
|
||||
@@ -297,7 +297,7 @@ function AI_ESCORT_REQUEST:onafterStop( EscortGroupSet )
|
||||
self:F()
|
||||
|
||||
EscortGroupSet:ForEachGroup(
|
||||
--- @param Core.Group#GROUP EscortGroup
|
||||
--- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( EscortGroup )
|
||||
EscortGroup:WayPointInitialize()
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20Formation)
|
||||
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation)
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@@ -31,11 +31,11 @@
|
||||
-- @field Core.Set#SET_GROUP FollowGroupSet
|
||||
-- @field #string FollowName
|
||||
-- @field #AI_FORMATION.MODE FollowMode The mode the escort is in.
|
||||
-- @field Scheduler#SCHEDULER FollowScheduler The instance of the SCHEDULER class.
|
||||
-- @field Core.Scheduler#SCHEDULER FollowScheduler The instance of the SCHEDULER class.
|
||||
-- @field #number FollowDistance The current follow distance.
|
||||
-- @field #boolean ReportTargets If true, nearby targets are reported.
|
||||
-- @Field DCSTypes#AI.Option.Air.val.ROE OptionROE Which ROE is set to the FollowGroup.
|
||||
-- @field DCSTypes#AI.Option.Air.val.REACTION_ON_THREAT OptionReactionOnThreat Which REACTION_ON_THREAT is set to the FollowGroup.
|
||||
-- @field DCS#AI.Option.Air.val.ROE OptionROE Which ROE is set to the FollowGroup.
|
||||
-- @field DCS#AI.Option.Air.val.REACTION_ON_THREAT OptionReactionOnThreat Which REACTION_ON_THREAT is set to the FollowGroup.
|
||||
-- @field #number dtFollow Time step between position updates.
|
||||
|
||||
|
||||
@@ -92,12 +92,12 @@
|
||||
-- local LargeFormation = AI_FORMATION:New( LeaderUnit, FollowGroupSet, "Center Wing Formation", "Briefing" )
|
||||
-- LargeFormation:FormationCenterWing( 500, 50, 0, 250, 250 )
|
||||
-- LargeFormation:__Start( 1 )
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- @field #AI_FORMATION
|
||||
AI_FORMATION = {
|
||||
ClassName = "AI_FORMATION",
|
||||
@@ -164,15 +164,6 @@ AI_FORMATION.__Enum.ReportType = {
|
||||
Ground = "G",
|
||||
}
|
||||
|
||||
|
||||
|
||||
--- MENUPARAM type
|
||||
-- @type MENUPARAM
|
||||
-- @field #AI_FORMATION ParamSelf
|
||||
-- @field #number ParamDistance
|
||||
-- @field #function ParamFunction
|
||||
-- @field #string ParamMessage
|
||||
|
||||
--- AI_FORMATION class constructor for an AI group
|
||||
-- @param #AI_FORMATION self
|
||||
-- @param Wrapper.Unit#UNIT FollowUnit The UNIT leading the FolllowGroupSet.
|
||||
@@ -1005,7 +996,7 @@ function AI_FORMATION:SetFlightModeMission( FollowGroup )
|
||||
FollowGroup:SetState( FollowGroup, "Mode", self.__Enum.Mode.Mission )
|
||||
else
|
||||
self.FollowGroupSet:ForSomeGroupAlive(
|
||||
--- @param Core.Group#GROUP EscortGroup
|
||||
--- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( FollowGroup )
|
||||
FollowGroup:SetState( FollowGroup, "PreviousMode", FollowGroup:GetState( FollowGroup, "Mode" ) )
|
||||
FollowGroup:SetState( FollowGroup, "Mode", self.__Enum.Mode.Mission )
|
||||
@@ -1029,7 +1020,7 @@ function AI_FORMATION:SetFlightModeAttack( FollowGroup )
|
||||
FollowGroup:SetState( FollowGroup, "Mode", self.__Enum.Mode.Attack )
|
||||
else
|
||||
self.FollowGroupSet:ForSomeGroupAlive(
|
||||
--- @param Core.Group#GROUP EscortGroup
|
||||
--- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( FollowGroup )
|
||||
FollowGroup:SetState( FollowGroup, "PreviousMode", FollowGroup:GetState( FollowGroup, "Mode" ) )
|
||||
FollowGroup:SetState( FollowGroup, "Mode", self.__Enum.Mode.Attack )
|
||||
@@ -1053,7 +1044,7 @@ function AI_FORMATION:SetFlightModeFormation( FollowGroup )
|
||||
FollowGroup:SetState( FollowGroup, "Mode", self.__Enum.Mode.Formation )
|
||||
else
|
||||
self.FollowGroupSet:ForSomeGroupAlive(
|
||||
--- @param Core.Group#GROUP EscortGroup
|
||||
--- @param Wrapper.Group#GROUP EscortGroup
|
||||
function( FollowGroup )
|
||||
FollowGroup:SetState( FollowGroup, "PreviousMode", FollowGroup:GetState( FollowGroup, "Mode" ) )
|
||||
FollowGroup:SetState( FollowGroup, "Mode", self.__Enum.Mode.Formation )
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
-- ### Author: **FlightControl**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Dutch_Baron](https://forums.eagle.ru/member.php?u=112075)**: Working together with James has resulted in the creation of the AI_BALANCER class. James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)
|
||||
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Testing and API concept review.
|
||||
-- * **Dutch_Baron**: Working together with James has resulted in the creation of the AI_BALANCER class. James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)
|
||||
-- * **Pikey**: Testing and API concept review.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@@ -144,12 +144,12 @@
|
||||
-- When the AI is damaged, it is required that a new AIControllable is started. However, damage cannon be foreseen early on.
|
||||
-- Therefore, when the damage threshold is reached, the AI will return immediately to the home base (RTB).
|
||||
-- Use the method @{#AI_PATROL_ZONE.ManageDamage}() to have this process in place.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_PATROL_ZONE
|
||||
|
||||
@@ -142,7 +142,7 @@ end -- ACT_ACCOUNT
|
||||
|
||||
do -- ACT_ACCOUNT_DEADS
|
||||
|
||||
--- # @{#ACT_ACCOUNT_DEADS} FSM class, extends @{Core.Fsm.Account#ACT_ACCOUNT}
|
||||
--- # @{#ACT_ACCOUNT_DEADS} FSM class, extends @{#ACT_ACCOUNT}
|
||||
--
|
||||
-- The ACT_ACCOUNT_DEADS class accounts (detects, counts and reports) successful kills of DCS units.
|
||||
-- The process is given a @{Core.Set} of units that will be tracked upon successful destruction.
|
||||
|
||||
@@ -51,15 +51,15 @@
|
||||
-- * **After** the state transition.
|
||||
-- The state transition method needs to start with the name **OnAfter + the name of the state**.
|
||||
-- These state transition methods need to provide a return value, which is specified at the function description.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 1) @{#ACT_ASSIGN_ACCEPT} class, extends @{Core.Fsm.Assign#ACT_ASSIGN}
|
||||
-- # 1) @{#ACT_ASSIGN_ACCEPT} class, extends @{Core.Fsm#ACT_ASSIGN}
|
||||
--
|
||||
-- The ACT_ASSIGN_ACCEPT class accepts by default a task for a player. No player intervention is allowed to reject the task.
|
||||
--
|
||||
@@ -69,7 +69,7 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 2) @{#ACT_ASSIGN_MENU_ACCEPT} class, extends @{Core.Fsm.Assign#ACT_ASSIGN}
|
||||
-- # 2) @{#ACT_ASSIGN_MENU_ACCEPT} class, extends @{Core.Fsm#ACT_ASSIGN}
|
||||
--
|
||||
-- The ACT_ASSIGN_MENU_ACCEPT class accepts a task when the player accepts the task through an added menu option.
|
||||
-- This assignment type is useful to conditionally allow the player to choose whether or not he would accept the task.
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 1) @{#ACT_ASSIST_SMOKE_TARGETS_ZONE} class, extends @{Core.Fsm.Route#ACT_ASSIST}
|
||||
-- # 1) @{#ACT_ASSIST_SMOKE_TARGETS_ZONE} class, extends @{#ACT_ASSIST}
|
||||
--
|
||||
-- The ACT_ASSIST_SMOKE_TARGETS_ZONE class implements the core functions to smoke targets in a @{Core.Zone}.
|
||||
-- The targets are smoked within a certain range around each target, simulating a realistic smoking behaviour.
|
||||
@@ -57,12 +57,12 @@
|
||||
-- # 1.1) ACT_ASSIST_SMOKE_TARGETS_ZONE constructor:
|
||||
--
|
||||
-- * @{#ACT_ASSIST_SMOKE_TARGETS_ZONE.New}(): Creates a new ACT_ASSIST_SMOKE_TARGETS_ZONE object.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Actions.Act_Assist
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 1) @{#ACT_ROUTE_ZONE} class, extends @{Core.Fsm.Route#ACT_ROUTE}
|
||||
-- # 1) @{#ACT_ROUTE_ZONE} class, extends @{#ACT_ROUTE}
|
||||
--
|
||||
-- The ACT_ROUTE_ZONE class implements the core functions to route an AIR @{Wrapper.Controllable} player @{Wrapper.Unit} to a @{Core.Zone}.
|
||||
-- The player receives on perioding times messages with the coordinates of the route to follow.
|
||||
@@ -69,12 +69,12 @@
|
||||
-- # 1.1) ACT_ROUTE_ZONE constructor:
|
||||
--
|
||||
-- * @{#ACT_ROUTE_ZONE.New}(): Creates a new ACT_ROUTE_ZONE object.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Actions.Act_Route
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
-- There are also dispatchers that make AI work together to transport cargo automatically!!!
|
||||
--
|
||||
-- - @{AI.AI_Cargo_Dispatcher_APC} derived classes will create for your dynamic cargo handlers controlled by AI ground vehicle groups (APCs) to transport cargo between sites.
|
||||
-- - @{AI.AI_Cargo_Dispatcher_Helicopters} derived classes will create for your dynamic cargo handlers controlled by AI helicopter groups to transport cargo between sites.
|
||||
-- - @{AI.AI_Cargo_Dispatcher_Helicopter} derived classes will create for your dynamic cargo handlers controlled by AI helicopter groups to transport cargo between sites.
|
||||
--
|
||||
-- ## 3.3) Cargo transportation tasking.
|
||||
--
|
||||
@@ -233,12 +233,12 @@
|
||||
-- Note that this option is optional, so can be omitted. The default value of the RR is 250 meters.
|
||||
-- * **NR=** Provide the maximum range in meters when the cargo units will be boarded within the carrier during boarding.
|
||||
-- Note that this option is optional, so can be omitted. The default value of the RR is 10 meters.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **FlightControl**
|
||||
@@ -398,7 +398,7 @@ do -- CARGO
|
||||
--
|
||||
-- * AI Armoured Personnel Carriers to transport cargo and engage in battles, using the @{AI.AI_Cargo_APC#AI_CARGO_APC} class.
|
||||
-- * AI Helicopters to transport cargo, using the @{AI.AI_Cargo_Helicopter#AI_CARGO_HELICOPTER} class.
|
||||
-- * AI Planes to transport cargo, using the @{AI.AI_Cargo_Plane#AI_CARGO_PLANE} class.
|
||||
-- * AI Planes to transport cargo, using the @{AI.AI_Cargo_Airplane#AI_CARGO_AIRPLANE} class.
|
||||
-- * AI Ships is planned.
|
||||
--
|
||||
-- The above cargo classes are also used by the TASK\_CARGO\_ classes to allow human players to transport cargo as part of a tasking:
|
||||
@@ -980,7 +980,7 @@ do -- CARGO
|
||||
|
||||
--- Report to a Carrier Group with a Flaring signal.
|
||||
-- @param #CARGO self
|
||||
-- @param Utils#UTILS.FlareColor FlareColor the color of the flare.
|
||||
-- @param Utilities.Utils#UTILS.FlareColor FlareColor the color of the flare.
|
||||
-- @return #CARGO
|
||||
function CARGO:ReportFlare( FlareColor )
|
||||
|
||||
@@ -989,7 +989,7 @@ do -- CARGO
|
||||
|
||||
--- Report to a Carrier Group with a Smoking signal.
|
||||
-- @param #CARGO self
|
||||
-- @param Utils#UTILS.SmokeColor SmokeColor the color of the smoke.
|
||||
-- @param Utilities.Utils#UTILS.SmokeColor SmokeColor the color of the smoke.
|
||||
-- @return #CARGO
|
||||
function CARGO:ReportSmoke( SmokeColor )
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
--
|
||||
-- # Calculate the Path
|
||||
--
|
||||
-- Finally, we have to calculate the path. This is done by the @{ASTAR.GetPath}(*ExcludeStart, ExcludeEnd*) function. This function returns a table of nodes, which
|
||||
-- Finally, we have to calculate the path. This is done by the @{#GetPath}(*ExcludeStart, ExcludeEnd*) function. This function returns a table of nodes, which
|
||||
-- describe the optimal path from the start node to the end node.
|
||||
--
|
||||
-- By default, the start and end node are include in the table that is returned.
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
--
|
||||
-- ## Example Missions:
|
||||
--
|
||||
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/OPS%20-%20Operation).
|
||||
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Core/Condition).
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
|
||||
@@ -680,7 +680,7 @@ do -- cargo
|
||||
--- Finds an CARGO based on the CargoName.
|
||||
-- @param #DATABASE self
|
||||
-- @param #string CargoName
|
||||
-- @return Wrapper.Cargo#CARGO The found CARGO.
|
||||
-- @return Cargo.Cargo#CARGO The found CARGO.
|
||||
function DATABASE:FindCargo( CargoName )
|
||||
|
||||
local CargoFound = self.CARGOS[CargoName]
|
||||
|
||||
@@ -313,7 +313,7 @@ EVENTS = {
|
||||
-- @field Cargo.Cargo#CARGO Cargo The cargo object.
|
||||
-- @field #string CargoName The name of the cargo object.
|
||||
--
|
||||
-- @field Core.ZONE#ZONE Zone The zone object.
|
||||
-- @field Core.Zone#ZONE Zone The zone object.
|
||||
-- @field #string ZoneName The name of the zone.
|
||||
|
||||
|
||||
@@ -988,7 +988,7 @@ do -- Event Creation
|
||||
|
||||
--- Creation of a New ZoneGoal Event.
|
||||
-- @param #EVENT self
|
||||
-- @param Core.Functional#ZONE_GOAL ZoneGoal The ZoneGoal created.
|
||||
-- @param Functional.ZoneGoal#ZONE_GOAL ZoneGoal The ZoneGoal created.
|
||||
function EVENT:CreateEventNewZoneGoal( ZoneGoal )
|
||||
self:F( { ZoneGoal } )
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ do -- FSM
|
||||
--
|
||||
-- ### Linear Transition Example
|
||||
--
|
||||
-- This example is fully implemented in the MOOSE test mission on GITHUB: [FSM-100 - Transition Explanation](https://github.com/FlightControl-Master/MOOSE/blob/master/Moose%20Test%20Missions/FSM%20-%20Finite%20State%20Machine/FSM-100%20-%20Transition%20Explanation/FSM-100%20-%20Transition%20Explanation.lua)
|
||||
-- This example is fully implemented in the MOOSE test mission on GITHUB: [FSM-100 - Transition Explanation](https://github.com/FlightControl-Master/MOOSE_MISSIONS/blob/master/FSM%20-%20Finite%20State%20Machine/FSM-100%20-%20Transition%20Explanation/FSM-100%20-%20Transition%20Explanation.lua)
|
||||
--
|
||||
-- It models a unit standing still near Batumi, and flaring every 5 seconds while switching between a Green flare and a Red flare.
|
||||
-- The purpose of this example is not to show how exciting flaring is, but it demonstrates how a Linear Transition FSM can be build.
|
||||
@@ -1260,7 +1260,7 @@ do -- FSM_PROCESS
|
||||
|
||||
--- Assign the process to a @{Wrapper.Unit} and activate the process.
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @param Task.Tasking#TASK Task
|
||||
-- @param Tasking.Task#TASK Task
|
||||
-- @param Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @return #FSM_PROCESS self
|
||||
function FSM_PROCESS:Assign( ProcessUnit, Task )
|
||||
|
||||
@@ -513,7 +513,7 @@ do -- MENU_COALITION
|
||||
--- @type MENU_COALITION
|
||||
-- @extends Core.Menu#MENU_BASE
|
||||
|
||||
--- Manages the main menus for @{DCS.coalition}s.
|
||||
--- Manages the main menus for DCS.coalition.
|
||||
--
|
||||
-- You can add menus with the @{#MENU_COALITION.New} method, which constructs a MENU_COALITION object and returns you the object reference.
|
||||
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_COALITION.Remove}.
|
||||
|
||||
@@ -73,7 +73,7 @@ MESSAGE.Type = {
|
||||
Detailed = "Detailed Report",
|
||||
}
|
||||
|
||||
--- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
|
||||
--- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{#MESSAGE.ToClient} or @{#MESSAGE.ToCoalition} or @{#MESSAGE.ToAll} to send these Messages to the respective recipients.
|
||||
-- @param self
|
||||
-- @param #string MessageText is the text of the Message.
|
||||
-- @param #number MessageDuration is a number in seconds of how long the MESSAGE should be shown on the display panel.
|
||||
@@ -127,7 +127,7 @@ end
|
||||
|
||||
--- Creates a new MESSAGE object of a certain type.
|
||||
-- Note that these MESSAGE objects are not yet displayed on the display panel.
|
||||
-- You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
|
||||
-- You must use the functions @{Core.Message#ToClient} or @{Core.Message#ToCoalition} or @{Core.Message#ToAll} to send these Messages to the respective recipients.
|
||||
-- The message display times are automatically defined based on the timing settings in the @{Core.Settings} menu.
|
||||
-- @param self
|
||||
-- @param #string MessageText is the text of the Message.
|
||||
@@ -343,7 +343,7 @@ end
|
||||
|
||||
--- Sends a MESSAGE to a Coalition.
|
||||
-- @param #MESSAGE self
|
||||
-- @param #DCS.coalition.side CoalitionSide @{#DCS.coalition.side} to which the message is displayed.
|
||||
-- @param DCS#coalition.side CoalitionSide @{#DCS.coalition.side} to which the message is displayed.
|
||||
-- @param Core.Settings#SETTINGS Settings (Optional) Settings for message display.
|
||||
-- @return #MESSAGE Message object.
|
||||
-- @usage
|
||||
@@ -379,7 +379,7 @@ end
|
||||
|
||||
--- Sends a MESSAGE to a Coalition if the given Condition is true.
|
||||
-- @param #MESSAGE self
|
||||
-- @param CoalitionSide needs to be filled out by the defined structure of the standard scripting engine @{coalition.side}.
|
||||
-- @param CoalitionSide needs to be filled out by the defined structure of the standard scripting engine @{#DCS.coalition.side}.
|
||||
-- @param #boolean Condition Sends the message only if the condition is true.
|
||||
-- @return #MESSAGE self
|
||||
function MESSAGE:ToCoalitionIf( CoalitionSide, Condition )
|
||||
@@ -480,21 +480,24 @@ _MESSAGESRS = {}
|
||||
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS()
|
||||
--
|
||||
function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,Gender,Culture,Voice,Coalition,Volume,Label,Coordinate)
|
||||
local path = PathToSRS or "C:\\Program Files\\DCS-SimpleRadio-Standalone"
|
||||
_MESSAGESRS.MSRS = MSRS:New(path,Frequency,Modulation,Volume)
|
||||
_MESSAGESRS.MSRS = MSRS:New(PathToSRS,Frequency,Modulation,Volume)
|
||||
_MESSAGESRS.MSRS:SetCoalition(Coalition)
|
||||
_MESSAGESRS.MSRS:SetCoordinate(Coordinate)
|
||||
_MESSAGESRS.MSRS:SetCulture(Culture)
|
||||
_MESSAGESRS.MSRS:SetFrequencies(Frequency)
|
||||
_MESSAGESRS.Culture = Culture
|
||||
--_MESSAGESRS.MSRS:SetFrequencies(Frequency)
|
||||
_MESSAGESRS.MSRS:SetGender(Gender)
|
||||
_MESSAGESRS.Gender = Gender
|
||||
_MESSAGESRS.MSRS:SetGoogle(PathToCredentials)
|
||||
_MESSAGESRS.MSRS:SetLabel(Label or "MESSAGE")
|
||||
_MESSAGESRS.MSRS:SetModulations(Modulation)
|
||||
_MESSAGESRS.MSRS:SetPath(PathToSRS)
|
||||
--_MESSAGESRS.MSRS:SetModulations(Modulation)
|
||||
--_MESSAGESRS.MSRS:SetPath(PathToSRS)
|
||||
_MESSAGESRS.MSRS:SetPort(Port)
|
||||
_MESSAGESRS.MSRS:SetVolume(Volume)
|
||||
-- _MESSAGESRS.MSRS:SetVolume(Volume)
|
||||
_MESSAGESRS.MSRS:SetVoice(Voice)
|
||||
_MESSAGESRS.Voice = Voice
|
||||
_MESSAGESRS.SRSQ = MSRSQUEUE:New(Label or "MESSAGE")
|
||||
env.info(_MESSAGESRS.MSRS.provider,false)
|
||||
end
|
||||
|
||||
--- Sends a message via SRS.
|
||||
@@ -517,26 +520,8 @@ end
|
||||
--
|
||||
function MESSAGE:ToSRS(frequency,modulation,gender,culture,voice,coalition,volume,coordinate)
|
||||
if _MESSAGESRS.SRSQ then
|
||||
_MESSAGESRS.MSRS:SetLabel(self.MessageCategory or _MESSAGESRS.MSRS.Label or "MESSAGE")
|
||||
if gender then
|
||||
_MESSAGESRS.MSRS:SetGender(gender)
|
||||
end
|
||||
if coalition then
|
||||
_MESSAGESRS.MSRS:SetCoalition(coalition)
|
||||
end
|
||||
if culture then
|
||||
_MESSAGESRS.MSRS:SetCulture(culture)
|
||||
end
|
||||
if volume then
|
||||
_MESSAGESRS.MSRS:SetVolume(volume)
|
||||
end
|
||||
if coordinate then
|
||||
_MESSAGESRS.MSRS:SetCoordinate(coordinate)
|
||||
end
|
||||
if voice then
|
||||
_MESSAGESRS.MSRS:SetVoice(voice)
|
||||
end
|
||||
_MESSAGESRS.SRSQ:NewTransmission(self.MessageText,nil,_MESSAGESRS.MSRS,nil,1,nil,nil,nil,frequency,modulation)
|
||||
_MESSAGESRS.MSRS:SetVoice(voice or _MESSAGESRS.Voice)
|
||||
_MESSAGESRS.SRSQ:NewTransmission(self.MessageText,nil,_MESSAGESRS.MSRS,nil,nil,nil,nil,nil,frequency,modulation,gender or _MESSAGESRS.Gender,culture or _MESSAGESRS.Culture,voice or _MESSAGESRS.Voice,volume,self.MessageCategory)
|
||||
end
|
||||
return self
|
||||
end
|
||||
@@ -606,4 +591,3 @@ function MESSAGE:ToSRSAll(frequency,modulation,gender,culture,voice,volume,coord
|
||||
self:ToSRS(frequency,modulation,gender,culture,voice,coalition.side.NEUTRAL,volume,coordinate)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **funkyfranky**
|
||||
--
|
||||
--
|
||||
-- ===
|
||||
-- @module Core.Pathline
|
||||
-- @image CORE_Pathline.png
|
||||
@@ -31,30 +31,30 @@
|
||||
-- ===
|
||||
--
|
||||
-- # The PATHLINE Concept
|
||||
--
|
||||
--
|
||||
-- List of points defining a path from A to B. The pathline can consist of multiple points. Each point holds the information of its position, the surface type, the land height
|
||||
-- and the water depth (if over sea).
|
||||
--
|
||||
--
|
||||
-- Line drawings created in the mission editor are automatically registered as pathlines and stored in the MOOSE database.
|
||||
-- They can be accessed with the @{#PATHLINE.FindByName) function.
|
||||
--
|
||||
--
|
||||
-- # Constructor
|
||||
--
|
||||
--
|
||||
-- The @{PATHLINE.New) function creates a new PATHLINE object. This does not hold any points. Points can be added with the @{#PATHLINE.AddPointFromVec2} and @{#PATHLINE.AddPointFromVec3}
|
||||
--
|
||||
--
|
||||
-- For a given table of 2D or 3D positions, a new PATHLINE object can be created with the @{#PATHLINE.NewFromVec2Array} or @{#PATHLINE.NewFromVec3Array}, respectively.
|
||||
--
|
||||
--
|
||||
-- # Line Drawings
|
||||
--
|
||||
--
|
||||
-- The most convenient way to create a pathline is the draw panel feature in the DCS mission editor. You can select "Line" and then "Segments", "Segment" or "Free" to draw your lines.
|
||||
-- These line drawings are then automatically added to the MOOSE database as PATHLINE objects and can be retrieved with the @{#PATHLINE.FindByName) function, where the name is the one
|
||||
-- you specify in the draw panel.
|
||||
--
|
||||
--
|
||||
-- # Mark on F10 map
|
||||
--
|
||||
-- The ponints of the PATHLINE can be marked on the F10 map with the @{#PATHLINE.MarkPoints}(`true`) function. The mark points contain information of the surface type, land height and
|
||||
--
|
||||
-- The ponints of the PATHLINE can be marked on the F10 map with the @{#PATHLINE.MarkPoints}(`true`) function. The mark points contain information of the surface type, land height and
|
||||
-- water depth.
|
||||
--
|
||||
--
|
||||
-- To remove the marks, use @{#PATHLINE.MarkPoints}(`false`).
|
||||
--
|
||||
-- @field #PATHLINE
|
||||
@@ -108,7 +108,7 @@ function PATHLINE:New(Name)
|
||||
|
||||
-- Inherit everything from INTEL class.
|
||||
local self=BASE:Inherit(self, BASE:New()) --#PATHLINE
|
||||
|
||||
|
||||
self.name=Name or "Unknown Path"
|
||||
|
||||
self.lid=string.format("PATHLINE %s | ", self.name)
|
||||
@@ -172,7 +172,7 @@ end
|
||||
function PATHLINE:AddPointFromVec2(Vec2, Index, Point)
|
||||
|
||||
if Vec2 then
|
||||
|
||||
|
||||
-- Create a new point.
|
||||
local point=self:_CreatePoint(Vec2)
|
||||
|
||||
@@ -189,9 +189,9 @@ function PATHLINE:AddPointFromVec2(Vec2, Index, Point)
|
||||
-- Add add the end.
|
||||
table.insert(self.points, point)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -204,7 +204,7 @@ end
|
||||
function PATHLINE:AddPointFromVec3(Vec3, Index, Point)
|
||||
|
||||
if Vec3 then
|
||||
|
||||
|
||||
local point=self:_CreatePoint(Vec3)
|
||||
|
||||
if Index then
|
||||
@@ -219,17 +219,17 @@ function PATHLINE:AddPointFromVec3(Vec3, Index, Point)
|
||||
table.insert(self.points, point)
|
||||
end
|
||||
end
|
||||
|
||||
return point
|
||||
|
||||
return point
|
||||
end
|
||||
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get name of pathline.
|
||||
-- @param #PATHLINE self
|
||||
-- @return #string Name of the pathline.
|
||||
function PATHLINE:GetName()
|
||||
function PATHLINE:GetName()
|
||||
return self.name
|
||||
end
|
||||
|
||||
@@ -244,7 +244,7 @@ end
|
||||
--- Get points of pathline. Not that points are tables, that contain more information as just the 2D or 3D position but also the surface type etc.
|
||||
-- @param #PATHLINE self
|
||||
-- @return #list <Core.Pathline#PATHLINE.Point> List of points.
|
||||
function PATHLINE:GetPoints()
|
||||
function PATHLINE:GetPoints()
|
||||
return self.points
|
||||
end
|
||||
|
||||
@@ -261,7 +261,7 @@ function PATHLINE:GetSetments()
|
||||
segment.p2=self.points[i+1]
|
||||
table.insert(segments, segment)
|
||||
end
|
||||
|
||||
|
||||
return segments
|
||||
end
|
||||
|
||||
@@ -271,7 +271,7 @@ end
|
||||
function PATHLINE:GetPoints3D()
|
||||
|
||||
local vecs={}
|
||||
|
||||
|
||||
for _,_point in pairs(self.points) do
|
||||
local point=_point --#PATHLINE.Point
|
||||
table.insert(vecs, point.vec3)
|
||||
@@ -286,7 +286,7 @@ end
|
||||
function PATHLINE:GetPoints2D()
|
||||
|
||||
local vecs={}
|
||||
|
||||
|
||||
for _,_point in pairs(self.points) do
|
||||
local point=_point --#PATHLINE.Point
|
||||
table.insert(vecs, point.vec2)
|
||||
@@ -301,7 +301,7 @@ end
|
||||
function PATHLINE:GetCoordinats()
|
||||
|
||||
local vecs={}
|
||||
|
||||
|
||||
for _,_point in pairs(self.points) do
|
||||
local point=_point --#PATHLINE.Point
|
||||
local coord=COORDINATE:NewFromVec3(point.vec3)
|
||||
@@ -318,11 +318,11 @@ end
|
||||
function PATHLINE:GetPointFromIndex(n)
|
||||
|
||||
local N=self:GetNumberOfPoints()
|
||||
|
||||
|
||||
n=n or 1
|
||||
|
||||
local point=nil --#PATHLINE.Point
|
||||
|
||||
|
||||
if n>=1 and n<=N then
|
||||
point=self.point[n]
|
||||
else
|
||||
@@ -339,11 +339,11 @@ end
|
||||
function PATHLINE:GetPoint3DFromIndex(n)
|
||||
|
||||
local point=self:GetPointFromIndex(n)
|
||||
|
||||
|
||||
if point then
|
||||
return point.vec3
|
||||
end
|
||||
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -354,11 +354,11 @@ end
|
||||
function PATHLINE:GetPoint2DFromIndex(n)
|
||||
|
||||
local point=self:GetPointFromIndex(n)
|
||||
|
||||
|
||||
if point then
|
||||
return point.vec2
|
||||
end
|
||||
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -371,28 +371,28 @@ function PATHLINE:MarkPoints(Switch)
|
||||
|
||||
for i,_point in pairs(self.points) do
|
||||
local point=_point --#PATHLINE.Point
|
||||
|
||||
|
||||
if Switch==false then
|
||||
|
||||
|
||||
if point.markerID then
|
||||
UTILS.RemoveMark(point.markerID)
|
||||
end
|
||||
|
||||
|
||||
else
|
||||
|
||||
|
||||
if point.markerID then
|
||||
UTILS.RemoveMark(point.markerID)
|
||||
end
|
||||
|
||||
|
||||
point.markerID=UTILS.GetMarkID()
|
||||
|
||||
|
||||
local text=string.format("Pathline %s: Point #%d [UID=%d]\nSurface Type=%d\nHeight=%.1f m\nDepth=%.1f m", self.name, i, point.uid, point.surfaceType, point.landHeight, point.depth)
|
||||
|
||||
|
||||
trigger.action.markToAll(point.markerID, text, point.vec3, "")
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -414,32 +414,32 @@ function PATHLINE:Draw(Switch, Coalition, Color, LineType)
|
||||
|
||||
for i,_point in pairs(self.points) do
|
||||
local point=_point --#PATHLINE.Point
|
||||
|
||||
|
||||
if point.lineID then
|
||||
UTILS.RemoveMark(point.lineID)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
else
|
||||
|
||||
for i=2,#self.points do
|
||||
|
||||
|
||||
local p1=self.points[i-1] --#PATHLINE.Point
|
||||
local p2=self.points[i] --#PATHLINE.Point
|
||||
|
||||
|
||||
if p2.lineID then
|
||||
UTILS.RemoveMark(p2.lineID)
|
||||
end
|
||||
|
||||
|
||||
p2.lineID=UTILS.GetMarkID()
|
||||
|
||||
|
||||
trigger.action.lineToAll(Coalition, p2.lineID, p1.vec3, p2.vec3, Color, LineType)
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -451,31 +451,31 @@ end
|
||||
-- @return #PATHLINE.Segment Closest segment of ref point.
|
||||
function PATHLINE:GetClosestPoint2D(Vec2)
|
||||
|
||||
local P=nil --DCS#Vec2
|
||||
local P=nil --DCS#Vec2
|
||||
local D=math.huge
|
||||
local S={} --#PATHLINE.Segment
|
||||
|
||||
|
||||
for i=2,#self.points do
|
||||
|
||||
local A=self.points[i-1] --#PATHLINE.Point
|
||||
local B=self.points[i] --#PATHLINE.Point
|
||||
|
||||
|
||||
local a=A.vec2
|
||||
local b=B.vec2
|
||||
|
||||
local ab=UTILS.Vec2Substract(b, a)
|
||||
|
||||
local ab=UTILS.Vec2Substract(b, a)
|
||||
local ap=UTILS.Vec2Substract(Vec2, a)
|
||||
|
||||
|
||||
local proj=UTILS.Vec2Dot(ap, ab)
|
||||
|
||||
|
||||
local lab=UTILS.Vec2Norm(ab)
|
||||
|
||||
|
||||
local f=proj/lab/lab
|
||||
|
||||
|
||||
-- Debug info.
|
||||
local text=string.format("FF Proj=%.1f, |ab|=%.1f, f=%.1f", proj, lab, f)
|
||||
self:T(self.lid..text)
|
||||
|
||||
|
||||
-- Cases for finite segment.
|
||||
local p=nil --DCS#Vec2
|
||||
if f<0 then
|
||||
@@ -484,21 +484,21 @@ function PATHLINE:GetClosestPoint2D(Vec2)
|
||||
p=b
|
||||
else
|
||||
local r=UTILS.Vec2Mult(ab, f)
|
||||
p=UTILS.Vec2Add(a, r)
|
||||
p=UTILS.Vec2Add(a, r)
|
||||
end
|
||||
|
||||
|
||||
-- Distance.
|
||||
local d=UTILS.VecDist2D(p, Vec2)
|
||||
|
||||
|
||||
if d<=D then
|
||||
D=d
|
||||
P=p
|
||||
S.p1=A
|
||||
S.p2=B
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
return P, D, S
|
||||
end
|
||||
|
||||
@@ -514,32 +514,32 @@ function PATHLINE:GetClosestPoint3D(Vec3)
|
||||
local P=nil --DCS#Vec3
|
||||
local D=math.huge
|
||||
local S={} --#PATHLINE.Segment
|
||||
|
||||
|
||||
if not Vec3 then
|
||||
self:E(self.lid.."ERROR: input Vec3 is nil!")
|
||||
return nil, nil, nil
|
||||
end
|
||||
|
||||
|
||||
for i=2,#self.points do
|
||||
|
||||
local A=self.points[i-1] --#PATHLINE.Point
|
||||
local B=self.points[i] --#PATHLINE.Point
|
||||
|
||||
|
||||
local a=A.vec3
|
||||
local b=B.vec3
|
||||
|
||||
local ab=UTILS.VecSubstract(b, a)
|
||||
|
||||
local ab=UTILS.VecSubstract(b, a)
|
||||
local ap=UTILS.VecSubstract(Vec3, a)
|
||||
|
||||
|
||||
local proj=UTILS.VecDot(ap, ab)
|
||||
|
||||
|
||||
local lab=UTILS.VecNorm(ab)
|
||||
|
||||
|
||||
local f=proj/lab/lab
|
||||
|
||||
|
||||
-- Debug info.
|
||||
self:T(self.lid..string.format("Proj=%.1f, |ab|=%.1f, f=%.1f", proj, lab, f))
|
||||
|
||||
|
||||
-- Cases for finite segment.
|
||||
local p=nil --DCS#Vec2
|
||||
if f<0 then
|
||||
@@ -548,21 +548,21 @@ function PATHLINE:GetClosestPoint3D(Vec3)
|
||||
p=b
|
||||
else
|
||||
local r=UTILS.VecMult(ab, f)
|
||||
p=UTILS.VecAdd(a, r)
|
||||
p=UTILS.VecAdd(a, r)
|
||||
end
|
||||
|
||||
|
||||
-- Distance.
|
||||
local d=UTILS.VecDist3D(p, Vec3)
|
||||
|
||||
|
||||
if d<=D then
|
||||
D=d
|
||||
P=p
|
||||
S.p1=A
|
||||
S.p2=B
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
return P, D, S
|
||||
end
|
||||
|
||||
@@ -578,26 +578,26 @@ function PATHLINE:WriteJSON(FileName)
|
||||
|
||||
-- JSON script.
|
||||
local json=loadfile("Scripts\\JSON.lua")()
|
||||
|
||||
|
||||
local data={}
|
||||
|
||||
|
||||
-- We store the name and the points.
|
||||
data.name=self.name
|
||||
data.name=self.name
|
||||
data.points=self.points
|
||||
for i,_point in pairs(self.points) do
|
||||
local point=_point --#PATHLINE.Point
|
||||
--point.markerID=nil
|
||||
end
|
||||
|
||||
|
||||
-- Encode data to raw JSON. Encode converts a lua table into JSON string that can be written to file.
|
||||
local raw_json=json:encode(data)
|
||||
|
||||
|
||||
-- Debug data.
|
||||
self:T(data)
|
||||
|
||||
-- Write in "User/Saved Games/" Folder.
|
||||
local filepath=lfs.writedir() .. FileName
|
||||
|
||||
|
||||
-- Open file for writing.
|
||||
local f = io.open(filepath, "wb")
|
||||
if f then
|
||||
@@ -607,10 +607,10 @@ function PATHLINE:WriteJSON(FileName)
|
||||
else
|
||||
self:E(self.lid .. string.format( "ERROR: Could not save PATHLINE to file %s", tostring(filepath)))
|
||||
end
|
||||
|
||||
|
||||
else
|
||||
self:E(self.lid .. string.format( "ERROR: Could not save results because IO and/or LFS are not de-sanitized!"))
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -625,12 +625,12 @@ function PATHLINE:NewFromJSON(FileName)
|
||||
|
||||
-- JSON script.
|
||||
local json=loadfile("Scripts\\JSON.lua")()
|
||||
|
||||
|
||||
local data={}
|
||||
|
||||
|
||||
-- Write in "User/Saved Games/" Folder.
|
||||
local filepath=lfs.writedir() .. FileName
|
||||
|
||||
|
||||
--env.info(filepath)
|
||||
|
||||
-- Open file in binary mode for reading.
|
||||
@@ -642,36 +642,36 @@ function PATHLINE:NewFromJSON(FileName)
|
||||
env.info(string.format("WARNING: Could not load PATHLINE from file %s!", tostring(filepath)))
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
-- Decode JSON data to get a lua table.
|
||||
local data=json:decode(data)
|
||||
|
||||
|
||||
if data and data.name then
|
||||
|
||||
-- Create a new pathline instance.
|
||||
local self=PATHLINE:New(data.name)
|
||||
|
||||
|
||||
for i=1,#data.points do
|
||||
local point=data.points[i] --#PATHLINE.Point
|
||||
|
||||
|
||||
-- Create new point from data.
|
||||
local p=self:AddPointFromVec3(point.vec3)
|
||||
|
||||
|
||||
-- Set name.
|
||||
p.name=point.name
|
||||
|
||||
|
||||
-- Remove marker ID.
|
||||
p.markerID=nil
|
||||
end
|
||||
|
||||
return self
|
||||
|
||||
return self
|
||||
else
|
||||
BASE:E("ERROR: Cannot find pathline name in data from JSON file. File may be corrupted!")
|
||||
end
|
||||
else
|
||||
BASE:E("ERROR: IO and/or LFS not de-sanitized! Cannot read file.")
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -685,12 +685,12 @@ end
|
||||
function PATHLINE:_CreatePoint(Vec)
|
||||
|
||||
local point={} --#PATHLINE.Point
|
||||
|
||||
|
||||
self.counter=self.counter+1
|
||||
|
||||
|
||||
point.uid=self.counter
|
||||
point.mother=self.name
|
||||
|
||||
|
||||
point.name=string.format("%s #%d", self.name, point.uid)
|
||||
|
||||
if Vec.z then
|
||||
@@ -698,17 +698,17 @@ function PATHLINE:_CreatePoint(Vec)
|
||||
point.vec3=UTILS.DeepCopy(Vec)
|
||||
point.vec2={x=Vec.x, y=Vec.z}
|
||||
else
|
||||
-- Given vec is 2D
|
||||
-- Given vec is 2D
|
||||
point.vec2=UTILS.DeepCopy(Vec)
|
||||
point.vec3={x=Vec.x, y=land.getHeight(Vec), z=Vec.y}
|
||||
end
|
||||
|
||||
-- Get surface type.
|
||||
point.surfaceType=land.getSurfaceType(point.vec2)
|
||||
|
||||
|
||||
-- Get land height and depth.
|
||||
point.landHeight, point.depth=land.getSurfaceHeightWithSeabed(point.vec2)
|
||||
|
||||
|
||||
point.markerID=nil
|
||||
|
||||
return point
|
||||
@@ -722,11 +722,11 @@ function PATHLINE:_GetPointIndex(Point)
|
||||
|
||||
for i,_point in pairs(self.points) do
|
||||
local point=_point --#PATHLINE.Point
|
||||
|
||||
|
||||
if point.uid==Point.uid then
|
||||
return i
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
return nil
|
||||
@@ -734,4 +734,4 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
--
|
||||
-- A SCHEDULER can manage **multiple** (repeating) schedules. Each planned or executing schedule has a unique **ScheduleID**.
|
||||
-- The ScheduleID is returned when the method @{#SCHEDULER.Schedule}() is called.
|
||||
-- It is recommended to store the ScheduleID in a variable, as it is used in the methods @{SCHEDULER.Start}() and @{SCHEDULER.Stop}(),
|
||||
-- It is recommended to store the ScheduleID in a variable, as it is used in the methods @{#SCHEDULER.Start}() and @{#SCHEDULER.Stop}(),
|
||||
-- which can start and stop specific repeating schedules respectively within a SCHEDULER object.
|
||||
--
|
||||
-- ## SCHEDULER constructor
|
||||
|
||||
@@ -5471,7 +5471,7 @@ do -- SET_CARGO
|
||||
|
||||
--- (R2.1) Remove CARGOs from SET_CARGO.
|
||||
-- @param Core.Set#SET_CARGO self
|
||||
-- @param Wrapper.Cargo#CARGO RemoveCargoNames A single name or an array of CARGO names.
|
||||
-- @param Cargo.Cargo#CARGO RemoveCargoNames A single name or an array of CARGO names.
|
||||
-- @return Core.Set#SET_CARGO self
|
||||
function SET_CARGO:RemoveCargosByName( RemoveCargoNames ) -- R2.1
|
||||
|
||||
@@ -5487,7 +5487,7 @@ do -- SET_CARGO
|
||||
--- (R2.1) Finds a Cargo based on the Cargo Name.
|
||||
-- @param #SET_CARGO self
|
||||
-- @param #string CargoName
|
||||
-- @return Wrapper.Cargo#CARGO The found Cargo.
|
||||
-- @return Cargo.Cargo#CARGO The found Cargo.
|
||||
function SET_CARGO:FindCargo( CargoName ) -- R2.1
|
||||
|
||||
local CargoFound = self.Set[CargoName]
|
||||
@@ -5630,7 +5630,7 @@ do -- SET_CARGO
|
||||
--- (R2.1) Iterate the SET_CARGO while identifying the nearest @{Cargo.Cargo#CARGO} from a @{Core.Point#POINT_VEC2}.
|
||||
-- @param #SET_CARGO self
|
||||
-- @param Core.Point#POINT_VEC2 PointVec2 A @{Core.Point#POINT_VEC2} object from where to evaluate the closest @{Cargo.Cargo#CARGO}.
|
||||
-- @return Wrapper.Cargo#CARGO The closest @{Cargo.Cargo#CARGO}.
|
||||
-- @return Cargo.Cargo#CARGO The closest @{Cargo.Cargo#CARGO}.
|
||||
function SET_CARGO:FindNearestCargoFromPointVec2( PointVec2 ) -- R2.1
|
||||
self:F2( PointVec2 )
|
||||
|
||||
@@ -5842,6 +5842,7 @@ do -- SET_ZONE
|
||||
},
|
||||
FilterMeta = {
|
||||
},
|
||||
Checktime = 5,
|
||||
}
|
||||
|
||||
--- Creates a new SET_ZONE object, building a set of zones.
|
||||
@@ -6182,7 +6183,170 @@ do -- SET_ZONE
|
||||
|
||||
return zmin, dmin
|
||||
end
|
||||
|
||||
|
||||
--- Set the check time for SET_ZONE:Trigger()
|
||||
-- @param #SET_ZONE self
|
||||
-- @param #number seconds Check every seconds for objects entering or leaving the zone. Defaults to 5 secs.
|
||||
-- @return #SET_ZONE self
|
||||
function SET_ZONE:SetCheckTime(seconds)
|
||||
self.Checktime = seconds or 5
|
||||
return self
|
||||
end
|
||||
|
||||
--- Start watching if the Object or Objects move into or out of our set of zones.
|
||||
-- @param #SET_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Objects Object or Objects to watch, can be of type UNIT, GROUP, CLIENT, or SET\_UNIT, SET\_GROUP, SET\_CLIENT
|
||||
-- @return #SET_ZONE self
|
||||
-- @usage
|
||||
-- -- Create a SET_GROUP and a SET_ZONE for this:
|
||||
--
|
||||
-- local groupset = SET_GROUP:New():FilterPrefixes("Aerial"):FilterStart()
|
||||
--
|
||||
-- -- Trigger will check each zone of the SET_ZONE every 5 secs for objects entering or leaving from the groupset
|
||||
-- local zoneset = SET_ZONE:New():FilterPrefixes("Target Zone"):FilterOnce():Trigger(groupset)
|
||||
--
|
||||
-- -- Draw zones on map so we see what's going on
|
||||
-- zoneset:ForEachZone(
|
||||
-- function(zone)
|
||||
-- zone:DrawZone(-1, {0,1,0}, Alpha, FillColor, FillAlpha, 4, ReadOnly)
|
||||
-- end
|
||||
-- )
|
||||
--
|
||||
-- -- This FSM function will be called for entering objects
|
||||
-- function zoneset:OnAfterEnteredZone(From,Event,To,Controllable,Zone)
|
||||
-- MESSAGE:New("Group "..Controllable:GetName() .. " entered zone "..Zone:GetName(),10,"Set Trigger"):ToAll()
|
||||
-- end
|
||||
--
|
||||
-- -- This FSM function will be called for leaving objects
|
||||
-- function zoneset:OnAfterLeftZone(From,Event,To,Controllable,Zone)
|
||||
-- MESSAGE:New("Group "..Controllable:GetName() .. " left zone "..Zone:GetName(),10,"Set Trigger"):ToAll()
|
||||
-- end
|
||||
--
|
||||
-- -- Stop watching after 1 hour
|
||||
-- zoneset:__TriggerStop(3600)
|
||||
function SET_ZONE:Trigger(Objects)
|
||||
--self:I("Added Set_Zone Trigger")
|
||||
self:AddTransition("*","TriggerStart","TriggerRunning")
|
||||
self:AddTransition("*","EnteredZone","*")
|
||||
self:AddTransition("*","LeftZone","*")
|
||||
self:AddTransition("*","TriggerRunCheck","*")
|
||||
self:AddTransition("*","TriggerStop","TriggerStopped")
|
||||
self:TriggerStart()
|
||||
self.checkobjects = Objects
|
||||
if UTILS.IsInstanceOf(Objects,"SET_BASE") then
|
||||
self.objectset = Objects.Set
|
||||
else
|
||||
self.objectset = {Objects}
|
||||
end
|
||||
self:_TriggerCheck(true)
|
||||
self:__TriggerRunCheck(self.Checktime)
|
||||
return self
|
||||
|
||||
------------------------
|
||||
--- Pseudo Functions ---
|
||||
------------------------
|
||||
|
||||
--- Triggers the FSM event "TriggerStop". Stops the SET_ZONE Trigger.
|
||||
-- @function [parent=#SET_ZONE] TriggerStop
|
||||
-- @param #SET_ZONE self
|
||||
|
||||
--- Triggers the FSM event "TriggerStop" after a delay.
|
||||
-- @function [parent=#SET_ZONE] __TriggerStop
|
||||
-- @param #SET_ZONE self
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
--- On After "EnteredZone" event. An observed object has entered the zone.
|
||||
-- @function [parent=#SET_ZONE] OnAfterEnteredZone
|
||||
-- @param #SET_ZONE self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The controllable entering the zone.
|
||||
-- @param Core.Zone#ZONE_BASE Zone The zone entered.
|
||||
|
||||
--- On After "LeftZone" event. An observed object has left the zone.
|
||||
-- @function [parent=#SET_ZONE] OnAfterLeftZone
|
||||
-- @param #SET_ZONE self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The controllable leaving the zone.
|
||||
-- @param Core.Zone#ZONE_BASE Zone The zone left.
|
||||
end
|
||||
|
||||
--- (Internal) Check the assigned objects for being in/out of the zone
|
||||
-- @param #SET_ZONE self
|
||||
-- @param #boolean fromstart If true, do the init of the objects
|
||||
-- @return #SET_ZONE self
|
||||
function SET_ZONE:_TriggerCheck(fromstart)
|
||||
--self:I("_TriggerCheck | FromStart = "..tostring(fromstart))
|
||||
if fromstart then
|
||||
for _,_object in pairs(self.objectset) do
|
||||
local obj = _object -- Wrapper.Controllable#CONTROLLABLE
|
||||
if obj and obj:IsAlive() then
|
||||
for _,_zone in pairs(self.Set) do
|
||||
if not obj.TriggerInZone then obj.TriggerInZone = {} end
|
||||
if _zone:IsCoordinateInZone(obj:GetCoordinate()) then
|
||||
obj.TriggerInZone[_zone.ZoneName] = true
|
||||
else
|
||||
obj.TriggerInZone[_zone.ZoneName] = false
|
||||
end
|
||||
--self:I("Object "..obj:GetName().." is in zone = "..tostring(obj.TriggerInZone[_zone.ZoneName]))
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for _,_object in pairs(self.objectset) do
|
||||
local obj = _object -- Wrapper.Controllable#CONTROLLABLE
|
||||
if obj and obj:IsAlive() then
|
||||
for _,_zone in pairs(self.Set) do
|
||||
-- Check for pop-up objects
|
||||
if not obj.TriggerInZone then
|
||||
-- has not been tagged previously - wasn't in set!
|
||||
obj.TriggerInZone = {}
|
||||
end
|
||||
if not obj.TriggerInZone[_zone.ZoneName] then
|
||||
-- has not been tagged previously - wasn't in set!
|
||||
obj.TriggerInZone[_zone.ZoneName] = false
|
||||
end
|
||||
-- is obj in zone?
|
||||
local inzone = _zone:IsCoordinateInZone(obj:GetCoordinate())
|
||||
--self:I("Object "..obj:GetName().." is in zone: "..tostring(inzone))
|
||||
if inzone and not obj.TriggerInZone[_zone.ZoneName] then
|
||||
-- wasn't in zone before
|
||||
--self:I("Newly entered")
|
||||
self:__EnteredZone(0.5,obj,_zone)
|
||||
obj.TriggerInZone[_zone.ZoneName] = true
|
||||
elseif (not inzone) and obj.TriggerInZone[_zone.ZoneName] then
|
||||
-- has left the zone
|
||||
--self:I("Newly left")
|
||||
self:__LeftZone(0.5,obj,_zone)
|
||||
obj.TriggerInZone[_zone.ZoneName] = false
|
||||
else
|
||||
--self:I("Not left or not entered, or something went wrong!")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- (Internal) Check the assigned objects for being in/out of the zone
|
||||
-- @param #SET_ZONE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string to
|
||||
-- @return #SET_ZONE self
|
||||
function SET_ZONE:onafterTriggerRunCheck(From,Event,To)
|
||||
--self:I("onafterTriggerRunCheck")
|
||||
--self:I({From, Event, To})
|
||||
if self:GetState() ~= "TriggerStopped" then
|
||||
self:_TriggerCheck()
|
||||
self:__TriggerRunCheck(self.Checktime)
|
||||
end
|
||||
return self
|
||||
end
|
||||
end
|
||||
|
||||
do -- SET_ZONE_GOAL
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
--
|
||||
-- Will customize which display format is used to indicate A2G coordinates in text as part of the Command Center communications.
|
||||
--
|
||||
-- - A2G BR: [Bearing Range](https://en.wikipedia.org/wiki/Bearing_(navigation)).
|
||||
-- - A2G BR: [Bearing Range](https://en.wikipedia.org/wiki/Bearing_\(navigation\)).
|
||||
-- - A2G MGRS: The [Military Grid Reference System](https://en.wikipedia.org/wiki/Military_Grid_Reference_System). The accuracy can also be adapted.
|
||||
-- - A2G LL DMS: Latitude Longitude [Degrees Minutes Seconds](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion). The accuracy can also be adapted.
|
||||
-- - A2G LL DDM: Latitude Longitude [Decimal Degrees Minutes](https://en.wikipedia.org/wiki/Decimal_degrees). The accuracy can also be adapted.
|
||||
@@ -105,9 +105,9 @@
|
||||
-- There are different methods that can be used to change the **System settings** using the \_SETTINGS object.
|
||||
--
|
||||
-- - @{#SETTINGS.SetA2G_BR}(): Enable the BR display formatting by default.
|
||||
-- - @{#SETTINGS.SetA2G_MGRS}(): Enable the MGRS display formatting by default. Use @{SETTINGS.SetMGRS_Accuracy}() to adapt the accuracy of the MGRS formatting.
|
||||
-- - @{#SETTINGS.SetA2G_LL_DMS}(): Enable the LL DMS display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
-- - @{#SETTINGS.SetA2G_LL_DDM}(): Enable the LL DDM display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
-- - @{#SETTINGS.SetA2G_MGRS}(): Enable the MGRS display formatting by default. Use @{#SETTINGS.SetMGRS_Accuracy}() to adapt the accuracy of the MGRS formatting.
|
||||
-- - @{#SETTINGS.SetA2G_LL_DMS}(): Enable the LL DMS display formatting by default. Use @{#SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
-- - @{#SETTINGS.SetA2G_LL_DDM}(): Enable the LL DDM display formatting by default. Use @{#SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
--
|
||||
-- ### 3.1.4) A2G coordinates setting - additional notes
|
||||
--
|
||||
@@ -120,7 +120,7 @@
|
||||
--
|
||||
-- Will customize which display format is used to indicate A2A coordinates in text as part of the Command Center communications.
|
||||
--
|
||||
-- - A2A BRAA: [Bearing Range Altitude Aspect](https://en.wikipedia.org/wiki/Bearing_(navigation)).
|
||||
-- - A2A BRAA: [Bearing Range Altitude Aspect](https://en.wikipedia.org/wiki/Bearing_\(navigation\)).
|
||||
-- - A2A MGRS: The [Military Grid Reference System](https://en.wikipedia.org/wiki/Military_Grid_Reference_System). The accuracy can also be adapted.
|
||||
-- - A2A LL DMS: Lattitude Longitude [Degrees Minutes Seconds](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion). The accuracy can also be adapted.
|
||||
-- - A2A LL DDM: Lattitude Longitude [Decimal Degrees and Minutes](https://en.wikipedia.org/wiki/Decimal_degrees). The accuracy can also be adapted.
|
||||
@@ -135,9 +135,9 @@
|
||||
-- There are different methods that can be used to change the **System settings** using the \_SETTINGS object.
|
||||
--
|
||||
-- - @{#SETTINGS.SetA2A_BRAA}(): Enable the BR display formatting by default.
|
||||
-- - @{#SETTINGS.SetA2A_MGRS}(): Enable the MGRS display formatting by default. Use @{SETTINGS.SetMGRS_Accuracy}() to adapt the accuracy of the MGRS formatting.
|
||||
-- - @{#SETTINGS.SetA2A_LL_DMS}(): Enable the LL DMS display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
-- - @{#SETTINGS.SetA2A_LL_DDM}(): Enable the LL DDM display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
-- - @{#SETTINGS.SetA2A_MGRS}(): Enable the MGRS display formatting by default. Use @{#SETTINGS.SetMGRS_Accuracy}() to adapt the accuracy of the MGRS formatting.
|
||||
-- - @{#SETTINGS.SetA2A_LL_DMS}(): Enable the LL DMS display formatting by default. Use @{#SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
-- - @{#SETTINGS.SetA2A_LL_DDM}(): Enable the LL DDM display formatting by default. Use @{#SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
-- - @{#SETTINGS.SetA2A_BULLS}(): Enable the BULLSeye display formatting by default.
|
||||
--
|
||||
-- ### 3.2.4) A2A coordinates settings - additional notes
|
||||
@@ -190,8 +190,8 @@
|
||||
--
|
||||
-- There are different methods that can be used to change the **System settings** using the \_SETTINGS object.
|
||||
--
|
||||
-- - @{#SETTINGS.SetMessageTime}(): Define for a specific @{Message.MESSAGE.MessageType} the duration to be displayed in seconds.
|
||||
-- - @{#SETTINGS.GetMessageTime}(): Retrieves for a specific @{Message.MESSAGE.MessageType} the duration to be displayed in seconds.
|
||||
-- - @{#SETTINGS.SetMessageTime}(): Define for a specific @{Core.Message#MESSAGE.MessageType} the duration to be displayed in seconds.
|
||||
-- - @{#SETTINGS.GetMessageTime}(): Retrieves for a specific @{Core.Message#MESSAGE.MessageType} the duration to be displayed in seconds.
|
||||
--
|
||||
-- ## 3.5) **Era** of the battle
|
||||
--
|
||||
@@ -283,21 +283,21 @@ do -- SETTINGS
|
||||
function SETTINGS:SetMetric()
|
||||
self.Metric = true
|
||||
end
|
||||
|
||||
|
||||
--- Sets the SETTINGS default text locale.
|
||||
-- @param #SETTINGS self
|
||||
-- @param #string Locale
|
||||
function SETTINGS:SetLocale(Locale)
|
||||
self.Locale = Locale or "en"
|
||||
end
|
||||
|
||||
|
||||
--- Gets the SETTINGS text locale.
|
||||
-- @param #SETTINGS self
|
||||
-- @return #string
|
||||
function SETTINGS:GetLocale()
|
||||
return self.Locale or _SETTINGS:GetLocale()
|
||||
end
|
||||
|
||||
|
||||
--- Gets if the SETTINGS is metric.
|
||||
-- @param #SETTINGS self
|
||||
-- @return #boolean true if metric.
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
-- @field #SPAWN.SpawnZoneTable SpawnZoneTable
|
||||
-- @extends Core.Base#BASE
|
||||
|
||||
--- Allows to spawn dynamically new @{Core.Group}s.
|
||||
--- Allows to spawn dynamically new @{Wrapper.Group}s.
|
||||
--
|
||||
-- Each SPAWN object needs to be have related **template groups** setup in the Mission Editor (ME),
|
||||
-- which is a normal group with the **Late Activation** flag set.
|
||||
@@ -1331,7 +1331,7 @@ do -- Delay methods
|
||||
return self
|
||||
end
|
||||
|
||||
--- Turns the Delay On for the @{Wrapper.Group} when spawning with @{SpawnScheduled}(). In effect then the 1st group will only be spawned
|
||||
--- Turns the Delay On for the @{Wrapper.Group} when spawning with @{#SpawnScheduled}(). In effect then the 1st group will only be spawned
|
||||
-- after the number of seconds given in SpawnScheduled as arguments, and not immediately.
|
||||
-- @param #SPAWN self
|
||||
-- @return #SPAWN The SPAWN object
|
||||
@@ -1669,7 +1669,7 @@ end
|
||||
-- @param #number SpawnTimeVariation The variation to be applied on the defined time interval between each new spawn.
|
||||
-- The variation is a number between 0 and 1, representing the % of variation to be applied on the time interval.
|
||||
-- @param #boolean WithDelay Do not spawn the **first** group immediately, but delay the spawn as per the calculation below.
|
||||
-- Effectively the same as @{InitDelayOn}().
|
||||
-- Effectively the same as @{#InitDelayOn}().
|
||||
-- @return #SPAWN self
|
||||
-- @usage
|
||||
-- -- NATO helicopters engaging in the battle field.
|
||||
@@ -3622,7 +3622,7 @@ function SPAWN:_OnLand( EventData )
|
||||
end
|
||||
|
||||
--- Will detect AIR Units shutting down their engines ...
|
||||
-- When the event takes place, and the method @{RepeatOnEngineShutDown} was called, the spawned Group will Re-SPAWN.
|
||||
-- When the event takes place, and the method @{#InitRepeatOnEngineShutDown} was called, the spawned Group will Re-SPAWN.
|
||||
-- But only when the Unit was registered to have landed.
|
||||
-- @param #SPAWN self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
-- ### Author: **FlightControl**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * [**Ciribob**](https://forums.eagle.ru/member.php?u=112175): Showing the way how to lase targets + how laser codes work!!! Explained the autolase script.
|
||||
-- * [**EasyEB**](https://forums.eagle.ru/member.php?u=112055): Ideas and Beta Testing
|
||||
-- * [**Wingthor**](https://forums.eagle.ru/member.php?u=123698): Beta Testing
|
||||
-- * **Ciribob**: Showing the way how to lase targets + how laser codes work!!! Explained the autolase script.
|
||||
-- * **EasyEB**: Ideas and Beta Testing
|
||||
-- * **Wingthor**: Beta Testing
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
-- @field #number ZoneID ID of zone. Only zones defined in the ME have an ID!
|
||||
-- @field #table Table of any trigger zone properties from the ME. The key is the Name of the property, and the value is the property's Value.
|
||||
-- @field #number Surface Type of surface. Only determined at the center of the zone!
|
||||
-- @field #number Checktime Check every Checktime seconds, used for ZONE:Trigger()
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
|
||||
@@ -122,6 +123,7 @@ ZONE_BASE = {
|
||||
ZoneID=nil,
|
||||
Properties={},
|
||||
Surface=nil,
|
||||
Checktime = 5,
|
||||
}
|
||||
|
||||
--- The ZONE_BASE.BoundingSquare
|
||||
@@ -571,6 +573,154 @@ function ZONE_BASE:GetZoneMaybe()
|
||||
end
|
||||
end
|
||||
|
||||
--- Set the check time for ZONE:Trigger()
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #number seconds Check every seconds for objects entering or leaving the zone. Defaults to 5 secs.
|
||||
-- @return #ZONE_BASE self
|
||||
function ZONE_BASE:SetCheckTime(seconds)
|
||||
self.Checktime = seconds or 5
|
||||
return self
|
||||
end
|
||||
|
||||
--- Start watching if the Object or Objects move into or out of a zone.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Objects Object or Objects to watch, can be of type UNIT, GROUP, CLIENT, or SET\_UNIT, SET\_GROUP, SET\_CLIENT
|
||||
-- @return #ZONE_BASE self
|
||||
-- @usage
|
||||
-- -- Create a new zone and start watching it every 5 secs for a defined GROUP entering or leaving
|
||||
-- local triggerzone = ZONE:New("ZonetoWatch"):Trigger(GROUP:FindByName("Aerial-1"))
|
||||
--
|
||||
-- -- This FSM function will be called when the group enters the zone
|
||||
-- function triggerzone:OnAfterEnteredZone(From,Event,To,Group)
|
||||
-- MESSAGE:New("Group has entered zone!",15):ToAll()
|
||||
-- end
|
||||
--
|
||||
-- -- This FSM function will be called when the group leaves the zone
|
||||
-- function triggerzone:OnAfterLeftZone(From,Event,To,Group)
|
||||
-- MESSAGE:New("Group has left zone!",15):ToAll()
|
||||
-- end
|
||||
--
|
||||
-- -- Stop watching the zone after 1 hour
|
||||
-- triggerzone:__TriggerStop(3600)
|
||||
function ZONE_BASE:Trigger(Objects)
|
||||
--self:I("Added Zone Trigger")
|
||||
self:SetStartState("TriggerStopped")
|
||||
self:AddTransition("TriggerStopped","TriggerStart","TriggerRunning")
|
||||
self:AddTransition("*","EnteredZone","*")
|
||||
self:AddTransition("*","LeftZone","*")
|
||||
self:AddTransition("*","TriggerRunCheck","*")
|
||||
self:AddTransition("*","TriggerStop","TriggerStopped")
|
||||
self:TriggerStart()
|
||||
self.checkobjects = Objects
|
||||
if UTILS.IsInstanceOf(Objects,"SET_BASE") then
|
||||
self.objectset = Objects.Set
|
||||
else
|
||||
self.objectset = {Objects}
|
||||
end
|
||||
self:_TriggerCheck(true)
|
||||
self:__TriggerRunCheck(self.Checktime)
|
||||
return self
|
||||
|
||||
------------------------
|
||||
--- Pseudo Functions ---
|
||||
------------------------
|
||||
|
||||
--- Triggers the FSM event "TriggerStop". Stops the ZONE_BASE Trigger.
|
||||
-- @function [parent=#ZONE_BASE] TriggerStop
|
||||
-- @param #ZONE_BASE self
|
||||
|
||||
--- Triggers the FSM event "TriggerStop" after a delay.
|
||||
-- @function [parent=#ZONE_BASE] __TriggerStop
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
--- On After "EnteredZone" event. An observed object has entered the zone.
|
||||
-- @function [parent=#ZONE_BASE] OnAfterEnteredZone
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The controllable entering the zone.
|
||||
|
||||
--- On After "LeftZone" event. An observed object has left the zone.
|
||||
-- @function [parent=#ZONE_BASE] OnAfterLeftZone
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The controllable leaving the zone.
|
||||
end
|
||||
|
||||
--- (Internal) Check the assigned objects for being in/out of the zone
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #boolean fromstart If true, do the init of the objects
|
||||
-- @return #ZONE_BASE self
|
||||
function ZONE_BASE:_TriggerCheck(fromstart)
|
||||
--self:I("_TriggerCheck | FromStart = "..tostring(fromstart))
|
||||
local objectset = self.objectset or {}
|
||||
if fromstart then
|
||||
-- just earmark everyone in/out
|
||||
for _,_object in pairs(objectset) do
|
||||
local obj = _object -- Wrapper.Controllable#CONTROLLABLE
|
||||
if not obj.TriggerInZone then obj.TriggerInZone = {} end
|
||||
if obj and obj:IsAlive() and self:IsCoordinateInZone(obj:GetCoordinate()) then
|
||||
obj.TriggerInZone[self.ZoneName] = true
|
||||
else
|
||||
obj.TriggerInZone[self.ZoneName] = false
|
||||
end
|
||||
--self:I("Object "..obj:GetName().." is in zone = "..tostring(obj.TriggerInZone[self.ZoneName]))
|
||||
end
|
||||
else
|
||||
-- Check for changes
|
||||
for _,_object in pairs(objectset) do
|
||||
local obj = _object -- Wrapper.Controllable#CONTROLLABLE
|
||||
if obj and obj:IsAlive() then
|
||||
if not obj.TriggerInZone then
|
||||
-- has not been tagged previously - wasn't in set!
|
||||
obj.TriggerInZone = {}
|
||||
end
|
||||
if not obj.TriggerInZone[self.ZoneName] then
|
||||
-- has not been tagged previously - wasn't in set!
|
||||
obj.TriggerInZone[self.ZoneName] = false
|
||||
end
|
||||
-- is obj in zone?
|
||||
local inzone = self:IsCoordinateInZone(obj:GetCoordinate())
|
||||
--self:I("Object "..obj:GetName().." is in zone: "..tostring(inzone))
|
||||
if inzone and not obj.TriggerInZone[self.ZoneName] then
|
||||
-- wasn't in zone before
|
||||
--self:I("Newly entered")
|
||||
self:__EnteredZone(0.5,obj)
|
||||
obj.TriggerInZone[self.ZoneName] = true
|
||||
elseif (not inzone) and obj.TriggerInZone[self.ZoneName] then
|
||||
-- has left the zone
|
||||
--self:I("Newly left")
|
||||
self:__LeftZone(0.5,obj)
|
||||
obj.TriggerInZone[self.ZoneName] = false
|
||||
else
|
||||
--self:I("Not left or not entered, or something went wrong!")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- (Internal) Check the assigned objects for being in/out of the zone
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string to
|
||||
-- @return #ZONE_BASE self
|
||||
function ZONE_BASE:onafterTriggerRunCheck(From,Event,To)
|
||||
if self:GetState() ~= "TriggerStopped" then
|
||||
self:_TriggerCheck()
|
||||
self:__TriggerRunCheck(self.Checktime)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Returns the Value of the zone with the given PropertyName, or nil if no matching property exists.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #string PropertyName The name of a the TriggerZone Property to be retrieved.
|
||||
@@ -921,11 +1071,11 @@ end
|
||||
--- Scan the zone for the presence of units of the given ObjectCategories.
|
||||
-- Note that **only after** a zone has been scanned, the zone can be evaluated by:
|
||||
--
|
||||
-- * @{ZONE_RADIUS.IsAllInZoneOfCoalition}(): Scan the presence of units in the zone of a coalition.
|
||||
-- * @{ZONE_RADIUS.IsAllInZoneOfOtherCoalition}(): Scan the presence of units in the zone of an other coalition.
|
||||
-- * @{ZONE_RADIUS.IsSomeInZoneOfCoalition}(): Scan if there is some presence of units in the zone of the given coalition.
|
||||
-- * @{ZONE_RADIUS.IsNoneInZoneOfCoalition}(): Scan if there isn't any presence of units in the zone of an other coalition than the given one.
|
||||
-- * @{ZONE_RADIUS.IsNoneInZone}(): Scan if the zone is empty.
|
||||
-- * @{Core.Zone#ZONE_RADIUS.IsAllInZoneOfCoalition}(): Scan the presence of units in the zone of a coalition.
|
||||
-- * @{Core.Zone#ZONE_RADIUS.IsAllInZoneOfOtherCoalition}(): Scan the presence of units in the zone of an other coalition.
|
||||
-- * @{Core.Zone#ZONE_RADIUS.IsSomeInZoneOfCoalition}(): Scan if there is some presence of units in the zone of the given coalition.
|
||||
-- * @{Core.Zone#ZONE_RADIUS.IsNoneInZoneOfCoalition}(): Scan if there isn't any presence of units in the zone of an other coalition than the given one.
|
||||
-- * @{Core.Zone#ZONE_RADIUS.IsNoneInZone}(): Scan if the zone is empty.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param ObjectCategories An array of categories of the objects to find in the zone. E.g. `{Object.Category.UNIT}`
|
||||
-- @param UnitCategories An array of unit categories of the objects to find in the zone. E.g. `{Unit.Category.GROUND_UNIT,Unit.Category.SHIP}`
|
||||
@@ -1651,7 +1801,7 @@ ZONE_UNIT = {
|
||||
-- @param #ZONE_UNIT self
|
||||
-- @param #string ZoneName Name of the zone.
|
||||
-- @param Wrapper.Unit#UNIT ZoneUNIT The unit as the center of the zone.
|
||||
-- @param Dcs.DCSTypes#Distance Radius The radius of the zone.
|
||||
-- @param #number Radius The radius of the zone in meters.
|
||||
-- @param #table Offset A table specifying the offset. The offset table may have the following elements:
|
||||
-- dx The offset in X direction, +x is north.
|
||||
-- dy The offset in Y direction, +y is east.
|
||||
@@ -2613,11 +2763,11 @@ end
|
||||
--- Scan the zone for the presence of units of the given ObjectCategories. Does **not** scan for scenery at the moment.
|
||||
-- Note that **only after** a zone has been scanned, the zone can be evaluated by:
|
||||
--
|
||||
-- * @{ZONE_POLYGON.IsAllInZoneOfCoalition}(): Scan the presence of units in the zone of a coalition.
|
||||
-- * @{ZONE_POLYGON.IsAllInZoneOfOtherCoalition}(): Scan the presence of units in the zone of an other coalition.
|
||||
-- * @{ZONE_POLYGON.IsSomeInZoneOfCoalition}(): Scan if there is some presence of units in the zone of the given coalition.
|
||||
-- * @{ZONE_POLYGON.IsNoneInZoneOfCoalition}(): Scan if there isn't any presence of units in the zone of an other coalition than the given one.
|
||||
-- * @{ZONE_POLYGON.IsNoneInZone}(): Scan if the zone is empty.
|
||||
-- * @{Core.Zone#ZONE_POLYGON.IsAllInZoneOfCoalition}(): Scan the presence of units in the zone of a coalition.
|
||||
-- * @{Core.Zone#ZONE_POLYGON.IsAllInZoneOfOtherCoalition}(): Scan the presence of units in the zone of an other coalition.
|
||||
-- * @{Core.Zone#ZONE_POLYGON.IsSomeInZoneOfCoalition}(): Scan if there is some presence of units in the zone of the given coalition.
|
||||
-- * @{Core.Zone#ZONE_POLYGON.IsNoneInZoneOfCoalition}(): Scan if there isn't any presence of units in the zone of an other coalition than the given one.
|
||||
-- * @{Core.Zone#ZONE_POLYGON.IsNoneInZone}(): Scan if the zone is empty.
|
||||
-- @param #ZONE_POLYGON self
|
||||
-- @param ObjectCategories An array of categories of the objects to find in the zone. E.g. `{Object.Category.UNIT}`
|
||||
-- @param UnitCategories An array of unit categories of the objects to find in the zone. E.g. `{Unit.Category.GROUND_UNIT,Unit.Category.SHIP}`
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,9 +25,9 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **[funkyfranky](https://forums.eagle.ru/member.php?u=115026)**
|
||||
-- ### Author: **funkyfranky**
|
||||
--
|
||||
-- ### Contributions: [FlightControl](https://forums.eagle.ru/member.php?u=89536)
|
||||
-- ### Contributions: FlightControl
|
||||
--
|
||||
-- ====
|
||||
-- @module Functional.Artillery
|
||||
@@ -291,14 +291,14 @@
|
||||
-- ### Illumination Shells
|
||||
--
|
||||
-- ARTY groups that possess shells can fire shells with illumination bombs. First, the group needs to be equipped with this weapon. This is done by the
|
||||
-- function @{ARTY.SetIlluminationShells}(*n*, *power*), where *n* is the number of shells the group has available and *power* the illumination power in mega candela (mcd).
|
||||
-- function @{#ARTY.SetIlluminationShells}(*n*, *power*), where *n* is the number of shells the group has available and *power* the illumination power in mega candela (mcd).
|
||||
--
|
||||
-- In order to execute an engagement with illumination shells one has to use the weapon type *ARTY.WeaponType.IlluminationShells* in the
|
||||
-- @{#ARTY.AssignTargetCoord}() function.
|
||||
--
|
||||
-- In the simulation, the explosive shell that is fired is destroyed once it gets close to the target point but before it can actually impact.
|
||||
-- At this position an illumination bomb is triggered at a random altitude between 500 and 1000 meters. This interval can be set by the function
|
||||
-- @{ARTY.SetIlluminationMinMaxAlt}(*minalt*, *maxalt*).
|
||||
-- @{#ARTY.SetIlluminationMinMaxAlt}(*minalt*, *maxalt*).
|
||||
--
|
||||
-- ### Smoke Shells
|
||||
--
|
||||
|
||||
@@ -167,9 +167,9 @@
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * [**Ciribob**](https://forums.eagle.ru/member.php?u=112175): Showing the way how to lase targets + how laser codes work!!! Explained the autolase script.
|
||||
-- * [**EasyEB**](https://forums.eagle.ru/member.php?u=112055): Ideas and Beta Testing
|
||||
-- * [**Wingthor**](https://forums.eagle.ru/member.php?u=123698): Beta Testing
|
||||
-- * **Ciribob**: Showing the way how to lase targets + how laser codes work!!! Explained the autolase script.
|
||||
-- * **EasyEB**: Ideas and Beta Testing
|
||||
-- * **Wingthor**: Beta Testing
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
|
||||
@@ -2452,7 +2452,7 @@ do -- DETECTION_AREAS
|
||||
--
|
||||
-- Retrieve the DetectedItems[].Set with the method @{Functional.Detection#DETECTION_BASE.GetDetectedSet}(). A @{Core.Set#SET_UNIT} object will be returned.
|
||||
--
|
||||
-- Retrieve the formed @{Zone@ZONE_UNIT}s as a result of the grouping the detected units within the DetectionZoneRange, use the method @{Functional.Detection#DETECTION_AREAS.GetDetectionZones}().
|
||||
-- Retrieve the formed @{Core.Zone@ZONE_UNIT}s as a result of the grouping the detected units within the DetectionZoneRange, use the method @{Functional.Detection#DETECTION_AREAS.GetDetectionZones}().
|
||||
-- To understand the amount of zones created, use the method @{Functional.Detection#DETECTION_AREAS.GetDetectionZoneCount}().
|
||||
-- If you want to obtain a specific zone from the DetectedZones, use the method @{Functional.Detection#DETECTION_AREAS.GetDetectionZoneByID}() with a given index.
|
||||
--
|
||||
|
||||
@@ -21,7 +21,7 @@ do -- DETECTION_ZONES
|
||||
--
|
||||
-- Retrieve the DetectedItems[].Set with the method @{Functional.Detection#DETECTION_BASE.GetDetectedSet}(). A @{Core.Set#SET_UNIT} object will be returned.
|
||||
--
|
||||
-- Retrieve the formed @{Zone@ZONE_UNIT}s as a result of the grouping the detected units within the DetectionZoneRange, use the method @{Functional.Detection#DETECTION_BASE.GetDetectionZones}().
|
||||
-- Retrieve the formed @{Core.Zone#ZONE_UNIT}s as a result of the grouping the detected units within the DetectionZoneRange, use the method @{Functional.Detection#DETECTION_BASE.GetDetectionZones}().
|
||||
-- To understand the amount of zones created, use the method @{Functional.Detection#DETECTION_BASE.GetDetectionZoneCount}().
|
||||
-- If you want to obtain a specific zone from the DetectedZones, use the method @{Functional.Detection#DETECTION_BASE.GetDetectionZone}() with a given index.
|
||||
--
|
||||
|
||||
@@ -252,7 +252,7 @@ end
|
||||
--- Set a Detection method for the EscortClient to be reported upon.
|
||||
-- Detection methods are based on the derived classes from DETECTION_BASE.
|
||||
-- @param #ESCORT self
|
||||
-- @param Function.Detection#DETECTION_BASE Detection
|
||||
-- @param Functional.Detection#DETECTION_BASE Detection
|
||||
function ESCORT:SetDetection( Detection )
|
||||
|
||||
self.Detection = Detection
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
--
|
||||
-- # The FOX Concept
|
||||
--
|
||||
-- As you probably know [Fox](https://en.wikipedia.org/wiki/Fox_(code_word)) is a NATO brevity code for launching air-to-air munition. Therefore, the class name is not 100% accurate as this
|
||||
-- As you probably know [Fox](https://en.wikipedia.org/wiki/Fox_\(code_word\)) is a NATO brevity code for launching air-to-air munition. Therefore, the class name is not 100% accurate as this
|
||||
-- script handles air-to-air but also surface-to-air missiles.
|
||||
--
|
||||
-- # Basic Script
|
||||
|
||||
@@ -893,7 +893,7 @@ do
|
||||
|
||||
--- Function to get the HQ object for further use
|
||||
-- @param #MANTIS self
|
||||
-- @return Wrapper.GROUP#GROUP The HQ #GROUP object or *nil* if it doesn't exist
|
||||
-- @return Wrapper.Group#GROUP The HQ #GROUP object or *nil* if it doesn't exist
|
||||
function MANTIS:GetCommandCenter()
|
||||
self:T(self.lid .. "GetCommandCenter")
|
||||
if self.HQ_CC then
|
||||
@@ -929,7 +929,7 @@ do
|
||||
|
||||
--- Function to set the HQ object for further use
|
||||
-- @param #MANTIS self
|
||||
-- @param Wrapper.GROUP#GROUP group The #GROUP object to be set as HQ
|
||||
-- @param Wrapper.Group#GROUP group The #GROUP object to be set as HQ
|
||||
function MANTIS:SetCommandCenter(group)
|
||||
self:T(self.lid .. "SetCommandCenter")
|
||||
local group = group or nil
|
||||
@@ -991,7 +991,7 @@ do
|
||||
|
||||
--- Set using your own #INTEL_DLINK object instead of #DETECTION
|
||||
-- @param #MANTIS self
|
||||
-- @param Ops.Intelligence#INTEL_DLINK DLink The data link object to be used.
|
||||
-- @param Ops.Intel#INTEL_DLINK DLink The data link object to be used.
|
||||
function MANTIS:SetUsingDLink(DLink)
|
||||
self:T(self.lid .. "SetUsingDLink")
|
||||
self.DLink = true
|
||||
|
||||
@@ -46,9 +46,9 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **[funkyfranky](https://forums.eagle.ru/member.php?u=115026)**
|
||||
-- ### Author: **funkyfranky**
|
||||
--
|
||||
-- ### Contributions: [FlightControl](https://forums.eagle.ru/member.php?u=89536)
|
||||
-- ### Contributions: FlightControl
|
||||
--
|
||||
-- ===
|
||||
-- @module Functional.RAT
|
||||
@@ -225,7 +225,7 @@
|
||||
--
|
||||
-- * Landing: When an aircraft tries to land at an airport where it does not have a valid parking spot, it is immidiately despawned the moment its wheels touch the runway, i.e.
|
||||
-- when a landing event is triggered. This leads to the loss of the RAT aircraft. On possible way to circumvent the this problem is to let another RAT aircraft spawn at landing
|
||||
-- and not when it shuts down its engines. See the @{RAT.RespawnAfterLanding}() function.
|
||||
-- and not when it shuts down its engines. See the @{#RAT.RespawnAfterLanding}() function.
|
||||
-- * Spawning: When a big aircraft is dynamically spawned on a small airbase a few things can go wrong. For example, it could be spawned at a parking spot with a shelter.
|
||||
-- Or it could be damaged by a scenery object when it is taxiing out to the runway, or it could overlap with other aircraft on parking spots near by.
|
||||
--
|
||||
@@ -2474,11 +2474,11 @@ end
|
||||
-- @param #RAT self
|
||||
-- @param #number takeoff Takeoff type. Could also be air start.
|
||||
-- @param #number landing Landing type. Could also be a destination in air.
|
||||
-- @param Wrapper.Airport#AIRBASE _departure (Optional) Departure airbase.
|
||||
-- @param Wrapper.Airport#AIRBASE _destination (Optional) Destination airbase.
|
||||
-- @param Wrapper.Airbase#AIRBASE _departure (Optional) Departure airbase.
|
||||
-- @param Wrapper.Airbase#AIRBASE _destination (Optional) Destination airbase.
|
||||
-- @param #table _waypoint Initial waypoint.
|
||||
-- @return Wrapper.Airport#AIRBASE Departure airbase.
|
||||
-- @return Wrapper.Airport#AIRBASE Destination airbase.
|
||||
-- @return Wrapper.Airbase#AIRBASE Departure airbase.
|
||||
-- @return Wrapper.Airbase#AIRBASE Destination airbase.
|
||||
-- @return #table Table of flight plan waypoints.
|
||||
-- @return #nil If no valid departure or destination airport could be found.
|
||||
function RAT:_SetRoute(takeoff, landing, _departure, _destination, _waypoint)
|
||||
@@ -4605,7 +4605,7 @@ function RAT:_TaskHolding(P1, Altitude, Speed, Duration)
|
||||
end
|
||||
|
||||
--- Function which is called after passing every waypoint. Info on waypoint is given and special functions are executed.
|
||||
-- @param Core.Group#GROUP group Group of aircraft.
|
||||
-- @param Wrapper.Group#GROUP group Group of aircraft.
|
||||
-- @param #RAT rat RAT object.
|
||||
-- @param #number wp Waypoint index. Running number of the waypoints. Determines the actions to be executed.
|
||||
function RAT._WaypointFunction(group, rat, wp)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
--
|
||||
-- The RANGE class enables easy set up of bombing and strafing ranges within DCS World.
|
||||
--
|
||||
-- Implementation is based on the [Simple Range Script](https://forums.eagle.ru/showthread.php?t=157991) by [Ciribob](https://forums.eagle.ru/member.php?u=112175), which itself was motivated
|
||||
-- Implementation is based on the [Simple Range Script](https://forums.eagle.ru/showthread.php?t=157991) by Ciribob, which itself was motivated
|
||||
-- by a script by SNAFU [see here](https://forums.eagle.ru/showthread.php?t=109174).
|
||||
--
|
||||
-- [476th - Air Weapons Range Objects mod](http://www.476vfightergroup.com/downloads.php?do=file&id=287) is highly recommended for this class.
|
||||
@@ -42,9 +42,9 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **[funkyfranky](https://forums.eagle.ru/member.php?u=115026)**
|
||||
-- ### Author: **funkyfranky**
|
||||
--
|
||||
-- ### Contributions: [FlightControl](https://forums.eagle.ru/member.php?u=89536), [Ciribob](https://forums.eagle.ru/member.php?u=112175)
|
||||
-- ### Contributions: FlightControl, Ciribob
|
||||
-- ### SRS Additions: Applevangelist
|
||||
--
|
||||
-- ===
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
-- and creates a CSV file logging the scoring events and results for use at team or squadron websites.
|
||||
--
|
||||
-- SCORING automatically calculates the threat level of the objects hit and destroyed by players,
|
||||
-- which can be @{Wrapper.Unit}, @{Static) and @{Scenery} objects.
|
||||
-- which can be @{Wrapper.Unit}, @{Wrapper.Static) and @{Scenery} objects.
|
||||
--
|
||||
-- Positive score points are granted when enemy or neutral targets are destroyed.
|
||||
-- Negative score points or penalties are given when a friendly target is hit or destroyed.
|
||||
@@ -81,7 +81,7 @@
|
||||
--
|
||||
-- * **Wingthor (TAW)**: Testing & Advice.
|
||||
-- * **Dutch-Baron (TAW)**: Testing & Advice.
|
||||
-- * **[Whisper](http://forums.eagle.ru/member.php?u=3829): Testing and Advice.
|
||||
-- * **Whisper**: Testing and Advice.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **[funkyfranky](https://forums.eagle.ru/member.php?u=115026)**
|
||||
-- ### Author: **funkyfranky**
|
||||
--
|
||||
-- ### Contributions: [FlightControl](https://forums.eagle.ru/member.php?u=89536)
|
||||
-- ### Contributions: FlightControl
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
|
||||
@@ -742,7 +742,7 @@
|
||||
--
|
||||
-- ## Save Assets
|
||||
--
|
||||
-- Saving asset data to file is achieved by the @{WAREHOUSE.Save}(*path*, *filename*) function. The parameter *path* specifies the path on the file system where the
|
||||
-- Saving asset data to file is achieved by the @{#WAREHOUSE.Save}(*path*, *filename*) function. The parameter *path* specifies the path on the file system where the
|
||||
-- warehouse data is saved. If you do not specify a path, the file is saved your the DCS installation root directory.
|
||||
-- The parameter *filename* is optional and defines the name of the saved file. By default this is automatically created from the warehouse id and name, for example
|
||||
-- "Warehouse-1234_Batumi.txt".
|
||||
@@ -753,13 +753,13 @@
|
||||
--
|
||||
-- ### Automatic Save at Mission End
|
||||
--
|
||||
-- The assets can be saved automatically when the mission is ended via the @{WAREHOUSE.SetSaveOnMissionEnd}(*path*, *filename*) function, i.e.
|
||||
-- The assets can be saved automatically when the mission is ended via the @{#WAREHOUSE.SetSaveOnMissionEnd}(*path*, *filename*) function, i.e.
|
||||
--
|
||||
-- warehouseBatumi:SetSaveOnMissionEnd("D:\\My Warehouse Data\\")
|
||||
--
|
||||
-- ## Load Assets
|
||||
--
|
||||
-- Loading assets data from file is achieved by the @{WAREHOUSE.Load}(*path*, *filename*) function. The parameter *path* specifies the path on the file system where the
|
||||
-- Loading assets data from file is achieved by the @{#WAREHOUSE.Load}(*path*, *filename*) function. The parameter *path* specifies the path on the file system where the
|
||||
-- warehouse data is loaded from. If you do not specify a path, the file is loaded from your the DCS installation root directory.
|
||||
-- The parameter *filename* is optional and defines the name of the file to load. By default this is automatically generated from the warehouse id and name, for example
|
||||
-- "Warehouse-1234_Batumi.txt".
|
||||
@@ -3616,9 +3616,10 @@ function WAREHOUSE:onafterStatus(From, Event, To)
|
||||
end
|
||||
|
||||
-- Print queue after processing requests.
|
||||
self:_PrintQueue(self.queue, "Queue waiting")
|
||||
self:_PrintQueue(self.pending, "Queue pending")
|
||||
|
||||
if self.verbosity > 2 then
|
||||
self:_PrintQueue(self.queue, "Queue waiting")
|
||||
self:_PrintQueue(self.pending, "Queue pending")
|
||||
end
|
||||
-- Check fuel for all assets.
|
||||
--self:_CheckFuel()
|
||||
|
||||
@@ -8234,7 +8235,7 @@ end
|
||||
-- @return #number Request ID.
|
||||
function WAREHOUSE:_GetIDsFromGroupName(groupname)
|
||||
|
||||
---@param #string text The text to analyse.
|
||||
-- @param #string text The text to analyse.
|
||||
local function analyse(text)
|
||||
|
||||
-- Get rid of #0001 tail from spawn.
|
||||
|
||||
@@ -363,8 +363,8 @@ do -- ZONE_CAPTURE_COALITION
|
||||
|
||||
--- ZONE_CAPTURE_COALITION Constructor.
|
||||
-- @param #ZONE_CAPTURE_COALITION self
|
||||
-- @param Core.Zone#ZONE Zone A @{Core.Zone} object with the goal to be achieved. Alternatively, can be handed as the name of late activated group describing a @{ZONE_POLYGON} with its waypoints.
|
||||
-- @param DCSCoalition.DCSCoalition#coalition Coalition The initial coalition owning the zone.
|
||||
-- @param Core.Zone#ZONE Zone A @{Core.Zone} object with the goal to be achieved. Alternatively, can be handed as the name of late activated group describing a @{Core.Zone#ZONE_POLYGON} with its waypoints.
|
||||
-- @param #number Coalition The initial coalition owning the zone.
|
||||
-- @param #table UnitCategories Table of unit categories. See [DCS Class Unit](https://wiki.hoggitworld.com/view/DCS_Class_Unit). Default {Unit.Category.GROUND_UNIT}.
|
||||
-- @param #table ObjectCategories Table of unit categories. See [DCS Class Object](https://wiki.hoggitworld.com/view/DCS_Class_Object). Default {Object.Category.UNIT, Object.Category.STATIC}, i.e. all UNITS and STATICS.
|
||||
-- @return #ZONE_CAPTURE_COALITION
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
--
|
||||
-- ZONE_GOAL_CARGO models processes that have a Goal with a defined achievement involving a Zone and Cargo.
|
||||
-- Derived classes implement the ways how the achievements can be realized.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **FlightControl**
|
||||
@@ -61,7 +61,7 @@ do -- ZoneGoal
|
||||
--- ZONE_GOAL_CARGO Constructor.
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param Core.Zone#ZONE Zone A @{Core.Zone} object with the goal to be achieved.
|
||||
-- @param DCSCoalition.DCSCoalition#coalition Coalition The initial coalition owning the zone.
|
||||
-- @param #number Coalition The initial coalition owning the zone.
|
||||
-- @return #ZONE_GOAL_CARGO
|
||||
function ZONE_GOAL_CARGO:New( Zone, Coalition )
|
||||
|
||||
@@ -259,7 +259,7 @@ do -- ZoneGoal
|
||||
|
||||
--- Set the owning coalition of the zone.
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param DCSCoalition.DCSCoalition#coalition Coalition
|
||||
-- @param #number Coalition
|
||||
function ZONE_GOAL_CARGO:SetCoalition( Coalition )
|
||||
self.Coalition = Coalition
|
||||
end
|
||||
@@ -267,7 +267,7 @@ do -- ZoneGoal
|
||||
|
||||
--- Get the owning coalition of the zone.
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @return DCSCoalition.DCSCoalition#coalition Coalition.
|
||||
-- @return #number Coalition.
|
||||
function ZONE_GOAL_CARGO:GetCoalition()
|
||||
return self.Coalition
|
||||
end
|
||||
|
||||
@@ -54,7 +54,7 @@ do -- ZoneGoal
|
||||
--- ZONE_GOAL_COALITION Constructor.
|
||||
-- @param #ZONE_GOAL_COALITION self
|
||||
-- @param Core.Zone#ZONE Zone A @{Core.Zone} object with the goal to be achieved.
|
||||
-- @param DCSCoalition.DCSCoalition#coalition Coalition The initial coalition owning the zone. Default coalition.side.NEUTRAL.
|
||||
-- @param #number Coalition The initial coalition owning the zone. Default coalition.side.NEUTRAL.
|
||||
-- @param #table UnitCategories Table of unit categories. See [DCS Class Unit](https://wiki.hoggitworld.com/view/DCS_Class_Unit). Default {Unit.Category.GROUND_UNIT}.
|
||||
-- @return #ZONE_GOAL_COALITION
|
||||
function ZONE_GOAL_COALITION:New( Zone, Coalition, UnitCategories )
|
||||
@@ -80,7 +80,7 @@ do -- ZoneGoal
|
||||
|
||||
--- Set the owning coalition of the zone.
|
||||
-- @param #ZONE_GOAL_COALITION self
|
||||
-- @param DCSCoalition.DCSCoalition#coalition Coalition The coalition ID, e.g. *coalition.side.RED*.
|
||||
-- @param #number Coalition The coalition ID, e.g. *coalition.side.RED*.
|
||||
-- @return #ZONE_GOAL_COALITION
|
||||
function ZONE_GOAL_COALITION:SetCoalition( Coalition )
|
||||
self.PreviousCoalition = self.Coalition or Coalition
|
||||
@@ -120,14 +120,14 @@ do -- ZoneGoal
|
||||
|
||||
--- Get the owning coalition of the zone.
|
||||
-- @param #ZONE_GOAL_COALITION self
|
||||
-- @return DCSCoalition.DCSCoalition#coalition Coalition.
|
||||
-- @return #number Coalition.
|
||||
function ZONE_GOAL_COALITION:GetCoalition()
|
||||
return self.Coalition
|
||||
end
|
||||
|
||||
--- Get the previous coalition, i.e. the one owning the zone before the current one.
|
||||
-- @param #ZONE_GOAL_COALITION self
|
||||
-- @return DCSCoalition.DCSCoalition#coalition Coalition.
|
||||
-- @return #number Coalition.
|
||||
function ZONE_GOAL_COALITION:GetPreviousCoalition()
|
||||
return self.PreviousCoalition
|
||||
end
|
||||
|
||||
@@ -134,9 +134,9 @@ __Moose.Include( 'Scripts/Moose/AI/AI_A2G_CAS.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/AI/AI_A2G_SEAD.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/AI/AI_A2G_Dispatcher.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/AI/AI_Patrol.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/AI/AI_Cap.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/AI/AI_Cas.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/AI/AI_Bai.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/AI/AI_CAP.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/AI/AI_CAS.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/AI/AI_BAI.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/AI/AI_Formation.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/AI/AI_Escort.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/AI/AI_Escort_Request.lua' )
|
||||
@@ -175,7 +175,7 @@ __Moose.Include( 'Scripts/Moose/Tasking/Task_A2G_Dispatcher.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/Tasking/Task_A2G.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/Tasking/Task_A2A_Dispatcher.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/Tasking/Task_A2A.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/Tasking/Task_Cargo.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/Tasking/Task_CARGO.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/Tasking/Task_Cargo_Transport.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/Tasking/Task_Cargo_CSAR.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/Tasking/Task_Cargo_Dispatcher.lua' )
|
||||
|
||||
@@ -1524,7 +1524,7 @@ end
|
||||
-- @param #string GoogleKey Path to Google JSON-Key.
|
||||
-- @return #ATIS self
|
||||
function ATIS:SetSRS(PathToSRS, Gender, Culture, Voice, Port, GoogleKey)
|
||||
if PathToSRS then
|
||||
if PathToSRS or MSRS.path then
|
||||
self.useSRS=true
|
||||
self.msrs=MSRS:New(PathToSRS, self.frequency, self.modulation)
|
||||
self.msrs:SetGender(Gender)
|
||||
@@ -1555,7 +1555,7 @@ end
|
||||
|
||||
--- Get the coalition of the associated airbase.
|
||||
-- @param #ATIS self
|
||||
-- @return #number Coalition of the associcated airbase.
|
||||
-- @return #number Coalition of the associated airbase.
|
||||
function ATIS:GetCoalition()
|
||||
local coal = self.airbase and self.airbase:GetCoalition() or nil
|
||||
return coal
|
||||
|
||||
@@ -54,7 +54,9 @@
|
||||
-- @field #string takeoffType Take of type.
|
||||
-- @field #boolean despawnAfterLanding Aircraft are despawned after landing.
|
||||
-- @field #boolean despawnAfterHolding Aircraft are despawned after holding.
|
||||
--
|
||||
-- @field #boolean capOptionPatrolRaceTrack Use closer patrol race track or standard orbit auftrag.
|
||||
-- @field #number capFormation If capOptionPatrolRaceTrack is true, set the formation, also.
|
||||
--
|
||||
-- @extends Ops.Legion#LEGION
|
||||
|
||||
--- *I fly because it releases my mind from the tyranny of petty things.* -- Antoine de Saint-Exupery
|
||||
@@ -128,6 +130,8 @@ AIRWING = {
|
||||
pointsAWACS = {},
|
||||
pointsRecon = {},
|
||||
markpoints = false,
|
||||
capOptionPatrolRaceTrack = false,
|
||||
capFormation = nil,
|
||||
}
|
||||
|
||||
--- Payload data.
|
||||
@@ -179,7 +183,7 @@ AIRWING = {
|
||||
|
||||
--- AIRWING class version.
|
||||
-- @field #string version
|
||||
AIRWING.version="0.9.3"
|
||||
AIRWING.version="0.9.4"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- ToDo list
|
||||
@@ -699,6 +703,24 @@ function AIRWING:SetNumberCAP(n)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set CAP flight formation.
|
||||
-- @param #AIRWING self
|
||||
-- @param #number Formation Formation to take, e.g. ENUMS.Formation.FixedWing.Trail.Close, also see [Hoggit Wiki](https://wiki.hoggitworld.com/view/DCS_option_formation).
|
||||
-- @return #AIRWING self
|
||||
function AIRWING:SetCAPFormation(Formation)
|
||||
self.capFormation = Formation
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set CAP close race track.We'll utilize the AUFTRAG PatrolRaceTrack instead of a standard race track orbit task.
|
||||
-- @param #AIRWING self
|
||||
-- @param #boolean OnOff If true, switch this on, else switch off. Off by default.
|
||||
-- @return #AIRWING self
|
||||
function AIRWING:SetCapCloseRaceTrack(OnOff)
|
||||
self.capOptionPatrolRaceTrack = OnOff
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set number of TANKER flights with Boom constantly in the air.
|
||||
-- @param #AIRWING self
|
||||
-- @param #number Nboom Number of flights. Default 1.
|
||||
@@ -1112,13 +1134,14 @@ end
|
||||
-- @return #AIRWING self
|
||||
function AIRWING:CheckCAP()
|
||||
|
||||
local Ncap=0 --self:CountMissionsInQueue({AUFTRAG.Type.GCICAP, AUFTRAG.Type.INTERCEPT})
|
||||
local Ncap=0
|
||||
|
||||
|
||||
-- Count CAP missions.
|
||||
for _,_mission in pairs(self.missionqueue) do
|
||||
local mission=_mission --Ops.Auftrag#AUFTRAG
|
||||
|
||||
if mission:IsNotOver() and mission.type==AUFTRAG.Type.GCICAP and mission.patroldata then
|
||||
if mission:IsNotOver() and (mission.type==AUFTRAG.Type.GCICAP or mission.type == AUFTRAG.Type.PATROLRACETRACK) and mission.patroldata then
|
||||
Ncap=Ncap+1
|
||||
end
|
||||
|
||||
@@ -1130,8 +1153,18 @@ function AIRWING:CheckCAP()
|
||||
|
||||
local altitude=patrol.altitude+1000*patrol.noccupied
|
||||
|
||||
local missionCAP=AUFTRAG:NewGCICAP(patrol.coord, altitude, patrol.speed, patrol.heading, patrol.leg)
|
||||
|
||||
local missionCAP = nil -- Ops.Auftrag#AUFTRAG
|
||||
|
||||
if self.capOptionPatrolRaceTrack then
|
||||
|
||||
missionCAP=AUFTRAG:NewPATROL_RACETRACK(patrol.coord,altitude,patrol.speed,patrol.heading,patrol.leg, self.capFormation)
|
||||
|
||||
else
|
||||
|
||||
missionCAP=AUFTRAG:NewGCICAP(patrol.coord, altitude, patrol.speed, patrol.heading, patrol.leg)
|
||||
|
||||
end
|
||||
|
||||
missionCAP.patroldata=patrol
|
||||
|
||||
patrol.noccupied=patrol.noccupied+1
|
||||
@@ -1150,7 +1183,7 @@ end
|
||||
-- @return #AIRWING self
|
||||
function AIRWING:CheckRECON()
|
||||
|
||||
local Ncap=0 --self:CountMissionsInQueue({AUFTRAG.Type.GCICAP, AUFTRAG.Type.INTERCEPT})
|
||||
local Ncap=0
|
||||
|
||||
-- Count CAP missions.
|
||||
for _,_mission in pairs(self.missionqueue) do
|
||||
@@ -1278,7 +1311,6 @@ function AIRWING:CheckAWACS()
|
||||
|
||||
end
|
||||
|
||||
|
||||
for i=1,self.nflightsAWACS-N do
|
||||
|
||||
local patrol=self:_GetPatrolData(self.pointsAWACS)
|
||||
|
||||
@@ -27,17 +27,17 @@
|
||||
-- **Supported Carriers:**
|
||||
--
|
||||
-- * [USS John C. Stennis](https://en.wikipedia.org/wiki/USS_John_C._Stennis) (CVN-74)
|
||||
-- * [USS Theodore Roosevelt](https://en.wikipedia.org/wiki/USS_Theodore_Roosevelt_(CVN-71\)) (CVN-71) [Super Carrier Module]
|
||||
-- * [USS Abraham Lincoln](https://en.wikipedia.org/wiki/USS_Abraham_Lincoln_(CVN-72\)) (CVN-72) [Super Carrier Module]
|
||||
-- * [USS George Washington](https://en.wikipedia.org/wiki/USS_George_Washington_(CVN-73\)) (CVN-73) [Super Carrier Module]
|
||||
-- * [USS Theodore Roosevelt](https://en.wikipedia.org/wiki/USS_Theodore_Roosevelt_\(CVN-71\)) (CVN-71) [Super Carrier Module]
|
||||
-- * [USS Abraham Lincoln](https://en.wikipedia.org/wiki/USS_Abraham_Lincoln_\(CVN-72\)) (CVN-72) [Super Carrier Module]
|
||||
-- * [USS George Washington](https://en.wikipedia.org/wiki/USS_George_Washington_\(CVN-73\)) (CVN-73) [Super Carrier Module]
|
||||
-- * [USS Harry S. Truman](https://en.wikipedia.org/wiki/USS_Harry_S._Truman) (CVN-75) [Super Carrier Module]
|
||||
-- * [USS Forrestal](https://en.wikipedia.org/wiki/USS_Forrestal_(CV-59\)) (CV-59) [Heatblur Carrier Module]
|
||||
-- * [HMS Hermes](https://en.wikipedia.org/wiki/HMS_Hermes_(R12\)) (R12)
|
||||
-- * [HMS Invincible](https://en.wikipedia.org/wiki/HMS_Invincible_(R05\)) (R05)
|
||||
-- * [USS Tarawa](https://en.wikipedia.org/wiki/USS_Tarawa_(LHA-1\)) (LHA-1)
|
||||
-- * [USS America](https://en.wikipedia.org/wiki/USS_America_(LHA-6\)) (LHA-6)
|
||||
-- * [USS Forrestal](https://en.wikipedia.org/wiki/USS_Forrestal_\(CV-59\)) (CV-59) [Heatblur Carrier Module]
|
||||
-- * [HMS Hermes](https://en.wikipedia.org/wiki/HMS_Hermes_\(R12\)) (R12)
|
||||
-- * [HMS Invincible](https://en.wikipedia.org/wiki/HMS_Invincible_\(R05\)) (R05)
|
||||
-- * [USS Tarawa](https://en.wikipedia.org/wiki/USS_Tarawa_\(LHA-1\)) (LHA-1)
|
||||
-- * [USS America](https://en.wikipedia.org/wiki/USS_America_\(LHA-6\)) (LHA-6)
|
||||
-- * [Juan Carlos I](https://en.wikipedia.org/wiki/Spanish_amphibious_assault_ship_Juan_Carlos_I) (L61)
|
||||
-- * [HMAS Canberra](https://en.wikipedia.org/wiki/HMAS_Canberra_(L02\)) (L02)
|
||||
-- * [HMAS Canberra](https://en.wikipedia.org/wiki/HMAS_Canberra_\(L02\)) (L02)
|
||||
--
|
||||
-- **Supported Aircraft:**
|
||||
--
|
||||
@@ -45,7 +45,7 @@
|
||||
-- * [F-14A/B Tomcat](https://forums.eagle.ru/forumdisplay.php?f=395) (Player & AI)
|
||||
-- * [A-4E Skyhawk Community Mod](https://forums.eagle.ru/showthread.php?t=224989) (Player & AI)
|
||||
-- * [AV-8B N/A Harrier](https://forums.eagle.ru/forumdisplay.php?f=555) (Player & AI)
|
||||
-- * [T-45C Goshawk](https://www.vnao-cvw-7.com/t-45-goshawk) (VNAO mod) (Player & AI)
|
||||
-- * [T-45C Goshawk](https://forum.dcs.world/topic/203816-vnao-t-45-goshawk/) (VNAO mod) (Player & AI)
|
||||
-- * [FE/A-18E/F/G Superhornet](https://forum.dcs.world/topic/316971-cjs-super-hornet-community-mod-v20-official-thread/) (CJS mod) (Player & AI)
|
||||
-- * F/A-18C Hornet (AI)
|
||||
-- * F-14A Tomcat (AI)
|
||||
@@ -61,7 +61,7 @@
|
||||
--
|
||||
-- Heatblur's mighty F-14B Tomcat has been added (March 13th 2019) as well. Same goes for the A version.
|
||||
--
|
||||
-- The [DCS Supercarriers](https://forums.eagle.ru/forum/151-dcs-supercarrier/) are also supported.
|
||||
-- The [DCS Supercarriers](https://www.digitalcombatsimulator.com/de/shop/modules/supercarrier/) are also supported.
|
||||
--
|
||||
-- ## Discussion
|
||||
--
|
||||
@@ -95,11 +95,6 @@
|
||||
-- * [[MOOSE] Airboss - CASE I, "Until We Go Down" featuring the F-14B by Pikes](https://www.youtube.com/watch?v=ojgHDSw3Doc)
|
||||
-- * [[MOOSE] Airboss - Skipper Menu](https://youtu.be/awnecCxRoNQ)
|
||||
--
|
||||
-- ### Lex explaining Boat Ops:
|
||||
--
|
||||
-- * [( DCS HORNET ) Some boat ops basics VID 1](https://www.youtube.com/watch?v=LvGQS-3AzMc)
|
||||
-- * [( DCS HORNET ) Some boat ops basics VID 2](https://www.youtube.com/watch?v=bN44wvtRsw0)
|
||||
--
|
||||
-- ### Jabbers Case I and III Recovery Tutorials:
|
||||
--
|
||||
-- * [DCS World - F/A-18 - Case I Carrier Recovery Tutorial](https://www.youtube.com/watch?v=lm-M3VUy-_I)
|
||||
|
||||
@@ -2043,82 +2043,90 @@ end
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param #table Template Template used to init the group. Default is `self.template`.
|
||||
-- @return #ARMYGROUP self
|
||||
function ARMYGROUP:_InitGroup(Template)
|
||||
function ARMYGROUP:_InitGroup(Template, Delay)
|
||||
|
||||
-- First check if group was already initialized.
|
||||
if self.groupinitialized then
|
||||
self:T(self.lid.."WARNING: Group was already initialized! Will NOT do it again!")
|
||||
return
|
||||
end
|
||||
|
||||
-- Get template of group.
|
||||
local template=Template or self:_GetTemplate()
|
||||
|
||||
-- Ground are always AI.
|
||||
self.isAI=true
|
||||
|
||||
-- Is (template) group late activated.
|
||||
self.isLateActivated=template.lateActivation
|
||||
|
||||
-- Ground groups cannot be uncontrolled.
|
||||
self.isUncontrolled=false
|
||||
|
||||
-- Max speed in km/h.
|
||||
self.speedMax=self.group:GetSpeedMax()
|
||||
|
||||
-- Is group mobile?
|
||||
if self.speedMax>3.6 then
|
||||
self.isMobile=true
|
||||
if Delay and Delay>0 then
|
||||
self:ScheduleOnce(Delay, ARMYGROUP._InitGroup, self, Template, 0)
|
||||
else
|
||||
self.isMobile=false
|
||||
end
|
||||
|
||||
-- Cruise speed in km/h
|
||||
self.speedCruise=self.speedMax*0.7
|
||||
|
||||
-- Group ammo.
|
||||
self.ammo=self:GetAmmoTot()
|
||||
|
||||
-- Radio parameters from template.
|
||||
self.radio.On=false -- Radio is always OFF for ground.
|
||||
self.radio.Freq=133
|
||||
self.radio.Modu=radio.modulation.AM
|
||||
|
||||
-- Set default radio.
|
||||
self:SetDefaultRadio(self.radio.Freq, self.radio.Modu, self.radio.On)
|
||||
|
||||
-- Get current formation from first waypoint.
|
||||
self.option.Formation=template.route.points[1].action
|
||||
|
||||
-- Set default formation to "on road".
|
||||
self.optionDefault.Formation=ENUMS.Formation.Vehicle.OnRoad
|
||||
|
||||
-- Default TACAN off.
|
||||
self:SetDefaultTACAN(nil, nil, nil, nil, true)
|
||||
self.tacan=UTILS.DeepCopy(self.tacanDefault)
|
||||
-- First check if group was already initialized.
|
||||
if self.groupinitialized then
|
||||
self:T(self.lid.."WARNING: Group was already initialized! Will NOT do it again!")
|
||||
return
|
||||
end
|
||||
|
||||
self:I(self.lid.."FF Initializing Group")
|
||||
|
||||
-- Units of the group.
|
||||
local units=self.group:GetUnits()
|
||||
-- Get template of group.
|
||||
local template=Template or self:_GetTemplate()
|
||||
|
||||
-- Ground are always AI.
|
||||
self.isAI=true
|
||||
|
||||
-- Is (template) group late activated.
|
||||
self.isLateActivated=template.lateActivation
|
||||
|
||||
-- Ground groups cannot be uncontrolled.
|
||||
self.isUncontrolled=false
|
||||
|
||||
-- Max speed in km/h.
|
||||
self.speedMax=self.group:GetSpeedMax()
|
||||
|
||||
-- Is group mobile?
|
||||
if self.speedMax>3.6 then
|
||||
self.isMobile=true
|
||||
else
|
||||
self.isMobile=false
|
||||
end
|
||||
|
||||
-- Cruise speed in km/h
|
||||
self.speedCruise=self.speedMax*0.7
|
||||
|
||||
-- Group ammo.
|
||||
self.ammo=self:GetAmmoTot()
|
||||
|
||||
-- Radio parameters from template.
|
||||
self.radio.On=false -- Radio is always OFF for ground.
|
||||
self.radio.Freq=133
|
||||
self.radio.Modu=radio.modulation.AM
|
||||
|
||||
-- Set default radio.
|
||||
self:SetDefaultRadio(self.radio.Freq, self.radio.Modu, self.radio.On)
|
||||
|
||||
-- Get current formation from first waypoint.
|
||||
self.option.Formation=template.route.points[1].action
|
||||
|
||||
-- Set default formation to "on road".
|
||||
self.optionDefault.Formation=ENUMS.Formation.Vehicle.OnRoad
|
||||
|
||||
-- DCS group.
|
||||
local dcsgroup=Group.getByName(self.groupname)
|
||||
local size0=dcsgroup:getInitialSize()
|
||||
-- Default TACAN off.
|
||||
self:SetDefaultTACAN(nil, nil, nil, nil, true)
|
||||
self.tacan=UTILS.DeepCopy(self.tacanDefault)
|
||||
|
||||
-- Units of the group.
|
||||
local units=self.group:GetUnits()
|
||||
|
||||
-- DCS group.
|
||||
local dcsgroup=Group.getByName(self.groupname)
|
||||
local size0=dcsgroup:getInitialSize()
|
||||
local u=dcsgroup:getUnits()
|
||||
|
||||
-- Quick check.
|
||||
if #units~=size0 then
|
||||
self:T(self.lid..string.format("ERROR: Got #units=%d but group consists of %d units! u=%d", #units, size0, #u))
|
||||
end
|
||||
|
||||
-- Add elemets.
|
||||
for _,unit in pairs(units) do
|
||||
local unitname=unit:GetName()
|
||||
self:_AddElementByName(unitname)
|
||||
end
|
||||
|
||||
|
||||
-- Quick check.
|
||||
if #units~=size0 then
|
||||
self:T(self.lid..string.format("ERROR: Got #units=%d but group consists of %d units!", #units, size0))
|
||||
-- Init done.
|
||||
self.groupinitialized=true
|
||||
end
|
||||
|
||||
-- Add elemets.
|
||||
for _,unit in pairs(units) do
|
||||
local unitname=unit:GetName()
|
||||
self:_AddElementByName(unitname)
|
||||
end
|
||||
|
||||
|
||||
-- Init done.
|
||||
self.groupinitialized=true
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
@@ -443,6 +443,7 @@ _AUFTRAGSNR=0
|
||||
-- @field #string REARMING Rearming mission.
|
||||
-- @field #string CAPTUREZONE Capture zone mission.
|
||||
-- @field #string NOTHING Nothing.
|
||||
-- @field #string PATROLRACETRACK Patrol Racetrack.
|
||||
AUFTRAG.Type={
|
||||
ANTISHIP="Anti Ship",
|
||||
AWACS="AWACS",
|
||||
@@ -484,10 +485,10 @@ AUFTRAG.Type={
|
||||
RELOCATECOHORT="Relocate Cohort",
|
||||
AIRDEFENSE="Air Defence",
|
||||
EWR="Early Warning Radar",
|
||||
--RECOVERYTANKER="Recovery Tanker",
|
||||
REARMING="Rearming",
|
||||
CAPTUREZONE="Capture Zone",
|
||||
NOTHING="Nothing",
|
||||
PATROLRACETRACK="Patrol Racetrack",
|
||||
}
|
||||
|
||||
--- Special task description.
|
||||
@@ -511,6 +512,7 @@ AUFTRAG.Type={
|
||||
-- @field #string REARMING Rearming.
|
||||
-- @field #string CAPTUREZONE Capture OPS zone.
|
||||
-- @field #string NOTHING Nothing.
|
||||
-- @field #string PATROLRACETRACK Patrol Racetrack.
|
||||
AUFTRAG.SpecialTask={
|
||||
FORMATION="Formation",
|
||||
PATROLZONE="PatrolZone",
|
||||
@@ -532,6 +534,7 @@ AUFTRAG.SpecialTask={
|
||||
REARMING="Rearming",
|
||||
CAPTUREZONE="Capture Zone",
|
||||
NOTHING="Nothing",
|
||||
PATROLRACETRACK="Patrol Racetrack",
|
||||
}
|
||||
|
||||
--- Mission status.
|
||||
@@ -652,7 +655,7 @@ AUFTRAG.Category={
|
||||
|
||||
--- AUFTRAG class version.
|
||||
-- @field #string version
|
||||
AUFTRAG.version="1.2.0"
|
||||
AUFTRAG.version="1.2.1"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
@@ -1017,7 +1020,7 @@ end
|
||||
-- @param #number Altitude Hover altitude in feet AGL. Default is 50 feet above ground.
|
||||
-- @param #number Time Time in seconds to hold the hover. Default 300 seconds.
|
||||
-- @param #number Speed Speed in knots to fly to the target coordinate. Default 150kn.
|
||||
-- @param #number MissionAlt Altitide to fly towards the mission in feet AGL. Default 1000ft.
|
||||
-- @param #number MissionAlt Altitude to fly towards the mission in feet AGL. Default 1000ft.
|
||||
-- @return #AUFTRAG self
|
||||
function AUFTRAG:NewHOVER(Coordinate, Altitude, Time, Speed, MissionAlt)
|
||||
|
||||
@@ -1049,6 +1052,58 @@ function AUFTRAG:NewHOVER(Coordinate, Altitude, Time, Speed, MissionAlt)
|
||||
return mission
|
||||
end
|
||||
|
||||
--- **[AIR]** Create an enhanced orbit race track mission. Planes will keep closer to the track.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param Core.Point#COORDINATE Coordinate Where to start the race track.
|
||||
-- @param #number Altitude (Optional) Altitude in feet. Defaults to 20,000ft ASL.
|
||||
-- @param #number Speed (Optional) Speed in knots. Defaults to 300kn TAS.
|
||||
-- @param #number Heading (Optional) Heading in degrees, 0 to 360. Defaults to 90 degree (East).
|
||||
-- @param #number Leg (Optional) Leg of the race track in NM. Defaults to 10nm.
|
||||
-- @param #number Formation (Optional) Formation to take, e.g. ENUMS.Formation.FixedWing.Trail.Close, also see [Hoggit Wiki](https://wiki.hoggitworld.com/view/DCS_option_formation).
|
||||
-- @return #AUFTRAG self
|
||||
function AUFTRAG:NewPATROL_RACETRACK(Coordinate,Altitude,Speed,Heading,Leg,Formation)
|
||||
|
||||
local mission = AUFTRAG:New(AUFTRAG.Type.PATROLRACETRACK)
|
||||
|
||||
-- Target.
|
||||
mission:_TargetFromObject(Coordinate)
|
||||
|
||||
-- Set Altitude.
|
||||
if Altitude then
|
||||
mission.TrackAltitude=UTILS.FeetToMeters(Altitude)
|
||||
else
|
||||
mission.TrackAltitude=UTILS.FeetToMeters(20000)
|
||||
end
|
||||
|
||||
-- Points
|
||||
mission.TrackPoint1 = Coordinate
|
||||
|
||||
local leg = UTILS.NMToMeters(Leg) or UTILS.NMToMeters(10)
|
||||
|
||||
local heading = Heading or 90
|
||||
|
||||
if heading < 0 or heading > 360 then heading = 90 end
|
||||
|
||||
mission.TrackPoint2 = Coordinate:Translate(leg,heading,true)
|
||||
|
||||
-- Orbit speed in m/s TAS.
|
||||
mission.TrackSpeed = UTILS.IasToTas(UTILS.KnotsToKmph(Speed or 300), mission.TrackAltitude)
|
||||
|
||||
-- Mission speed in km/h and altitude
|
||||
mission.missionSpeed = UTILS.KnotsToKmph(Speed or 300)
|
||||
mission.missionAltitude = mission.TrackAltitude * 0.9
|
||||
mission.missionTask=ENUMS.MissionTask.CAP
|
||||
mission.optionROE=ENUMS.ROE.ReturnFire
|
||||
mission.optionROT=ENUMS.ROT.PassiveDefense
|
||||
|
||||
mission.categories={AUFTRAG.Category.AIRCRAFT}
|
||||
|
||||
mission.DCStask=mission:GetDCSMissionTask()
|
||||
|
||||
return mission
|
||||
end
|
||||
|
||||
|
||||
--- **[AIR]** Create an ORBIT mission, which can be either a circular orbit or a race-track pattern.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param Core.Point#COORDINATE Coordinate Where to orbit.
|
||||
@@ -1181,7 +1236,7 @@ function AUFTRAG:NewORBIT_GROUP(Group, Altitude, Speed, Leg, Heading, OffsetVec2
|
||||
end
|
||||
|
||||
|
||||
--- **[AIR]** Create a Ground Controlled CAP (GCICAP) mission. Flights with this task are considered for A2A INTERCEPT missions by the CHIEF class. They will perform a compat air patrol but not engage by
|
||||
--- **[AIR]** Create a Ground Controlled CAP (GCICAP) mission. Flights with this task are considered for A2A INTERCEPT missions by the CHIEF class. They will perform a combat air patrol but not engage by
|
||||
-- themselfs. They wait for the CHIEF to tell them whom to engage.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param Core.Point#COORDINATE Coordinate Where to orbit.
|
||||
@@ -2688,6 +2743,8 @@ function AUFTRAG:NewAUTO(EngageGroup)
|
||||
mission=AUFTRAG:NewTANKER(Coordinate,Altitude,Speed,Heading,Leg,RefuelSystem)
|
||||
elseif auftrag==AUFTRAG.Type.TROOPTRANSPORT then
|
||||
mission=AUFTRAG:NewTROOPTRANSPORT(TransportGroupSet,DropoffCoordinate,PickupCoordinate)
|
||||
elseif auftrag==AUFTRAG.Type.PATROLRACETRACK then
|
||||
mission=AUFTRAG:NewPATROL_RACETRACK(Coordinate,Altitude,Speed,Heading,Leg,Formation)
|
||||
else
|
||||
|
||||
end
|
||||
@@ -6343,8 +6400,32 @@ function AUFTRAG:GetDCSMissionTask()
|
||||
|
||||
DCStask.params=param
|
||||
|
||||
table.insert(DCStasks, DCStask)
|
||||
table.insert(DCStasks, DCStask)
|
||||
|
||||
elseif self.type==AUFTRAG.Type.PATROLRACETRACK then
|
||||
|
||||
---------------------
|
||||
-- Enhanced Orbit Racetrack --
|
||||
---------------------
|
||||
|
||||
local DCStask={}
|
||||
DCStask.id=AUFTRAG.SpecialTask.PATROLRACETRACK
|
||||
|
||||
local param={}
|
||||
-- ONTROLLABLE:PatrolRaceTrack(Point1, Point2, Altitude, Speed, Formation, Delay)
|
||||
|
||||
param.TrackAltitude = self.TrackAltitude
|
||||
param.TrackSpeed = self.TrackSpeed
|
||||
param.TrackPoint1 = self.TrackPoint1
|
||||
param.TrackPoint2 = self.TrackPoint2
|
||||
param.missionSpeed = self.missionSpeed
|
||||
param.missionAltitude = self.missionAltitude
|
||||
param.TrackFormation = self.TrackFormation
|
||||
|
||||
DCStask.params=param
|
||||
|
||||
table.insert(DCStasks, DCStask)
|
||||
|
||||
elseif self.type==AUFTRAG.Type.HOVER then
|
||||
|
||||
---------------------
|
||||
@@ -6619,6 +6700,8 @@ function AUFTRAG:GetMissionTaskforMissionType(MissionType)
|
||||
mtask=ENUMS.MissionTask.NOTHING
|
||||
elseif MissionType==AUFTRAG.Type.HOVER then
|
||||
mtask=ENUMS.MissionTask.NOTHING
|
||||
elseif MissionType==AUFTRAG.Type.PATROLRACETRACK then
|
||||
mtask=ENUMS.MissionTask.CAP
|
||||
end
|
||||
|
||||
return mtask
|
||||
|
||||
@@ -46,8 +46,6 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- # CSAR Concept
|
||||
--
|
||||
-- * MOOSE-based Helicopter CSAR Operations for Players.
|
||||
|
||||
@@ -19,10 +19,12 @@
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **Applevangelist** (Moose Version), ***Ciribob*** (original), Thanks to: Shadowze, Cammel (testing), bbirchnz (additional code!!)
|
||||
-- ### Repack addition for crates: **Raiden**
|
||||
--
|
||||
-- @module Ops.CTLD
|
||||
-- @image OPS_CTLD.jpg
|
||||
|
||||
-- Last Update June 2023
|
||||
-- Last Update October 2023
|
||||
|
||||
do
|
||||
|
||||
@@ -599,7 +601,7 @@ do
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 
|
||||
-- 
|
||||
--
|
||||
-- # CTLD Concept
|
||||
--
|
||||
@@ -700,6 +702,7 @@ do
|
||||
--
|
||||
-- my_ctld.useprefix = true -- (DO NOT SWITCH THIS OFF UNLESS YOU KNOW WHAT YOU ARE DOING!) Adjust **before** starting CTLD. If set to false, *all* choppers of the coalition side will be enabled for CTLD.
|
||||
-- my_ctld.CrateDistance = 35 -- List and Load crates in this radius only.
|
||||
-- my_ctld.PackDistance = 35 -- Pack crates in this radius only
|
||||
-- my_ctld.dropcratesanywhere = false -- Option to allow crates to be dropped anywhere.
|
||||
-- my_ctld.dropAsCargoCrate = false -- Parachuted herc cargo is not unpacked automatically but placed as crate to be unpacked. Needs a cargo with the same name defined like the cargo that was dropped.
|
||||
-- my_ctld.maximumHoverHeight = 15 -- Hover max this high to load.
|
||||
@@ -1121,6 +1124,7 @@ CTLD = {
|
||||
Spawned_Crates = {}, -- Holds objects for crates spawned generally
|
||||
Spawned_Cargo = {}, -- Binds together spawned_crates and their CTLD_CARGO objects
|
||||
CrateDistance = 35, -- list crates in this radius
|
||||
PackDistance = 35, -- pack crates in this radius
|
||||
debug = false,
|
||||
wpZones = {},
|
||||
dropOffZones = {},
|
||||
@@ -1144,6 +1148,7 @@ CTLD = {
|
||||
-- DONE: List cargo in stock
|
||||
-- DONE: Limit of troops, crates buildable?
|
||||
-- DONE: Allow saving of Troops & Vehicles
|
||||
-- DONE: Adding re-packing dropped units
|
||||
------------------------------
|
||||
|
||||
--- Radio Beacons
|
||||
@@ -1223,7 +1228,7 @@ CTLD.UnitTypes = {
|
||||
|
||||
--- CTLD class version.
|
||||
-- @field #string version
|
||||
CTLD.version="1.0.40"
|
||||
CTLD.version="1.0.41"
|
||||
|
||||
--- Instantiate a new CTLD.
|
||||
-- @param #CTLD self
|
||||
@@ -1341,6 +1346,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
||||
|
||||
-- setup
|
||||
self.CrateDistance = 35 -- list/load crates in this radius
|
||||
self.PackDistance = 35 -- pack objects in this radius
|
||||
self.ExtractFactor = 3.33 -- factor for troops extraction, i.e. CrateDistance * Extractfactor
|
||||
self.prefixes = Prefixes or {"Cargoheli"}
|
||||
self.useprefix = true
|
||||
@@ -2260,9 +2266,10 @@ end
|
||||
-- @param #CTLD_CARGO Cargo
|
||||
-- @param #number number Number of crates to generate (for dropping)
|
||||
-- @param #boolean drop If true we\'re dropping from heli rather than loading.
|
||||
function CTLD:_GetCrates(Group, Unit, Cargo, number, drop)
|
||||
-- @param #boolean pack If true we\'re packing crates from a template rather than loading or dropping
|
||||
function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack)
|
||||
self:T(self.lid .. " _GetCrates")
|
||||
if not drop then
|
||||
if not drop and not pack then
|
||||
local cgoname = Cargo:GetName()
|
||||
-- check if we have stock
|
||||
local instock = Cargo:GetStock()
|
||||
@@ -2279,18 +2286,20 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop)
|
||||
local width = 20
|
||||
local distance = nil
|
||||
local zone = nil
|
||||
if not drop then
|
||||
if not drop and not pack then
|
||||
inzone = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD)
|
||||
if not inzone then
|
||||
---@diagnostic disable-next-line: cast-local-type
|
||||
inzone, ship, zone, distance, width = self:IsUnitInZone(Unit,CTLD.CargoZoneType.SHIP)
|
||||
end
|
||||
else
|
||||
elseif drop and not pack then
|
||||
if self.dropcratesanywhere then -- #1570
|
||||
inzone = true
|
||||
else
|
||||
inzone = self:IsUnitInZone(Unit,CTLD.CargoZoneType.DROP)
|
||||
end
|
||||
elseif pack and not drop then
|
||||
inzone = true
|
||||
end
|
||||
|
||||
if not inzone then
|
||||
@@ -3229,6 +3238,42 @@ function CTLD:_BuildCrates(Group, Unit,Engineering)
|
||||
return self
|
||||
end
|
||||
|
||||
--- (Internal) Function to repair nearby vehicles / FOBs
|
||||
-- @param #CTLD self
|
||||
-- @param Wrapper.Group#GROUP Group
|
||||
-- @param Wrapper.Unit#UNIT Unit
|
||||
|
||||
function CTLD:_PackCratesNearby(Group, Unit)
|
||||
self:T(self.lid .. " _PackCratesNearby")
|
||||
-----------------------------------------
|
||||
-- search for nearest group to player
|
||||
-- determine if group is packable
|
||||
-- generate crates and destroy group
|
||||
-----------------------------------------
|
||||
|
||||
-- get nearby vehicles
|
||||
local location = Group:GetCoordinate() -- get coordinate of group using function
|
||||
local nearestGroups = SET_GROUP:New():FilterCoalitions("blue"):FilterZones({ZONE_RADIUS:New("TempZone", location:GetVec2(), self.PackDistance, false)}):FilterOnce() -- get all groups withing PackDistance from group using function
|
||||
-- get template name of all vehicles in zone
|
||||
|
||||
-- determine if group is packable
|
||||
for _, _Group in pairs(nearestGroups.Set) do -- convert #SET_GROUP to a list of Wrapper.Group#GROUP
|
||||
for _, _Template in pairs(_DATABASE.Templates.Groups) do -- iterate through the database of templates
|
||||
if (string.match(_Group:GetName(), _Template.GroupName)) then -- check if the Wrapper.Group#GROUP near the player is in the list of templates by name
|
||||
-- generate crates and destroy group
|
||||
for _, _entry in pairs(self.Cargo_Crates) do -- iterate through #CTLD_CARGO
|
||||
if (_entry.Templates[1] == _Template.GroupName) then -- check if the #CTLD_CARGO matches the template name
|
||||
_Group:Destroy() -- if a match is found destroy the Wrapper.Group#GROUP near the player
|
||||
self:_GetCrates(Group, Unit, _entry, nil, false, true) -- spawn the appropriate crates near the player
|
||||
return self
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- (Internal) Function to repair nearby vehicles / FOBs
|
||||
-- @param #CTLD self
|
||||
-- @param Wrapper.Group#GROUP Group
|
||||
@@ -3541,6 +3586,7 @@ function CTLD:_RefreshF10Menus()
|
||||
if cancrates then
|
||||
local loadmenu = MENU_GROUP_COMMAND:New(_group,"Load crates",topcrates, self._LoadCratesNearby, self, _group, _unit)
|
||||
local cratesmenu = MENU_GROUP:New(_group,"Get Crates",topcrates)
|
||||
local packmenu = MENU_GROUP_COMMAND:New(_group, "Pack crates", topcrates, self._PackCratesNearby, self, _group, _unit)
|
||||
|
||||
if self.usesubcats then
|
||||
local subcatmenus = {}
|
||||
|
||||
@@ -75,7 +75,7 @@ COHORT = {
|
||||
livery = nil,
|
||||
skill = nil,
|
||||
legion = nil,
|
||||
Ngroups = nil,
|
||||
--Ngroups = nil,
|
||||
Ngroups = 0,
|
||||
engageRange = nil,
|
||||
tacanChannel = {},
|
||||
@@ -1098,7 +1098,7 @@ function COHORT:RecruitAssets(MissionType, Npayloads)
|
||||
-- Assets on mission NOTHING are considered.
|
||||
table.insert(assets, asset)
|
||||
|
||||
elseif self.legion:IsAssetOnMission(asset, AUFTRAG.Type.GCICAP) and MissionType==AUFTRAG.Type.INTERCEPT then
|
||||
elseif self.legion:IsAssetOnMission(asset, {AUFTRAG.Type.GCICAP, AUFTRAG.Type.PATROLRACETRACK}) and MissionType==AUFTRAG.Type.INTERCEPT then
|
||||
|
||||
-- Check if the payload of this asset is compatible with the mission.
|
||||
-- Note: we do not check the payload as an asset that is on a GCICAP mission should be able to do an INTERCEPT as well!
|
||||
@@ -1595,4 +1595,3 @@ end
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
-- @field Core.Set#SET_ZONE NoGoZoneSet
|
||||
-- @field #boolean Monitor
|
||||
-- @field #boolean TankerInvisible
|
||||
-- @field #number CapFormation
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
--- *“Airspeed, altitude, and brains. Two are always needed to successfully complete the flight.”* -- Unknown.
|
||||
@@ -207,6 +208,7 @@ EASYGCICAP = {
|
||||
NoGoZoneSet = nil,
|
||||
Monitor = false,
|
||||
TankerInvisible = true,
|
||||
CapFormation = nil,
|
||||
}
|
||||
|
||||
--- Internal Squadron data type
|
||||
@@ -242,7 +244,7 @@ EASYGCICAP = {
|
||||
|
||||
--- EASYGCICAP class version.
|
||||
-- @field #string version
|
||||
EASYGCICAP.version="0.0.8"
|
||||
EASYGCICAP.version="0.0.9"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
@@ -289,6 +291,7 @@ function EASYGCICAP:New(Alias, AirbaseName, Coalition, EWRName)
|
||||
self.repeatsonfailure = 3
|
||||
self.Monitor = false
|
||||
self.TankerInvisible = true
|
||||
self.CapFormation = ENUMS.Formation.FixedWing.FingerFour.Group
|
||||
|
||||
-- Set some string id for output to DCS.log file.
|
||||
self.lid=string.format("EASYGCICAP %s | ", self.alias)
|
||||
@@ -313,6 +316,14 @@ end
|
||||
-- Functions
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
--- Set CAP formation.
|
||||
-- @param #EASYGCICAP self
|
||||
-- @param #number Formation Formation to fly, defaults to ENUMS.Formation.FixedWing.FingerFour.Group
|
||||
-- @return #EASYGCICAP self
|
||||
function EASYGCICAP:SetCAPFormation(Formation)
|
||||
self.CapFormation = Formation
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set Tanker and AWACS to be invisible to enemy AI eyes
|
||||
-- @param #EASYGCICAP self
|
||||
@@ -476,6 +487,8 @@ end
|
||||
function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
||||
self:T(self.lid.."_AddAirwing "..Airbasename)
|
||||
|
||||
local CapFormation = self.CapFormation
|
||||
|
||||
-- Create Airwing
|
||||
local CAP_Wing = AIRWING:New(Airbasename,Alias)
|
||||
CAP_Wing:SetVerbosityLevel(3)
|
||||
@@ -484,11 +497,15 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
||||
CAP_Wing:SetAirbase(AIRBASE:FindByName(Airbasename))
|
||||
CAP_Wing:SetRespawnAfterDestroyed()
|
||||
CAP_Wing:SetNumberCAP(self.capgrouping)
|
||||
CAP_Wing:SetCapCloseRaceTrack(true)
|
||||
if CapFormation then
|
||||
CAP_Wing:SetCAPFormation(CapFormation)
|
||||
end
|
||||
if #self.ManagedTK > 0 then
|
||||
CAP_Wing:SetNumberTankerBoom(1)
|
||||
CAP_Wing:SetNumberTankerProbe(1)
|
||||
end
|
||||
if #self.ManagedAW > 0 then
|
||||
if #self.ManagedEWR > 0 then
|
||||
CAP_Wing:SetNumberAWACS(1)
|
||||
end
|
||||
if #self.ManagedREC > 0 then
|
||||
@@ -515,6 +532,9 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
||||
flightgroup:SetDetection(true)
|
||||
flightgroup:SetEngageDetectedOn(self.engagerange,{"Air"},self.GoZoneSet,self.NoGoZoneSet)
|
||||
flightgroup:SetOutOfAAMRTB()
|
||||
if CapFormation then
|
||||
flightgroup:GetGroup():SetOption(AI.Option.Air.id.FORMATION,CapFormation)
|
||||
end
|
||||
end
|
||||
if Mission.type == AUFTRAG.Type.TANKER or Mission.type == AUFTRAG.Type.AWACS or Mission.type == AUFTRAG.Type.RECON then
|
||||
if TankerInvisible then
|
||||
@@ -549,8 +569,8 @@ end
|
||||
-- @param #EASYGCICAP self
|
||||
-- @param #string AirbaseName Name of the Wing's airbase
|
||||
-- @param Core.Point#COORDINATE Coordinate.
|
||||
-- @param #number Altitude Defaults to 25000 feet.
|
||||
-- @param #number Speed Defaults to 300 knots.
|
||||
-- @param #number Altitude Defaults to 25000 feet ASL.
|
||||
-- @param #number Speed Defaults to 300 knots TAS.
|
||||
-- @param #number Heading Defaults to 90 degrees (East).
|
||||
-- @param #number LegLength Defaults to 15 NM.
|
||||
-- @return #EASYGCICAP self
|
||||
@@ -888,7 +908,7 @@ function EASYGCICAP:_AddSquadron(TemplateName, SquadName, AirbaseName, AirFrames
|
||||
self:T(self.lid.."_AddSquadron "..SquadName)
|
||||
-- Add Squadrons
|
||||
local Squadron_One = SQUADRON:New(TemplateName,AirFrames,SquadName)
|
||||
Squadron_One:AddMissionCapability({AUFTRAG.Type.CAP, AUFTRAG.Type.GCICAP, AUFTRAG.Type.INTERCEPT, AUFTRAG.Type.ALERT5})
|
||||
Squadron_One:AddMissionCapability({AUFTRAG.Type.CAP, AUFTRAG.Type.GCICAP, AUFTRAG.Type.INTERCEPT, AUFTRAG.Type.PATROLRACETRACK, AUFTRAG.Type.ALERT5})
|
||||
--Squadron_One:SetFuelLowRefuel(true)
|
||||
Squadron_One:SetFuelLowThreshold(0.3)
|
||||
Squadron_One:SetTurnoverTime(10,20)
|
||||
@@ -900,7 +920,7 @@ function EASYGCICAP:_AddSquadron(TemplateName, SquadName, AirbaseName, AirFrames
|
||||
local wing = self.wings[AirbaseName][1] -- Ops.AirWing#AIRWING
|
||||
|
||||
wing:AddSquadron(Squadron_One)
|
||||
wing:NewPayload(TemplateName,-1,{AUFTRAG.Type.CAP, AUFTRAG.Type.GCICAP, AUFTRAG.Type.INTERCEPT, AUFTRAG.Type.ALERT5},75)
|
||||
wing:NewPayload(TemplateName,-1,{AUFTRAG.Type.CAP, AUFTRAG.Type.GCICAP, AUFTRAG.Type.INTERCEPT, AUFTRAG.Type.PATROLRACETRACK, AUFTRAG.Type.ALERT5},75)
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -1234,12 +1254,16 @@ function EASYGCICAP:onafterStatus(From,Event,To)
|
||||
local capmission = 0
|
||||
local interceptmission = 0
|
||||
local reconmission = 0
|
||||
local awacsmission = 0
|
||||
local tankermission = 0
|
||||
for _,_wing in pairs(self.wings) do
|
||||
local count = _wing[1]:CountAssetsOnMission(MissionTypes,Cohort)
|
||||
local count2 = _wing[1]:CountAssets(true,MissionTypes,Attributes)
|
||||
capmission = capmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.GCICAP})
|
||||
capmission = capmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.GCICAP,AUFTRAG.Type.PATROLRACETRACK})
|
||||
interceptmission = interceptmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.INTERCEPT})
|
||||
reconmission = reconmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.RECON})
|
||||
awacsmission = awacsmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.AWACS})
|
||||
tankermission = tankermission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.TANKER})
|
||||
assets = assets + count
|
||||
instock = instock + count2
|
||||
end
|
||||
@@ -1251,6 +1275,8 @@ function EASYGCICAP:onafterStatus(From,Event,To)
|
||||
text = text.."\nMissions: "..capmission+interceptmission
|
||||
text = text.."\n - CAP: "..capmission
|
||||
text = text.."\n - Intercept: "..interceptmission
|
||||
text = text.."\n - AWACS: "..awacsmission
|
||||
text = text.."\n - TANKER: "..tankermission
|
||||
text = text.."\n - Recon: "..reconmission
|
||||
MESSAGE:New(text,15,"GCICAP"):ToAll():ToLogIf(self.debug)
|
||||
end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2630,6 +2630,9 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n, N)
|
||||
elseif task.dcstask.id==AUFTRAG.SpecialTask.RECON then
|
||||
-- For recon missions, we need to allow the update as we insert new waypoints.
|
||||
self:T2(self.lid.."Allowing update route for Task: ReconMission")
|
||||
elseif task.dcstask.id==AUFTRAG.SpecialTask.PATROLRACETRACK then
|
||||
-- For recon missions, we need to allow the update as we insert new waypoints.
|
||||
self:T2(self.lid.."Allowing update route for Task: Patrol Race Track")
|
||||
elseif task.dcstask.id==AUFTRAG.SpecialTask.HOVER then
|
||||
-- For recon missions, we need to allow the update as we insert new waypoints.
|
||||
self:T2(self.lid.."Allowing update route for Task: Hover")
|
||||
|
||||
@@ -965,7 +965,7 @@ function LEGION:onafterMissionRequest(From, Event, To, Mission, Assets)
|
||||
local pause=false
|
||||
|
||||
-- Check if mission is INTERCEPT and asset is currently on GCI mission. If so, GCI is paused.
|
||||
if currM.type==AUFTRAG.Type.GCICAP and Mission.type==AUFTRAG.Type.INTERCEPT then
|
||||
if (currM.type==AUFTRAG.Type.GCICAP or currM.type==AUFTRAG.Type.PATROLRACETRACK) and Mission.type==AUFTRAG.Type.INTERCEPT then
|
||||
pause=true
|
||||
elseif (currM.type==AUFTRAG.Type.ONGUARD or currM.type==AUFTRAG.Type.PATROLZONE) and (Mission.type==AUFTRAG.Type.ARTY or Mission.type==AUFTRAG.Type.GROUNDATTACK) then
|
||||
pause=true
|
||||
@@ -1445,7 +1445,7 @@ end
|
||||
-- @param Functional.Warehouse#WAREHOUSE.Assetitem Asset The asset that returned.
|
||||
function LEGION:onafterLegionAssetReturned(From, Event, To, Cohort, Asset)
|
||||
-- Debug message.
|
||||
self:I(self.lid..string.format("Asset %s from Cohort %s returned! asset.assignment=\"%s\"", Asset.spawngroupname, Cohort.name, tostring(Asset.assignment)))
|
||||
self:T(self.lid..string.format("Asset %s from Cohort %s returned! asset.assignment=\"%s\"", Asset.spawngroupname, Cohort.name, tostring(Asset.assignment)))
|
||||
|
||||
-- Stop flightgroup.
|
||||
if Asset.flightgroup and not Asset.flightgroup:IsStopped() then
|
||||
@@ -2557,9 +2557,10 @@ function LEGION._CohortCan(Cohort, MissionType, Categories, Attributes, Properti
|
||||
|
||||
-- Distance to target.
|
||||
local TargetDistance=TargetVec2 and UTILS.VecDist2D(TargetVec2, cohort.legion:GetVec2()) or 0
|
||||
|
||||
|
||||
-- Is in range?
|
||||
local Rmax=cohort:GetMissionRange(WeaponTypes)
|
||||
local RangeMax = RangeMax or 0
|
||||
local InRange=(RangeMax and math.max(RangeMax, Rmax) or Rmax) >= TargetDistance
|
||||
|
||||
return InRange
|
||||
@@ -2610,6 +2611,7 @@ function LEGION._CohortCan(Cohort, MissionType, Categories, Attributes, Properti
|
||||
-- Is capable of the mission type?
|
||||
local can=AUFTRAG.CheckMissionCapability(MissionType, Cohort.missiontypes)
|
||||
|
||||
|
||||
if can then
|
||||
can=CheckCategory(Cohort)
|
||||
else
|
||||
@@ -2687,7 +2689,7 @@ function LEGION._CohortCan(Cohort, MissionType, Categories, Attributes, Properti
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Recruit assets from Cohorts for the given parameters. **NOTE** that we set the `asset.isReserved=true` flag so it cant be recruited by anyone else.
|
||||
--- Recruit assets from Cohorts for the given parameters. **NOTE** that we set the `asset.isReserved=true` flag so it cannot be recruited by anyone else.
|
||||
-- @param #table Cohorts Cohorts included.
|
||||
-- @param #string MissionTypeRecruit Mission type for recruiting the cohort assets.
|
||||
-- @param #string MissionTypeOpt Mission type for which the assets are optimized. Default is the same as `MissionTypeRecruit`.
|
||||
@@ -3181,7 +3183,7 @@ function LEGION.CalculateAssetMissionScore(asset, MissionType, TargetVec2, Inclu
|
||||
if currmission.type==AUFTRAG.Type.ALERT5 and currmission.alert5MissionType==MissionType then
|
||||
-- Prefer assets that are on ALERT5 for this mission type.
|
||||
score=score+25
|
||||
elseif currmission.type==AUFTRAG.Type.GCICAP and MissionType==AUFTRAG.Type.INTERCEPT then
|
||||
elseif (currmission.type==AUFTRAG.Type.GCICAP or currmission.type==AUFTRAG.Type.PATROLRACETRACK) and MissionType==AUFTRAG.Type.INTERCEPT then
|
||||
-- Prefer assets that are on GCICAP to perform INTERCEPTS. We set this even higher than alert5 because they are already in the air.
|
||||
score=score+35
|
||||
elseif (currmission.type==AUFTRAG.Type.ONGUARD or currmission.type==AUFTRAG.Type.PATROLZONE) and (MissionType==AUFTRAG.Type.ARTY or MissionType==AUFTRAG.Type.GROUNDATTACK) then
|
||||
|
||||
@@ -1774,6 +1774,8 @@ function OPSGROUP:GetDCSUnit(UnitNumber)
|
||||
if DCSGroup then
|
||||
local unit=DCSGroup:getUnit(UnitNumber or 1)
|
||||
return unit
|
||||
else
|
||||
self:E(self.lid..string.format("ERROR: DCS group does not exist! Cannot get unit"))
|
||||
end
|
||||
|
||||
return nil
|
||||
@@ -3523,9 +3525,11 @@ function OPSGROUP:OnEventBirth(EventData)
|
||||
local element=self:GetElementByName(unitname)
|
||||
|
||||
if element and element.status~=OPSGROUP.ElementStatus.SPAWNED then
|
||||
|
||||
|
||||
-- Debug info.
|
||||
self:T(self.lid..string.format("EVENT: Element %s born ==> spawned", unitname))
|
||||
|
||||
self:T2(self.lid..string.format("DCS unit=%s isExist=%s", tostring(EventData.IniDCSUnit:getName()), tostring(EventData.IniDCSUnit:isExist()) ))
|
||||
|
||||
-- Set element to spawned state.
|
||||
self:ElementSpawned(element)
|
||||
@@ -4469,6 +4473,26 @@ function OPSGROUP:_UpdateTask(Task, Mission)
|
||||
if target then
|
||||
self:EngageTarget(target, speed, Task.dcstask.params.formation)
|
||||
end
|
||||
|
||||
elseif Task.dcstask.id==AUFTRAG.SpecialTask.PATROLRACETRACK then
|
||||
|
||||
---
|
||||
-- Task "Patrol Race Track" Mission.
|
||||
---
|
||||
|
||||
if self.isFlightgroup then
|
||||
self:T("We are Special Auftrag Patrol Race Track, starting now ...")
|
||||
--self:I({Task.dcstask.params})
|
||||
--[[
|
||||
Task.dcstask.params.TrackAltitude = self.TrackAltitude
|
||||
Task.dcstask.params.TrackSpeed = self.TrackSpeed
|
||||
Task.dcstask.params.TrackPoint1 = self.TrackPoint1
|
||||
Task.dcstask.params.TrackPoint2 = self.TrackPoint2
|
||||
Task.dcstask.params.TrackFormation = self.TrackFormation
|
||||
--]]
|
||||
local aircraft = self:GetGroup()
|
||||
aircraft:PatrolRaceTrack(Task.dcstask.params.TrackPoint1,Task.dcstask.params.TrackPoint2,Task.dcstask.params.TrackAltitude,Task.dcstask.params.TrackSpeed,Task.dcstask.params.TrackFormation,false,1)
|
||||
end
|
||||
|
||||
elseif Task.dcstask.id==AUFTRAG.SpecialTask.HOVER then
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-- ===
|
||||
-- @module Ops.PlayerTask
|
||||
-- @image OPS_PlayerTask.jpg
|
||||
-- @date Last Update Sept 2023
|
||||
-- @date Last Update Oct 2023
|
||||
|
||||
|
||||
do
|
||||
@@ -98,7 +98,7 @@ PLAYERTASK = {
|
||||
|
||||
--- PLAYERTASK class version.
|
||||
-- @field #string version
|
||||
PLAYERTASK.version="0.1.20"
|
||||
PLAYERTASK.version="0.1.21"
|
||||
|
||||
--- Generic task condition.
|
||||
-- @type PLAYERTASK.Condition
|
||||
@@ -470,10 +470,11 @@ end
|
||||
--- [User] Remove a client from this task
|
||||
-- @param #PLAYERTASK self
|
||||
-- @param Wrapper.Client#CLIENT Client
|
||||
-- @param #string Name Name of the client
|
||||
-- @return #PLAYERTASK self
|
||||
function PLAYERTASK:RemoveClient(Client)
|
||||
function PLAYERTASK:RemoveClient(Client,Name)
|
||||
self:T(self.lid.."RemoveClient")
|
||||
local name = Client:GetPlayerName()
|
||||
local name = Name or Client:GetPlayerName()
|
||||
if self.Clients:HasUniqueID(name) then
|
||||
self.Clients:PullByID(name)
|
||||
if self.verbose then
|
||||
@@ -1551,7 +1552,7 @@ PLAYERTASKCONTROLLER.Messages = {
|
||||
|
||||
--- PLAYERTASK class version.
|
||||
-- @field #string version
|
||||
PLAYERTASKCONTROLLER.version="0.1.61"
|
||||
PLAYERTASKCONTROLLER.version="0.1.62"
|
||||
|
||||
--- Create and run a new TASKCONTROLLER instance.
|
||||
-- @param #PLAYERTASKCONTROLLER self
|
||||
@@ -2186,6 +2187,10 @@ function PLAYERTASKCONTROLLER:_EventHandler(EventData)
|
||||
task:RemoveClient(Client)
|
||||
--text = "Task aborted!"
|
||||
text = self.gettext:GetEntry("TASKABORT",self.locale)
|
||||
else
|
||||
task:RemoveClient(nil,EventData.IniPlayerName)
|
||||
--text = "Task aborted!"
|
||||
text = self.gettext:GetEntry("TASKABORT",self.locale)
|
||||
end
|
||||
else
|
||||
--text = "No active task!"
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
-- @field #boolean eplrs If true, enable data link, e.g. if used as AWACS.
|
||||
-- @field #boolean recovery If true, tanker will recover using the AIRBOSS marshal pattern.
|
||||
-- @field #number terminaltype Terminal type of used parking spots on airbases.
|
||||
-- @field #boolean unlimitedfuel If true, the tanker will have unlimited fuel.
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
--- Recovery Tanker.
|
||||
@@ -300,6 +301,7 @@ RECOVERYTANKER = {
|
||||
eplrs = nil,
|
||||
recovery = nil,
|
||||
terminaltype = nil,
|
||||
unlimitedfuel = false,
|
||||
}
|
||||
|
||||
--- Unique ID (global).
|
||||
@@ -308,7 +310,7 @@ _RECOVERYTANKERID=0
|
||||
|
||||
--- Class version.
|
||||
-- @field #string version
|
||||
RECOVERYTANKER.version="1.0.9"
|
||||
RECOVERYTANKER.version="1.0.10"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
@@ -326,6 +328,7 @@ RECOVERYTANKER.version="1.0.9"
|
||||
-- DONE: Set AA TACAN.
|
||||
-- DONE: Add refueling event/state.
|
||||
-- DONE: Possibility to add already present/spawned aircraft, e.g. for warehouse.
|
||||
-- DONE: Add unlimited fuel
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Constructor
|
||||
@@ -550,6 +553,15 @@ end
|
||||
-- User functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Set the tanker to have unlimited fuel.
|
||||
-- @param #RECOVERYTANKER self
|
||||
-- @param #boolean OnOff If true, the tanker will have unlimited fuel.
|
||||
-- @return #RECOVERYTANKER self
|
||||
function RECOVERYTANKER:SetUnlimitedFuel(OnOff)
|
||||
self.unlimitedfuel = OnOff
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set the speed the tanker flys in its orbit pattern.
|
||||
-- @param #RECOVERYTANKER self
|
||||
-- @param #number speed True air speed (TAS) in knots. Default 274 knots, which results in ~250 KIAS.
|
||||
@@ -899,6 +911,14 @@ function RECOVERYTANKER:onafterStart(From, Event, To)
|
||||
-- Spawn tanker. We need to introduce an alias in case this class is used twice. This would confuse the spawn routine.
|
||||
local Spawn=SPAWN:NewWithAlias(self.tankergroupname, self.alias)
|
||||
|
||||
if self.unlimitedfuel then
|
||||
Spawn:OnSpawnGroup(
|
||||
function (grp)
|
||||
grp:CommandSetUnlimitedFuel(self.unlimitedfuel)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- Set radio frequency and modulation.
|
||||
Spawn:InitRadioCommsOnOff(true)
|
||||
Spawn:InitRadioFrequency(self.RadioFreq)
|
||||
|
||||
@@ -64,8 +64,6 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- # Recue Helo
|
||||
--
|
||||
-- The rescue helo will fly in close formation with another unit, which is typically an aircraft carrier.
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
--
|
||||
-- * First, you need to **"add a @{#RADIO} object** to your @{Wrapper.Positionable#POSITIONABLE}. This is done using the @{Wrapper.Positionable#POSITIONABLE.GetRadio}() function,
|
||||
-- * Then, you will **set the relevant parameters** to the transmission (see below),
|
||||
-- * When done, you can actually **broadcast the transmission** (i.e. play the sound) with the @{RADIO.Broadcast}() function.
|
||||
-- * When done, you can actually **broadcast the transmission** (i.e. play the sound) with the @{#RADIO.Broadcast}() function.
|
||||
--
|
||||
-- Methods to set relevant parameters for both a @{Wrapper.Unit#UNIT} or a @{Wrapper.Group#GROUP} or any other @{Wrapper.Positionable#POSITIONABLE}
|
||||
--
|
||||
|
||||
@@ -17,15 +17,15 @@
|
||||
--- Makes the radio speak.
|
||||
--
|
||||
-- # RADIOSPEECH usage
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- @type RADIOSPEECH
|
||||
-- @extends Core.RadioQueue#RADIOQUEUE
|
||||
-- @extends Sound.RadioQueue#RADIOQUEUE
|
||||
RADIOSPEECH = {
|
||||
ClassName = "RADIOSPEECH",
|
||||
Vocabulary = {
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
-- @field #string google Full path google credentials JSON file, e.g. "C:\Users\username\Downloads\service-account-file.json".
|
||||
-- @field #string Label Label showing up on the SRS radio overlay. Default is "ROBOT". No spaces allowed.
|
||||
-- @field #table AltBackend Table containing functions and variables to enable an alternate backend to transmit to SRS.
|
||||
-- @field #string ConfigFileName Name of the standard config file
|
||||
-- @field #string ConfigFilePath Path to the standard config file
|
||||
-- @field #boolean ConfigLoaded
|
||||
-- @extends Core.Base#BASE
|
||||
|
||||
--- *It is a very sad thing that nowadays there is so little useless information.* - Oscar Wilde
|
||||
@@ -91,7 +94,7 @@
|
||||
-- ## Set Google
|
||||
--
|
||||
-- Use Google's text-to-speech engine with the @{#MSRS.SetGoogle} function, e.g. ':SetGoogle()'.
|
||||
-- By enabling this it also allows you to utilize SSML in your text for added flexibilty.
|
||||
-- By enabling this it also allows you to utilize SSML in your text for added flexibility.
|
||||
-- For more information on setting up a cloud account, visit: https://cloud.google.com/text-to-speech
|
||||
-- Google's supported SSML reference: https://cloud.google.com/text-to-speech/docs/ssml
|
||||
--
|
||||
@@ -185,6 +188,9 @@ MSRS = {
|
||||
coordinate = nil,
|
||||
Label = "ROBOT",
|
||||
AltBackend = nil,
|
||||
ConfigFileName = "Moose_MSRS.lua",
|
||||
ConfigFilePath = "Config\\",
|
||||
ConfigLoaded = false,
|
||||
}
|
||||
|
||||
--- MSRS class version.
|
||||
@@ -292,6 +298,37 @@ MSRS.Voices = {
|
||||
},
|
||||
}
|
||||
|
||||
---
|
||||
-- @type MSRS.ProviderOptions
|
||||
-- @field #string key
|
||||
-- @field #string secret
|
||||
-- @field #string region
|
||||
-- @field #string defaultVoice
|
||||
-- @field #string voice
|
||||
|
||||
--- GRPC options
|
||||
-- @type MSRS.GRPCOptions
|
||||
-- @field #string plaintext
|
||||
-- @field #string srsClientName
|
||||
-- @field #table position
|
||||
-- @field #string coalition
|
||||
-- @field #MSRS.ProviderOptions gcloud
|
||||
-- @field #MSRS.ProviderOptions win
|
||||
-- @field #MSRS.ProviderOptions azure
|
||||
-- @field #MSRS.ProviderOptions aws
|
||||
-- @field #string DefaultProvider
|
||||
|
||||
MSRS.GRPCOptions = {} -- #MSRS.GRPCOptions
|
||||
MSRS.GRPCOptions.gcloud = {} -- #MSRS.ProviderOptions
|
||||
MSRS.GRPCOptions.win = {} -- #MSRS.ProviderOptions
|
||||
MSRS.GRPCOptions.azure = {} -- #MSRS.ProviderOptions
|
||||
MSRS.GRPCOptions.aws = {} -- #MSRS.ProviderOptions
|
||||
|
||||
MSRS.GRPCOptions.win.defaultVoice = "Hedda"
|
||||
MSRS.GRPCOptions.win.voice = "Hedda"
|
||||
|
||||
MSRS.GRPCOptions.DefaultProvider = "win"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -299,6 +336,8 @@ MSRS.Voices = {
|
||||
-- TODO: Add functions to remove freqs and modulations.
|
||||
-- DONE: Add coordinate.
|
||||
-- DONE: Add google.
|
||||
-- DONE: Add gRPC google options
|
||||
-- DONE: Add loading default config file
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Constructor
|
||||
@@ -328,25 +367,49 @@ function MSRS:New(PathToSRS, Frequency, Modulation, Volume, AltBackend)
|
||||
|
||||
-- Add parameters to vars so alternate backends can use them if applicable
|
||||
Backend.Vars = Backend.Vars or {}
|
||||
Backend.Vars.PathToSRS = UTILS.DeepCopy(PathToSRS) -- DeepCopy probably unecessary
|
||||
Backend.Vars.PathToSRS = PathToSRS
|
||||
Backend.Vars.Frequency = UTILS.DeepCopy(Frequency)
|
||||
Backend.Vars.Modulation = UTILS.DeepCopy(Modulation)
|
||||
Backend.Vars.Volume = UTILS.DeepCopy(Volume) -- DeepCopy probably unecessary
|
||||
Backend.Vars.Volume = Volume
|
||||
|
||||
Backend.Functions = Backend.Functions or {}
|
||||
|
||||
return self:_NewAltBackend(Backend)
|
||||
end
|
||||
|
||||
-- If no AltBackend table, the proceed with default initialization
|
||||
self:SetPath(PathToSRS)
|
||||
self:SetPort()
|
||||
self:SetFrequencies(Frequency)
|
||||
self:SetModulations(Modulation)
|
||||
self:SetGender()
|
||||
self:SetCoalition()
|
||||
self:SetLabel()
|
||||
self:SetVolume()
|
||||
local success = self:LoadConfigFile(nil,nil,self.ConfigLoaded)
|
||||
|
||||
if (not success) and (not self.ConfigLoaded) then
|
||||
|
||||
-- If no AltBackend table, the proceed with default initialisation
|
||||
self:SetPath(PathToSRS)
|
||||
self:SetPort()
|
||||
self:SetFrequencies(Frequency)
|
||||
self:SetModulations(Modulation)
|
||||
self:SetGender()
|
||||
self:SetCoalition()
|
||||
self:SetLabel()
|
||||
self:SetVolume(Volume)
|
||||
|
||||
else
|
||||
|
||||
-- there might be some overwrites from :New()
|
||||
|
||||
if PathToSRS then
|
||||
self:SetPath(PathToSRS)
|
||||
end
|
||||
|
||||
if Frequency then
|
||||
self:SetFrequencies(Frequency)
|
||||
self:SetModulations(Modulation)
|
||||
end
|
||||
|
||||
if Volume then
|
||||
self:SetVolume(Volume)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
self.lid = string.format("%s-%s | ", self.name, self.version)
|
||||
|
||||
if not io or not os then
|
||||
@@ -366,24 +429,25 @@ end
|
||||
-- @return #MSRS self
|
||||
function MSRS:SetPath(Path)
|
||||
|
||||
if Path==nil then
|
||||
if Path==nil and not self.path then
|
||||
self:E("ERROR: No path to SRS directory specified!")
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Set path.
|
||||
self.path=Path
|
||||
|
||||
-- Remove (back)slashes.
|
||||
local n=1 ; local nmax=1000
|
||||
while (self.path:sub(-1)=="/" or self.path:sub(-1)==[[\]]) and n<=nmax do
|
||||
self.path=self.path:sub(1,#self.path-1)
|
||||
n=n+1
|
||||
if Path then
|
||||
-- Set path.
|
||||
self.path=Path
|
||||
|
||||
-- Remove (back)slashes.
|
||||
local n=1 ; local nmax=1000
|
||||
while (self.path:sub(-1)=="/" or self.path:sub(-1)==[[\]]) and n<=nmax do
|
||||
self.path=self.path:sub(1,#self.path-1)
|
||||
n=n+1
|
||||
end
|
||||
|
||||
-- Debug output.
|
||||
self:I(string.format("SRS path=%s", self:GetPath()))
|
||||
end
|
||||
|
||||
-- Debug output.
|
||||
self:T(string.format("SRS path=%s", self:GetPath()))
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -579,6 +643,10 @@ function MSRS:SetVoice(Voice)
|
||||
|
||||
self.voice=Voice
|
||||
|
||||
--local defaultprovider = self.provider or self.GRPCOptions.DefaultProvider or MSRS.GRPCOptions.DefaultProvider or "win"
|
||||
|
||||
--self.GRPCOptions[defaultprovider].voice = Voice
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -589,6 +657,8 @@ end
|
||||
function MSRS:SetDefaultVoice(Voice)
|
||||
|
||||
self.defaultVoice=Voice
|
||||
local provider = self.provider or self.GRPCOptions.DefaultProvider or MSRS.GRPCOptions.DefaultProvider or "win"
|
||||
self.GRPCOptions[provider].defaultVoice = Voice
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -606,13 +676,20 @@ end
|
||||
|
||||
--- Use google text-to-speech.
|
||||
-- @param #MSRS self
|
||||
-- @param PathToCredentials Full path to the google credentials JSON file, e.g. "C:\Users\username\Downloads\service-account-file.json".
|
||||
-- @param #string PathToCredentials Full path to the google credentials JSON file, e.g. "C:\Users\username\Downloads\service-account-file.json". Can also be the Google API key.
|
||||
-- @return #MSRS self
|
||||
function MSRS:SetGoogle(PathToCredentials)
|
||||
|
||||
self.google=PathToCredentials
|
||||
self.APIKey=PathToCredentials
|
||||
self.provider = "gcloud"
|
||||
|
||||
if PathToCredentials then
|
||||
|
||||
self.google=PathToCredentials
|
||||
self.APIKey=PathToCredentials
|
||||
self.provider = "gcloud"
|
||||
|
||||
self.GRPCOptions.DefaultProvider = "gcloud"
|
||||
self.GRPCOptions.gcloud.key = PathToCredentials
|
||||
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -622,10 +699,12 @@ end
|
||||
-- @param #string APIKey API Key, usually a string of length 40 with characters and numbers.
|
||||
-- @return #MSRS self
|
||||
function MSRS:SetGoogleAPIKey(APIKey)
|
||||
|
||||
self.APIKey=APIKey
|
||||
self.provider = "gcloud"
|
||||
|
||||
if APIKey then
|
||||
self.APIKey=APIKey
|
||||
self.provider = "gcloud"
|
||||
self.GRPCOptions.DefaultProvider = "gcloud"
|
||||
self.GRPCOptions.gcloud.key = APIKey
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -690,7 +769,7 @@ end
|
||||
|
||||
--- Play sound file (ogg or mp3) via SRS.
|
||||
-- @param #MSRS self
|
||||
-- @param Sound.SoundFile#SOUNDFILE Soundfile Sound file to play.
|
||||
-- @param Sound.SoundOutput#SOUNDFILE Soundfile Sound file to play.
|
||||
-- @param #number Delay Delay in seconds, before the sound file is played.
|
||||
-- @return #MSRS self
|
||||
function MSRS:PlaySoundFile(Soundfile, Delay)
|
||||
@@ -718,7 +797,7 @@ end
|
||||
|
||||
--- Play a SOUNDTEXT text-to-speech object.
|
||||
-- @param #MSRS self
|
||||
-- @param Sound.SoundFile#SOUNDTEXT SoundText Sound text.
|
||||
-- @param Sound.SoundOutput#SOUNDTEXT SoundText Sound text.
|
||||
-- @param #number Delay Delay in seconds, before the sound file is played.
|
||||
-- @return #MSRS self
|
||||
function MSRS:PlaySoundText(SoundText, Delay)
|
||||
@@ -1041,6 +1120,171 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp
|
||||
return command
|
||||
end
|
||||
|
||||
--- Get central SRS configuration to be able to play tts over SRS radio using the `DCS-SR-ExternalAudio.exe`.
|
||||
-- @param #MSRS self
|
||||
-- @param #string Path Path to config file, defaults to "C:\Users\<yourname>\Saved Games\DCS\Config"
|
||||
-- @param #string Filename File to load, defaults to "Moose_MSRS.lua"
|
||||
-- @param #boolean ConfigLoaded - if true, skip the loading
|
||||
-- @return #boolean success
|
||||
-- @usage
|
||||
-- 0) Benefits: Centralize configuration of SRS, keep paths and keys out of the mission source code, making it safer and easier to move missions to/between servers,
|
||||
-- and also make config easier to use in the code.
|
||||
-- 1) Create a config file named "Moose_MSRS.lua" at this location "C:\Users\<yourname>\Saved Games\DCS\Config" (or wherever your Saved Games folder resides).
|
||||
-- 2) The file needs the following structure:
|
||||
--
|
||||
-- -- Moose MSRS default Config
|
||||
-- MSRS_Config = {
|
||||
-- Path = "C:\\Program Files\\DCS-SimpleRadio-Standalone", -- adjust as needed
|
||||
-- Port = 5002, -- adjust as needed
|
||||
-- Frequency = {127,243}, -- must be a table, 1..n entries!
|
||||
-- Modulation = {0,0}, -- must be a table, 1..n entries, one for each frequency!
|
||||
-- Volume = 1.0,
|
||||
-- Coalition = 0, -- 0 = Neutral, 1 = Red, 2 = Blue
|
||||
-- Coordinate = {0,0,0}, -- x,y,alt - optional
|
||||
-- Culture = "en-GB",
|
||||
-- Gender = "male",
|
||||
-- Google = "C:\\Program Files\\DCS-SimpleRadio-Standalone\\yourfilename.json", -- path to google json key file - optional
|
||||
-- Label = "MSRS",
|
||||
-- Voice = "Microsoft Hazel Desktop",
|
||||
-- -- gRPC (optional)
|
||||
-- GRPC = { -- see https://github.com/DCS-gRPC/rust-server
|
||||
-- coalition = "blue", -- blue, red, neutral
|
||||
-- DefaultProvider = "gcloud", -- win, gcloud, aws, or azure, some of the values below depend on your cloud provider
|
||||
-- gcloud = {
|
||||
-- key = "<API Google Key>", -- for gRPC Google API key
|
||||
-- --secret = "", -- needed for aws
|
||||
-- --region = "",-- needed for aws
|
||||
-- defaultVoice = MSRS.Voices.Google.Standard.en_GB_Standard_F,
|
||||
-- },
|
||||
-- win = {
|
||||
-- defaultVoice = "Hazel",
|
||||
-- },
|
||||
-- }
|
||||
-- }
|
||||
--
|
||||
-- 3) Load the config into the MSRS raw class before you do anything else:
|
||||
--
|
||||
-- MSRS.LoadConfigFile() -- Note the "." here
|
||||
--
|
||||
-- This will populate variables for the MSRS raw class and all instances you create with e.g. `mysrs = MSRS:New()`
|
||||
-- Optionally you can also load this per **single instance** if so needed, i.e.
|
||||
--
|
||||
-- mysrs:LoadConfig(Path,Filename)
|
||||
--
|
||||
-- 4) Use the config in your code like so, variable names are basically the same as in the config file, but all lower case, examples:
|
||||
--
|
||||
-- -- Needed once only
|
||||
-- MESSAGE.SetMSRS(MSRS.path,nil,MSRS.google,243,radio.modulation.AM,nil,nil,
|
||||
-- MSRS.Voices.Google.Standard.de_DE_Standard_B,coalition.side.BLUE)
|
||||
--
|
||||
-- -- later on in your code
|
||||
--
|
||||
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS(243,radio.modulation.AM,nil,nil,MSRS.Voices.Google.Standard.fr_FR_Standard_C)
|
||||
--
|
||||
-- -- Create new ATIS as usual
|
||||
-- atis=ATIS:New(AIRBASE.Caucasus.Batumi, 123, radio.modulation.AM)
|
||||
-- atis:SetSRS(nil,nil,nil,MSRS.Voices.Google.Standard.en_US_Standard_H)
|
||||
-- --Start ATIS
|
||||
-- atis:Start()
|
||||
function MSRS:LoadConfigFile(Path,Filename,ConfigLoaded)
|
||||
|
||||
local path = Path or lfs.writedir()..MSRS.ConfigFilePath
|
||||
local file = Filename or MSRS.ConfigFileName or "Moose_MSRS.lua"
|
||||
|
||||
if UTILS.CheckFileExists(path,file) and not ConfigLoaded then
|
||||
assert(loadfile(path..file))()
|
||||
-- now we should have a global var MSRS_Config
|
||||
if MSRS_Config then
|
||||
--[[
|
||||
-- Moose MSRS default Config
|
||||
MSRS_Config = {
|
||||
Path = "C:\\Program Files\\DCS-SimpleRadio-Standalone", -- adjust as needed
|
||||
Port = 5002, -- adjust as needed
|
||||
Frequency = {127,243}, -- must be a table, 1..n entries!
|
||||
Modulation = {0,0}, -- must be a table, 1..n entries, one for each frequency!
|
||||
Volume = 1.0,
|
||||
Coalition = 0, -- 0 = Neutral, 1 = Red, 2 = Blue
|
||||
Coordinate = {0,0,0}, -- x,y,alt - optional
|
||||
Culture = "en-GB",
|
||||
Gender = "male",
|
||||
Google = "C:\\Program Files\\DCS-SimpleRadio-Standalone\\yourfilename.json", -- path to google json key file - optional
|
||||
Label = "MSRS",
|
||||
Voice = "Microsoft Hazel Desktop",
|
||||
-- gRPC (optional)
|
||||
GRPC = { -- see https://github.com/DCS-gRPC/rust-server
|
||||
coalition = "blue", -- blue, red, neutral
|
||||
DefaultProvider = "gcloud", -- win, gcloud, aws, or azure, some of the values below depend on your cloud provider
|
||||
gcloud = {
|
||||
key = "<API Google Key>", -- for gRPC Google API key
|
||||
--secret = "", -- needed for aws
|
||||
--region = "",-- needed for aws
|
||||
defaultVoice = MSRS.Voices.Google.Standard.en_GB_Standard_F,
|
||||
},
|
||||
win = {
|
||||
defaultVoice = "Hazel",
|
||||
},
|
||||
}
|
||||
}
|
||||
--]]
|
||||
if self then
|
||||
self.path = MSRS_Config.Path or "C:\\Program Files\\DCS-SimpleRadio-Standalone"
|
||||
self.port = MSRS_Config.Port or 5002
|
||||
self.frequencies = MSRS_Config.Frequency or {127,243}
|
||||
self.modulations = MSRS_Config.Modulation or {0,0}
|
||||
self.coalition = MSRS_Config.Coalition or 0
|
||||
if MSRS_Config.Coordinate then
|
||||
self.coordinate = COORDINATE:New( MSRS_Config.Coordinate[1],MSRS_Config.Coordinate[2],MSRS_Config.Coordinate[3])
|
||||
end
|
||||
self.culture = MSRS_Config.Culture or "en-GB"
|
||||
self.gender = MSRS_Config.Gender or "male"
|
||||
self.google = MSRS_Config.Google
|
||||
self.Label = MSRS_Config.Label or "MSRS"
|
||||
self.voice = MSRS_Config.Voice or MSRS.Voices.Microsoft.Hazel
|
||||
if MSRS_Config.GRPC then
|
||||
self.provider = MSRS_Config.GRPC.DefaultProvider
|
||||
if MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider] then
|
||||
self.APIKey = MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].key
|
||||
self.defaultVoice = MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].defaultVoice
|
||||
self.region = MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].secret
|
||||
self.secret = MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].region
|
||||
end
|
||||
end
|
||||
self.ConfigLoaded = true
|
||||
else
|
||||
MSRS.path = MSRS_Config.Path or "C:\\Program Files\\DCS-SimpleRadio-Standalone"
|
||||
MSRS.port = MSRS_Config.Port or 5002
|
||||
MSRS.frequencies = MSRS_Config.Frequency or {127,243}
|
||||
MSRS.modulations = MSRS_Config.Modulation or {0,0}
|
||||
MSRS.coalition = MSRS_Config.Coalition or 0
|
||||
if MSRS_Config.Coordinate then
|
||||
MSRS.coordinate = COORDINATE:New( MSRS_Config.Coordinate[1],MSRS_Config.Coordinate[2],MSRS_Config.Coordinate[3])
|
||||
end
|
||||
MSRS.culture = MSRS_Config.Culture or "en-GB"
|
||||
MSRS.gender = MSRS_Config.Gender or "male"
|
||||
MSRS.google = MSRS_Config.Google
|
||||
MSRS.Label = MSRS_Config.Label or "MSRS"
|
||||
MSRS.voice = MSRS_Config.Voice or MSRS.Voices.Microsoft.Hazel
|
||||
if MSRS_Config.GRPC then
|
||||
MSRS.provider = MSRS_Config.GRPC.DefaultProvider
|
||||
if MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider] then
|
||||
MSRS.APIKey = MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].key
|
||||
MSRS.defaultVoice = MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].defaultVoice
|
||||
MSRS.region = MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].secret
|
||||
MSRS.secret = MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].region
|
||||
end
|
||||
end
|
||||
MSRS.ConfigLoaded = true
|
||||
end
|
||||
end
|
||||
env.info("MSRS - Sucessfully loaded default configuration from disk!",false)
|
||||
else
|
||||
env.info("MSRS - Cannot load default configuration from disk!",false)
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- MSRS DCS-gRPC alternate backend
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -1173,7 +1417,7 @@ end
|
||||
|
||||
--- Replacement function for @{#MSRS.PlaySoundText}
|
||||
-- @param #MSRS self
|
||||
-- @param Sound.SoundFile#SOUNDTEXT SoundText Sound text.
|
||||
-- @param Sound.SoundOutput#SOUNDTEXT SoundText Sound text.
|
||||
-- @param #number Delay Delay in seconds, before the sound file is played.
|
||||
-- @return #MSRS self
|
||||
MSRS_BACKEND_DCSGRPC.Functions.PlaySoundText = function (self, SoundText, Delay)
|
||||
@@ -1285,7 +1529,7 @@ MSRS_BACKEND_DCSGRPC.Functions._DCSgRPCtts = function (self, Text, Plaintext, Fr
|
||||
BASE:T("MSRS_BACKEND_DCSGRPC:_DCSgRPCtts()")
|
||||
BASE:T({Text, Plaintext, Frequencies, Voice, Label})
|
||||
|
||||
local options = {}
|
||||
local options = self.ProviderOptions or MSRS.ProviderOptions or {} -- #MSRS.GRPCOptions
|
||||
local ssml = Text or ''
|
||||
|
||||
local XmitFrequencies = Frequencies or self.Frequency
|
||||
@@ -1297,7 +1541,7 @@ MSRS_BACKEND_DCSGRPC.Functions._DCSgRPCtts = function (self, Text, Plaintext, Fr
|
||||
options.srsClientName = Label or self.Label
|
||||
options.position = {}
|
||||
if self.coordinate then
|
||||
options.position.lat, options.position.lat, options.position.alt = self:_GetLatLongAlt(self.coordinate)
|
||||
options.position.lat, options.position.lon, options.position.alt = self:_GetLatLongAlt(self.coordinate)
|
||||
end
|
||||
|
||||
options.position.lat = options.position.lat or 0.0
|
||||
@@ -1309,12 +1553,23 @@ MSRS_BACKEND_DCSGRPC.Functions._DCSgRPCtts = function (self, Text, Plaintext, Fr
|
||||
elseif UTILS.GetCoalitionName(self.coalition) == 'Red' then
|
||||
options.coalition = 'red'
|
||||
end
|
||||
|
||||
|
||||
local provider = self.provider or self.GRPCOptions.DefaultProvider or MSRS.GRPCOptions.DefaultProvider
|
||||
|
||||
options.provider = {}
|
||||
options.provider[self.provider] = {}
|
||||
|
||||
|
||||
options.provider[provider] = {}
|
||||
|
||||
if self.APIKey then
|
||||
options.provider[provider].key = self.APIKey
|
||||
end
|
||||
|
||||
if self.defaultVoice then
|
||||
options.provider[provider].defaultVoice = self.defaultVoice
|
||||
end
|
||||
|
||||
if self.voice then
|
||||
options.provider[self.provider].voice = Voice or self.voice
|
||||
options.provider[provider].voice = Voice or self.voice or self.defaultVoice
|
||||
elseif ssml then
|
||||
-- DCS-gRPC doesn't directly support language/gender, but can use SSML
|
||||
-- Only use if a voice isn't explicitly set
|
||||
@@ -1340,7 +1595,7 @@ MSRS_BACKEND_DCSGRPC.Functions._DCSgRPCtts = function (self, Text, Plaintext, Fr
|
||||
BASE:T("GRPC.tts")
|
||||
BASE:T(ssml)
|
||||
BASE:T(freq)
|
||||
BASE:T(options)
|
||||
BASE:T({options})
|
||||
GRPC.tts(ssml, freq, options)
|
||||
end
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@ do -- Text-To-Speech
|
||||
--
|
||||
-- ## Specific Voice
|
||||
--
|
||||
-- You can use a specific voice for the transmission with the @{SOUNDTEXT.SetVoice}(*VoiceName*) function. Here are some examples
|
||||
-- You can use a specific voice for the transmission with the @{#SOUNDTEXT.SetVoice}(*VoiceName*) function. Here are some examples
|
||||
--
|
||||
-- * Name: Microsoft Hazel Desktop, Culture: en-GB, Gender: Female, Age: Adult, Desc: Microsoft Hazel Desktop - English (Great Britain)
|
||||
-- * Name: Microsoft David Desktop, Culture: en-US, Gender: Male, Age: Adult, Desc: Microsoft David Desktop - English (United States)
|
||||
|
||||
@@ -162,12 +162,12 @@
|
||||
-- choose from 2 added menu options either to accept or reject the assigned task within 30 seconds.
|
||||
-- If the task is not accepted within 30 seconds; the task will be cancelled and a new task will be assigned.
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- @field #COMMANDCENTER
|
||||
COMMANDCENTER = {
|
||||
ClassName = "COMMANDCENTER",
|
||||
@@ -339,7 +339,7 @@ end
|
||||
|
||||
--- Gets the coalition of the command center.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @return DCScoalition#coalition
|
||||
-- @return #number Coalition of the command center.
|
||||
function COMMANDCENTER:GetCoalition()
|
||||
|
||||
return self.CommandCenterCoalition
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
-- Derived classes need to implement the method @{#DETECTION_MANAGER.GetReportDisplayTime}() to use the correct display time for displayed messages during a report.
|
||||
--
|
||||
-- Reporting can be started and stopped using the methods @{#DETECTION_MANAGER.StartReporting}() and @{#DETECTION_MANAGER.StopReporting}() respectively.
|
||||
-- If an ad-hoc report is requested, use the method @{#DETECTION_MANAGER#ReportNow}().
|
||||
-- If an ad-hoc report is requested, use the method @{#DETECTION_MANAGER.ReportNow}().
|
||||
--
|
||||
-- The default reporting interval is every 60 seconds. The reporting messages are displayed 15 seconds.
|
||||
--
|
||||
@@ -32,12 +32,12 @@
|
||||
-- -------------------------------
|
||||
-- The @{#DETECTION_REPORTING.New}() method creates a new DETECTION_REPORTING instance.
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Contributions: Mechanist, Prof_Hilactic, FlightControl - Concept & Testing
|
||||
|
||||
@@ -117,12 +117,12 @@
|
||||
-- - @{#MISSION.ReportPlayersPerTask}(): Generates a report showing the active players per task.
|
||||
-- - @{#MISSION.ReportPlayersProgress}(): Generates a report showing the task progress per player.
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- @field #MISSION
|
||||
MISSION = {
|
||||
ClassName = "MISSION",
|
||||
|
||||
@@ -203,12 +203,12 @@
|
||||
--
|
||||
-- These different completion states are important for the mission designer to reflect scoring to a player.
|
||||
-- A success could mean a positive score to be given, while a failure could mean a negative score or penalties to be awarded.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author(s): **FlightControl**
|
||||
@@ -1773,7 +1773,7 @@ do -- Links
|
||||
|
||||
--- Set detection of a task
|
||||
-- @param #TASK self
|
||||
-- @param Function.Detection#DETECTION_BASE Detection
|
||||
-- @param Functional.Detection#DETECTION_BASE Detection
|
||||
-- @param DetectedItem
|
||||
-- @return #TASK
|
||||
function TASK:SetDetection( Detection, DetectedItem )
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
-- # TASKINFO class, extends @{Core.Base#BASE}
|
||||
--
|
||||
-- ## The TASKINFO class implements the methods to contain information and display information of a task.
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
--
|
||||
-- # Developer Note
|
||||
--
|
||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||
-- Therefore, this class is considered to be deprecated
|
||||
--
|
||||
-- @field #TASKINFO
|
||||
TASKINFO = {
|
||||
ClassName = "TASKINFO",
|
||||
@@ -256,7 +256,7 @@ end
|
||||
|
||||
--- Add Cargo.
|
||||
-- @param #TASKINFO self
|
||||
-- @param Core.Cargo#CARGO Cargo
|
||||
-- @param Cargo.Cargo#CARGO Cargo
|
||||
-- @param #number Order The display order, which is a number from 0 to 100.
|
||||
-- @param #TASKINFO.Detail Detail The detail Level.
|
||||
-- @param #boolean Keep (optional) If true, this would indicate that the planned taskinfo would be persistent when the task is completed, so that the original planned task info is used at the completed reports.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user