diff --git a/.appveyor/appveyor.yml b/.appveyor/appveyor.yml deleted file mode 100644 index 2af7fd529..000000000 --- a/.appveyor/appveyor.yml +++ /dev/null @@ -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')) diff --git a/.gitattributes b/.gitattributes index bdb0cabc8..2e755a77c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml new file mode 100644 index 000000000..5769e409b --- /dev/null +++ b/.github/workflows/build-docs.yml @@ -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 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 }}." diff --git a/.github/workflows/build-includes.yml b/.github/workflows/build-includes.yml new file mode 100644 index 000000000..4bd22bdbe --- /dev/null +++ b/.github/workflows/build-includes.yml @@ -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 }}." diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml new file mode 100644 index 000000000..48870d12c --- /dev/null +++ b/.github/workflows/gh-pages.yml @@ -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 diff --git a/.gitignore b/.gitignore index c84f22bdf..38430d132 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/Moose Development/Moose/AI/AI_A2A_Cap.lua b/Moose Development/Moose/AI/AI_A2A_Cap.lua index 2b82e6d6c..0c8aff8fa 100644 --- a/Moose Development/Moose/AI/AI_A2A_Cap.lua +++ b/Moose Development/Moose/AI/AI_A2A_Cap.lua @@ -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 diff --git a/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua b/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua index c0e20617b..59941b899 100644 --- a/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua @@ -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. diff --git a/Moose Development/Moose/AI/AI_A2A_Gci.lua b/Moose Development/Moose/AI/AI_A2A_Gci.lua index e3e7adb04..e40e8513b 100644 --- a/Moose Development/Moose/AI/AI_A2A_Gci.lua +++ b/Moose Development/Moose/AI/AI_A2A_Gci.lua @@ -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. -- --- ![Process](..\Presentations\AI_GCI\Dia3.JPG) --- -- 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. -- --- ![Process](..\Presentations\AI_GCI\Dia4.JPG) --- -- 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. -- --- ![Process](..\Presentations\AI_GCI\Dia5.JPG) --- -- This cycle will continue. -- --- ![Process](..\Presentations\AI_GCI\Dia6.JPG) --- -- During the patrol, the AI will detect enemy targets, which are reported through the **Detected** event. -- --- ![Process](..\Presentations\AI_GCI\Dia9.JPG) --- -- When enemies are detected, the AI will automatically engage the enemy. -- --- ![Process](..\Presentations\AI_GCI\Dia10.JPG) --- -- 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. -- --- ![Process](..\Presentations\AI_GCI\Dia13.JPG) --- -- ## 1. AI_A2A_GCI constructor -- -- * @{#AI_A2A_GCI.New}(): Creates a new AI_A2A_GCI object. -- -- ## 2. AI_A2A_GCI is a FSM -- --- ![Process](..\Presentations\AI_GCI\Dia2.JPG) --- -- ### 2.1 AI_A2A_GCI States -- -- * **None** ( Group ): The process is not started yet. @@ -77,27 +61,16 @@ -- -- ## 3. Set the Range of Engagement -- --- ![Range](..\Presentations\AI_GCI\Dia11.JPG) --- -- 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 -- --- ![Zone](..\Presentations\AI_GCI\Dia12.JPG) +-- 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 diff --git a/Moose Development/Moose/AI/AI_A2A_Patrol.lua b/Moose Development/Moose/AI/AI_A2A_Patrol.lua index 0c882a39a..1e66eb167 100644 --- a/Moose Development/Moose/AI/AI_A2A_Patrol.lua +++ b/Moose Development/Moose/AI/AI_A2A_Patrol.lua @@ -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 diff --git a/Moose Development/Moose/AI/AI_A2G_BAI.lua b/Moose Development/Moose/AI/AI_A2G_BAI.lua index 330110cca..28acea07f 100644 --- a/Moose Development/Moose/AI/AI_A2G_BAI.lua +++ b/Moose Development/Moose/AI/AI_A2G_BAI.lua @@ -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 ) diff --git a/Moose Development/Moose/AI/AI_A2G_CAS.lua b/Moose Development/Moose/AI/AI_A2G_CAS.lua index cc16cc187..7bae80ea3 100644 --- a/Moose Development/Moose/AI/AI_A2G_CAS.lua +++ b/Moose Development/Moose/AI/AI_A2G_CAS.lua @@ -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 ) diff --git a/Moose Development/Moose/AI/AI_A2G_Dispatcher.lua b/Moose Development/Moose/AI/AI_A2G_Dispatcher.lua index 6be8a0872..1fe9b4c5a 100644 --- a/Moose Development/Moose/AI/AI_A2G_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_A2G_Dispatcher.lua @@ -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: -- - -- ![Banner Image](..\Presentations\AI_A2G_DISPATCHER\AI_A2G_DISPATCHER-ME_1.JPG) - -- -- -- 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. -- - -- ![Banner Image](..\Presentations\AI_A2G_DISPATCHER\Dia5.JPG) - -- -- 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. -- - -- ![Banner Image](..\Presentations\AI_A2G_DISPATCHER\Dia12.JPG) - -- -- 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**. -- - -- ![Banner Image](..\Presentations\AI_A2G_DISPATCHER\Dia11.JPG) - -- -- 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": -- - -- ![Banner Image](..\Presentations\AI_A2G_DISPATCHER\AI_A2G_DISPATCHER-ME_11.JPG) - -- -- -- 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" ) diff --git a/Moose Development/Moose/AI/AI_A2G_SEAD.lua b/Moose Development/Moose/AI/AI_A2G_SEAD.lua index 2a4e8856c..b6f9d9426 100644 --- a/Moose Development/Moose/AI/AI_A2G_SEAD.lua +++ b/Moose Development/Moose/AI/AI_A2G_SEAD.lua @@ -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. -- --- ![Process](..\Presentations\AI_GCI\Dia3.JPG) --- -- 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. -- --- ![Process](..\Presentations\AI_GCI\Dia4.JPG) --- -- 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. -- --- ![Process](..\Presentations\AI_GCI\Dia5.JPG) --- -- This cycle will continue. -- --- ![Process](..\Presentations\AI_GCI\Dia6.JPG) --- -- During the patrol, the AI will detect enemy targets, which are reported through the **Detected** event. --- --- ![Process](..\Presentations\AI_GCI\Dia9.JPG) -- -- When enemies are detected, the AI will automatically engage the enemy. -- --- ![Process](..\Presentations\AI_GCI\Dia10.JPG) --- -- 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. -- --- ![Process](..\Presentations\AI_GCI\Dia13.JPG) --- -- ## 1. AI_A2G_SEAD constructor -- -- * @{#AI_A2G_SEAD.New}(): Creates a new AI_A2G_SEAD object. -- -- ## 3. Set the Range of Engagement -- --- ![Range](..\Presentations\AI_GCI\Dia11.JPG) --- -- 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 -- --- ![Zone](..\Presentations\AI_GCI\Dia12.JPG) --- --- 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 ) diff --git a/Moose Development/Moose/AI/AI_Air.lua b/Moose Development/Moose/AI/AI_Air.lua index 8db48ad99..07325c819 100644 --- a/Moose Development/Moose/AI/AI_Air.lua +++ b/Moose Development/Moose/AI/AI_Air.lua @@ -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", diff --git a/Moose Development/Moose/AI/AI_Air_Dispatcher.lua b/Moose Development/Moose/AI/AI_Air_Dispatcher.lua index 39fdf17f5..b422ac03e 100644 --- a/Moose Development/Moose/AI/AI_Air_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_Air_Dispatcher.lua @@ -292,8 +292,6 @@ do -- AI_AIR_DISPATCHER -- -- ## 1. AI\_AIR\_DISPATCHER constructor: -- - -- ![Banner Image](..\Presentations\AI_AIR_DISPATCHER\AI_AIR_DISPATCHER-ME_1.JPG) - -- -- -- 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. -- - -- ![Banner Image](..\Presentations\AI_AIR_DISPATCHER\Dia5.JPG) - -- -- 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. -- - -- ![Banner Image](..\Presentations\AI_AIR_DISPATCHER\Dia12.JPG) - -- -- 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**. -- - -- ![Banner Image](..\Presentations\AI_AIR_DISPATCHER\Dia11.JPG) - -- -- 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": -- - -- ![Banner Image](..\Presentations\AI_AIR_DISPATCHER\AI_AIR_DISPATCHER-ME_11.JPG) - -- -- -- 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 ) diff --git a/Moose Development/Moose/AI/AI_Air_Engage.lua b/Moose Development/Moose/AI/AI_Air_Engage.lua index f75f48240..90c20b79e 100644 --- a/Moose Development/Moose/AI/AI_Air_Engage.lua +++ b/Moose Development/Moose/AI/AI_Air_Engage.lua @@ -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. -- --- ![Process](..\Presentations\AI_GCI\Dia3.JPG) --- -- 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. -- --- ![Process](..\Presentations\AI_GCI\Dia4.JPG) --- -- 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. -- --- ![Process](..\Presentations\AI_GCI\Dia5.JPG) --- -- This cycle will continue. -- --- ![Process](..\Presentations\AI_GCI\Dia6.JPG) --- -- During the patrol, the AI will detect enemy targets, which are reported through the **Detected** event. --- --- ![Process](..\Presentations\AI_GCI\Dia9.JPG) -- -- When enemies are detected, the AI will automatically engage the enemy. -- --- ![Process](..\Presentations\AI_GCI\Dia10.JPG) --- -- 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. -- --- ![Process](..\Presentations\AI_GCI\Dia13.JPG) --- -- ## 1. AI_AIR_ENGAGE constructor -- -- * @{#AI_AIR_ENGAGE.New}(): Creates a new AI_AIR_ENGAGE object. -- -- ## 3. Set the Range of Engagement -- --- ![Range](..\Presentations\AI_GCI\Dia11.JPG) --- -- 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 --- --- ![Zone](..\Presentations\AI_GCI\Dia12.JPG) --- --- 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 = {} diff --git a/Moose Development/Moose/AI/AI_Air_Patrol.lua b/Moose Development/Moose/AI/AI_Air_Patrol.lua index 179f3d30f..00fc7f2d0 100644 --- a/Moose Development/Moose/AI/AI_Air_Patrol.lua +++ b/Moose Development/Moose/AI/AI_Air_Patrol.lua @@ -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 -- --- ![Zone](..\Presentations\AI_CAP\Dia12.JPG) --- --- 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 diff --git a/Moose Development/Moose/AI/AI_Air_Squadron.lua b/Moose Development/Moose/AI/AI_Air_Squadron.lua index b9bfee7a1..0c744b4ac 100644 --- a/Moose Development/Moose/AI/AI_Air_Squadron.lua +++ b/Moose Development/Moose/AI/AI_Air_Squadron.lua @@ -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 diff --git a/Moose Development/Moose/AI/AI_BAI.lua b/Moose Development/Moose/AI/AI_BAI.lua index 58b33e14f..3c5464343 100644 --- a/Moose Development/Moose/AI/AI_BAI.lua +++ b/Moose Development/Moose/AI/AI_BAI.lua @@ -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 diff --git a/Moose Development/Moose/AI/AI_Balancer.lua b/Moose Development/Moose/AI/AI_Balancer.lua index 14eba62c6..fad0746ff 100644 --- a/Moose Development/Moose/AI/AI_Balancer.lua +++ b/Moose Development/Moose/AI/AI_Balancer.lua @@ -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 -- --- ![Process](..\Presentations\AI_Balancer\Dia13.JPG) +-- ![Process](..\Presentations\AI_BALANCER\Dia13.JPG) -- -- ### 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", diff --git a/Moose Development/Moose/AI/AI_CAP.lua b/Moose Development/Moose/AI/AI_CAP.lua index c2bce7d39..bb81f3f15 100644 --- a/Moose Development/Moose/AI/AI_CAP.lua +++ b/Moose Development/Moose/AI/AI_CAP.lua @@ -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 diff --git a/Moose Development/Moose/AI/AI_CAS.lua b/Moose Development/Moose/AI/AI_CAS.lua index f4bcd5b27..b99be5ef7 100644 --- a/Moose Development/Moose/AI/AI_CAS.lua +++ b/Moose Development/Moose/AI/AI_CAS.lua @@ -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 diff --git a/Moose Development/Moose/AI/AI_Cargo.lua b/Moose Development/Moose/AI/AI_Cargo.lua index 3f4da5cac..14a403c48 100644 --- a/Moose Development/Moose/AI/AI_Cargo.lua +++ b/Moose Development/Moose/AI/AI_Cargo.lua @@ -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", diff --git a/Moose Development/Moose/AI/AI_Cargo_APC.lua b/Moose Development/Moose/AI/AI_Cargo_APC.lua index 1c522ea64..6088ea865 100644 --- a/Moose Development/Moose/AI/AI_Cargo_APC.lua +++ b/Moose Development/Moose/AI/AI_Cargo_APC.lua @@ -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 = { diff --git a/Moose Development/Moose/AI/AI_Cargo_Airplane.lua b/Moose Development/Moose/AI/AI_Cargo_Airplane.lua index feb5e827e..9dad75f25 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Airplane.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Airplane.lua @@ -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", diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua index 9847f17ee..ea954b97d 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua @@ -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** diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_APC.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_APC.lua index 1316e36d2..ab25a8e60 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_APC.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_APC.lua @@ -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 diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Airplane.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Airplane.lua index b8c25aac4..a971936f6 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Airplane.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Airplane.lua @@ -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 = { diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua index a7a90c7d1..c391324e4 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua @@ -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 diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Ship.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Ship.lua index 3011184ac..152ea7881 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Ship.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Ship.lua @@ -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 diff --git a/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua b/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua index 420e2cd12..6edfc3894 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua @@ -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 diff --git a/Moose Development/Moose/AI/AI_Cargo_Ship.lua b/Moose Development/Moose/AI/AI_Cargo_Ship.lua index 3a2fc13a5..669da09b5 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Ship.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Ship.lua @@ -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", diff --git a/Moose Development/Moose/AI/AI_Escort.lua b/Moose Development/Moose/AI/AI_Escort.lua index adf56bcbc..4eeba1fe3 100644 --- a/Moose Development/Moose/AI/AI_Escort.lua +++ b/Moose Development/Moose/AI/AI_Escort.lua @@ -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 ) diff --git a/Moose Development/Moose/AI/AI_Escort_Dispatcher.lua b/Moose Development/Moose/AI/AI_Escort_Dispatcher.lua index 15d21c30f..7bb869899 100644 --- a/Moose Development/Moose/AI/AI_Escort_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_Escort_Dispatcher.lua @@ -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 diff --git a/Moose Development/Moose/AI/AI_Escort_Dispatcher_Request.lua b/Moose Development/Moose/AI/AI_Escort_Dispatcher_Request.lua index c507e04f4..0b3180910 100644 --- a/Moose Development/Moose/AI/AI_Escort_Dispatcher_Request.lua +++ b/Moose Development/Moose/AI/AI_Escort_Dispatcher_Request.lua @@ -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 diff --git a/Moose Development/Moose/AI/AI_Escort_Request.lua b/Moose Development/Moose/AI/AI_Escort_Request.lua index cac0b57d5..c5d1782e0 100644 --- a/Moose Development/Moose/AI/AI_Escort_Request.lua +++ b/Moose Development/Moose/AI/AI_Escort_Request.lua @@ -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() diff --git a/Moose Development/Moose/AI/AI_Formation.lua b/Moose Development/Moose/AI/AI_Formation.lua index fa4e4ea4b..949ad9875 100644 --- a/Moose Development/Moose/AI/AI_Formation.lua +++ b/Moose Development/Moose/AI/AI_Formation.lua @@ -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 ) diff --git a/Moose Development/Moose/AI/AI_Patrol.lua b/Moose Development/Moose/AI/AI_Patrol.lua index 6a502f679..d630f5197 100644 --- a/Moose Development/Moose/AI/AI_Patrol.lua +++ b/Moose Development/Moose/AI/AI_Patrol.lua @@ -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 diff --git a/Moose Development/Moose/Actions/Act_Account.lua b/Moose Development/Moose/Actions/Act_Account.lua index 0fe2d6eb6..5b809af44 100644 --- a/Moose Development/Moose/Actions/Act_Account.lua +++ b/Moose Development/Moose/Actions/Act_Account.lua @@ -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. diff --git a/Moose Development/Moose/Actions/Act_Assign.lua b/Moose Development/Moose/Actions/Act_Assign.lua index 75f9e2e3f..3b261cfb1 100644 --- a/Moose Development/Moose/Actions/Act_Assign.lua +++ b/Moose Development/Moose/Actions/Act_Assign.lua @@ -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. diff --git a/Moose Development/Moose/Actions/Act_Assist.lua b/Moose Development/Moose/Actions/Act_Assist.lua index e7017ce90..9b4744561 100644 --- a/Moose Development/Moose/Actions/Act_Assist.lua +++ b/Moose Development/Moose/Actions/Act_Assist.lua @@ -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 diff --git a/Moose Development/Moose/Actions/Act_Route.lua b/Moose Development/Moose/Actions/Act_Route.lua index d83133752..b387b6584 100644 --- a/Moose Development/Moose/Actions/Act_Route.lua +++ b/Moose Development/Moose/Actions/Act_Route.lua @@ -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 diff --git a/Moose Development/Moose/Cargo/Cargo.lua b/Moose Development/Moose/Cargo/Cargo.lua index 257e118a9..c9297378a 100644 --- a/Moose Development/Moose/Cargo/Cargo.lua +++ b/Moose Development/Moose/Cargo/Cargo.lua @@ -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 ) diff --git a/Moose Development/Moose/Core/Astar.lua b/Moose Development/Moose/Core/Astar.lua index ece354492..a02d16444 100644 --- a/Moose Development/Moose/Core/Astar.lua +++ b/Moose Development/Moose/Core/Astar.lua @@ -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. diff --git a/Moose Development/Moose/Core/Condition.lua b/Moose Development/Moose/Core/Condition.lua index 7e9842a7b..9d65f43cd 100644 --- a/Moose Development/Moose/Core/Condition.lua +++ b/Moose Development/Moose/Core/Condition.lua @@ -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). -- -- === -- diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index 836c840ed..1e8bd40d4 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -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] diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index 95c4f6a35..d057805f3 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -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 } ) diff --git a/Moose Development/Moose/Core/Fsm.lua b/Moose Development/Moose/Core/Fsm.lua index 2b5f499e5..3b2f3b52c 100644 --- a/Moose Development/Moose/Core/Fsm.lua +++ b/Moose Development/Moose/Core/Fsm.lua @@ -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 ) diff --git a/Moose Development/Moose/Core/Menu.lua b/Moose Development/Moose/Core/Menu.lua index 8a6edf657..fc9a75394 100644 --- a/Moose Development/Moose/Core/Menu.lua +++ b/Moose Development/Moose/Core/Menu.lua @@ -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}. diff --git a/Moose Development/Moose/Core/Message.lua b/Moose Development/Moose/Core/Message.lua index 764f33602..843f55d0b 100644 --- a/Moose Development/Moose/Core/Message.lua +++ b/Moose Development/Moose/Core/Message.lua @@ -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 - diff --git a/Moose Development/Moose/Core/Pathline.lua b/Moose Development/Moose/Core/Pathline.lua index 1bab11e14..3c5ebed0b 100644 --- a/Moose Development/Moose/Core/Pathline.lua +++ b/Moose Development/Moose/Core/Pathline.lua @@ -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 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 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Development/Moose/Core/Scheduler.lua b/Moose Development/Moose/Core/Scheduler.lua index 36804e2ab..231157a5d 100644 --- a/Moose Development/Moose/Core/Scheduler.lua +++ b/Moose Development/Moose/Core/Scheduler.lua @@ -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 diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index dac994af1..0f200e532 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -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 diff --git a/Moose Development/Moose/Core/Settings.lua b/Moose Development/Moose/Core/Settings.lua index 4a97a35eb..017bfda9b 100644 --- a/Moose Development/Moose/Core/Settings.lua +++ b/Moose Development/Moose/Core/Settings.lua @@ -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. diff --git a/Moose Development/Moose/Core/Spawn.lua b/Moose Development/Moose/Core/Spawn.lua index adcafc31f..8e62efe4b 100644 --- a/Moose Development/Moose/Core/Spawn.lua +++ b/Moose Development/Moose/Core/Spawn.lua @@ -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 diff --git a/Moose Development/Moose/Core/Spot.lua b/Moose Development/Moose/Core/Spot.lua index af00fee8f..9db60f640 100644 --- a/Moose Development/Moose/Core/Spot.lua +++ b/Moose Development/Moose/Core/Spot.lua @@ -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 -- -- === -- diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index ca5f428c6..bb022b50f 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -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}` diff --git a/Moose Development/Moose/DCS.lua b/Moose Development/Moose/DCS.lua index 65197ff17..642d3edbc 100644 --- a/Moose Development/Moose/DCS.lua +++ b/Moose Development/Moose/DCS.lua @@ -1,9 +1,9 @@ --- **DCS API** Prototypes. --- +-- -- === --- +-- -- See the [Simulator Scripting Engine Documentation](https://wiki.hoggitworld.com/view/Simulator_Scripting_Engine_Documentation) on Hoggit for further explanation and examples. --- +-- -- @module DCS -- @image MOOSE.JPG @@ -18,14 +18,14 @@ do -- world --- The world singleton contains functions centered around two different but extremely useful functions. -- * Events and event handlers are all governed within world. -- * A number of functions to get information about the game world. - -- + -- -- See [https://wiki.hoggitworld.com/view/DCS_singleton_world](https://wiki.hoggitworld.com/view/DCS_singleton_world) -- @field #world world world = {} - + --- [https://wiki.hoggitworld.com/view/DCS_enum_world](https://wiki.hoggitworld.com/view/DCS_enum_world) -- @type world.event - -- @field S_EVENT_INVALID + -- @field S_EVENT_INVALID -- @field S_EVENT_SHOT [https://wiki.hoggitworld.com/view/DCS_event_shot](https://wiki.hoggitworld.com/view/DCS_event_shot) -- @field S_EVENT_HIT [https://wiki.hoggitworld.com/view/DCS_event_hit](https://wiki.hoggitworld.com/view/DCS_event_hit) -- @field S_EVENT_TAKEOFF [https://wiki.hoggitworld.com/view/DCS_event_takeoff](https://wiki.hoggitworld.com/view/DCS_event_takeoff) @@ -38,7 +38,7 @@ do -- world -- @field S_EVENT_BASE_CAPTURED [https://wiki.hoggitworld.com/view/DCS_event_base_captured](https://wiki.hoggitworld.com/view/DCS_event_base_captured) -- @field S_EVENT_MISSION_START [https://wiki.hoggitworld.com/view/DCS_event_mission_start](https://wiki.hoggitworld.com/view/DCS_event_mission_start) -- @field S_EVENT_MISSION_END [https://wiki.hoggitworld.com/view/DCS_event_mission_end](https://wiki.hoggitworld.com/view/DCS_event_mission_end) - -- @field S_EVENT_TOOK_CONTROL + -- @field S_EVENT_TOOK_CONTROL -- @field S_EVENT_REFUELING_STOP [https://wiki.hoggitworld.com/view/DCS_event_refueling_stop](https://wiki.hoggitworld.com/view/DCS_event_refueling_stop) -- @field S_EVENT_BIRTH [https://wiki.hoggitworld.com/view/DCS_event_birth](https://wiki.hoggitworld.com/view/DCS_event_birth) -- @field S_EVENT_HUMAN_FAILURE [https://wiki.hoggitworld.com/view/DCS_event_human_failure](https://wiki.hoggitworld.com/view/DCS_event_human_failure) @@ -46,7 +46,7 @@ do -- world -- @field S_EVENT_ENGINE_SHUTDOWN [https://wiki.hoggitworld.com/view/DCS_event_engine_shutdown](https://wiki.hoggitworld.com/view/DCS_event_engine_shutdown) -- @field S_EVENT_PLAYER_ENTER_UNIT [https://wiki.hoggitworld.com/view/DCS_event_player_enter_unit](https://wiki.hoggitworld.com/view/DCS_event_player_enter_unit) -- @field S_EVENT_PLAYER_LEAVE_UNIT [https://wiki.hoggitworld.com/view/DCS_event_player_leave_unit](https://wiki.hoggitworld.com/view/DCS_event_player_leave_unit) - -- @field S_EVENT_PLAYER_COMMENT + -- @field S_EVENT_PLAYER_COMMENT -- @field S_EVENT_SHOOTING_START [https://wiki.hoggitworld.com/view/DCS_event_shooting_start](https://wiki.hoggitworld.com/view/DCS_event_shooting_start) -- @field S_EVENT_SHOOTING_END [https://wiki.hoggitworld.com/view/DCS_event_shooting_end](https://wiki.hoggitworld.com/view/DCS_event_shooting_end) -- @field S_EVENT_MARK ADDED [https://wiki.hoggitworld.com/view/DCS_event_mark_added](https://wiki.hoggitworld.com/view/DCS_event_mark_added) DCS>=2.5.1 @@ -57,7 +57,7 @@ do -- world -- @field S_EVENT_UNIT_LOST [https://wiki.hoggitworld.com/view/DCS_event_unit_lost](https://wiki.hoggitworld.com/view/DCS_event_unit_lost) DCS>=2.5.6 -- @field S_EVENT_LANDING_AFTER_EJECTION [https://wiki.hoggitworld.com/view/DCS_event_landing_after_ejection](https://wiki.hoggitworld.com/view/DCS_event_landing_after_ejection) DCS>=2.5.6 -- @field S_EVENT_MAX - + --- The birthplace enumerator is used to define where an aircraft or helicopter has spawned in association with birth events. -- @type world.BirthPlace -- @field wsBirthPlace_Air @@ -76,24 +76,24 @@ do -- world --- Adds a function as an event handler that executes whenever a simulator event occurs. See [hoggit](https://wiki.hoggitworld.com/view/DCS_func_addEventHandler). -- @function [parent=#world] addEventHandler -- @param #table handler Event handler table. - + --- Removes the specified event handler from handling events. -- @function [parent=#world] removeEventHandler -- @param #table handler Event handler table. - + --- Returns a table of the single unit object in the game who's skill level is set as "Player". See [hoggit](https://wiki.hoggitworld.com/view/DCS_func_getPlayer). -- There is only a single player unit in a mission and in single player the user will always spawn into this unit automatically unless other client or Combined Arms slots are available. -- @function [parent=#world] getPlayer - -- @return DCS#Unit - + -- @return DCS#Unit + --- Searches a defined volume of 3d space for the specified objects within it and then can run function on each returned object. See [hoggit](https://wiki.hoggitworld.com/view/DCS_func_searchObjects). -- @function [parent=#world] searchObjects -- @param DCS#Object.Category objectcategory Category (can be a table) of objects to search. -- @param DCS#word.VolumeType volume Shape of the search area/volume. -- @param ObjectSeachHandler handler A function that handles the search. -- @param #table any Additional data. - -- @return DCS#Unit - + -- @return DCS#Unit + --- Returns a table of mark panels indexed numerically that are present within the mission. See [hoggit](https://wiki.hoggitworld.com/view/DCS_func_getMarkPanels) -- @function [parent=#world] getMarkPanels -- @return #table Table of marks. @@ -102,7 +102,7 @@ do -- world -- @function [parent=#world] getAirbases -- @param #number coalitionId The coalition side number ID. Default is all airbases are returned. -- @return #table Table of DCS airbase objects. - + end -- world @@ -115,74 +115,90 @@ do -- env -- @function [parent=#env] info -- @param #string message message string to add to log. -- @param #boolean showMessageBox If the parameter is true Message Box will appear. Optional. - - --- Add message to simulator log with caption "WARNING". Message box is optional. + + --- Add message to simulator log with caption "WARNING". Message box is optional. -- @function [parent=#env] warning -- @param #string message message string to add to log. -- @param #boolean showMessageBox If the parameter is true Message Box will appear. Optional. - + --- Add message to simulator log with caption "ERROR". Message box is optional. -- @function [parent=#env] error -- @param #string message message string to add to log. -- @param #boolean showMessageBox If the parameter is true Message Box will appear. Optional. - + --- Enables/disables appearance of message box each time lua error occurs. -- @function [parent=#env] setErrorMessageBoxEnabled -- @param #boolean on if true message box appearance is enabled. --- [DCS Singleton env](https://wiki.hoggitworld.com/view/DCS_singleton_env) - env = {} --#env - + env = {} --#env + end -- env +do -- radio + + ---@type radio + -- @field #radio.modulation modulation + + --- + -- @type radio.modulation + -- @field AM + -- @field FM + + radio = {} + radio.modulation = {} + radio.modulation.AM = 0 + radio.modulation.FM = 1 + +end do -- timer --- [DCS Singleton timer](https://wiki.hoggitworld.com/view/DCS_singleton_timer) -- @type timer - + --- Returns model time in seconds. -- @function [parent=#timer] getTime - -- @return #Time - + -- @return #Time + --- Returns mission time in seconds. -- @function [parent=#timer] getAbsTime -- @return #Time - + --- Returns mission start time in seconds. -- @function [parent=#timer] getTime0 -- @return #Time - + --- Schedules function to call at desired model time. -- Time function FunctionToCall(any argument, Time time) - -- + -- -- ... - -- + -- -- return ... - -- + -- -- end - -- - -- Must return model time of next call or nil. Note that the DCS scheduler calls the function in protected mode and any Lua errors in the called function will be trapped and not reported. If the function triggers a Lua error then it will be terminated and not scheduled to run again. + -- + -- Must return model time of next call or nil. Note that the DCS scheduler calls the function in protected mode and any Lua errors in the called function will be trapped and not reported. If the function triggers a Lua error then it will be terminated and not scheduled to run again. -- @function [parent=#timer] scheduleFunction - -- @param #FunctionToCall functionToCall Lua-function to call. Must have prototype of FunctionToCall. + -- @param #FunctionToCall functionToCall Lua-function to call. Must have prototype of FunctionToCall. -- @param functionArgument Function argument of any type to pass to functionToCall. -- @param #Time time Model time of the function call. -- @return functionId - + --- Re-schedules function to call at another model time. - -- @function [parent=#timer] setFunctionTime - -- @param functionId Lua-function to call. Must have prototype of FunctionToCall. - -- @param #Time time Model time of the function call. - - + -- @function [parent=#timer] setFunctionTime + -- @param functionId Lua-function to call. Must have prototype of FunctionToCall. + -- @param #Time time Model time of the function call. + + --- Removes the function from schedule. -- @function [parent=#timer] removeFunction - -- @param functionId Function identifier to remove from schedule - + -- @param functionId Function identifier to remove from schedule + --- [DCS Singleton timer](https://wiki.hoggitworld.com/view/DCS_singleton_timer) timer = {} --#timer -end +end do -- land @@ -190,7 +206,7 @@ do -- land --- [DCS Singleton land](https://wiki.hoggitworld.com/view/DCS_singleton_land) -- @type land -- @field #land.SurfaceType SurfaceType - + --- [Type of surface enumerator](https://wiki.hoggitworld.com/view/DCS_singleton_land) -- @type land.SurfaceType -- @field LAND Land=1 @@ -198,25 +214,25 @@ do -- land -- @field WATER Water=3 -- @field ROAD Road=4 -- @field RUNWAY Runway=5 - + --- Returns the distance from sea level (y-axis) of a given vec2 point. -- @function [parent=#land] getHeight - -- @param #Vec2 point Point on the ground. + -- @param #Vec2 point Point on the ground. -- @return #number Height in meters. - --- Returns the surface height and depth of a point. Useful for checking if the path is deep enough to support a given ship. - -- Both values are positive. When checked over water at sea level the first value is always zero. + --- Returns the surface height and depth of a point. Useful for checking if the path is deep enough to support a given ship. + -- Both values are positive. When checked over water at sea level the first value is always zero. -- When checked over water at altitude, for example the reservoir of the Inguri Dam, the first value is the corresponding altitude the water level is at. -- @function [parent=#land] getSurfaceHeightWithSeabed -- @param #Vec2 point Position where to check. -- @return #number Height in meters. -- @return #number Depth in meters. - + --- Returns surface type at the given point. -- @function [parent=#land] getSurfaceType - -- @param #Vec2 point Point on the land. + -- @param #Vec2 point Point on the land. -- @return #number Enumerator value from `land.SurfaceType` (LAND=1, SHALLOW_WATER=2, WATER=3, ROAD=4, RUNWAY=5) - + --- [DCS Singleton land](https://wiki.hoggitworld.com/view/DCS_singleton_land) land = {} --#land @@ -241,9 +257,9 @@ do -- country --- [DCS Enum country](https://wiki.hoggitworld.com/view/DCS_enum_country) -- @type country - -- @field #country.id id - - + -- @field #country.id id + + --- [DCS enumerator country](https://wiki.hoggitworld.com/view/DCS_enum_country) -- @type country.id -- @field RUSSIA @@ -309,7 +325,7 @@ do -- country -- @field HONDURAS -- @field ETHIOPIA -- @field CHILE - -- @field BRAZIL + -- @field BRAZIL -- @field BAHRAIN -- @field THIRDREICH -- @field YUGOSLAVIA @@ -344,11 +360,11 @@ end -- country do -- Command - --- @type Command + -- @type Command -- @field #string id -- @field #Command.params params - - --- @type Command.params + + -- @type Command.params end -- Command @@ -357,13 +373,13 @@ do -- coalition --- [DCS Enum coalition](https://wiki.hoggitworld.com/view/DCS_enum_coalition) -- @type coalition -- @field #coalition.side side - + --- [DCS Enum coalition.side](https://wiki.hoggitworld.com/view/DCS_enum_coalition) -- @type coalition.side -- @field NEUTRAL -- @field RED -- @field BLUE - + --- Get country coalition. -- @function [parent=#coalition] getCountryCoalition -- @param #number countryId Country ID. @@ -381,7 +397,7 @@ do -- coalition -- @param #number countryId Id of the country. -- @param #table groupData Group data table. -- @return DCS#Static The spawned static object. - + coalition = {} -- #coalition end -- coalition @@ -412,101 +428,101 @@ do -- Types -- @field #TypeName typeName Type Name. -- @field #string displayName Localized display name. -- @field #number category Unit category. - + --- A distance type -- @type Distance - + --- An angle type -- @type Angle - + --- Time is given in seconds. -- @type Time -- @extends #number Time in seconds. - - --- Model time is the time that drives the simulation. Model time may be stopped, accelerated and decelerated relative real time. + + --- Model time is the time that drives the simulation. Model time may be stopped, accelerated and decelerated relative real time. -- @type ModelTime -- @extends #number - + --- Mission time is a model time plus time of the mission start. -- @type MissionTime -- @extends #number Time in seconds. - - + + --- Distance is given in meters. -- @type Distance -- @extends #number Distance in meters. - + --- Angle is given in radians. -- @type Angle -- @extends #number Angle in radians. - + --- Azimuth is an angle of rotation around world axis y counter-clockwise. -- @type Azimuth -- @extends #number Angle in radians. - + --- Mass is given in kilograms. -- @type Mass -- @extends #number - + --- Vec3 type is a 3D-vector. -- DCS world has 3-dimensional coordinate system. DCS ground is an infinite plain. -- @type Vec3 -- @field #Distance x is directed to the North -- @field #Distance z is directed to the East -- @field #Distance y is directed up - + --- Vec2 is a 2D-vector for the ground plane as a reference plane. -- @type Vec2 -- @field #Distance x Vec2.x = Vec3.x -- @field #Distance y Vec2.y = Vec3.z - - --- Position is a composite structure. It consists of both coordinate vector and orientation matrix. Position3 (also known as "Pos3" for short) is a table that has following format: + + --- Position is a composite structure. It consists of both coordinate vector and orientation matrix. Position3 (also known as "Pos3" for short) is a table that has following format: -- @type Position3 -- @field #Vec3 p 3D position vector. -- @field #Vec3 x Orientation component of vector pointing East. -- @field #Vec3 y Orientation component of vector pointing up. -- @field #Vec3 z Orientation component of vector pointing North. - + --- 3-dimensional box. -- @type Box3 -- @field #Vec3 min Min. -- @field #Vec3 max Max - - --- Each object belongs to a type. Object type is a named couple of properties those independent of mission and common for all units of the same type. Name of unit type is a string. Samples of unit type: "Su-27", "KAMAZ" and "M2 Bradley". + + --- Each object belongs to a type. Object type is a named couple of properties those independent of mission and common for all units of the same type. Name of unit type is a string. Samples of unit type: "Su-27", "KAMAZ" and "M2 Bradley". -- @type TypeName -- @extends #string - - --- AttributeName = string + + --- AttributeName = string -- Each object type may have attributes. -- Attributes are enlisted in ./Scripts/Database/db_attributes.Lua. - -- To know what attributes the object type has, look for the unit type script in sub-directories planes/, helicopter/s, vehicles, navy/ of ./Scripts/Database/ directory. + -- To know what attributes the object type has, look for the unit type script in sub-directories planes/, helicopter/s, vehicles, navy/ of ./Scripts/Database/ directory. -- @type AttributeName -- @extends #string - + --- List of @{#AttributeName} - -- @type AttributeNameArray + -- @type AttributeNameArray -- @list <#AttributeName> - --- @type Zone + -- @type Zone -- @field DCSVec3#Vec3 point -- @field #number radius Zone = {} - --- @type ModelTime + -- @type ModelTime -- @extends #number - - --- @type Time + + -- @type Time -- @extends #number - + --- A task descriptor (internal structure for DCS World). See [https://wiki.hoggitworld.com/view/Category:Tasks](https://wiki.hoggitworld.com/view/Category:Tasks). -- In MOOSE, these tasks can be accessed via @{Wrapper.Controllable#CONTROLLABLE}. -- @type Task -- @field #string id -- @field #Task.param param - - --- @type Task.param - + + -- @type Task.param + --- List of @{#Task} -- @type TaskArray -- @list <#Task> @@ -523,8 +539,8 @@ do -- Types -- @field #number x 2D Position on x-axis in meters. -- @field #number y 2D Position on y-axis in meters. -- @field #table units Unit list. - -- - + -- + --- Unit data structure. --@type Template.Unit --@field #string name Name of the unit. @@ -542,7 +558,7 @@ do -- Object -- @type Object -- @field #Object.Category Category -- @field #Object.Desc Desc - + --- [DCS Enum Object.Category](https://wiki.hoggitworld.com/view/DCS_Class_Object) -- @type Object.Category -- @field UNIT @@ -551,12 +567,12 @@ do -- Object -- @field BASE -- @field SCENERY -- @field CARGO - - --- @type Object.Desc + + -- @type Object.Desc -- @extends #Desc -- @field #number life initial life level -- @field #Box3 box bounding box of collision geometry - + --- @function [parent=#Object] isExist -- @param #Object self -- @return #boolean @@ -564,55 +580,55 @@ do -- Object --- @function [parent=#Object] isActive -- @param #Object self -- @return #boolean - + --- @function [parent=#Object] destroy -- @param #Object self - + --- @function [parent=#Object] getCategory -- @param #Object self -- @return #Object.Category - + --- Returns type name of the Object. -- @function [parent=#Object] getTypeName -- @param #Object self - -- @return #string - + -- @return #string + --- Returns object descriptor. -- @function [parent=#Object] getDesc -- @param #Object self -- @return #Object.Desc - + --- Returns true if the object belongs to the category. -- @function [parent=#Object] hasAttribute -- @param #Object self -- @param #AttributeName attributeName Attribute name to check. -- @return #boolean - + --- Returns name of the object. This is the name that is assigned to the object in the Mission Editor. -- @function [parent=#Object] getName -- @param #Object self -- @return #string - + --- Returns object coordinates for current time. -- @function [parent=#Object] getPoint -- @param #Object self -- @return #Vec3 3D position vector with x,y,z components. - - --- Returns object position for current time. + + --- Returns object position for current time. -- @function [parent=#Object] getPosition -- @param #Object self -- @return #Position3 - + --- Returns the unit's velocity vector. -- @function [parent=#Object] getVelocity -- @param #Object self -- @return #Vec3 3D velocity vector. - + --- Returns true if the unit is in air. -- @function [parent=#Object] inAir -- @param #Object self -- @return #boolean - + Object = {} --#Object end -- Object @@ -622,12 +638,12 @@ do -- CoalitionObject --- [DCS Class CoalitionObject](https://wiki.hoggitworld.com/view/DCS_Class_Coalition_Object) -- @type CoalitionObject -- @extends #Object - + --- Returns coalition of the object. -- @function [parent=#CoalitionObject] getCoalition -- @param #CoalitionObject self -- @return #coalition.side - + --- Returns object country. -- @function [parent=#CoalitionObject] getCountry -- @param #CoalitionObject self @@ -646,7 +662,7 @@ do -- Weapon -- @field #Weapon.flag flag enum stores weapon flags. Some of them are combination of another flags. -- @field #Weapon.Category Category enum that stores weapon categories. -- @field #Weapon.GuidanceType GuidanceType enum that stores guidance methods. Available only for guided weapon (Weapon.Category.MISSILE and some Weapon.Category.BOMB). - -- @field #Weapon.MissileCategory MissileCategory enum that stores missile category. Available only for missiles (Weapon.Category.MISSILE). + -- @field #Weapon.MissileCategory MissileCategory enum that stores missile category. Available only for missiles (Weapon.Category.MISSILE). -- @field #Weapon.WarheadType WarheadType enum that stores warhead types. -- @field #Weapon.Desc Desc The descriptor of a weapon. @@ -679,20 +695,20 @@ do -- Weapon -- @field TeleASM -- @field CruiseMissile -- @field GuidedASM = LaserASM + TeleASM - -- @field TacticASM = GuidedASM + FireAndForgetASM + -- @field TacticASM = GuidedASM + FireAndForgetASM -- @field AnyASM = AntiRadarMissile + AntiShipMissile + AntiTankMissile + FireAndForgetASM + GuidedASM + CruiseMissile -- @field SRAAM - -- @field MRAAM - -- @field LRAAM - -- @field IR_AAM - -- @field SAR_AAM - -- @field AR_AAM - -- @field AnyAAM = IR_AAM + SAR_AAM + AR_AAM + SRAAM + MRAAM + LRAAM + -- @field MRAAM + -- @field LRAAM + -- @field IR_AAM + -- @field SAR_AAM + -- @field AR_AAM + -- @field AnyAAM = IR_AAM + SAR_AAM + AR_AAM + SRAAM + MRAAM + LRAAM -- @field AnyMissile = AnyASM + AnyAAM -- @field AnyAutonomousMissile = IR_AAM + AntiRadarMissile + AntiShipMissile + FireAndForgetASM + CruiseMissile -- @field GUN_POD -- @field BuiltInCannon - -- @field Cannons = GUN_POD + BuiltInCannon + -- @field Cannons = GUN_POD + BuiltInCannon -- @field AnyAGWeapon = BuiltInCannon + GUN_POD + AnyBomb + AnyRocket + AnyASM -- @field AnyAAWeapon = BuiltInCannon + GUN_POD + AnyAAM -- @field UnguidedWeapon = Cannons + BuiltInCannon + GUN_POD + AnyUnguidedBomb + AnyRocket @@ -708,9 +724,9 @@ do -- Weapon -- @field #number ROCKET Rocket. -- @field #number BOMB Bomb. -- @field #number TORPEDO Torpedo. - - --- Weapon.GuidanceType enum that stores guidance methods. Available only for guided weapon (Weapon.Category.MISSILE and some Weapon.Category.BOMB). + + --- Weapon.GuidanceType enum that stores guidance methods. Available only for guided weapon (Weapon.Category.MISSILE and some Weapon.Category.BOMB). -- @type Weapon.GuidanceType -- @field INS -- @field IR @@ -719,10 +735,10 @@ do -- Weapon -- @field RADAR_PASSIVE -- @field TV -- @field LASER - -- @field TELE + -- @field TELE - - --- Weapon.MissileCategory enum that stores missile category. Available only for missiles (Weapon.Category.MISSILE). + + --- Weapon.MissileCategory enum that stores missile category. Available only for missiles (Weapon.Category.MISSILE). -- @type Weapon.MissileCategory -- @field AAM -- @field SAM @@ -731,23 +747,23 @@ do -- Weapon -- @field CRUISE -- @field OTHER - --- Weapon.WarheadType enum that stores warhead types. + --- Weapon.WarheadType enum that stores warhead types. -- @type Weapon.WarheadType -- @field AP -- @field HE -- @field SHAPED_EXPLOSIVE - + --- Returns the unit that launched the weapon. -- @function [parent=#Weapon] getLauncher -- @param #Weapon self -- @return #Unit - - --- returns target of the guided weapon. Unguided weapons and guided weapon that is targeted at the point on the ground will return nil. + + --- returns target of the guided weapon. Unguided weapons and guided weapon that is targeted at the point on the ground will return nil. -- @function [parent=#Weapon] getTarget -- @param #Weapon self -- @return #Object - - --- returns weapon descriptor. Descriptor type depends on weapon category. + + --- returns weapon descriptor. Descriptor type depends on weapon category. -- @function [parent=#Weapon] getDesc -- @param #Weapon self -- @return #Weapon.Desc @@ -762,50 +778,50 @@ end -- Weapon do -- Airbase --- [DCS Class Airbase](https://wiki.hoggitworld.com/view/DCS_Class_Airbase) - -- Represents airbases: airdromes, helipads and ships with flying decks or landing pads. + -- Represents airbases: airdromes, helipads and ships with flying decks or landing pads. -- @type Airbase -- @extends #CoalitionObject - -- @field #Airbase.ID ID Identifier of an airbase. It assigned to an airbase by the Mission Editor automatically. This identifier is used in AI tasks to refer an airbase that exists (spawned and not dead) or not. - -- @field #Airbase.Category Category enum contains identifiers of airbase categories. - -- @field #Airbase.Desc Desc Airbase descriptor. Airdromes are unique and their types are unique, but helipads and ships are not always unique and may have the same type. - + -- @field #Airbase.ID ID Identifier of an airbase. It assigned to an airbase by the Mission Editor automatically. This identifier is used in AI tasks to refer an airbase that exists (spawned and not dead) or not. + -- @field #Airbase.Category Category enum contains identifiers of airbase categories. + -- @field #Airbase.Desc Desc Airbase descriptor. Airdromes are unique and their types are unique, but helipads and ships are not always unique and may have the same type. + --- Enum contains identifiers of airbase categories. -- @type Airbase.Category -- @field AIRDROME -- @field HELIPAD -- @field SHIP - - --- Airbase descriptor. Airdromes are unique and their types are unique, but helipads and ships are not always unique and may have the same type. + + --- Airbase descriptor. Airdromes are unique and their types are unique, but helipads and ships are not always unique and may have the same type. -- @type Airbase.Desc -- @extends #Desc -- @field #Airbase.Category category Category of the airbase type. - + --- Returns airbase by its name. If no airbase found the function will return nil. -- @function [parent=#Airbase] getByName -- @param #string name -- @return #Airbase - + --- Returns airbase descriptor by type name. If no descriptor is found the function will return nil. -- @function [parent=#Airbase] getDescByName -- @param #TypeName typeName Airbase type name. -- @return #Airbase.Desc - + --- Returns Unit that is corresponded to the airbase. Works only for ships. -- @function [parent=#Airbase] getUnit -- @param self -- @return #Unit - + --- Returns identifier of the airbase. -- @function [parent=#Airbase] getID -- @param self -- @return #Airbase.ID - + --- Returns the airbase's callsign - the localized string. -- @function [parent=#Airbase] getCallsign -- @param self -- @return #string - - --- Returns descriptor of the airbase. + + --- Returns descriptor of the airbase. -- @function [parent=#Airbase] getDesc -- @param self -- @return #Airbase.Desc @@ -815,7 +831,7 @@ do -- Airbase -- @param self -- @return #Warehouse The DCS warehouse object of this airbase. - --- Enables or disables the airbase and FARP auto capture game mechanic where ownership of a base can change based on the presence of ground forces or the + --- Enables or disables the airbase and FARP auto capture game mechanic where ownership of a base can change based on the presence of ground forces or the -- default setting assigned in the editor. -- @function [parent=#Airbase] autoCapture -- @param self @@ -826,13 +842,13 @@ do -- Airbase -- @param self -- @return #boolean `true` if autoCapture behavior is enabled and `false` otherwise. - --- Changes the passed airbase object's coalition to the set value. Must be used with Airbase.autoCapture to disable auto capturing of the base, + --- Changes the passed airbase object's coalition to the set value. Must be used with Airbase.autoCapture to disable auto capturing of the base, -- otherwise the base can revert back to a different coalition depending on the situation and built in game capture rules. -- @function [parent=#Airbase] setCoalition -- @param self -- @param #number coa The new owner coalition: 0=neutra, 1=red, 2=blue. - --- Returns the wsType of every object that exists in DCS. A wsType is a table consisting of 4 entries indexed numerically. + --- Returns the wsType of every object that exists in DCS. A wsType is a table consisting of 4 entries indexed numerically. -- It can be used to broadly categorize object types. The table can be broken down as: {mainCategory, subCat1, subCat2, index} -- @function [parent=#Airbase] getResourceMap -- @param self @@ -849,7 +865,7 @@ do -- Warehouse -- The warehouse class gives control over warehouses that exist in airbase objects. These warehouses can limit the aircraft, munitions, and fuel available to coalition aircraft. -- @type Warehouse - + --- Get a warehouse by passing its name. -- @function [parent=#Warehouse] getByName -- @param #string Name Name of the warehouse. @@ -917,7 +933,7 @@ do -- Warehouse -- @return #table Itemized list of everything currently in a warehouse - Warehouse = {} --#Warehouse + Warehouse = {} --#Warehouse end @@ -925,15 +941,15 @@ do -- Spot --- [DCS Class Spot](https://wiki.hoggitworld.com/view/DCS_Class_Spot) -- Represents a spot from laser or IR-pointer. - -- @type Spot - -- @field #Spot.Category Category enum that stores spot categories. - - --- Enum that stores spot categories. + -- @type Spot + -- @field #Spot.Category Category enum that stores spot categories. + + --- Enum that stores spot categories. -- @type Spot.Category -- @field #string INFRA_RED -- @field #string LASER - + --- Creates a laser ray emanating from the given object to a point in 3d space. -- @function [parent=#Spot] createLaser -- @param DCS#Object Source The source object of the laser. @@ -953,7 +969,7 @@ do -- Spot -- @function [parent=#Spot] getPoint -- @param #Spot self -- @return DCS#Vec3 Point in 3D, where the beam is pointing at. - + --- Sets the destination point from which the source of the spot is drawn toward. -- @function [parent=#Spot] setPoint -- @param #Spot self @@ -968,7 +984,7 @@ do -- Spot -- @function [parent=#Spot] setCode -- @param #Spot self -- @param #number Code The laser code. Default value is 1688. - + --- Destroys the spot. -- @function [parent=#Spot] destroy -- @param #Spot self @@ -983,73 +999,73 @@ do -- Spot end -- Spot do -- Controller - --- Controller is an object that performs A.I.-tasks. Other words controller is an instance of A.I.. Controller stores current main task, active enroute tasks and behavior options. Controller performs commands. Please, read DCS A-10C GUI Manual EN.pdf chapter "Task Planning for Unit Groups", page 91 to understand A.I. system of DCS:A-10C. - -- + --- Controller is an object that performs A.I.-tasks. Other words controller is an instance of A.I.. Controller stores current main task, active enroute tasks and behavior options. Controller performs commands. Please, read DCS A-10C GUI Manual EN.pdf chapter "Task Planning for Unit Groups", page 91 to understand A.I. system of DCS:A-10C. + -- -- This class has 2 types of functions: - -- + -- -- * Tasks - -- * Commands: Commands are instant actions those required zero time to perform. Commands may be used both for control unit/group behavior and control game mechanics. + -- * Commands: Commands are instant actions those required zero time to perform. Commands may be used both for control unit/group behavior and control game mechanics. -- @type Controller - -- @field #Controller.Detection Detection Enum contains identifiers of surface types. - + -- @field #Controller.Detection Detection Enum contains identifiers of surface types. + --- Enables and disables the controller. -- Note: Now it works only for ground / naval groups! -- @function [parent=#Controller] setOnOff -- @param self -- @param #boolean value Enable / Disable. - + -- Tasks - + --- Resets current task and then sets the task to the controller. Task is a table that contains task identifier and task parameters. -- @function [parent=#Controller] setTask -- @param self -- @param #Task task - + --- Resets current task of the controller. - -- @function [parent=#Controller] resetTask + -- @function [parent=#Controller] resetTask -- @param self - + --- Pushes the task to the front of the queue and makes the task active. Further call of function Controller.setTask() function will stop current task, clear the queue and set the new task active. If the task queue is empty the function will work like function Controller.setTask() function. -- @function [parent=#Controller] pushTask -- @param self -- @param #Task task - + --- Pops current (front) task from the queue and makes active next task in the queue (if exists). If no more tasks in the queue the function works like function Controller.resetTask() function. Does nothing if the queue is empty. -- @function [parent=#Controller] popTask -- @param self - - --- Returns true if the controller has a task. + + --- Returns true if the controller has a task. -- @function [parent=#Controller] hasTask -- @param self -- @return #boolean - + -- Commands - + --TODO: describe #Command structure --- Sets the command to perform by controller. -- @function [parent=#Controller] setCommand -- @param self - -- @param #Command command Table that contains command identifier and command parameters. - - + -- @param #Command command Table that contains command identifier and command parameters. + + -- Behaviours - + --- Sets the option to the controller. -- Option is a pair of identifier and value. Behavior options are global parameters those affect controller behavior in all tasks it performs. -- Option identifiers and values are stored in table AI.Option in subtables Air, Ground and Naval. - -- + -- -- OptionId = @{#AI.Option.Air.id} or @{#AI.Option.Ground.id} or @{#AI.Option.Naval.id} -- OptionValue = AI.Option.Air.val[optionName] or AI.Option.Ground.val[optionName] or AI.Option.Naval.val[optionName] - -- + -- -- @function [parent=#Controller] setOption -- @param self - -- @param #OptionId optionId Option identifier. + -- @param #OptionId optionId Option identifier. -- @param #OptionValue optionValue Value of the option. - - + + -- Detection - - --- Enum contains identifiers of surface types. + + --- Enum contains identifiers of surface types. -- @type Controller.Detection -- @field VISUAL -- @field OPTIC @@ -1057,43 +1073,43 @@ do -- Controller -- @field IRST -- @field RWR -- @field DLINK - - --- Detected target. + + --- Detected target. -- @type DetectedTarget -- @field Wrapper.Object#Object object The target -- @field #boolean visible The target is visible -- @field #boolean type The target type is known -- @field #boolean distance Distance to the target is known - - - --- Checks if the target is detected or not. If one or more detection method is specified the function will return true if the target is detected by at least one of these methods. If no detection methods are specified the function will return true if the target is detected by any method. + + + --- Checks if the target is detected or not. If one or more detection method is specified the function will return true if the target is detected by at least one of these methods. If no detection methods are specified the function will return true if the target is detected by any method. -- @function [parent=#Controller] isTargetDetected -- @param self -- @param Wrapper.Object#Object target Target to check - -- @param #Controller.Detection detection Controller.Detection detection1, Controller.Detection detection2, ... Controller.Detection detectionN - -- @return #boolean detected True if the target is detected. - -- @return #boolean visible Has effect only if detected is true. True if the target is visible now. - -- @return #ModelTime lastTime Has effect only if visible is false. Last time when target was seen. - -- @return #boolean type Has effect only if detected is true. True if the target type is known. - -- @return #boolean distance Has effect only if detected is true. True if the distance to the target is known. - -- @return #Vec3 lastPos Has effect only if visible is false. Last position of the target when it was seen. - -- @return #Vec3 lastVel Has effect only if visible is false. Last velocity of the target when it was seen. - - + -- @param #Controller.Detection detection Controller.Detection detection1, Controller.Detection detection2, ... Controller.Detection detectionN + -- @return #boolean detected True if the target is detected. + -- @return #boolean visible Has effect only if detected is true. True if the target is visible now. + -- @return #ModelTime lastTime Has effect only if visible is false. Last time when target was seen. + -- @return #boolean type Has effect only if detected is true. True if the target type is known. + -- @return #boolean distance Has effect only if detected is true. True if the distance to the target is known. + -- @return #Vec3 lastPos Has effect only if visible is false. Last position of the target when it was seen. + -- @return #Vec3 lastVel Has effect only if visible is false. Last velocity of the target when it was seen. + + --- Returns list of detected targets. If one or more detection method is specified the function will return targets which were detected by at least one of these methods. If no detection methods are specified the function will return targets which were detected by any method. -- @function [parent=#Controller] getDetectedTargets -- @param self - -- @param #Controller.Detection detection Controller.Detection detection1, Controller.Detection detection2, ... Controller.Detection detectionN + -- @param #Controller.Detection detection Controller.Detection detection1, Controller.Detection detection2, ... Controller.Detection detectionN -- @return #list<#DetectedTarget> array of DetectedTarget - + --- Know a target. -- @function [parent=#Controller] knowTarget -- @param self -- @param Wrapper.Object#Object object The target. -- @param #boolean type Target type is known. -- @param #boolean distance Distance to target is known. - - + + Controller = {} --#Controller end -- Controller @@ -1101,9 +1117,9 @@ end -- Controller do -- Unit - --- @type Unit + -- @type Unit -- @extends #CoalitionObject - -- @field ID Identifier of an unit. It assigned to an unit by the Mission Editor automatically. + -- @field ID Identifier of an unit. It assigned to an unit by the Mission Editor automatically. -- @field #Unit.Category Category -- @field #Unit.RefuelingSystem RefuelingSystem -- @field #Unit.SensorType SensorType @@ -1121,8 +1137,8 @@ do -- Unit -- @field #Unit.Optic Optic -- @field #Unit.Radar Radar -- @field #Unit.IRST IRST - - + + --- Enum that stores unit categories. -- @type Unit.Category -- @field AIRPLANE @@ -1130,39 +1146,39 @@ do -- Unit -- @field GROUND_UNIT -- @field SHIP -- @field STRUCTURE - + --- Enum that stores aircraft refueling system types. -- @type Unit.RefuelingSystem -- @field BOOM_AND_RECEPTACLE Tanker with a boom. -- @field PROBE_AND_DROGUE Tanker with a probe. - + --- Enum that stores sensor types. -- @type Unit.SensorType -- @field OPTIC -- @field RADAR -- @field IRST -- @field RWR - + --- Enum that stores types of optic sensors. -- @type Unit.OpticType -- @field TV TV-sensor -- @field LLTV Low-level TV-sensor -- @field IR Infra-Red optic sensor - + --- Enum that stores radar types. -- @type Unit.RadarType -- @field AS air search radar -- @field SS surface/land search radar - - - --- A unit descriptor. + + + --- A unit descriptor. -- @type Unit.Desc -- @extends #Object.Desc -- @field #Unit.Category category Unit Category -- @field #Mass massEmpty mass of empty unit -- @field #number speedMax istance / Time, --maximal velocity - - --- An aircraft descriptor. + + --- An aircraft descriptor. -- @type Unit.DescAircraft -- @extends #Unit.Desc -- @field #Mass fuelMassMax maximal inner fuel mass @@ -1172,134 +1188,137 @@ do -- Unit -- @field #number NyMin minimal safe acceleration -- @field #number NyMax maximal safe acceleration -- @field #Unit.RefuelingSystem tankerType refueling system type - + --- An airplane descriptor. - -- @type Unit.DescAirplane + -- @type Unit.DescAirplane -- @extends #Unit.DescAircraft -- @field #number speedMax0 Distance / Time maximal TAS at ground level -- @field #number speedMax10K Distance / Time maximal TAS at altitude of 10 km - + --- A helicopter descriptor. - -- @type Unit.DescHelicopter + -- @type Unit.DescHelicopter -- @extends #Unit.DescAircraft -- @field #Distance HmaxStat static ceiling - + --- A vehicle descriptor. - -- @type Unit.DescVehicle + -- @type Unit.DescVehicle -- @extends #Unit.Desc -- @field #Angle maxSlopeAngle maximal slope angle -- @field #boolean riverCrossing can the vehicle cross a rivers - + --- A ship descriptor. - -- @type Unit.DescShip + -- @type Unit.DescShip -- @extends #Unit.Desc - + --- ammunition item: "type-count" pair. -- @type Unit.AmmoItem -- @field #Weapon.Desc desc ammunition descriptor -- @field #number count ammunition count - + --- A unit sensor. -- @type Unit.Sensor -- @field #TypeName typeName -- @field #Unit.SensorType type - + --- An optic sensor. - -- @type Unit.Optic + -- @type Unit.Optic -- @extends #Unit.Sensor -- @field #Unit.OpticType opticType - + --- A radar. - -- @type Unit.Radar + -- @type Unit.Radar -- @extends #Unit.Sensor -- @field #Distance detectionDistanceRBM detection distance for RCS=1m^2 in real-beam mapping mode, nil if radar doesn't support surface/land search -- @field #Distance detectionDistanceHRM detection distance for RCS=1m^2 in high-resolution mapping mode, nil if radar has no HRM -- @field #Unit.Radar.detectionDistanceAir detectionDistanceAir detection distance for RCS=1m^2 airborne target, nil if radar doesn't support air search - - --- @type Unit.Radar.detectionDistanceAir + + --- A radar. + -- @type Unit.Radar.detectionDistanceAir -- @field #Unit.Radar.detectionDistanceAir.upperHemisphere upperHemisphere -- @field #Unit.Radar.detectionDistanceAir.lowerHemisphere lowerHemisphere - - --- @type Unit.Radar.detectionDistanceAir.upperHemisphere + + --- A radar. + -- @type Unit.Radar.detectionDistanceAir.upperHemisphere -- @field #Distance headOn -- @field #Distance tailOn - - --- @type Unit.Radar.detectionDistanceAir.lowerHemisphere + + --- A radar. + -- @type Unit.Radar.detectionDistanceAir.lowerHemisphere -- @field #Distance headOn -- @field #Distance tailOn - + --- An IRST. - -- @type Unit.IRST + -- @type Unit.IRST -- @extends #Unit.Sensor -- @field #Distance detectionDistanceIdle detection of tail-on target with heat signature = 1 in upper hemisphere, engines are in idle -- @field #Distance detectionDistanceMaximal ..., engines are in maximal mode -- @field #Distance detectionDistanceAfterburner ..., engines are in afterburner mode - + --- An RWR. - -- @type Unit.RWR + -- @type Unit.RWR -- @extends #Unit.Sensor - + --- table that stores all unit sensors. -- TODO @type Sensors - -- - - - --- Returns unit object by the name assigned to the unit in Mission Editor. If there is unit with such name or the unit is destroyed the function will return nil. The function provides access to non-activated units too. + -- + + + --- Returns unit object by the name assigned to the unit in Mission Editor. If there is unit with such name or the unit is destroyed the function will return nil. The function provides access to non-activated units too. -- @function [parent=#Unit] getByName -- @param #string name -- @return #Unit - + --- Returns if the unit is activated. -- @function [parent=#Unit] isActive -- @param #Unit self -- @return #boolean - + --- Returns name of the player that control the unit or nil if the unit is controlled by A.I. -- @function [parent=#Unit] getPlayerName -- @param #Unit self -- @return #string - + --- returns the unit's unique identifier. -- @function [parent=#Unit] getID -- @param #Unit self -- @return #Unit.ID - - + + --- Returns the unit's number in the group. The number is the same number the unit has in ME. It may not be changed during the mission. If any unit in the group is destroyed, the numbers of another units will not be changed. -- @function [parent=#Unit] getNumber -- @param #Unit self -- @return #number - + --- Returns controller of the unit if it exist and nil otherwise -- @function [parent=#Unit] getController -- @param #Unit self -- @return #Controller - + --- Returns the unit's group if it exist and nil otherwise -- @function [parent=#Unit] getGroup -- @param #Unit self -- @return #Group - + --- Returns the unit's callsign - the localized string. -- @function [parent=#Unit] getCallsign -- @param #Unit self -- @return #string - + --- Returns the unit's health. Dead units has health <= 1.0 -- @function [parent=#Unit] getLife -- @param #Unit self -- @return #number - + --- returns the unit's initial health. -- @function [parent=#Unit] getLife0 -- @param #Unit self -- @return #number - + --- Returns relative amount of fuel (from 0.0 to 1.0) the unit has in its internal tanks. If there are additional fuel tanks the value may be greater than 1.0. -- @function [parent=#Unit] getFuel -- @param #Unit self -- @return #number - + --- Returns the unit ammunition. -- @function [parent=#Unit] getAmmo -- @param #Unit self @@ -1309,12 +1328,12 @@ do -- Unit -- @function [parent=#Unit] getDescentCapacity -- @param #Unit self -- @return #number Number of soldiers that embark. - - --- Returns the unit sensors. + + --- Returns the unit sensors. -- @function [parent=#Unit] getSensors -- @param #Unit self -- @return #Unit.Sensors - + --- Returns true if the unit has specified types of sensors. This function is more preferable than Unit.getSensors() if you don't want to get information about all the unit's sensors, and just want to check if the unit has specified types of sensors. -- @function [parent=#Unit] hasSensors -- @param #Unit self @@ -1328,25 +1347,25 @@ do -- Unit -- unit:hasSensors(Unit.SensorType.RADAR, Unit.RadarType.AS) -- If no additional parameters are specified the function returns true if the unit has at least one sensor of specified type. -- If sensor type is not specified the function returns true if the unit has at least one sensor of any type. - -- - + -- + --- returns two values: -- First value indicates if at least one of the unit's radar(s) is on. - -- Second value is the object of the radar's interest. Not nil only if at least one radar of the unit is tracking a target. + -- Second value is the object of the radar's interest. Not nil only if at least one radar of the unit is tracking a target. -- @function [parent=#Unit] getRadar -- @param #Unit self -- @return #boolean, Wrapper.Object#Object - - --- Returns unit descriptor. Descriptor type depends on unit category. + + --- Returns unit descriptor. Descriptor type depends on unit category. -- @function [parent=#Unit] getDesc -- @param #Unit self -- @return #Unit.Desc - + --- GROUND - Switch on/off radar emissions -- @function [parent=#Unit] enableEmission -- @param #Unit self -- @param #boolean switch - + Unit = {} --#Unit end -- Unit @@ -1356,9 +1375,9 @@ do -- Group --- Represents group of Units. -- @type Group - -- @field #ID ID Identifier of a group. It is assigned to a group by Mission Editor automatically. - -- @field #Group.Category Category Enum contains identifiers of group types. - + -- @field #ID ID Identifier of a group. It is assigned to a group by Mission Editor automatically. + -- @field #Group.Category Category Enum contains identifiers of group types. + --- Enum contains identifiers of group types. -- @type Group.Category -- @field AIRPLANE @@ -1366,76 +1385,76 @@ do -- Group -- @field GROUND -- @field SHIP -- @field TRAIN - + -- Static Functions - - --- Returns group by the name assigned to the group in Mission Editor. + + --- Returns group by the name assigned to the group in Mission Editor. -- @function [parent=#Group] getByName -- @param #string name -- @return #Group - + -- Member Functions - - --- returns true if the group exist or false otherwise. + + --- returns true if the group exist or false otherwise. -- @function [parent=#Group] isExist - -- @param #Group self + -- @param #Group self -- @return #boolean - + --- Destroys the group and all of its units. -- @function [parent=#Group] destroy - -- @param #Group self - + -- @param #Group self + --- Returns category of the group. -- @function [parent=#Group] getCategory - -- @param #Group self + -- @param #Group self -- @return #Group.Category - + --- Returns the coalition of the group. -- @function [parent=#Group] getCoalition - -- @param #Group self + -- @param #Group self -- @return #coalition.side - + --- Returns the group's name. This is the same name assigned to the group in Mission Editor. -- @function [parent=#Group] getName - -- @param #Group self + -- @param #Group self -- @return #string - + --- Returns the group identifier. -- @function [parent=#Group] getID - -- @param #Group self + -- @param #Group self -- @return #ID - + --- Returns the unit with number unitNumber. If the unit is not exists the function will return nil. -- @function [parent=#Group] getUnit - -- @param #Group self + -- @param #Group self -- @param #number unitNumber -- @return #Unit - + --- Returns current size of the group. If some of the units will be destroyed, As units are destroyed the size of the group will be changed. -- @function [parent=#Group] getSize - -- @param #Group self + -- @param #Group self -- @return #number - + --- Returns initial size of the group. If some of the units will be destroyed, initial size of the group will not be changed; Initial size limits the unitNumber parameter for Group.getUnit() function. -- @function [parent=#Group] getInitialSize - -- @param #Group self + -- @param #Group self -- @return #number - + --- Returns array of the units present in the group now. Destroyed units will not be enlisted at all. -- @function [parent=#Group] getUnits - -- @param #Group self + -- @param #Group self -- @return #list<#Unit> array of Units - - --- Returns controller of the group. + + --- Returns controller of the group. -- @function [parent=#Group] getController - -- @param #Group self + -- @param #Group self -- @return #Controller - + --- GROUND - Switch on/off radar emissions -- @function [parent=#Group] enableEmission -- @param #Group self -- @param #boolean switch - + Group = {} --#Group end -- Group @@ -1484,7 +1503,7 @@ do -- AI -- @field #AI.Skill Skill -- @field #AI.Task Task -- @field #AI.Option Option - + --- [https://wiki.hoggitworld.com/view/DCS_enum_AI](https://wiki.hoggitworld.com/view/DCS_enum_AI) -- @type AI.Skill -- @field AVERAGE @@ -1493,7 +1512,7 @@ do -- AI -- @field EXCELLENT -- @field PLAYER -- @field CLIENT - + --- [https://wiki.hoggitworld.com/view/DCS_enum_AI](https://wiki.hoggitworld.com/view/DCS_enum_AI) -- @type AI.Task -- @field #AI.Task.WeaponExpend WeaponExpend @@ -1503,7 +1522,7 @@ do -- AI -- @field #AI.Task.TurnMethod TurnMethod -- @field #AI.Task.AltitudeType AltitudeType -- @field #AI.Task.VehicleFormation VehicleFormation - + --- [https://wiki.hoggitworld.com/view/DCS_enum_AI](https://wiki.hoggitworld.com/view/DCS_enum_AI) -- @type AI.Task.WeaponExpend -- @field ONE @@ -1512,12 +1531,12 @@ do -- AI -- @field QUARTER -- @field HALF -- @field ALL - + --- [https://wiki.hoggitworld.com/view/DCS_enum_AI](https://wiki.hoggitworld.com/view/DCS_enum_AI) -- @type AI.Task.OrbitPattern -- @field CIRCLE -- @field RACE_TRACK - + --- [https://wiki.hoggitworld.com/view/DCS_enum_AI](https://wiki.hoggitworld.com/view/DCS_enum_AI) -- @type AI.Task.Designation -- @field NO @@ -1525,23 +1544,27 @@ do -- AI -- @field WP -- @field IR_POINTER -- @field LASER - - --- @type AI.Task.WaypointType + + --- + -- @type AI.Task.WaypointType -- @field TAKEOFF -- @field TAKEOFF_PARKING -- @field TURNING_POINT -- @field TAKEOFF_PARKING_HOT -- @field LAND - - --- @type AI.Task.TurnMethod + + --- + -- @type AI.Task.TurnMethod -- @field FLY_OVER_POINT -- @field FIN_POINT - - --- @type AI.Task.AltitudeType + + --- + -- @type AI.Task.AltitudeType -- @field BARO -- @field RADIO - - --- @type AI.Task.VehicleFormation + + --- + -- @type AI.Task.VehicleFormation -- @field OFF_ROAD -- @field ON_ROAD -- @field RANK @@ -1550,28 +1573,31 @@ do -- AI -- @field VEE -- @field ECHELON_LEFT -- @field ECHELON_RIGHT - - --- @type AI.Option + + --- + -- @type AI.Option -- @field #AI.Option.Air Air -- @field #AI.Option.Ground Ground -- @field #AI.Option.Naval Naval - - --- @type AI.Option.Air + + --- + -- @type AI.Option.Air -- @field #AI.Option.Air.id id -- @field #AI.Option.Air.val val - - --- @type AI.Option.Ground + + --- + -- @type AI.Option.Ground -- @field #AI.Option.Ground.id id -- @field #AI.Option.Ground.val val -- @field #AI.Option.Ground.mid mid -- @field #AI.Option.Ground.mval mval - -- - --- @type AI.Option.Naval + -- + -- @type AI.Option.Naval -- @field #AI.Option.Naval.id id -- @field #AI.Option.Naval.val val - - - --- @type AI.Option.Air.id + + --- + -- @type AI.Option.Air.id -- @field NO_OPTION -- @field ROE -- @field REACTION_ON_THREAT @@ -1593,73 +1619,61 @@ do -- AI -- @field OPTION_RADIO_USAGE_KILL -- @field JETT_TANKS_IF_EMPTY -- @field FORCED_ATTACK - - --- @type AI.Option.Air.id.FORMATION - -- @field LINE_ABREAST - -- @field TRAIL - -- @field WEDGE - -- @field ECHELON_RIGHT - -- @field ECHELON_LEFT - -- @field FINGER_FOUR - -- @field SPREAD_FOUR - -- @field WW2_BOMBER_ELEMENT - -- @field WW2_BOMBER_ELEMENT_HEIGHT - -- @field WW2_FIGHTER_VIC - -- @field HEL_WEDGE - -- @field HEL_ECHELON - -- @field HEL_FRONT - -- @field HEL_COLUMN - -- @field COMBAT_BOX - -- @field JAVELIN_DOWN - - --- @type AI.Option.Air.val + --- + -- @type AI.Option.Air.val -- @field #AI.Option.Air.val.ROE ROE -- @field #AI.Option.Air.val.REACTION_ON_THREAT REACTION_ON_THREAT -- @field #AI.Option.Air.val.RADAR_USING RADAR_USING -- @field #AI.Option.Air.val.FLARE_USING FLARE_USING - - --- @type AI.Option.Air.val.ROE + + --- + -- @type AI.Option.Air.val.ROE -- @field WEAPON_FREE -- @field OPEN_FIRE_WEAPON_FREE -- @field OPEN_FIRE -- @field RETURN_FIRE -- @field WEAPON_HOLD - - --- @type AI.Option.Air.val.REACTION_ON_THREAT + + --- + -- @type AI.Option.Air.val.REACTION_ON_THREAT -- @field NO_REACTION -- @field PASSIVE_DEFENCE -- @field EVADE_FIRE -- @field BYPASS_AND_ESCAPE -- @field ALLOW_ABORT_MISSION - - --- @type AI.Option.Air.val.RADAR_USING + + --- + -- @type AI.Option.Air.val.RADAR_USING -- @field NEVER -- @field FOR_ATTACK_ONLY -- @field FOR_SEARCH_IF_REQUIRED -- @field FOR_CONTINUOUS_SEARCH - - --- @type AI.Option.Air.val.FLARE_USING + + --- + -- @type AI.Option.Air.val.FLARE_USING -- @field NEVER -- @field AGAINST_FIRED_MISSILE -- @field WHEN_FLYING_IN_SAM_WEZ -- @field WHEN_FLYING_NEAR_ENEMIES - --- @type AI.Option.Air.val.ECM_USING + --- + -- @type AI.Option.Air.val.ECM_USING -- @field NEVER_USE -- @field USE_IF_ONLY_LOCK_BY_RADAR -- @field USE_IF_DETECTED_LOCK_BY_RADAR -- @field ALWAYS_USE - --- @type AI.Option.Air.val.MISSILE_ATTACK + --- + -- @type AI.Option.Air.val.MISSILE_ATTACK -- @field MAX_RANGE -- @field NEZ_RANGE -- @field HALF_WAY_RMAX_NEZ -- @field TARGET_THREAT_EST -- @field RANDOM_RANGE - - --- @type AI.Option.Ground.id + --- + -- @type AI.Option.Ground.id -- @field NO_OPTION -- @field ROE @{#AI.Option.Ground.val.ROE} -- @field FORMATION @@ -1667,47 +1681,56 @@ do -- AI -- @field ALARM_STATE @{#AI.Option.Ground.val.ALARM_STATE} -- @field ENGAGE_AIR_WEAPONS -- @field AC_ENGAGEMENT_RANGE_RESTRICTION - - --- @type AI.Option.Ground.mid -- Moose added + + --- + -- @type AI.Option.Ground.mid -- Moose added -- @field RESTRICT_AAA_MIN 27 -- @field RESTRICT_AAA_MAX 29 -- @field RESTRICT_TARGETS @{#AI.Option.Ground.mval.ENGAGE_TARGETS} 28 - - --- @type AI.Option.Ground.val + + --- + -- @type AI.Option.Ground.val -- @field #AI.Option.Ground.val.ROE ROE -- @field #AI.Option.Ground.val.ALARM_STATE ALARM_STATE -- @field #AI.Option.Ground.val.ENGAGE_TARGETS RESTRICT_TARGETS - - --- @type AI.Option.Ground.val.ROE + + --- + -- @type AI.Option.Ground.val.ROE -- @field OPEN_FIRE -- @field RETURN_FIRE -- @field WEAPON_HOLD - - --- @type AI.Option.Ground.mval -- Moose added + + --- + -- @type AI.Option.Ground.mval -- Moose added -- @field #AI.Option.Ground.mval.ENGAGE_TARGETS ENGAGE_TARGETS - - --- @type AI.Option.Ground.mval.ENGAGE_TARGETS -- Moose added + + --- + -- @type AI.Option.Ground.mval.ENGAGE_TARGETS -- Moose added -- @field ANY_TARGET -- 0 -- @field AIR_UNITS_ONLY -- 1 -- @field GROUND_UNITS_ONLY -- 2 - - --- @type AI.Option.Ground.val.ALARM_STATE + + --- + -- @type AI.Option.Ground.val.ALARM_STATE -- @field AUTO -- @field GREEN -- @field RED - - --- @type AI.Option.Naval.id + + --- + -- @type AI.Option.Naval.id -- @field NO_OPTION -- @field ROE - - --- @type AI.Option.Naval.val + + --- + -- @type AI.Option.Naval.val -- @field #AI.Option.Naval.val.ROE ROE - - --- @type AI.Option.Naval.val.ROE + + --- + -- @type AI.Option.Naval.val.ROE -- @field OPEN_FIRE -- @field RETURN_FIRE -- @field WEAPON_HOLD - + AI = {} --#AI end -- AI diff --git a/Moose Development/Moose/Functional/Artillery.lua b/Moose Development/Moose/Functional/Artillery.lua index 051ca8d91..02ad5f5d7 100644 --- a/Moose Development/Moose/Functional/Artillery.lua +++ b/Moose Development/Moose/Functional/Artillery.lua @@ -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 -- diff --git a/Moose Development/Moose/Functional/Designate.lua b/Moose Development/Moose/Functional/Designate.lua index 7bc0c7a82..a55cadbc2 100644 --- a/Moose Development/Moose/Functional/Designate.lua +++ b/Moose Development/Moose/Functional/Designate.lua @@ -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: -- diff --git a/Moose Development/Moose/Functional/Detection.lua b/Moose Development/Moose/Functional/Detection.lua index 3558354a1..9fc086cd9 100644 --- a/Moose Development/Moose/Functional/Detection.lua +++ b/Moose Development/Moose/Functional/Detection.lua @@ -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. -- diff --git a/Moose Development/Moose/Functional/DetectionZones.lua b/Moose Development/Moose/Functional/DetectionZones.lua index 8cb9b9d10..20680559d 100644 --- a/Moose Development/Moose/Functional/DetectionZones.lua +++ b/Moose Development/Moose/Functional/DetectionZones.lua @@ -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. -- diff --git a/Moose Development/Moose/Functional/Escort.lua b/Moose Development/Moose/Functional/Escort.lua index d0c470d3f..38d25de68 100644 --- a/Moose Development/Moose/Functional/Escort.lua +++ b/Moose Development/Moose/Functional/Escort.lua @@ -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 diff --git a/Moose Development/Moose/Functional/Fox.lua b/Moose Development/Moose/Functional/Fox.lua index 4d5a418e0..0c9c81b67 100644 --- a/Moose Development/Moose/Functional/Fox.lua +++ b/Moose Development/Moose/Functional/Fox.lua @@ -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 diff --git a/Moose Development/Moose/Functional/Mantis.lua b/Moose Development/Moose/Functional/Mantis.lua index 9bd80659b..72de47973 100644 --- a/Moose Development/Moose/Functional/Mantis.lua +++ b/Moose Development/Moose/Functional/Mantis.lua @@ -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 diff --git a/Moose Development/Moose/Functional/RAT.lua b/Moose Development/Moose/Functional/RAT.lua index f5b262277..57a0783da 100644 --- a/Moose Development/Moose/Functional/RAT.lua +++ b/Moose Development/Moose/Functional/RAT.lua @@ -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) diff --git a/Moose Development/Moose/Functional/Range.lua b/Moose Development/Moose/Functional/Range.lua index ab44ef3cd..18630e30b 100644 --- a/Moose Development/Moose/Functional/Range.lua +++ b/Moose Development/Moose/Functional/Range.lua @@ -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 -- -- === diff --git a/Moose Development/Moose/Functional/Scoring.lua b/Moose Development/Moose/Functional/Scoring.lua index a7093f8c1..1c86d5812 100644 --- a/Moose Development/Moose/Functional/Scoring.lua +++ b/Moose Development/Moose/Functional/Scoring.lua @@ -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. -- -- === -- diff --git a/Moose Development/Moose/Functional/Suppression.lua b/Moose Development/Moose/Functional/Suppression.lua index 8c6b88a93..d93959990 100644 --- a/Moose Development/Moose/Functional/Suppression.lua +++ b/Moose Development/Moose/Functional/Suppression.lua @@ -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 -- -- === -- diff --git a/Moose Development/Moose/Functional/Warehouse.lua b/Moose Development/Moose/Functional/Warehouse.lua index 1c5f02e0f..8ce1752d0 100644 --- a/Moose Development/Moose/Functional/Warehouse.lua +++ b/Moose Development/Moose/Functional/Warehouse.lua @@ -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. diff --git a/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua b/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua index 3215b9a12..113b3aa7f 100644 --- a/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua +++ b/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua @@ -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 diff --git a/Moose Development/Moose/Functional/ZoneGoalCargo.lua b/Moose Development/Moose/Functional/ZoneGoalCargo.lua index d957130da..7a19ed02a 100644 --- a/Moose Development/Moose/Functional/ZoneGoalCargo.lua +++ b/Moose Development/Moose/Functional/ZoneGoalCargo.lua @@ -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 diff --git a/Moose Development/Moose/Functional/ZoneGoalCoalition.lua b/Moose Development/Moose/Functional/ZoneGoalCoalition.lua index 1f5da5440..622843b10 100644 --- a/Moose Development/Moose/Functional/ZoneGoalCoalition.lua +++ b/Moose Development/Moose/Functional/ZoneGoalCoalition.lua @@ -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 diff --git a/Moose Development/Moose/Modules.lua b/Moose Development/Moose/Modules.lua index eb48b5949..6629a3b2e 100644 --- a/Moose Development/Moose/Modules.lua +++ b/Moose Development/Moose/Modules.lua @@ -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' ) diff --git a/Moose Development/Moose/Ops/ATIS.lua b/Moose Development/Moose/Ops/ATIS.lua index 8f110b07f..94bd002fc 100644 --- a/Moose Development/Moose/Ops/ATIS.lua +++ b/Moose Development/Moose/Ops/ATIS.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 diff --git a/Moose Development/Moose/Ops/AirWing.lua b/Moose Development/Moose/Ops/AirWing.lua index ed166e23d..9d918e5d9 100644 --- a/Moose Development/Moose/Ops/AirWing.lua +++ b/Moose Development/Moose/Ops/AirWing.lua @@ -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) diff --git a/Moose Development/Moose/Ops/Airboss.lua b/Moose Development/Moose/Ops/Airboss.lua index 8e2dc2332..d7250de3e 100644 --- a/Moose Development/Moose/Ops/Airboss.lua +++ b/Moose Development/Moose/Ops/Airboss.lua @@ -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) diff --git a/Moose Development/Moose/Ops/ArmyGroup.lua b/Moose Development/Moose/Ops/ArmyGroup.lua index 1bbad51e8..ac893ae85 100644 --- a/Moose Development/Moose/Ops/ArmyGroup.lua +++ b/Moose Development/Moose/Ops/ArmyGroup.lua @@ -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 diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index c70ce6377..92511531c 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -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 diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index 9d23a86e1..0c1950e41 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -46,8 +46,6 @@ -- -- === -- --- ![Banner Image](OPS_CSAR.jpg) --- -- # CSAR Concept -- -- * MOOSE-based Helicopter CSAR Operations for Players. diff --git a/Moose Development/Moose/Ops/CTLD.lua b/Moose Development/Moose/Ops/CTLD.lua index 8c77f8eb8..80c8d7d6e 100644 --- a/Moose Development/Moose/Ops/CTLD.lua +++ b/Moose Development/Moose/Ops/CTLD.lua @@ -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 -- -- === -- --- ![Banner Image](OPS_CTLD.jpg) +-- ![Banner Image](../Images/OPS_CTLD.jpg) -- -- # 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 = {} diff --git a/Moose Development/Moose/Ops/Cohort.lua b/Moose Development/Moose/Ops/Cohort.lua index 5ab2e97da..5ed60451c 100644 --- a/Moose Development/Moose/Ops/Cohort.lua +++ b/Moose Development/Moose/Ops/Cohort.lua @@ -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 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - diff --git a/Moose Development/Moose/Ops/EasyGCICAP.lua b/Moose Development/Moose/Ops/EasyGCICAP.lua index 248318fe7..0d2ce7d99 100644 --- a/Moose Development/Moose/Ops/EasyGCICAP.lua +++ b/Moose Development/Moose/Ops/EasyGCICAP.lua @@ -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 diff --git a/Moose Development/Moose/Ops/FlightControl.lua b/Moose Development/Moose/Ops/FlightControl.lua index 5df30d685..4b8c4fc94 100644 --- a/Moose Development/Moose/Ops/FlightControl.lua +++ b/Moose Development/Moose/Ops/FlightControl.lua @@ -1,13 +1,13 @@ --- **OPS** - Air Traffic Control for AI and human players. --- +-- -- **Main Features:** -- -- * Manage aircraft departure and arrival -- * Handles AI and human players --- * Limit number of AI groups taxiing, taking off and landing simultaniously +-- * Limit number of AI groups taxiing, taking off and landing simultaneously -- * Immersive voice overs via SRS text-to-speech -- * Define holding patterns for airdromes --- +-- -- === -- -- ## Example Missions: @@ -71,21 +71,21 @@ -- === -- -- # The FLIGHTCONTROL Concept --- +-- -- This class implements an ATC for human and AI controlled aircraft. It gives permission for take-off and landing based on a sophisticated queueing system. -- Therefore, it solves (or reduces) a lot of common problems with the DCS implementation. --- --- You might be familiar with the `AIRBOSS` class. This class is the analogue for land based airfields. One major difference is that no pre-recorded sound files are +-- +-- You might be familiar with the `AIRBOSS` class. This class is the analogue for land based airfields. One major difference is that no pre-recorded sound files are -- necessary. The radio transmissions use the SRS text-to-speech feature. --- +-- -- ## Prerequisites --- +-- -- * SRS is used for radio communications --- +-- -- ## Limitations --- +-- -- Some (DCS) limitations you should be aware of: --- +-- -- * As soon as AI aircraft taxi or land, we completely loose control. All is governed by the internal DCS AI logic. -- * We have no control over the active runway or which runway is used by the AI if there are multiple. -- * Only one player/client per group as we can create menus only for a group and not for a specific unit. @@ -93,154 +93,154 @@ -- * So far only airdromes are handled, *i.e.* no FARPs or ships. -- * Helicopters are not treated differently from fixed wing aircraft until now. -- * The active runway can only be determined by the wind direction. So at least set a very light wind speed in your mission. --- +-- -- # Basic Usage --- --- A flight control for a given airdrome can be created with the @{#FLIGHTCONTROL.New}(*AirbaseName, Frequency, Modulation, PathToSRS*) function. You need to specify the name of the airbase, the +-- +-- A flight control for a given airdrome can be created with the @{#FLIGHTCONTROL.New}(*AirbaseName, Frequency, Modulation, PathToSRS*) function. You need to specify the name of the airbase, the -- tower radio frequency, its modulation and the path, where SRS is located on the machine that is running this mission. --- +-- -- For the FC to be operating, it needs to be started with the @{#FLIGHTCONTROL.Start}() function. --- +-- -- ## Simple Script --- +-- -- The simplest script looks like --- +-- -- local FC_BATUMI=FLIGHTCONTROL:New(AIRBASE.Caucasus.Batumi, 251, nil, "D:\\SomeDirectory\\_SRS") -- FC_BATUMI:Start() --- +-- -- This will start the FC for at the Batumi airbase with tower frequency 251 MHz AM. SRS needs to be in the given directory. --- +-- -- Like this, a default holding pattern (see below) is parallel to the direction of the active runway. --- +-- -- # Holding Patterns --- +-- -- Holding pattern are air spaces where incoming aircraft are guided to and have to hold until they get landing clearance. --- +-- -- You can add a holding pattern with the @{#FLIGHTCONTROL.AddHoldingPattern}(*ArrivalZone, Heading, Length, FlightlevelMin, FlightlevelMax, Prio*) function, where --- +-- -- * `ArrivalZone` is the zone where the aircraft enter the pattern. -- * `Heading` is the direction into which the aircraft have to fly from the arrival zone. -- * `Length` is the length of the pattern. -- * `FlightLevelMin` is the lowest altitude at which aircraft can hold. -- * `FlightLevelMax` is the highest altitude at which aircraft can hold. --- * `Prio` is the priority of this holdig stacks. If multiple patterns are defined, patterns with higher prio will be filled first. --- +-- * `Prio` is the priority of this holding stacks. If multiple patterns are defined, patterns with higher prio will be filled first. +-- -- # Parking Guard --- +-- -- A "parking guard" is a group or static object, that is spawned in front of parking aircraft. This is useful to stop AI groups from taxiing if they are spawned with hot engines. -- It is also handy to forbid human players to taxi until they ask for clearance. --- +-- -- You can activate the parking guard with the @{#FLIGHTCONTROL.SetParkingGuard}(*GroupName*) function, where the parameter `GroupName` is the name of a late activated template group. -- This should consist of only *one* unit, *e.g.* a single infantry soldier. --- +-- -- You can also use static objects as parking guards with the @{#FLIGHTCONTROL.SetParkingGuardStatic}(*StaticName*), where the parameter `StaticName` is the name of a static object placed -- somewhere in the mission editor. --- +-- -- # Limits for Inbound and Outbound Flights --- --- You can define limits on how many aircraft are simultaniously landing and taking off. This avoids (DCS) problems where taxiing aircraft cause a "traffic jam" on the taxi way(s) +-- +-- You can define limits on how many aircraft are simultaneously landing and taking off. This avoids (DCS) problems where taxiing aircraft cause a "traffic jam" on the taxi way(s) -- and bring the whole airbase effectively to a stand still. --- +-- -- ## Landing Limits --- --- The number of groups getting landing clearance can be set with the @{#FLIGHTCONTROL.SetLimitLanding}(*Nlanding, Ntakeoff*) function. --- The first parameter, `Nlanding`, defines how many groups get clearance simultaniously. --- +-- +-- The number of groups getting landing clearance can be set with the @{#FLIGHTCONTROL.SetLimitLanding}(*Nlanding, Ntakeoff*) function. +-- The first parameter, `Nlanding`, defines how many groups get clearance simultaneously. +-- -- The second parameter, `Ntakeoff`, sets a limit on how many flights can take off whilst inbound flights still get clearance. By default, this is set to zero because the runway can only be used for takeoff *or* --- landing. So if you have a flight taking off, inbound fights will have to wait until the runway is clear. +-- landing. So if you have a flight taking off, inbound fights will have to wait until the runway is clear. -- If you have an airport with more than one runway, *e.g.* Nellis AFB, you can allow simultanious landings and takeoffs by setting this number greater zero. --- --- The time interval between clerances can be set with the @{#FLIGHTCONTROL.SetLandingInterval}(`dt`) function, where the parameter `dt` specifies the time interval in seconds before +-- +-- The time interval between clerances can be set with the @{#FLIGHTCONTROL.SetLandingInterval}(`dt`) function, where the parameter `dt` specifies the time interval in seconds before -- the next flight get clearance. This only has an effect if `Nlanding` is greater than one. --- +-- -- ## Taxiing/Takeoff Limits --- --- The number of AI flight groups getting clearance to taxi to the runway can be set with the @{#FLIGHTCONTROL.SetLimitTaxi}(*Nlanding, Ntakeoff*) function. --- The first parameter, `Ntaxi`, defines how many groups are allowed to taxi to the runway simultaniously. Note that once the AI starts to taxi, we loose complete control over it. +-- +-- The number of AI flight groups getting clearance to taxi to the runway can be set with the @{#FLIGHTCONTROL.SetLimitTaxi}(*Nlanding, Ntakeoff*) function. +-- The first parameter, `Ntaxi`, defines how many groups are allowed to taxi to the runway simultaneously. Note that once the AI starts to taxi, we loose complete control over it. -- They will follow their internal logic to get the the runway and take off. Therefore, giving clearance to taxi is equivalent to giving them clearance for takeoff. --- +-- -- By default, the parameter only counts the number of flights taxiing *to* the runway. If you set the second parameter, `IncludeInbound`, to `true`, this will also count the flights -- that are taxiing to their parking spot(s) after they landed. --- +-- -- The third parameter, `Nlanding`, defines how many aircraft can land whilst outbound fights still get taxi/takeoff clearance. By default, this is set to zero because the runway -- can only be used for takeoff *or* landing. If you have an airport with more than one runway, *e.g.* Nellis AFB, you can allow aircraft to taxi to the runway while other flights are landing --- by setting this number greater zero. +-- by setting this number greater zero. -- -- Note that the limits here are only affecting **AI** aircraft groups. *Human players* are assumed to be a lot more well behaved and capable as they are able to taxi around obstacles, *e.g.* -- other aircraft etc. Therefore, players will get taxi clearance independent of the number of inbound and/or outbound flights. Players will, however, still need to ask for takeoff clearance once -- they are holding short of the runway. --- +-- -- # Speeding Violations --- +-- -- You can set a speed limit for taxiing players with the @{#FLIGHTCONTROL.SetSpeedLimitTaxi}(*SpeedLimit*) function, where the parameter `SpeedLimit` is the max allowed speed in knots. -- If players taxi faster, they will get a radio message. Additionally, the FSM event `PlayerSpeeding` is triggered and can be captured with the `OnAfterPlayerSpeeding` function. -- For example, this can be used to kick players that do not behave well. --- +-- -- # Runway Destroyed --- +-- -- Once a runway is damaged, DCS AI will stop taxiing. Therefore, this class monitors if a runway is destroyed. If this is the case, all AI taxi and landing clearances will be suspended for --- one hour. This is the hard coded time in DCS until the runway becomes operational again. If that ever changes, you can manually set the repair time with the +-- one hour. This is the hard coded time in DCS until the runway becomes operational again. If that ever changes, you can manually set the repair time with the -- @{#FLIGHTCONTROL.SetRunwayRepairtime} function. --- +-- -- Note that human players we still get taxi, takeoff and landing clearances. --- +-- -- If the runway is destroyed, the FSM event `RunwayDestroyed` is triggered and can be captured with the @{#FLIGHTCONTROL.OnAfterRunwayDestroyed} function. --- +-- -- If the runway is repaired, the FSM event `RunwayRepaired` is triggered and can be captured with the @{#FLIGHTCONTROL.OnAfterRunwayRepaired} function. --- +-- -- # SRS --- +-- -- SRS text-to-speech is used to send radio messages from the tower and pilots. --- +-- -- ## Tower --- +-- -- You can set the options for the tower SRS voice with the @{#FLIGHTCONTROL.SetSRSTower}() function. --- +-- -- ## Pilot --- +-- -- You can set the options for the pilot SRS voice with the @{#FLIGHTCONTROL.SetSRSPilot}() function. --- +-- -- # Runways --- +-- -- First note, that we have extremely limited control over which runway the DCS AI groups use. The only parameter we can adjust is the direction of the wind. In many cases, the AI will try to takeoff and land -- against the wind, which therefore determines the active runway. There are, however, cases where this does not hold true. For example, at Nellis AFB the runway for takeoff is `03L` while the runway for -- landing is `21L`. --- +-- -- By default, the runways for landing and takeoff are determined from the wind direction as described above. For cases where this gives wrong results, you can set the active runways manually. This is -- done via @{Wrappper.Airbase#AIRBASE} class. --- +-- -- More specifically, you can use the @{Wrappper.Airbase#AIRBASE.SetActiveRunwayLanding} function to set the landing runway and the @{Wrappper.Airbase#AIRBASE.SetActiveRunwayTakeoff} function to set -- the runway for takeoff. --- +-- -- ## Example for Nellis AFB --- +-- -- For Nellis, you can use: --- +-- -- -- Nellis AFB. -- local Nellis=AIRBASE:FindByName(AIRBASE.Nevada.Nellis_AFB) -- Nellis:SetActiveRunwayLanding("21L") -- Nellis:SetActiveRunwayTakeoff("03L") --- +-- -- # DCS ATC --- +-- -- You can disable the DCS ATC with the @{Wrappper.Airbase#AIRBASE.SetRadioSilentMode}(*true*). This does not remove the DCS ATC airbase from the F10 menu but makes the ATC unresponsive. --- --- +-- +-- -- # Examples --- +-- -- In this section, you find examples for different airdromes. --- +-- -- ## Nellis AFB --- --- -- Create a new FLIGHTCONTROL object at Nellis AFB. The tower frequency is 251 MHz AM. Path to SRS has to be adjusted. +-- +-- -- Create a new FLIGHTCONTROL object at Nellis AFB. The tower frequency is 251 MHz AM. Path to SRS has to be adjusted. -- local atcNellis=FLIGHTCONTROL:New(AIRBASE.Nevada.Nellis_AFB, 251, nil, "D:\\My SRS Directory") -- -- Set a parking guard from a static named "Static Generator F Template". -- atcNellis:SetParkingGuardStatic("Static Generator F Template") -- -- Set taxi speed limit to 25 knots. -- atcNellis:SetSpeedLimitTaxi(25) --- -- Set that max 3 groups are allowed to taxi simultaniously. +-- -- Set that max 3 groups are allowed to taxi simultaneously. -- atcNellis:SetLimitTaxi(3, false, 1) --- -- Set that max 2 groups are allowd to land simultaniously and unlimited number (99) groups can land, while other groups are taking off. +-- -- Set that max 2 groups are allowd to land simultaneously and unlimited number (99) groups can land, while other groups are taking off. -- atcNellis:SetLimitLanding(2, 99) -- -- Use Google for text-to-speech. -- atcNellis:SetSRSTower(nil, nil, "en-AU-Standard-A", nil, nil, "D:\\Path To Google\\GoogleCredentials.json") @@ -250,7 +250,7 @@ -- atcNellis:AddHoldingPattern(ZONE:New("Nellis Holding Bravo"), 090, 15, 6, 10, 20) -- -- Start the ATC. -- atcNellis:Start() --- +-- -- @field #FLIGHTCONTROL FLIGHTCONTROL = { ClassName = "FLIGHTCONTROL", @@ -272,6 +272,7 @@ FLIGHTCONTROL = { holdingpatterns = {}, hpcounter = 0, warnings = {}, + nosubs = false, } --- Holding point. Contains holding stacks. @@ -323,7 +324,7 @@ FLIGHTCONTROL.FlightStatus={ READYTX="Ready To Taxi", TAXIOUT="Taxi To Runway", READYTO="Ready For Takeoff", - TAKEOFF="Takeoff", + TAKEOFF="Takeoff", INBOUND="Inbound", HOLDING="Holding", LANDING="Landing", @@ -350,7 +351,7 @@ FLIGHTCONTROL.Violation={ --- FlightControl class version. -- @field #string version -FLIGHTCONTROL.version="0.7.3" +FLIGHTCONTROL.version="0.7.4" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -397,16 +398,16 @@ function FLIGHTCONTROL:New(AirbaseName, Frequency, Modulation, PathToSRS, Port, -- Inherit everything from FSM class. local self=BASE:Inherit(self, FSM:New()) -- #FLIGHTCONTROL - + -- Try to get the airbase. self.airbase=AIRBASE:FindByName(AirbaseName) - + -- Name of the airbase. - self.airbasename=AirbaseName - + self.airbasename=AirbaseName + -- Set some string id for output to DCS.log file. - self.lid=string.format("FLIGHTCONTROL %s | ", AirbaseName) - + self.lid=string.format("FLIGHTCONTROL %s | ", AirbaseName) + -- Check if the airbase exists. if not self.airbase then self:E(string.format("ERROR: Could not find airbase %s!", tostring(AirbaseName))) @@ -417,22 +418,22 @@ function FLIGHTCONTROL:New(AirbaseName, Frequency, Modulation, PathToSRS, Port, self:E(string.format("ERROR: Airbase %s is not an AIRDROME! Script does not handle FARPS or ships.", tostring(AirbaseName))) return nil end - + -- Airbase category airdrome, FARP, SHIP. self.airbasetype=self.airbase:GetAirbaseCategory() - + -- Current map. - self.theatre=env.mission.theatre - + self.theatre=env.mission.theatre + -- 5 NM zone around the airbase. self.zoneAirbase=ZONE_RADIUS:New("FC", self:GetCoordinate():GetVec2(), UTILS.NMToMeters(5)) - + -- Add backup holding pattern. self:_AddHoldingPatternBackup() -- Set alias. self.alias=self.airbasename.." Tower" - + -- Defaults: self:SetLimitLanding(2, 0) self:SetLimitTaxi(2, false, 0) @@ -440,16 +441,17 @@ function FLIGHTCONTROL:New(AirbaseName, Frequency, Modulation, PathToSRS, Port, self:SetFrequency(Frequency, Modulation) self:SetMarkHoldingPattern(true) self:SetRunwayRepairtime() - + self.nosubs = false + -- Set SRS Port self:SetSRSPort(Port or 5002) - + -- Set Callsign Options self:SetCallSignOptions(true,true) - + -- Init msrs queue. self.msrsqueue=MSRSQUEUE:New(self.alias) - + -- SRS for Tower. self.msrsTower=MSRS:New(PathToSRS, Frequency, Modulation) self.msrsTower:SetPort(self.Port) @@ -457,7 +459,7 @@ function FLIGHTCONTROL:New(AirbaseName, Frequency, Modulation, PathToSRS, Port, self.msrsTower:SetGoogle(GoogleKey) end self:SetSRSTower() - + -- SRS for Pilot. self.msrsPilot=MSRS:New(PathToSRS, Frequency, Modulation) self.msrsPilot:SetPort(self.Port) @@ -465,10 +467,10 @@ function FLIGHTCONTROL:New(AirbaseName, Frequency, Modulation, PathToSRS, Port, self.msrsPilot:SetGoogle(GoogleKey) end self:SetSRSPilot() - + -- Wait at least 10 seconds after last radio message before calling the next status update. self.dTmessage=10 - + -- Start State. self:SetStartState("Stopped") @@ -476,15 +478,15 @@ function FLIGHTCONTROL:New(AirbaseName, Frequency, Modulation, PathToSRS, Port, -- From State --> Event --> To State self:AddTransition("Stopped", "Start", "Running") -- Start FSM. self:AddTransition("*", "StatusUpdate", "*") -- Update status. - + self:AddTransition("*", "PlayerKilledGuard", "*") -- Player killed parking guard self:AddTransition("*", "PlayerSpeeding", "*") -- Player speeding on taxi way. self:AddTransition("*", "RunwayDestroyed", "*") -- Runway of the airbase was destroyed. self:AddTransition("*", "RunwayRepaired", "*") -- Runway of the airbase was repaired. - + self:AddTransition("*", "Stop", "Stopped") -- Stop FSM. - + -- Add to data base. _DATABASE:AddFlightControl(self) @@ -577,7 +579,7 @@ function FLIGHTCONTROL:New(AirbaseName, Frequency, Modulation, PathToSRS, Port, -- @param Ops.FlightGroup#FLIGHTGROUP.PlayerData Player data. - return self + return self end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -593,6 +595,22 @@ function FLIGHTCONTROL:SetVerbosity(VerbosityLevel) return self end +--- Set subtitles to appear on SRS TTS messages. +-- @param #FLIGHTCONTROL self +-- @return #FLIGHTCONTROL self +function FLIGHTCONTROL:SwitchSubtitlesOn() + self.nosubs = false + return self +end + +--- Set subtitles to appear on SRS TTS messages. +-- @param #FLIGHTCONTROL self +-- @return #FLIGHTCONTROL self +function FLIGHTCONTROL:SwitchSubtitlesOff() + self.nosubs = true + return self +end + --- Set the tower frequency. -- @param #FLIGHTCONTROL self -- @param #number Frequency Frequency in MHz. Default 305 MHz. @@ -602,7 +620,7 @@ function FLIGHTCONTROL:SetFrequency(Frequency, Modulation) self.frequency=Frequency or 305 self.modulation=Modulation or radio.modulation.AM - + if self.msrsPilot then self.msrsPilot:SetFrequencies(Frequency) self.msrsPilot:SetModulations(Modulation) @@ -612,7 +630,7 @@ function FLIGHTCONTROL:SetFrequency(Frequency, Modulation) self.msrsTower:SetFrequencies(Frequency) self.msrsTower:SetModulations(Modulation) end - + return self end @@ -632,7 +650,7 @@ end -- @param #string Culture Culture, e.g. "en-GB" (default). -- @param #string Voice Specific voice. Overrides `Gender` and `Culture`. -- @param #number Volume Volume. Default 1.0. --- @param #string Label Name under which SRS transmitts. +-- @param #string Label Name under which SRS transmits. -- @param #string PathToGoogleCredentials Path to google credentials json file. -- @param #number Port Server port for SRS -- @return #FLIGHTCONTROL self @@ -665,7 +683,7 @@ end -- @param #string Culture Culture, e.g. "en-GB" (default). -- @param #string Voice Specific voice. Overrides `Gender` and `Culture`. See [Google Voices](https://cloud.google.com/text-to-speech/docs/voices). -- @param #number Volume Volume. Default 1.0. --- @param #string Label Name under which SRS transmitts. Default `self.alias`. +-- @param #string Label Name under which SRS transmits. Default `self.alias`. -- @param #string PathToGoogleCredentials Path to google credentials json file. -- @return #FLIGHTCONTROL self function FLIGHTCONTROL:SetSRSTower(Gender, Culture, Voice, Volume, Label, PathToGoogleCredentials) @@ -683,7 +701,7 @@ end -- @param #string Culture Culture, e.g. "en-US" (default). -- @param #string Voice Specific voice. Overrides `Gender` and `Culture`. -- @param #number Volume Volume. Default 1.0. --- @param #string Label Name under which SRS transmitts. Default "Pilot". +-- @param #string Label Name under which SRS transmits. Default "Pilot". -- @param #string PathToGoogleCredentials Path to google credentials json file. -- @return #FLIGHTCONTROL self function FLIGHTCONTROL:SetSRSPilot(Gender, Culture, Voice, Volume, Label, PathToGoogleCredentials) @@ -696,23 +714,23 @@ function FLIGHTCONTROL:SetSRSPilot(Gender, Culture, Voice, Volume, Label, PathTo end ---- Set the number of aircraft groups, that are allowed to land simultaniously. +--- Set the number of aircraft groups, that are allowed to land simultaneously. -- Note that this restricts AI and human players. --- +-- -- By default, up to two groups get landing clearance. They are spaced out in time, i.e. after the first one got cleared, the second has to wait a bit. -- This --- --- By default, landing clearance is only given when **no** other flight is taking off. You can adjust this for airports with more than one runway or --- in cases where simulatious takeoffs and landings are unproblematic. Note that only because there are multiple runways, it does not mean the AI uses them. --- +-- +-- By default, landing clearance is only given when **no** other flight is taking off. You can adjust this for airports with more than one runway or +-- in cases where simultaneous takeoffs and landings are unproblematic. Note that only because there are multiple runways, it does not mean the AI uses them. +-- -- @param #FLIGHTCONTROL self --- @param #number Nlanding Max number of aircraft landing simultaniously. Default 2. --- @param #number Ntakeoff Allowed number of aircraft taking off for groups to get landing clearance. Default 0. +-- @param #number Nlanding Max number of aircraft landing simultaneously. Default 2. +-- @param #number Ntakeoff Allowed number of aircraft taking off for groups to get landing clearance. Default 0. -- @return #FLIGHTCONTROL self function FLIGHTCONTROL:SetLimitLanding(Nlanding, Ntakeoff) self.NlandingTot=Nlanding or 2 - + self.NlandingTakeoff=Ntakeoff or 0 return self @@ -730,18 +748,18 @@ function FLIGHTCONTROL:SetLandingInterval(dt) end ---- Set the number of **AI** aircraft groups, that are allowed to taxi simultaniously. +--- Set the number of **AI** aircraft groups, that are allowed to taxi simultaneously. -- If the limit is reached, other AI groups not get taxi clearance to taxi to the runway. --- +-- -- By default, this only counts the number of AI that taxi from their parking position to the runway. -- You can also include inbound AI that taxi from the runway to their parking position. -- This can be handy for problematic (usually smaller) airdromes, where there is only one taxiway inbound and outbound flights. --- --- By default, AI will not get cleared for taxiing if at least one other flight is currently landing. If this is an unproblematic airdrome, you can +-- +-- By default, AI will not get cleared for taxiing if at least one other flight is currently landing. If this is an unproblematic airdrome, you can -- also allow groups to taxi if planes are landing, *e.g.* if there are two separate runways. --- +-- -- NOTE that human players are *not* restricted as they should behave better (hopefully) than the AI. --- +-- -- @param #FLIGHTCONTROL self -- @param #number Ntaxi Max number of groups allowed to taxi. Default 2. -- @param #boolean IncludeInbound If `true`, the above @@ -750,9 +768,9 @@ end function FLIGHTCONTROL:SetLimitTaxi(Ntaxi, IncludeInbound, Nlanding) self.NtaxiTot=Ntaxi or 2 - + self.NtaxiInbound=IncludeInbound - + self.NtaxiLanding=Nlanding or 0 return self @@ -774,20 +792,20 @@ function FLIGHTCONTROL:AddHoldingPattern(ArrivalZone, Heading, Length, Flightlev if type(ArrivalZone)=="string" then ArrivalZone=ZONE:FindByName(ArrivalZone) end - + -- Increase counter. self.hpcounter=self.hpcounter+1 local hp={} --#FLIGHTCONTROL.HoldingPattern hp.uid=self.hpcounter - hp.arrivalzone=ArrivalZone + hp.arrivalzone=ArrivalZone hp.name=string.format("%s-%d", ArrivalZone:GetName(), hp.uid) hp.pos0=ArrivalZone:GetCoordinate() hp.pos1=hp.pos0:Translate(UTILS.NMToMeters(Length or 15), Heading) hp.angelsmin=FlightlevelMin or 5 hp.angelsmax=FlightlevelMax or 15 hp.prio=Prio or 50 - + hp.stacks={} for i=hp.angelsmin, hp.angelsmax do local stack={} --#FLIGHTCONTROL.HoldingStack @@ -800,16 +818,16 @@ function FLIGHTCONTROL:AddHoldingPattern(ArrivalZone, Heading, Length, Flightlev stack.heading=Heading table.insert(hp.stacks, stack) end - + -- Add to table. table.insert(self.holdingpatterns, hp) - -- Sort holding patterns wrt to prio. + -- Sort holding patterns wrt to prio. local function _sort(a,b) return a.prio0 then -- Debug info. local text=string.format("Still got %d messages in the radio queue. Will call status again in %.1f sec", #self.msrsqueue, Tqueue) - self:I(self.lid..text) - + self:T(self.lid..text) + -- Call status again in dt seconds. self:__StatusUpdate(-Tqueue) -- Deny transition. - return false + return false end return true @@ -1100,10 +1118,10 @@ function FLIGHTCONTROL:onafterStatusUpdate() -- Debug message. self:T2(self.lid.."Status update") - + -- Check markers of holding patterns. self:_CheckMarkHoldingPatterns() - + -- Check if runway was repaired. if self:IsRunwayOperational()==false then local Trepair=self:GetRunwayRepairtime() @@ -1111,21 +1129,21 @@ function FLIGHTCONTROL:onafterStatusUpdate() if Trepair==0 then self:RunwayRepaired() end - end + end -- Check status of all registered flights. self:_CheckFlights() - + -- Check parking spots. --self:_CheckParking() - + -- Check waiting and landing queue. self:_CheckQueues() - + -- Get runway. local rwyLanding=self:GetActiveRunwayText() local rwyTakeoff=self:GetActiveRunwayText(true) - + -- Count flights. local Nflights= self:CountFlights() local NQparking=self:CountFlights(FLIGHTCONTROL.FlightStatus.PARKING) @@ -1148,32 +1166,32 @@ function FLIGHTCONTROL:onafterStatusUpdate() local Nfree=self:CountParking(AIRBASE.SpotStatus.FREE) local Noccu=self:CountParking(AIRBASE.SpotStatus.OCCUPIED) local Nresv=self:CountParking(AIRBASE.SpotStatus.RESERVED) - + if Nfree+Noccu+Nresv~=self.Nparkingspots then self:E(self.lid..string.format("WARNING: Number of parking spots does not match! Nfree=%d, Noccu=%d, Nreserved=%d != %d total", Nfree, Noccu, Nresv, self.Nparkingspots)) end -- Info text. if self.verbose>=1 then - local text=string.format("State %s - Runway Landing=%s, Takeoff=%s - Parking F=%d/O=%d/R=%d of %d - Flights=%s: Qpark=%d Qtxout=%d Qready=%d Qto=%d | Qinbound=%d Qhold=%d Qland=%d Qtxinb=%d Qarr=%d", + local text=string.format("State %s - Runway Landing=%s, Takeoff=%s - Parking F=%d/O=%d/R=%d of %d - Flights=%s: Qpark=%d Qtxout=%d Qready=%d Qto=%d | Qinbound=%d Qhold=%d Qland=%d Qtxinb=%d Qarr=%d", self:GetState(), rwyLanding, rwyTakeoff, Nfree, Noccu, Nresv, self.Nparkingspots, Nflights, NQparking, NQtaxiout, NQreadyto, NQtakeoff, NQinbound, NQholding, NQlanding, NQtaxiinb, NQarrived) self:I(self.lid..text) end - + if Nflights==Nqueues then --Check! else self:E(string.format("WARNING: Number of total flights %d!=%d number of flights in all queues!", Nflights, Nqueues)) end - + if self.verbose>=2 then local text="Holding Patterns:" for i,_pattern in pairs(self.holdingpatterns) do local pattern=_pattern --#FLIGHTCONTROL.HoldingPattern - + -- Pattern info. text=text..string.format("\n[%d] Pattern %s [Prio=%d, UID=%d]: Stacks=%d, Angels %d - %d", i, pattern.name, pattern.prio, pattern.uid, #pattern.stacks, pattern.angelsmin, pattern.angelsmax) - + if self.verbose>=4 then -- Explicit stack info. for _,_stack in pairs(pattern.stacks) do @@ -1212,40 +1230,40 @@ end -- @param Core.Event#EVENTDATA EventData function FLIGHTCONTROL:OnEventBirth(EventData) self:F3({EvendData=EventData}) - + if EventData and EventData.IniGroupName and EventData.IniUnit then - + self:T3(self.lid..string.format("BIRTH: unit = %s", tostring(EventData.IniUnitName))) self:T3(self.lid..string.format("BIRTH: group = %s", tostring(EventData.IniGroupName))) -- Unit that was born. - local unit=EventData.IniUnit - + local unit=EventData.IniUnit + -- We delay this, to have all elements of the group in the game. if unit:IsAir() then - + local bornhere=EventData.Place and EventData.Place:GetName()==self.airbasename or false --env.info("FF born here ".. tostring(bornhere)) - + -- We got a player? local playerunit, playername=self:_GetPlayerUnitAndName(EventData.IniUnitName) - + if playername or bornhere then - + -- Create player menu. self:ScheduleOnce(0.5, self._CreateFlightGroup, self, EventData.IniGroup) - + end - + -- Spawn parking guard. if bornhere then self:SpawnParkingGuard(unit) end end - + end - + end --- Event handling function. @@ -1258,12 +1276,12 @@ function FLIGHTCONTROL:OnEventCrashOrDead(EventData) -- Check if out runway was destroyed. if EventData.IniUnitName then if self.airbase and self.airbasename and self.airbasename==EventData.IniUnitName then - self:RunwayDestroyed() + self:RunwayDestroyed() end end - + end - + end --- Event handler for event land. @@ -1271,10 +1289,10 @@ end -- @param Core.Event#EVENTDATA EventData function FLIGHTCONTROL:OnEventLand(EventData) self:F3({EvendData=EventData}) - + self:T2(self.lid..string.format("LAND: unit = %s", tostring(EventData.IniUnitName))) self:T3(self.lid..string.format("LAND: group = %s", tostring(EventData.IniGroupName))) - + end --- Event handler for event takeoff. @@ -1282,22 +1300,22 @@ end -- @param Core.Event#EVENTDATA EventData function FLIGHTCONTROL:OnEventTakeoff(EventData) self:F3({EvendData=EventData}) - + self:T2(self.lid..string.format("TAKEOFF: unit = %s", tostring(EventData.IniUnitName))) self:T3(self.lid..string.format("TAKEOFF: group = %s", tostring(EventData.IniGroupName))) - + -- This would be the closest airbase. local airbase=EventData.Place - + -- Unit that took off. local unit=EventData.IniUnit - + -- Nil check for airbase. Crashed as player gave me no airbase. if not (airbase or unit) then self:E(self.lid.."WARNING: Airbase or IniUnit is nil in takeoff event!") return end - + end --- Event handler for event engine startup. @@ -1305,10 +1323,10 @@ end -- @param Core.Event#EVENTDATA EventData function FLIGHTCONTROL:OnEventEngineStartup(EventData) self:F3({EvendData=EventData}) - + self:T2(self.lid..string.format("ENGINESTARTUP: unit = %s", tostring(EventData.IniUnitName))) self:T3(self.lid..string.format("ENGINESTARTUP: group = %s", tostring(EventData.IniGroupName))) - + end --- Event handler for event engine shutdown. @@ -1316,10 +1334,10 @@ end -- @param Core.Event#EVENTDATA EventData function FLIGHTCONTROL:OnEventEngineShutdown(EventData) self:F3({EvendData=EventData}) - + self:T2(self.lid..string.format("ENGINESHUTDOWN: unit = %s", tostring(EventData.IniUnitName))) self:T3(self.lid..string.format("ENGINESHUTDOWN: group = %s", tostring(EventData.IniGroupName))) - + end --- Event handler for event kill. @@ -1327,23 +1345,23 @@ end -- @param Core.Event#EVENTDATA EventData function FLIGHTCONTROL:OnEventKill(EventData) self:F3({EvendData=EventData}) - + -- Debug info. self:T2(self.lid..string.format("KILL: ini unit = %s", tostring(EventData.IniUnitName))) self:T3(self.lid..string.format("KILL: ini group = %s", tostring(EventData.IniGroupName))) self:T2(self.lid..string.format("KILL: tgt unit = %s", tostring(EventData.TgtUnitName))) self:T3(self.lid..string.format("KILL: tgt group = %s", tostring(EventData.TgtGroupName))) - + -- Parking guard name prefix. local guardPrefix=string.format("Parking Guard %s", self.airbasename) - + local victimName=EventData.IniUnitName local killerName=EventData.TgtUnitName - + if victimName and victimName:find(guardPrefix) then - + env.info(string.format("Parking guard %s killed!", victimName)) - + for _,_flight in pairs(self.flights) do local flight=_flight --Ops.FlightGroup#FLIGHTGROUP local element=flight:GetElementByName(killerName) @@ -1352,9 +1370,9 @@ function FLIGHTCONTROL:OnEventKill(EventData) return end end - + end - + end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -1373,9 +1391,9 @@ function FLIGHTCONTROL:onafterRunwayDestroyed(From, Event, To) -- Set time stamp. self.runwaydestroyed=timer.getAbsTime() - + self:TransmissionTower("All flights, our runway was destroyed. All operations are suspended for one hour.",Flight,Delay) - + end --- On after "RunwayRepaired" event. @@ -1408,18 +1426,18 @@ function FLIGHTCONTROL:_CheckQueues() -- Get next flight in line: either holding or parking. local flight, isholding, parking=self:_GetNextFlight() - + -- Check if somebody wants something. if flight then - + if isholding then -------------- -- Arrivals -- -------------- - -- No other flight is taking off and number of landing flights is below threshold. + -- No other flight is taking off and number of landing flights is below threshold. if self:_CheckFlightLanding(flight) then -- Get interval to last flight that got landing clearance. @@ -1427,144 +1445,144 @@ function FLIGHTCONTROL:_CheckQueues() if self.Tlanding then dTlanding=timer.getAbsTime()-self.Tlanding end - + -- Check if parking is available and timely spacing okay. if parking and dTlanding>=self.dTlanding then - + -- Get callsign. local callsign=self:_GetCallsignName(flight) - + -- Runway. local runway=self:GetActiveRunwayText() - + -- Message. local text=string.format("%s, %s, you are cleared to land, runway %s", callsign, self.alias, runway) - + -- Transmit message. self:TransmissionTower(text, flight) - + -- Give AI the landing signal. if flight.isAI then - + -- Readback instructions. local text=string.format("Runway %s, cleared to land, %s", runway, callsign) - + -- Transmit message. self:TransmissionPilot(text, flight, 10) - - -- Land AI. + + -- Land AI. self:_LandAI(flight, parking) - + --TODO: Why do I not set the status to LANDING for AI? else - + -- We set this flight to landing. With this he is allowed to leave the pattern. self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.LANDING) - + end - - -- Set time last flight got landing clearance. + + -- Set time last flight got landing clearance. self.Tlanding=timer.getAbsTime() - + end else self:T3(self.lid..string.format("FYI: Landing clearance for flight %s denied", flight.groupname)) end - + else - + ---------------- -- Departures -- ---------------- - + -- No other flight is taking off or landing. if self:_CheckFlightTakeoff(flight) then - + -- Get callsign. local callsign=self:_GetCallsignName(flight) - + -- Runway text. local runway=self:GetActiveRunwayText(true) - + -- Runway for take-off. local rwy=self:GetActiveRunwayTakeoff() - + local coord=flight:GetCoordinate() - + if self:GetFlightStatus(flight)==FLIGHTCONTROL.FlightStatus.READYTO then - + --- -- Ready for TAKEOFF --- - + local text=string.format("%s, %s, cleared for take-off, runway %s", callsign, self.alias, runway) -- Player is ready for takeoff self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.TAKEOFF) - + else - + --- -- Ready to TAXI --- - + -- Message. local text=string.format("%s, %s, taxi to runway %s", callsign, self.alias, runway) - + -- Get taxi ways if they have been specified by the mission designer. local taxipath, taxiways=self.airbase:FindTaxiwaysFromAtoB(coord, rwy.position) - + if taxipath then - + taxipath:Draw(true) - + -- Get taxi way text. local taxiroute=self:_GetTaxiwayText(taxipath, false) - + text=text.." via "..taxiroute end - + -- Hold short instructions. - -- TODO: Does this need to be said? + -- TODO: Does this need to be said? text=text..string.format(", hold short of runway %s.", runway) - + -- Set taxiway to flight so he can read back. flight.taxipath=taxipath - + -- Transmit message. self:TransmissionTower(text, flight) - + -- Check if flight is AI. Humans have to request taxi via F10 menu. if flight.isAI then - + --- -- AI --- - + -- Read back runway. local text=string.format("Runway %s", runway) - + -- Read back taxi ways (if available). if flight.taxipath then text=text..string.format(" via %s", self:_GetTaxiwayText(flight.taxipath)) end - + -- Start uncontrolled aircraft. if flight:IsUncontrolled() then - + -- Message. text=text..string.format(", starting engines") - - -- Start uncontrolled aircraft. + + -- Start uncontrolled aircraft. flight:StartUncontrolled() end - + -- Append call sign. text=text..string.format(", %s.", callsign) - + -- Transmit message. self:TransmissionPilot(text, flight, 10) - + -- Remove parking guards. for _,_element in pairs(flight.elements) do local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element @@ -1573,18 +1591,18 @@ function FLIGHTCONTROL:_CheckQueues() self:RemoveParkingGuard(spot) end end - + -- Set flight to takeoff. No way we can stop the AI now. -- TODO: To improve this, we would need to monitor if the AI gets to the holding position or on the runway. -- Probably need some holding guard similar to the parking guard. self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.TAKEOFF) - + else - + --- -- PLAYER --- - + -- Remove parking guards. for _,_element in pairs(flight.elements) do local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element @@ -1595,13 +1613,13 @@ function FLIGHTCONTROL:_CheckQueues() else self:RemoveParkingGuard(spot, 10) end - end + end end - + end --AI/PLAYER - + end - + else -- Debug message. self:T3(self.lid..string.format("FYI: Take off for flight %s denied", flight.groupname)) @@ -1611,7 +1629,7 @@ function FLIGHTCONTROL:_CheckQueues() -- Debug message. self:T2(self.lid..string.format("FYI: No flight in queue for takeoff or landing")) end - + end --- Check if a flight can get clearance for taxi/takeoff. @@ -1622,23 +1640,23 @@ function FLIGHTCONTROL:_CheckFlightTakeoff(flight) -- Number of groups landing. local nlanding=self:CountFlights(FLIGHTCONTROL.FlightStatus.LANDING) - + -- Number of groups taking off. local ntakeoff=self:CountFlights(FLIGHTCONTROL.FlightStatus.TAKEOFF, nil, true) - + -- Current status. local status=self:GetFlightStatus(flight) - + if flight.isAI then --- -- AI --- - + if nlanding>self.NtaxiLanding then self:T(self.lid..string.format("AI flight %s [status=%s] NOT cleared for taxi/takeoff as %d>%d flight(s) landing", flight.groupname, status, nlanding, self.NtaxiLanding)) return false end - + local ninbound=0 if self.NtaxiInbound then ninbound=self:CountFlights(FLIGHTCONTROL.FlightStatus.TAXIINB, nil, true) @@ -1648,31 +1666,31 @@ function FLIGHTCONTROL:_CheckFlightTakeoff(flight) self:T(self.lid..string.format("AI flight %s [status=%s] NOT cleared for taxi/takeoff as %d>=%d flight(s) taxi/takeoff", flight.groupname, status, ntakeoff, self.NtaxiTot)) return false end - + self:T(self.lid..string.format("AI flight %s [status=%s] cleared for taxi/takeoff! nLanding=%d, nTakeoff=%d", flight.groupname, status, nlanding, ntakeoff)) return true else --- -- Player - -- + -- -- We allow unlimited number of players to taxi to runway. -- We do not allow takeoff if at least one flight is landing. --- - + if status==FLIGHTCONTROL.FlightStatus.READYTO then - + if nlanding>self.NtaxiLanding then -- Traffic landing. No permission to self:T(self.lid..string.format("Player flight %s [status=%s] not cleared for taxi/takeoff as %d>%d flight(s) landing", flight.groupname, status, nlanding, self.NtaxiLanding)) return false - end - + end + end - + self:T(self.lid..string.format("Player flight %s [status=%s] cleared for taxi/takeoff", flight.groupname, status)) - return true + return true end - + end @@ -1687,10 +1705,10 @@ function FLIGHTCONTROL:_CheckFlightLanding(flight) -- Number of groups taking off. local ntakeoff=self:CountFlights(FLIGHTCONTROL.FlightStatus.TAKEOFF, nil, true) - + -- Current status. local status=self:GetFlightStatus(flight) - + if flight.isAi then --- -- AI @@ -1711,9 +1729,9 @@ function FLIGHTCONTROL:_CheckFlightLanding(flight) return true end - return false + return false end - + end --- Get next flight in line, either waiting for landing or waiting for takeoff. @@ -1725,22 +1743,22 @@ function FLIGHTCONTROL:_GetNextFlight() -- Get flight that is holding. local flightholding=self:_GetNextFightHolding() - + -- Get flight that is parking. local flightparking=self:_GetNextFightParking() - + -- If no flight is waiting for landing just return the takeoff flight or nil. if not flightholding then --self:T(self.lid..string.format("Next flight that is not holding")) return flightparking, false, nil end - + -- Get number of alive elements of the holding flight. - local nH=flightholding:GetNelements() - + local nH=flightholding:GetNelements() + -- Free parking spots. - local parking=flightholding:GetParking(self.airbase) - + local parking=flightholding:GetParking(self.airbase) + -- If no flight is waiting for takeoff return the holding flight or nil. if not flightparking then if parking then @@ -1750,13 +1768,13 @@ function FLIGHTCONTROL:_GetNextFlight() return nil, nil, nil end end - + -- We got flights waiting for landing and for takeoff. if flightholding and flightparking then - + local text=string.format("We got a flight holding %s [%s] and parking %s [%s]", flightholding:GetName(), flightholding:GetState(), flightparking:GetName(), flightparking:GetState()) self:T(self.lid..text) - + -- Return holding flight if fuel is low. if flightholding.fuellow then if parking then @@ -1767,17 +1785,17 @@ function FLIGHTCONTROL:_GetNextFlight() return flightparking, false, nil end end - + local text=string.format("Flight holding for %d sec, flight parking for %d sec", flightholding:GetHoldingTime(), flightparking:GetParkingTime()) self:T(self.lid..text) - + -- Return the flight which is waiting longer. NOTE that Tholding and Tparking are abs. mission time. So a smaller value means waiting longer. if flightholding.Tholding and flightparking.Tparking and flightholding.TholdingTholdingMin then return fg end - + return nil end @@ -1865,7 +1883,7 @@ end function FLIGHTCONTROL:_GetNextFightParking() -- Return only AI or human player flights. - local OnlyAI=nil + local OnlyAI=nil if self:IsRunwayDestroyed() then OnlyAI=false -- If false, we return only player flights. end @@ -1874,11 +1892,11 @@ function FLIGHTCONTROL:_GetNextFightParking() local QreadyTO=self:GetFlights(FLIGHTCONTROL.FlightStatus.READYTO, OPSGROUP.GroupStatus.TAXIING, OnlyAI) -- First check human players. - if #QreadyTO>0 then + if #QreadyTO>0 then -- First come, first serve. return QreadyTO[1] end - + -- Get flights ready to taxi. local QreadyTX=self:GetFlights(FLIGHTCONTROL.FlightStatus.READYTX, OPSGROUP.GroupStatus.PARKING, OnlyAI) @@ -1887,16 +1905,16 @@ function FLIGHTCONTROL:_GetNextFightParking() -- First come, first serve. return QreadyTX[1] end - + -- Check if runway is destroyed. if self:IsRunwayDestroyed() then -- Runway destroyed. As we only look for AI later on, we return nil here. return nil end - + -- Get AI flights parking. local Qparking=self:GetFlights(FLIGHTCONTROL.FlightStatus.PARKING, nil, true) - + -- Number of flights parking. local Nparking=#Qparking @@ -1914,7 +1932,7 @@ function FLIGHTCONTROL:_GetNextFightParking() -- Return flight waiting longest. table.sort(Qparking, _sortByTparking) - + -- Debug. if self.verbose>=2 then local text="Parking flights:" @@ -1932,7 +1950,7 @@ function FLIGHTCONTROL:_GetNextFightParking() return flight end end - + return nil end @@ -1948,22 +1966,22 @@ function FLIGHTCONTROL:_PrintQueue(queue, name) -- Queue is empty. text=text.." empty." else - + local time=timer.getAbsTime() - + -- Loop over all flights in queue. for i,_flight in ipairs(queue) do local flight=_flight --Ops.FlightGroup#FLIGHTGROUP - + -- Gather info. local fuel=flight.group:GetFuelMin()*100 local ai=tostring(flight.isAI) local actype=tostring(flight.actype) - + -- Holding and parking time. local holding=flight.Tholding and UTILS.SecondsToClock(time-flight.Tholding, true) or "X" local parking=flight.Tparking and UTILS.SecondsToClock(time-flight.Tparking, true) or "X" - + local holding=flight:GetHoldingTime() if holding>=0 then holding=UTILS.SecondsToClock(holding, true) @@ -1975,20 +1993,20 @@ function FLIGHTCONTROL:_PrintQueue(queue, name) parking=UTILS.SecondsToClock(parking, true) else parking="X" - end - + end + -- Number of elements. local nunits=flight:CountElements() - + -- Status. local state=flight:GetState() local status=self:GetFlightStatus(flight) - + -- Main info. text=text..string.format("\n[%d] %s (%s*%d): status=%s | %s, ai=%s, fuel=%d, holding=%s, parking=%s", i, flight.groupname, actype, nunits, state, status, ai, fuel, holding, parking) - -- Elements info. + -- Elements info. for j,_element in pairs(flight.elements) do local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element local life=element.unit:GetLife() @@ -1999,10 +2017,10 @@ function FLIGHTCONTROL:_PrintQueue(queue, name) end end end - + -- Display text. self:I(self.lid..text) - + return text end @@ -2011,16 +2029,16 @@ end -- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group. -- @param #string status New status. function FLIGHTCONTROL:SetFlightStatus(flight, status) - + -- Debug message. self:T(self.lid..string.format("New status %s-->%s for flight %s", flight.controlstatus or "unknown", status, flight:GetName())) - + -- Update menu when flight status changed. if flight.controlstatus~=status and not flight.isAI then self:T(self.lid.."Updating menu in 0.2 sec after flight status change") flight:_UpdateMenu(0.2) end - + -- Set new status flight.controlstatus=status @@ -2035,14 +2053,14 @@ function FLIGHTCONTROL:GetFlightStatus(flight) if flight then return flight.controlstatus or "unkonwn" end - + return "unknown" end --- Check if FC has control over this flight. -- @param #FLIGHTCONTROL self -- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group. --- @return #boolean +-- @return #boolean function FLIGHTCONTROL:IsControlling(flight) -- Check that we are controlling this flight. @@ -2058,14 +2076,14 @@ end -- @return #boolean If true, group is in the queue. False otherwise. function FLIGHTCONTROL:_InQueue(queue, group) local name=group:GetName() - + for _,_flight in pairs(queue) do local flight=_flight --Ops.FlightGroup#FLIGHTGROUP if name==flight.groupname then return true end end - + return false end @@ -2078,14 +2096,14 @@ end function FLIGHTCONTROL:GetFlights(Status, GroupStatus, AI) if Status~=nil or GroupStatus~=nil or AI~=nil then - + local flights={} - + for _,_flight in pairs(self.flights) do local flight=_flight --Ops.FlightGroup#FLIGHTGROUP - + local status=self:GetFlightStatus(flight, Status) - + if status==Status then if AI==nil or AI==flight.isAI then if GroupStatus==nil or GroupStatus==flight:GetState() then @@ -2093,9 +2111,9 @@ function FLIGHTCONTROL:GetFlights(Status, GroupStatus, AI) end end end - + end - + return flights else return self.flights @@ -2110,17 +2128,17 @@ end -- @param #boolean AI If `true` only AI flights are counted. If `false`, only flights with clients are counted. If `nil` (default), all flights are counted. -- @return #number Number of flights. function FLIGHTCONTROL:CountFlights(Status, GroupStatus, AI) - + if Status~=nil or GroupStatus~=nil or AI~=nil then - + local flights=self:GetFlights(Status, GroupStatus, AI) - + return #flights - + else return #self.flights end - + end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -2166,7 +2184,7 @@ function FLIGHTCONTROL:GetActiveRunwayText(Takeoff) end local name=self.airbase:GetRunwayName(runway, true) - + return name or "XX" end @@ -2180,66 +2198,66 @@ function FLIGHTCONTROL:_InitParkingSpots() -- Parking spots of airbase. local parkingdata=self.airbase:GetParkingSpotsTable() - + -- Init parking spots table. self.parking={} - + self.Nparkingspots=0 for _,_spot in pairs(parkingdata) do local spot=_spot --Wrapper.Airbase#AIRBASE.ParkingSpot - + -- Mark position. local text=string.format("Parking ID=%d, Terminal=%d: Free=%s, Client=%s, Dist=%.1f", spot.TerminalID, spot.TerminalType, tostring(spot.Free), tostring(spot.ClientName), spot.DistToRwy) self:T3(self.lid..text) -- Add to table. self.parking[spot.TerminalID]=spot - + -- Marker. --spot.Marker=MARKER:New(spot.Coordinate, "Spot"):ReadOnly():ToCoalition(self:GetCoalition()) - + -- Check if spot is initially free or occupied. if spot.Free then - + -- Parking spot is free. self:SetParkingFree(spot) - + else - + -- Scan for the unit sitting here. local unit=spot.Coordinate:FindClosestUnit(20) - - + + if unit then local unitname=unit and unit:GetName() or "unknown" - + local isalive=unit:IsAlive() - + --env.info(string.format("FF parking spot %d is occupied by unit %s alive=%s", spot.TerminalID, unitname, tostring(isalive))) - + if isalive then - + -- Set parking occupied. self:SetParkingOccupied(spot, unitname) - + -- Spawn parking guard. self:SpawnParkingGuard(unit) - - + + local group=unit:GetGroup() FLIGHTGROUP:New(group) - + else - + -- TODO --env.info(string.format("FF parking spot %d is occupied by NOT ALIVE unit %s", spot.TerminalID, unitname)) - + -- Parking spot is free. self:SetParkingFree(spot) - + end - + else self:E(self.lid..string.format("ERROR: Parking spot is NOT FREE but no unit could be found there!")) end @@ -2248,7 +2266,7 @@ function FLIGHTCONTROL:_InitParkingSpots() -- Increase counter self.Nparkingspots=self.Nparkingspots+1 end - + end --- Get parking spot by its Terminal ID. @@ -2268,7 +2286,7 @@ function FLIGHTCONTROL:_UpdateSpotStatus(spot, status, unitname) -- Debug message. self:T2(self.lid..string.format("Updating parking spot %d status: %s --> %s (unit=%s)", spot.TerminalID, tostring(spot.Status), status, tostring(unitname))) - + -- Set new status. spot.Status=status @@ -2281,17 +2299,17 @@ function FLIGHTCONTROL:SetParkingFree(spot) -- Get spot. local spot=self:GetParkingSpotByID(spot.TerminalID) - + -- Update spot status. self:_UpdateSpotStatus(spot, AIRBASE.SpotStatus.FREE, spot.OccupiedBy or spot.ReservedBy) - + -- Not occupied or reserved. spot.OccupiedBy=nil spot.ReservedBy=nil - + -- Remove parking guard. self:RemoveParkingGuard(spot) - + -- Update marker. self:UpdateParkingMarker(spot) @@ -2300,18 +2318,18 @@ end --- Set parking spot to RESERVED and update F10 marker. -- @param #FLIGHTCONTROL self -- @param Wrapper.Airbase#AIRBASE.ParkingSpot spot The parking spot data table. --- @param #string unitname Name of the unit occupying the spot. Default "unknown". +-- @param #string unitname Name of the unit occupying the spot. Default "unknown". function FLIGHTCONTROL:SetParkingReserved(spot, unitname) -- Get spot. local spot=self:GetParkingSpotByID(spot.TerminalID) - + -- Update spot status. self:_UpdateSpotStatus(spot, AIRBASE.SpotStatus.RESERVED, unitname) - + -- Reserved. spot.ReservedBy=unitname or "unknown" - + -- Update marker. self:UpdateParkingMarker(spot) @@ -2328,10 +2346,10 @@ function FLIGHTCONTROL:SetParkingOccupied(spot, unitname) -- Update spot status. self:_UpdateSpotStatus(spot, AIRBASE.SpotStatus.OCCUPIED, unitname) - + -- Occupied. spot.OccupiedBy=unitname or "unknown" - + -- Update marker. self:UpdateParkingMarker(spot) @@ -2346,42 +2364,42 @@ function FLIGHTCONTROL:UpdateParkingMarker(spot) -- Get spot. local spot=self:GetParkingSpotByID(spot.TerminalID) - + -- Only mark OCCUPIED and RESERVED spots. if spot.Status==AIRBASE.SpotStatus.FREE then - + if spot.Marker then spot.Marker:Remove() end - + else - + local text=string.format("Spot %d (type %d): %s", spot.TerminalID, spot.TerminalType, spot.Status:upper()) if spot.OccupiedBy then text=text..string.format("\nOccupied by %s", tostring(spot.OccupiedBy)) end if spot.ReservedBy then text=text..string.format("\nReserved for %s", tostring(spot.ReservedBy)) - end + end if spot.ClientSpot then text=text..string.format("\nClient %s", tostring(spot.ClientName)) end - + if spot.Marker then - + if text~=spot.Marker.text or not spot.Marker.shown then spot.Marker:UpdateText(text) end - + else - + spot.Marker=MARKER:New(spot.Coordinate, text):ToAll() - + end - + end end - + end --- Check if parking spot is free. @@ -2424,13 +2442,13 @@ end -- @return #number Number of free spots. Total if terminal=nil or of the requested terminal type. -- @return #table Table of free parking spots of data type #FLIGHCONTROL.ParkingSpot. function FLIGHTCONTROL:_GetFreeParkingSpots(terminal) - + local freespots={} - + local n=0 for _,_parking in pairs(self.parking) do local parking=_parking --Wrapper.Airbase#AIRBASE.ParkingSpot - + if self:IsParkingFree(parking) then if terminal==nil or terminal==parking.terminal then n=n+1 @@ -2438,7 +2456,7 @@ function FLIGHTCONTROL:_GetFreeParkingSpots(terminal) end end end - + return n,freespots end @@ -2452,26 +2470,26 @@ function FLIGHTCONTROL:GetClosestParkingSpot(Coordinate, TerminalType, Status) local distmin=math.huge local spotmin=nil - + for TerminalID, Spot in pairs(self.parking) do local spot=Spot --Wrapper.Airbase#AIRBASE.ParkingSpot - + --env.info(self.lid..string.format("FF Spot %d: %s", spot.TerminalID, spot.Status)) - + if (Status==nil or Status==spot.Status) and AIRBASE._CheckTerminalType(spot.TerminalType, TerminalType) then - + -- Get distance from coordinate to spot. local dist=Coordinate:Get2DDistance(spot.Coordinate) - + -- Check if distance is smaller. if dist0 then text=text..string.format("\n- Arrived at parking %d", NQarrived) end - + -- Message to flight self:TextMessageToFlight(text, flight, 15, true) - + else self:E(self.lid..string.format("Cannot find flight group %s.", tostring(groupname))) end - + end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -2985,57 +3014,57 @@ function FLIGHTCONTROL:_PlayerRequestInbound(groupname) -- Get flight group. local flight=_DATABASE:GetOpsGroup(groupname) --Ops.FlightGroup#FLIGHTGROUP - + if flight then - + if flight:IsAirborne() then - + -- Call sign. local callsign=self:_GetCallsignName(flight) - + -- Get player element. - local player=flight:GetPlayerElement() - + local player=flight:GetPlayerElement() + -- Pilot calls inbound for landing. local text=string.format("%s, %s, inbound for landing", self.alias, callsign) - + -- Radio message. self:TransmissionPilot(text, flight) - + -- Current player coord. local flightcoord=flight:GetCoordinate(nil, player.name) - + -- Distance from player to airbase. local dist=flightcoord:Get2DDistance(self:GetCoordinate()) - + if dist This means no clearance for landing! - -- + -- --- -- Pilot leaves pattern for landing local text=string.format("%s, %s, leaving pattern for landing.", self.alias, callsign) - + -- Radio message. self:TransmissionPilot(text, flight) -- Message text. local text=string.format("%s, negative! Hold position until you get clearance.", callsign) - + -- Send message. self:TransmissionTower(text, flight, 10) end - + else - + -- Error you are not airborne! local text=string.format("Negative, you must be HOLDING or INBOUND and CONTROLLED by us!") - + -- Send message. self:TextMessageToFlight(text, flight, 10) end - + else self:E(self.lid..string.format("Cannot find flight group %s.", tostring(groupname))) end - + end --- Player aborts landing. @@ -3441,58 +3470,58 @@ function FLIGHTCONTROL:_PlayerAbortLanding(groupname) -- Get flight group. local flight=_DATABASE:GetOpsGroup(groupname) --Ops.FlightGroup#FLIGHTGROUP - + if flight then - + local flightstatus=self:GetFlightStatus(flight) - + if (flight:IsLanding() or flightstatus==FLIGHTCONTROL.FlightStatus.LANDING) and self:IsControlling(flight) then - + -- Call sign. local callsign=self:_GetCallsignName(flight) - + -- Pilot aborts landing. local text=string.format("%s, %s, abort landing", self.alias, callsign) - + -- Radio message. self:TransmissionPilot(text, flight) - + -- Message text. local text=string.format("%s, %s, roger, have a nice day!", callsign, self.alias) - + -- Send message. self:TransmissionTower(text, flight, 10) - + -- Set flight. if flight.stack then flight.stack.flightgroup=nil flight.stack=nil end - + -- Not holding any more. flight.Tholding=nil - + -- Set flight to cruise. flight:Cruise() - + flight.currbase=nil - + -- Remove flight. This also updates the menu. self:_RemoveFlight(flight) - + else - + -- Error you are not airborne! local text=string.format("Negative, you must be LANDING and CONTROLLED by us!") - + -- Send message. self:TextMessageToFlight(text, flight, 10) end - + else self:E(self.lid..string.format("Cannot find flight group %s.", tostring(groupname))) end - + end --- Player request direct approach. @@ -3502,61 +3531,61 @@ function FLIGHTCONTROL:_PlayerRequestDirectLanding(groupname) -- Get flight group. local flight=_DATABASE:GetOpsGroup(groupname) --Ops.FlightGroup#FLIGHTGROUP - + if flight then - + if flight:IsInbound() and self:IsControlling(flight) then - + -- Call sign. local callsign=self:_GetCallsignName(flight) - + -- Number of flights taking off. local nTakeoff=self:CountFlights(FLIGHTCONTROL.FlightStatus.TAKEOFF) - + -- Message. local text=string.format("%s, request direct approach.", callsign) - + -- Transmit message. - self:TransmissionPilot(text, flight) - + self:TransmissionPilot(text, flight) + if nTakeoff>self.NlandingTakeoff then -- Message text. - local text=string.format("%s, negative! We have currently traffic taking off", callsign) - + local text=string.format("%s, negative! We have currently traffic taking off!", callsign) + -- Send message. self:TransmissionTower(text, flight, 10) - + else - + -- Runway. - local runway=self:GetActiveRunwayText() + local runway=self:GetActiveRunwayText() -- Message text. local text=string.format("%s, affirmative, runway %s. Confirm approach!", callsign, runway) - + -- Send message. self:TransmissionTower(text, flight, 10) - + -- Set flight status to landing. self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.LANDING) - + end - + else - + -- Error you are not airborne! local text=string.format("Negative, you must be INBOUND and CONTROLLED by us!") - + -- Send message. self:TextMessageToFlight(text, flight, 10) end - + else self:E(self.lid..string.format("Cannot find flight group %s.", tostring(groupname))) end - + end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -3567,31 +3596,31 @@ end -- @param #FLIGHTCONTROL self -- @param #string groupname Name of the flight group. function FLIGHTCONTROL:_PlayerRequestTaxi(groupname) - + -- Get flight. local flight=_DATABASE:GetOpsGroup(groupname) --Ops.FlightGroup#FLIGHTGROUP - + if flight then - + -- Get callsign. local callsign=self:_GetCallsignName(flight) - + -- Pilot request for taxi. local text=string.format("%s, %s, request taxi to runway.", self.alias, callsign) self:TransmissionPilot(text, flight) - + if flight:IsParking() then - + -- Tell pilot to wait until cleared. local text=string.format("%s, %s, hold position until further notice.", callsign, self.alias) - + self:TransmissionTower(text, flight, 10) - + -- Set flight status to "Ready to Taxi". - self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.READYTX) - + self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.READYTX) + elseif flight:IsTaxiing() then - + -- Runway for takeoff. local runway=self:GetActiveRunwayText(true) @@ -3599,24 +3628,24 @@ function FLIGHTCONTROL:_PlayerRequestTaxi(groupname) local text=string.format("%s, %s, taxi to runway %s, hold short.", callsign, self.alias, runway) self:TransmissionTower(text, flight, 10) - -- Taxi out. + -- Taxi out. self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.TAXIOUT) - + -- Get player element. local playerElement=flight:GetPlayerElement() - + -- Set parking to free. Could be reserved. if playerElement and playerElement.parking then self:SetParkingFree(playerElement.parking) end - + else self:TextMessageToFlight(string.format("Negative, you must be PARKING to request TAXI!"), flight) end - + else self:E(self.lid..string.format("Cannot find flight group %s.", tostring(groupname))) - end + end end @@ -3624,12 +3653,12 @@ end -- @param #FLIGHTCONTROL self -- @param #string groupname Name of the flight group. function FLIGHTCONTROL:_PlayerConfirmTaxi(groupname) - + -- Get flight. local flight=_DATABASE:GetOpsGroup(groupname) --Ops.FlightGroup#FLIGHTGROUP - + if flight then - + -- Get callsign. local callsign=self:_GetCallsignName(flight) @@ -3638,75 +3667,75 @@ function FLIGHTCONTROL:_PlayerConfirmTaxi(groupname) -- Read back runway. local text=string.format("Taxi to runway %s", runway) - + -- Read back taxi ways (if available). if flight.taxipath then text=text..string.format(" via %s", self:_GetTaxiwayText(flight.taxipath)) end - + -- Append call sign. text=text..string.format(", %s.", callsign) - + -- Transmission. self:TransmissionPilot(text, flight) - -- Taxi out. + -- Taxi out. self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.TAXIOUT) - + end - + end --- Player aborts taxi. -- @param #FLIGHTCONTROL self -- @param #string groupname Name of the flight group. function FLIGHTCONTROL:_PlayerAbortTaxi(groupname) - + -- Get flight. local flight=_DATABASE:GetOpsGroup(groupname) --Ops.FlightGroup#FLIGHTGROUP - + if flight then - + -- Get callsign. local callsign=self:_GetCallsignName(flight) - + -- Pilot request for taxi. local text=string.format("%s, %s, cancel my taxi request.", self.alias, callsign) self:TransmissionPilot(text, flight) - + if flight:IsParking() then - + -- Tell pilot remain parking. local text=string.format("%s, %s, roger, remain on your parking position.", callsign, self.alias) self:TransmissionTower(text, flight, 10) - + -- Set flight status to "Parking". self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.PARKING) - + -- Get player element. local playerElement=flight:GetPlayerElement() - + -- Set parking guard. if playerElement then self:SpawnParkingGuard(playerElement.unit) end - + elseif flight:IsTaxiing() then - + -- Tell pilot to return to parking. local text=string.format("%s, %s, roger, return to your parking position.", callsign, self.alias) self:TransmissionTower(text, flight, 10) - + -- Set flight status to "Taxi Inbound". self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.TAXIINB) - + else self:TextMessageToFlight(string.format("Negative, you must be PARKING or TAXIING to abort TAXI!"), flight) end - + else self:E(self.lid..string.format("Cannot find flight group %s.", tostring(groupname))) - end + end end @@ -3718,42 +3747,42 @@ end -- @param #FLIGHTCONTROL self -- @param #string groupname Name of the flight group. function FLIGHTCONTROL:_PlayerRequestTakeoff(groupname) - + local flight=_DATABASE:GetOpsGroup(groupname) --Ops.FlightGroup#FLIGHTGROUP - + if flight then - + if flight:IsTaxiing() then - + -- TODO: Get closest runway local runway=self:GetActiveRunwayTakeoff() - + local runwayName=self:GetActiveRunwayText(true) - + local distToRunway=flight:GetCoordinate():Get2DDistance(runway.position) -- Get callsign. local callsign=self:_GetCallsignName(flight) - + if distToRunway < 100 then - + -- Pilot request for taxi. local text=string.format("%s, %s, ready for departure, runway %s", self.alias, callsign, runwayName) - self:TransmissionPilot(text, flight) - + self:TransmissionPilot(text, flight) + -- Get number of flights landing. local Nlanding=self:CountFlights(FLIGHTCONTROL.FlightStatus.LANDING) - + -- Get number of flights taking off. local Ntakeoff=self:CountFlights(FLIGHTCONTROL.FlightStatus.TAKEOFF) - + -- We only check for landing flights. local text=string.format("%s, %s, ", callsign, self.alias) if Nlanding==0 then - + -- No traffic. text=text.."no current traffic. You are cleared for takeoff." - + -- Set status to "Take off". self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.TAKEOFF) elseif Nlanding>0 then @@ -3762,23 +3791,23 @@ function FLIGHTCONTROL:_PlayerRequestTakeoff(groupname) else text=text..string.format("negative, we got %d flights inbound. Hold position until futher notice.", Nlanding) end - end - + end + -- Message from tower. self:TransmissionTower(text, flight, 10) - + else local text=string.format("%s, you are too far from the active runway. Proceed to runway %s and repeat your request when you are at the holding position", callsign, runwayName) end - + else self:TextMessageToFlight(string.format("Negative, you must request TAXI before you can request TAKEOFF!"), flight) end - + else self:E(self.lid..string.format("Cannot find flight group %s.", tostring(groupname))) end - + end --- Player wants to abort takeoff. @@ -3786,57 +3815,57 @@ end -- @param #string groupname Name of the flight group. function FLIGHTCONTROL:_PlayerAbortTakeoff(groupname) - -- Get flight group. + -- Get flight group. local flight=_DATABASE:GetOpsGroup(groupname) --Ops.FlightGroup#FLIGHTGROUP - + if flight then - -- Flight status. + -- Flight status. local status=self:GetFlightStatus(flight) - -- Check that we are taking off or ready for takeoff. + -- Check that we are taking off or ready for takeoff. if status==FLIGHTCONTROL.FlightStatus.TAKEOFF or status==FLIGHTCONTROL.FlightStatus.READYTO then - + -- Get callsign. local callsign=self:_GetCallsignName(flight) - + -- Pilot request for taxi. local text=string.format("%s, %s, abort takeoff.", self.alias, callsign) - self:TransmissionPilot(text, flight) - + self:TransmissionPilot(text, flight) + -- Set new flight status. if flight:IsParking() then - + text=string.format("%s, %s, affirm, remain on your parking position.", callsign, self.alias) - + self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.PARKING) - + -- Get player element. local playerElement=flight:GetPlayerElement() - + -- Set parking guard. if playerElement then self:SpawnParkingGuard(playerElement.unit) end - + elseif flight:IsTaxiing() then text=string.format("%s, %s, roger, report whether you want to taxi back or takeoff later.", callsign, self.alias) self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.TAXIOUT) else env.info(self.lid.."ERROR") end - + -- Message from tower. self:TransmissionTower(text, flight, 10) - + else self:TextMessageToFlight("Negative, You are NOT in the takeoff queue", flight) end - + else self:E(self.lid..string.format("Cannot find flight group %s.", tostring(groupname))) end - + end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -3850,65 +3879,65 @@ function FLIGHTCONTROL:_PlayerRequestParking(groupname) -- Get flight group. local flight=_DATABASE:GetOpsGroup(groupname) --Ops.FlightGroup#FLIGHTGROUP - + if flight then - + -- Get callsign. local callsign=self:_GetCallsignName(flight) - + -- Get player element. local player=flight:GetPlayerElement() - + -- Set terminal type. local TerminalType=AIRBASE.TerminalType.FighterAircraft if flight.isHelo then TerminalType=AIRBASE.TerminalType.HelicopterUsable - end + end -- Current coordinate. local coord=flight:GetCoordinate(nil, player.name) - -- Get spawn position if any. + -- Get spawn position if any. local spot=self:_GetPlayerSpot(player.name) - + -- Get closest FREE parking spot if player was not spawned here or spot is already taken. - if not spot then + if not spot then spot=self:GetClosestParkingSpot(coord, TerminalType, AIRBASE.SpotStatus.FREE) end - + if spot then - + -- Message text. local text=string.format("%s, your assigned parking position is terminal ID %d.", callsign, spot.TerminalID) - + -- Transmit message. self:TransmissionTower(text, flight) - + -- If player already has a spot. if player.parking then self:SetParkingFree(player.parking) end - + -- Reserve parking for player. player.parking=spot self:SetParkingReserved(spot, player.name) - + -- Update menu ==> Cancel Parking. flight:_UpdateMenu(0.2) - + else - + -- Message text. local text=string.format("%s, no free parking spot available. Try again later.", callsign) - + -- Transmit message. self:TransmissionTower(text, flight) - + end - + else self:E(self.lid..string.format("Cannot find flight group %s.", tostring(groupname))) end - + end --- Player cancels parking spot reservation. @@ -3918,15 +3947,15 @@ function FLIGHTCONTROL:_PlayerCancelParking(groupname) -- Get flight group. local flight=_DATABASE:GetOpsGroup(groupname) --Ops.FlightGroup#FLIGHTGROUP - + if flight then - + -- Get callsign. local callsign=self:_GetCallsignName(flight) - + -- Get player element. local player=flight:GetPlayerElement() - + -- If player already has a spot. if player.parking then self:SetParkingFree(player.parking) @@ -3935,14 +3964,14 @@ function FLIGHTCONTROL:_PlayerCancelParking(groupname) else self:TextMessageToFlight("You did not have a valid parking spot reservation.", flight) end - + -- Update menu ==> Reserve Parking. flight:_UpdateMenu(0.2) - + else self:E(self.lid..string.format("Cannot find flight group %s.", tostring(groupname))) end - + end --- Player arrived at parking position. @@ -3952,15 +3981,15 @@ function FLIGHTCONTROL:_PlayerArrived(groupname) -- Get flight group. local flight=_DATABASE:GetOpsGroup(groupname) --Ops.FlightGroup#FLIGHTGROUP - + if flight then - + -- Player element. local player=flight:GetPlayerElement() -- Get current coordinate. local coord=flight:GetCoordinate(nil, player.name) - + -- Parking spot. local spot=self:_GetPlayerSpot(player.name) --#FLIGHTCONTROL.ParkingSpot if player.parking then @@ -3970,58 +3999,58 @@ function FLIGHTCONTROL:_PlayerArrived(groupname) spot=self:GetClosestParkingSpot(coord) end end - + if spot then - + -- Get callsign. local callsign=self:_GetCallsignName(flight) - + -- Distance to parking spot. local dist=coord:Get2DDistance(spot.Coordinate) - + if dist<12 then - + -- Message text. local text=string.format("%s, %s, arrived at parking position. Terminal ID %d.", self.alias, callsign, spot.TerminalID) - + -- Transmit message. self:TransmissionPilot(text, flight) -- Message text. - local text="" + local text="" if spot.ReservedBy and spot.ReservedBy~=player.name then - + -- Reserved by someone else. text=string.format("%s, this spot is already reserved for %s. Find yourself a different parking position.", callsign, self.alias, spot.ReservedBy) - + else - + -- Okay, have a drink... text=string.format("%s, %s, roger. Enjoy a cool bevarage in the officers' club.", callsign, self.alias) - + -- Set player element to parking. flight:ElementParking(player, spot) - + -- Set flight status to PARKING. self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.PARKING) - + -- Set parking guard. if player then self:SpawnParkingGuard(player.unit) end - - end - + + end + -- Transmit message. self:TransmissionTower(text, flight, 10) - + else - + -- Message text. - local text=string.format("%s, %s, arrived at parking position", self.alias, callsign) - + local text=string.format("%s, %s, arrived at parking position.", self.alias, callsign) + -- Transmit message. self:TransmissionPilot(text, flight) - + local text="" if spot.ReservedBy then if spot.ReservedBy==player.name then @@ -4029,27 +4058,27 @@ function FLIGHTCONTROL:_PlayerArrived(groupname) text=string.format("%s, %s, you are still %d meters away from your reserved parking position at terminal ID %d. Continue taxiing!", callsign, self.alias, dist, spot.TerminalID) else -- Closest spot is reserved by someone else. - --local spotFree=self:GetClosestParkingSpot(coord, nil, AIRBASE.SpotStatus.Free) + --local spotFree=self:GetClosestParkingSpot(coord, nil, AIRBASE.SpotStatus.Free) text=string.format("%s, %s, the closest parking spot is already reserved. Continue taxiing to a free spot!", callsign, self.alias) - end + end else -- Too far from closest spot. text=string.format("%s, %s, you are still %d meters away from the closest parking position. Continue taxiing to a proper spot!", callsign, self.alias, dist) end - + -- Transmit message. - self:TransmissionTower(text, flight, 10) - + self:TransmissionTower(text, flight, 10) + end - + else -- TODO: No spot end - + else self:E(self.lid..string.format("Cannot find flight group %s.", tostring(groupname))) end - + end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -4061,24 +4090,24 @@ end -- @param Wrapper.Group#GROUP group Aircraft group. -- @return Ops.FlightGroup#FLIGHTGROUP Flight group. function FLIGHTCONTROL:_CreateFlightGroup(group) - + -- Check if not already in flights if self:_InQueue(self.flights, group) then self:E(self.lid..string.format("WARNING: Flight group %s does already exist!", group:GetName())) return end - + -- Debug info. self:T(self.lid..string.format("Creating new flight for group %s of aircraft type %s.", group:GetName(), group:GetTypeName())) - + -- Get flightgroup from data base. local flight=_DATABASE:GetOpsGroup(group:GetName()) - + -- If it does not exist yet, create one. if not flight then flight=FLIGHTGROUP:New(group:GetName()) end - + -- Set flightcontrol. if flight.homebase and flight.homebase:GetName()==self.airbasename then flight:SetFlightControl(self) @@ -4091,35 +4120,35 @@ end -- @param #FLIGHTCONTROL self -- @param Ops.FlightGroup#FLIGHTGROUP Flight The flight to be removed. function FLIGHTCONTROL:_RemoveFlight(Flight) - + -- Loop over all flights in group. for i,_flight in pairs(self.flights) do local flight=_flight --Ops.FlightGroup#FLIGHTGROUP - + -- Check for name. if flight.groupname==Flight.groupname then - + -- Debug message. self:T(self.lid..string.format("Removing flight group %s", flight.groupname)) - + -- Remove table entry. table.remove(self.flights, i) - + -- Remove myself. Flight.flightcontrol=nil - + -- Set flight status to unknown. self:SetFlightStatus(Flight, FLIGHTCONTROL.FlightStatus.UNKNOWN) - - return true + + return true end end - + -- Debug message. self:E(self.lid..string.format("WARNING: Could NOT remove flight group %s", Flight.groupname)) end ---- Get flight from group. +--- Get flight from group. -- @param #FLIGHTCONTROL self -- @param Wrapper.Group#GROUP group Group that will be removed from queue. -- @param #table queue The queue from which the group will be removed. @@ -4131,24 +4160,24 @@ function FLIGHTCONTROL:_GetFlightFromGroup(group) -- Group name local name=group:GetName() - + -- Loop over all flight groups in queue for i,_flight in pairs(self.flights) do local flight=_flight --Ops.FlightGroup#FLIGHTGROUP - + if flight.groupname==name then return flight, i end end - - self:T2(self.lid..string.format("WARNING: Flight group %s could not be found in queue.", name)) + + self:T2(self.lid..string.format("WARNING: Flight group %s could not be found in queue.", name)) end - + self:T2(self.lid..string.format("WARNING: Flight group could not be found in queue. Group is nil!")) return nil, nil end ---- Get element of flight from its unit name. +--- Get element of flight from its unit name. -- @param #FLIGHTCONTROL self -- @param #string unitname Name of the unit. -- @return Ops.OpsGroup#OPSGROUP.Element Element of the flight or nil. @@ -4158,29 +4187,29 @@ function FLIGHTCONTROL:_GetFlightElement(unitname) -- Get the unit. local unit=UNIT:FindByName(unitname) - + -- Check if unit exists. if unit then - + -- Get flight element from all flights. local flight=self:_GetFlightFromGroup(unit:GetGroup()) - + -- Check if fight exists. if flight then -- Loop over all elements in flight group. for i,_element in pairs(flight.elements) do local element=_element --Ops.OpsGroup#OPSGROUP.Element - + if element.unit:GetName()==unitname then return element, i, flight end end - + self:T2(self.lid..string.format("WARNING: Flight element %s could not be found in flight group.", unitname, flight.groupname)) end end - + return nil, nil, nil end @@ -4194,11 +4223,11 @@ function FLIGHTCONTROL:_CheckFlights() -- First remove all dead flights. for i=#self.flights,1,-1 do - local flight=self.flights[i] --Ops.FlightGroup#FLIGHTGROUP + local flight=self.flights[i] --Ops.FlightGroup#FLIGHTGROUP if flight:IsDead() then self:T(self.lid..string.format("Removing DEAD flight %s", tostring(flight.groupname))) self:_RemoveFlight(flight) - end + end end -- Loop over all flights. @@ -4207,93 +4236,93 @@ function FLIGHTCONTROL:_CheckFlights() -- Current flight status. local flightstatus=self:GetFlightStatus(flight) - - --- + + --- -- Track flight --- if false then - + for _,_element in pairs(flight.elements) do local element=_element --Ops.OpsGroup#OPSGROUP.Element - + local unit=element.unit - + if unit and unit:IsAlive() then - + local coord=unit:GetCoord() local vec3=coord:GetVec3() - + if vec3 and element.pos then - + local id=UTILS.GetMarkID() - + trigger.action.lineToAll(-1, id, vec3, element.pos, {1,1,1,0.5}, 1) - + end - + if coord then local taxipath, dist, tpcoord, seg=self.airbase:GetClosestTaxiway(coord) - + if taxipath then local text=string.format("Flight %s [%s/%s]: Unit %s close to taxiway %s. Dist=%.1f meters, Segment=%s-%s", flight:GetName(), flight:GetState(), self:GetFlightStatus(flight), element.name, taxipath:GetName(), dist, seg.p1.name, seg.p2.name) - MESSAGE:New(text,10):ToLog() + MESSAGE:New(text,10):ToLog() end - + end - + -- Store last position. element.pos=vec3 - + end - + end - + end - + if not flight.isAI then - + if flightstatus==FLIGHTCONTROL.FlightStatus.PARKING then - + -- Check if still on parking spot! - + elseif flightstatus==FLIGHTCONTROL.FlightStatus.READYTX then - + -- Flight is ready to taxi to the runway: ? - + elseif flightstatus==FLIGHTCONTROL.FlightStatus.TAXIOUT then - + if self.speedLimitTaxi then self:_CheckFlightSpeeding(flight) - end - + end + elseif flightstatus==FLIGHTCONTROL.FlightStatus.READYTO then - + -- Flight is ready for taking-off: ? - + elseif flightstatus==FLIGHTCONTROL.FlightStatus.TAKEOFF then - + -- Flight is taking-off: Check correct runway - + elseif flightstatus==FLIGHTCONTROL.FlightStatus.INBOUND then - + -- Flight is inbound to holding pattern: Nothing to do! - + elseif flightstatus==FLIGHTCONTROL.FlightStatus.HOLDING then --Check altitude and position local stack=flight.stack - + if stack then - + local altitude=stack.angels*1000 - + local alt=UTILS.MetersToFeet(flight:GetAltitude()) - + local diff=alt-altitude - + local callsign=self:_GetCallsignName(flight) - + -- TODO: issue warning and keep track. otherwise this will repeat unncessarily -- TODO: make a good warning structure and save it in the flightgroup or here. -- needs the kind of warning and the time stamp at least @@ -4301,31 +4330,31 @@ function FLIGHTCONTROL:_CheckFlights() -- Check if absolute difference > 300 ft (lower or higher). if math.abs(diff)>300 then - + -- Get last altitude warning. local warningAlt=self:_WarningGetLast(flight, FLIGHTCONTROL.Violation.Altitude) - + -- Check if no warning so far or last warning more than 5 min ago. if warningAlt==nil or timer.getAbsTime()-warningAlt.time>5*60 then - + -- Number of warnings. local N=self:_WarningCount(flight, FLIGHTCONTROL.Violation.Altitude) - + local text=string.format("%s, you are ", callsign) - + if diff<300 then - - -- Get number of warnings issued in the last 30 min. + + -- Get number of warnings issued in the last 30 min. if N==0 then text=text..string.format("too low. Climb to the assigned altitude.") elseif N==1 then text=text..string.format("still too low. Climb to the assigned altitude!") elseif N==2 then - text=text..string.format("still too low. Climb to the assigned altitude immediately!") + text=text..string.format("still too low. Climb to the assigned altitude immediately!") end - + elseif diff>300 then - + if N==0 then text=text..string.format("you are too high. Descent to the assigned altitude!") elseif N==1 then @@ -4333,9 +4362,9 @@ function FLIGHTCONTROL:_CheckFlights() elseif N==2 then text=text..string.format("still too high. Descent to the assigned altitude immediately!") end - + end - + if N==1 then text=text..string.format("This was your second warning for an altitude deviation!") elseif N==2 then @@ -4345,33 +4374,33 @@ function FLIGHTCONTROL:_CheckFlights() else text=nil end - - -- Transmission. + + -- Transmission. if text then self:TransmissionTower(text, flight) end - + -- Issue another warning. self:_WarningIssue(flight, FLIGHTCONTROL.Violation.Altitude) - - end -- No warning or warning more then threshold + + end -- No warning or warning more then threshold end -- Alt diff > 300 ft end -- Stack~=nil - + elseif flightstatus==FLIGHTCONTROL.FlightStatus.LANDING then - + --Talk down if on final - + elseif flightstatus==FLIGHTCONTROL.FlightStatus.TAXIINB then - + if self.speedLimitTaxi then self:_CheckFlightSpeeding(flight) - end - + end + elseif flightstatus==FLIGHTCONTROL.FlightStatus.ARRIVED then - + --Check if still on correct parking spot! - + elseif flightstatus==FLIGHTCONTROL.FlightStatus.UNKNOWN then -- Status Unknown: Nothing to do! else @@ -4389,41 +4418,41 @@ function FLIGHTCONTROL:_CheckFlightSpeeding(flight) -- Get player element. local playerElement=flight:GetPlayerElement() - + if playerElement then - + -- Current speed in m/s. local speed=playerElement.unit:GetVelocityMPS() - + -- Current position. local coord=playerElement.unit:GetCoord() - + -- We do not want to check speed on runways. local onRunway=self:IsCoordinateRunway(coord) - + -- Debug output. self:T(self.lid..string.format("Player %s speed %.1f knots (max=%.1f) onRunway=%s", playerElement.playerName, UTILS.MpsToKnots(speed), UTILS.MpsToKnots(self.speedLimitTaxi), tostring(onRunway))) - + if speed and speed>self.speedLimitTaxi and not onRunway then - + -- Callsign. - local callsign=self:_GetCallsignName(flight) - + local callsign=self:_GetCallsignName(flight) + -- Radio text. local text=string.format("%s, slow down, you are taxiing too fast!", callsign) - + -- Radio message to player. self:TransmissionTower(text, flight) - + -- Get player data. local PlayerData=flight:_GetPlayerData() - + -- Issue warning. local warning=self:_WarningIssue(flight, FLIGHTCONTROL.Violation.Speeding) - - -- Trigger FSM speeding event. + + -- Trigger FSM speeding event. self:PlayerSpeeding(PlayerData) - + end end @@ -4436,7 +4465,7 @@ function FLIGHTCONTROL:_CheckParking() for TerminalID,_spot in pairs(self.parking) do local spot=_spot --Wrapper.Airbase#AIRBASE.ParkingSpot - + if spot.Reserved then if spot.MarkerID then spot.Coordinate:RemoveMark(spot.MarkerID) @@ -4446,20 +4475,20 @@ function FLIGHTCONTROL:_CheckParking() -- First remove all dead flights. for i=1,#self.flights do - local flight=self.flights[i] --Ops.FlightGroup#FLIGHTGROUP + local flight=self.flights[i] --Ops.FlightGroup#FLIGHTGROUP for _,_element in pairs(flight.elements) do local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element if element.parking and element.parking.TerminalID==TerminalID then if spot.MarkerID then - spot.Coordinate:RemoveMark(spot.MarkerID) + spot.Coordinate:RemoveMark(spot.MarkerID) end spot.MarkerID=spot.Coordinate:MarkToCoalition(string.format("Parking spot occupied by %s", tostring(element.name)), self:GetCoalition()) end end - end + end + + end - end - end @@ -4475,54 +4504,54 @@ function FLIGHTCONTROL:_LandAI(flight, parking) -- Debug info. self:T(self.lid..string.format("Landing AI flight %s.", flight.groupname)) - - -- Respawn? + + -- Respawn? local respawn=false - + if respawn then - + -- Get group template. local Template=flight.group:GetTemplate() - + -- TODO: get landing waypoints from flightgroup. - + -- Set route points. Template.route.points=wp - + for i,unit in pairs(Template.units) do local spot=parking[i] --Wrapper.Airbase#AIRBASE.ParkingSpot - + local element=flight:GetElementByName(unit.name) if element then - + -- Set the parking spot at the destination airbase. unit.parking_landing=spot.TerminalID - + local text=string.format("Reserving parking spot %d for unit %s", spot.TerminalID, tostring(unit.name)) self:T(self.lid..text) - + -- Set parking to RESERVED. self:SetParkingReserved(spot, element.name) - + else - env.info("FF error could not get element to assign parking!") + env.info("FF error could not get element to assign parking!") end end - + -- Debug message. self:TextMessageToFlight(string.format("Respawning group %s", flight.groupname), flight) - + --Respawn the group. flight:Respawn(Template) - + else - + -- Give signal to land. flight:ClearToLand() - + end - + end --- Get holding stack. @@ -4533,12 +4562,12 @@ function FLIGHTCONTROL:_GetHoldingStack(flight) -- Debug message. self:T(self.lid..string.format("Getting holding point for flight %s", flight:GetName())) - + for i,_hp in pairs(self.holdingpatterns) do local holdingpattern=_hp --#FLIGHTCONTROL.HoldingPattern - + self:T(self.lid..string.format("Checking holding point %s", holdingpattern.name)) - + for j,_stack in pairs(holdingpattern.stacks) do local stack=_stack --#FLIGHTCONTROL.HoldingStack local name=stack.flightgroup and stack.flightgroup:GetName() or "empty" @@ -4547,7 +4576,7 @@ function FLIGHTCONTROL:_GetHoldingStack(flight) return stack end end - + end return nil @@ -4561,14 +4590,14 @@ end function FLIGHTCONTROL:_CountFlightsInPattern(Pattern) local N=0 - + for _,_stack in pairs(Pattern.stacks) do local stack=_stack --#FLIGHTCONTROL.HoldingStack if stack.flightgroup then N=N+1 end end - + return N end @@ -4584,7 +4613,7 @@ function FLIGHTCONTROL:_FlightOnFinal(flight) -- Message text. local text=string.format("%s, final", callsign) - + -- Transmit message. self:TransmissionPilot(text, flight) @@ -4608,13 +4637,13 @@ function FLIGHTCONTROL:_WarningIssue(Flight, Violation) local name=Flight:GetName() self.warnings[name]=self.warnings[name] or {} - + -- Create a new warning. local warning={} --#FLIGHTCONTROL.Warning warning.flight=Flight warning.type=Violation warning.time=timer.getAbsTime() - + table.insert(self.warnings[name], warning) return warning @@ -4630,7 +4659,7 @@ function FLIGHTCONTROL:_WarningGetLast(Flight, Violation) -- Get flight name. local name=Flight:GetName() - + -- All warnings of flight local warnings=self.warnings[name] or {} @@ -4641,7 +4670,7 @@ function FLIGHTCONTROL:_WarningGetLast(Flight, Violation) return warning end end - + return nil end @@ -4654,10 +4683,10 @@ function FLIGHTCONTROL:_WarningCount(Flight, Violation) -- Get flight name. local name=Flight:GetName() - + -- All warnings of flight local warnings=self.warnings[name] or {} - + -- Init counter. local N=0 @@ -4668,7 +4697,7 @@ function FLIGHTCONTROL:_WarningCount(Flight, Violation) N=N+1 end end - + return N end @@ -4682,7 +4711,7 @@ function FLIGHTCONTROL:_WarningClear(Flight, Violation) -- Get flight name. local name=Flight:GetName() - + -- All warnings of flight local warnings=self.warnings[name] or {} @@ -4709,23 +4738,23 @@ function FLIGHTCONTROL:TransmissionTower(Text, Flight, Delay) -- Spoken text. local text=self:_GetTextForSpeech(Text) - + -- "Subtitle". local subgroups=nil if Flight and not Flight.isAI then local playerData=Flight:_GetPlayerData() - if playerData.subtitles then + if playerData.subtitles and (not self.nosubs) then subgroups=subgroups or {} table.insert(subgroups, Flight.group) end end - - -- New transmission. + + -- New transmission. local transmission=self.msrsqueue:NewTransmission(text, nil, self.msrsTower, nil, 1, subgroups, Text) - + -- Set time stamp. Can be in the future. self.Tlastmessage=timer.getAbsTime() + (Delay or 0) - + -- Debug message. self:T(self.lid..string.format("Radio Tower: %s", Text)) @@ -4741,7 +4770,7 @@ function FLIGHTCONTROL:TransmissionGround(Text, Flight, Delay) -- Spoken text. local text=self:_GetTextForSpeech(Text) - + -- "Subtitle". local subgroups=nil if Flight and not Flight.isAI then @@ -4751,16 +4780,16 @@ function FLIGHTCONTROL:TransmissionGround(Text, Flight, Delay) table.insert(subgroups, Flight.group) end end - + -- Use ground or tower if ground not set up. local msrs=self.msrsGround~=nil and self.msrsGround or self.msrsTower - - -- New transmission. + + -- New transmission. local transmission=self.msrsqueue:NewTransmission(text, nil, msrs, nil, 1, subgroups, Text) - + -- Set time stamp. Can be in the future. self.Tlastmessage=timer.getAbsTime() + (Delay or 0) - + -- Debug message. self:T(self.lid..string.format("Radio Tower: %s", Text)) @@ -4775,36 +4804,36 @@ function FLIGHTCONTROL:TransmissionPilot(Text, Flight, Delay) -- Get player data. local playerData=Flight:_GetPlayerData() - + -- Check if player enabled his "voice". if playerData==nil or playerData.myvoice then -- Spoken text. local text=self:_GetTextForSpeech(Text) - + -- MSRS instance to use. local msrs=self.msrsPilot - + if Flight.useSRS and Flight.msrs then - + -- Pilot radio call using settings of the FLIGHTGROUP. We just overwrite the frequency. msrs=Flight.msrs - + end - + -- "Subtitle". local subgroups=nil if Flight and not Flight.isAI then local playerData=Flight:_GetPlayerData() - if playerData.subtitles then + if playerData.subtitles and (not self.nosubs) then subgroups=subgroups or {} table.insert(subgroups, Flight.group) end - end - + end + -- Add transmission to msrsqueue. self.msrsqueue:NewTransmission(text, nil, msrs, nil, 1, subgroups, Text, nil, self.frequency, self.modulation) - + end -- Set time stamp. @@ -4812,7 +4841,7 @@ function FLIGHTCONTROL:TransmissionPilot(Text, Flight, Delay) -- Debug message. self:T(self.lid..string.format("Radio Pilot: %s", Text)) - + end @@ -4830,15 +4859,15 @@ function FLIGHTCONTROL:TextMessageToFlight(Text, Flight, Duration, Clear, Delay) else if Flight and Flight.group and Flight.group:IsAlive() then - + -- Group ID. local gid=Flight.group:GetID() - + -- Out text. trigger.action.outTextForGroup(gid, self:_CleanText(Text), Duration or 5, Clear) - + end - + end end @@ -4861,13 +4890,13 @@ end -- @param #boolean Short Only return letter, e.g. "A" for "Alpha". -- @return #string Taxiway name, e.g. "Alpha". function FLIGHTCONTROL:_GetTaxiwayName(Name, Short) - + -- Split by blanks. local name=UTILS.Split(Name, " ") - + -- Get last part. local name=name[#name] - + if string.len(name)==1 then -- Taxiway given as "A" if not Short then @@ -4880,7 +4909,7 @@ function FLIGHTCONTROL:_GetTaxiwayName(Name, Short) -- Get only first character. name=string.sub(name, 1, 1) end - end + end return name end @@ -4891,16 +4920,16 @@ end -- @param #boolean short Only short names, e.g. "A" instead of "Alpha". -- @return #string Taxiway names. function FLIGHTCONTROL:_GetTaxiwayText(taxipath, short) - + -- Last taxiway name. local last=self:_GetTaxiwayName(taxipath.points[1].name, short) - + -- Init taxiways. local taxiroute=last - + for i=2,#taxipath.points do local p=taxipath.points[i] --Core.Pathline#PATHLINE.Point - + local name=self:_GetTaxiwayName(p.name, short) if last~=name then @@ -4908,7 +4937,7 @@ function FLIGHTCONTROL:_GetTaxiwayText(taxipath, short) last=name end end - + return taxiroute end @@ -4920,49 +4949,49 @@ end -- @param #FLIGHTCONTROL self -- @param Wrapper.Unit#UNIT unit The aircraft. function FLIGHTCONTROL:SpawnParkingGuard(unit) - + if unit and self.parkingGuard then - + -- Position of the unit. local coordinate=unit:GetCoordinate() -- Parking spot. local spot=self:GetClosestParkingSpot(coordinate) - + if not spot.ParkingGuard then - + -- Current heading of the unit. local heading=unit:GetHeading() - + -- Length of the unit + 3 meters. local size, x, y, z=unit:GetObjectSize() - + -- Debug message. self:T2(self.lid..string.format("Parking guard for %s: heading=%d, distance x=%.1f m", unit:GetName(), heading, x)) - + -- Coordinate for the guard. local Coordinate=coordinate:Translate(0.75*x+3, heading) - + -- Let him face the aircraft. local lookat=heading-180 - + -- Set heading and AI off to save resources. self.parkingGuard:InitHeading(lookat) - + -- Turn AI Off. if self.parkingGuard:IsInstanceOf("SPAWN") then --self.parkingGuard:InitAIOff() end - + -- Group that is spawned. spot.ParkingGuard=self.parkingGuard:SpawnFromCoordinate(Coordinate) - + else self:E(self.lid.."ERROR: Parking Guard already exists!") end - + end - + end --- Remove parking guard. @@ -4974,12 +5003,12 @@ function FLIGHTCONTROL:RemoveParkingGuard(spot, delay) if delay and delay>0 then self:ScheduleOnce(delay, FLIGHTCONTROL.RemoveParkingGuard, self, spot) else - + if spot.ParkingGuard then spot.ParkingGuard:Destroy() spot.ParkingGuard=nil end - + end end @@ -4992,13 +5021,13 @@ function FLIGHTCONTROL:_IsFlightOnRunway(flight) for _,_runway in pairs(self.airbase.runways) do local runway=_runway --Wrapper.Airbase#AIRBASE.Runway - + local inzone=flight:IsInZone(runway.zone) - + if inzone then return runway end - + end return nil @@ -5019,7 +5048,7 @@ function FLIGHTCONTROL:SetCallSignOptions(ShortCallsign,Keepnumber,CallsignTrans end self.Keepnumber = Keepnumber or false self.CallsignTranslations = CallsignTranslations - return self + return self end --- Get callsign name of a given flight. @@ -5029,10 +5058,10 @@ end function FLIGHTCONTROL:_GetCallsignName(flight) local callsign=flight:GetCallsignName(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations) - + --local name=string.match(callsign, "%a+") --local number=string.match(callsign, "%d+") - + return callsign end @@ -5046,22 +5075,22 @@ function FLIGHTCONTROL:_GetTextForSpeech(text) --- Function to space out text. local function space(text) - + local res="" - + for i=1, #text do local char=text:sub(i,i) res=res..char.." " end - + return res end - + -- Space out numbers. local t=text:gsub("(%d+)", space) - + --TODO: 9 to niner. - + return t end @@ -5108,13 +5137,13 @@ function FLIGHTCONTROL:_CheckMarkHoldingPatterns() local Pattern=pattern if self.markPatterns then - + self:_MarkHoldingPattern(Pattern) - + else - + self:_UnMarkHoldingPattern(Pattern) - + end end @@ -5125,32 +5154,32 @@ end -- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL.HoldingPattern Pattern Holding pattern table. function FLIGHTCONTROL:_MarkHoldingPattern(Pattern) - + if not Pattern.markArrow then - Pattern.markArrow=Pattern.pos0:ArrowToAll(Pattern.pos1, nil, {1,0,0}, 1, {1,1,0}, 0.5, 2, true) + Pattern.markArrow=Pattern.pos0:ArrowToAll(Pattern.pos1, nil, {1,0,0}, 1, {1,1,0}, 0.5, 2, true) end - + if not Pattern.markArrival then Pattern.markArrival=Pattern.arrivalzone:DrawZone() end - + end --- Removem markers of holding pattern (if they exist). -- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL.HoldingPattern Pattern Holding pattern table. function FLIGHTCONTROL:_UnMarkHoldingPattern(Pattern) - + if Pattern.markArrow then UTILS.RemoveMark(Pattern.markArrow) - Pattern.markArrow=nil + Pattern.markArrow=nil end if Pattern.markArrival then UTILS.RemoveMark(Pattern.markArrival) - Pattern.markArrival=nil + Pattern.markArrival=nil end - + end --- Add a holding pattern. @@ -5159,13 +5188,13 @@ end function FLIGHTCONTROL:_AddHoldingPatternBackup() local runway=self:GetActiveRunway() - + local heading=runway.heading - + local vec2=self.airbase:GetVec2() - + local Vec2=UTILS.Vec2Translate(vec2, UTILS.NMToMeters(5), heading+90) - + local ArrivalZone=ZONE_RADIUS:New("Arrival Zone", Vec2, 5000) -- Add holding pattern with very low priority. diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 5bb3ea9da..e59a56a52 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -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") diff --git a/Moose Development/Moose/Ops/Legion.lua b/Moose Development/Moose/Ops/Legion.lua index 7405fc02a..0f6535e99 100644 --- a/Moose Development/Moose/Ops/Legion.lua +++ b/Moose Development/Moose/Ops/Legion.lua @@ -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 diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index 135571e8d..da8b452da 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -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 diff --git a/Moose Development/Moose/Ops/PlayerTask.lua b/Moose Development/Moose/Ops/PlayerTask.lua index 15c2581ff..71a680cb4 100644 --- a/Moose Development/Moose/Ops/PlayerTask.lua +++ b/Moose Development/Moose/Ops/PlayerTask.lua @@ -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!" diff --git a/Moose Development/Moose/Ops/RecoveryTanker.lua b/Moose Development/Moose/Ops/RecoveryTanker.lua index 0489ccb3d..a4c00cfea 100644 --- a/Moose Development/Moose/Ops/RecoveryTanker.lua +++ b/Moose Development/Moose/Ops/RecoveryTanker.lua @@ -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) diff --git a/Moose Development/Moose/Ops/RescueHelo.lua b/Moose Development/Moose/Ops/RescueHelo.lua index b341c8a14..65f1e57c5 100644 --- a/Moose Development/Moose/Ops/RescueHelo.lua +++ b/Moose Development/Moose/Ops/RescueHelo.lua @@ -64,8 +64,6 @@ -- -- === -- --- ![Banner Image](..\Presentations\RESCUEHELO\RescueHelo_Main.png) --- -- # Recue Helo -- -- The rescue helo will fly in close formation with another unit, which is typically an aircraft carrier. diff --git a/Moose Development/Moose/Sound/Radio.lua b/Moose Development/Moose/Sound/Radio.lua index 56eb8ddf0..002e6ddaf 100644 --- a/Moose Development/Moose/Sound/Radio.lua +++ b/Moose Development/Moose/Sound/Radio.lua @@ -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} -- diff --git a/Moose Development/Moose/Sound/RadioSpeech.lua b/Moose Development/Moose/Sound/RadioSpeech.lua index 8f18e9d53..008909fcc 100644 --- a/Moose Development/Moose/Sound/RadioSpeech.lua +++ b/Moose Development/Moose/Sound/RadioSpeech.lua @@ -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 = { diff --git a/Moose Development/Moose/Sound/SRS.lua b/Moose Development/Moose/Sound/SRS.lua index 2dde65e80..05def5904 100644 --- a/Moose Development/Moose/Sound/SRS.lua +++ b/Moose Development/Moose/Sound/SRS.lua @@ -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\\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\\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 = "", -- 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 = "", -- 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 diff --git a/Moose Development/Moose/Sound/SoundOutput.lua b/Moose Development/Moose/Sound/SoundOutput.lua index 57ce2f9a4..38a8337fe 100644 --- a/Moose Development/Moose/Sound/SoundOutput.lua +++ b/Moose Development/Moose/Sound/SoundOutput.lua @@ -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) diff --git a/Moose Development/Moose/Tasking/CommandCenter.lua b/Moose Development/Moose/Tasking/CommandCenter.lua index 07a7ab2f4..873279e4a 100644 --- a/Moose Development/Moose/Tasking/CommandCenter.lua +++ b/Moose Development/Moose/Tasking/CommandCenter.lua @@ -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 diff --git a/Moose Development/Moose/Tasking/DetectionManager.lua b/Moose Development/Moose/Tasking/DetectionManager.lua index 3130ed4b1..da560e5d0 100644 --- a/Moose Development/Moose/Tasking/DetectionManager.lua +++ b/Moose Development/Moose/Tasking/DetectionManager.lua @@ -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 diff --git a/Moose Development/Moose/Tasking/Mission.lua b/Moose Development/Moose/Tasking/Mission.lua index ec4085109..1c65725d2 100644 --- a/Moose Development/Moose/Tasking/Mission.lua +++ b/Moose Development/Moose/Tasking/Mission.lua @@ -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", diff --git a/Moose Development/Moose/Tasking/Task.lua b/Moose Development/Moose/Tasking/Task.lua index ad760d83d..21be7dfd8 100644 --- a/Moose Development/Moose/Tasking/Task.lua +++ b/Moose Development/Moose/Tasking/Task.lua @@ -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 ) diff --git a/Moose Development/Moose/Tasking/TaskInfo.lua b/Moose Development/Moose/Tasking/TaskInfo.lua index 2c6ea9487..4007230dc 100644 --- a/Moose Development/Moose/Tasking/TaskInfo.lua +++ b/Moose Development/Moose/Tasking/TaskInfo.lua @@ -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. diff --git a/Moose Development/Moose/Tasking/Task_A2A.lua b/Moose Development/Moose/Tasking/Task_A2A.lua index 97221d63b..a43c79c9f 100644 --- a/Moose Development/Moose/Tasking/Task_A2A.lua +++ b/Moose Development/Moose/Tasking/Task_A2A.lua @@ -35,7 +35,7 @@ do -- TASK_A2A -- * @{#TASK_A2A.SetScoreOnDestroy}(): Set a score when a target in scope of the A2A attack, has been destroyed. -- * @{#TASK_A2A.SetScoreOnSuccess}(): Set a score when all the targets in scope of the A2A attack, have been destroyed. -- * @{#TASK_A2A.SetPenaltyOnFailed}(): Set a penalty when the A2A attack has failed. - -- + -- -- # Developer Note -- -- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE diff --git a/Moose Development/Moose/Tasking/Task_A2A_Dispatcher.lua b/Moose Development/Moose/Tasking/Task_A2A_Dispatcher.lua index 00c760141..9b0f8f5b5 100644 --- a/Moose Development/Moose/Tasking/Task_A2A_Dispatcher.lua +++ b/Moose Development/Moose/Tasking/Task_A2A_Dispatcher.lua @@ -401,7 +401,7 @@ do -- TASK_A2A_DISPATCHER --- Calculates which friendlies are nearby the area -- @param #TASK_A2A_DISPATCHER self -- @param DetectedItem - -- @return #number, Core.CommandCenter#REPORT + -- @return #number, Tasking.CommandCenter#REPORT function TASK_A2A_DISPATCHER:GetFriendliesNearBy( DetectedItem ) local DetectedSet = DetectedItem.Set @@ -444,7 +444,7 @@ do -- TASK_A2A_DISPATCHER --- Calculates which HUMAN friendlies are nearby the area -- @param #TASK_A2A_DISPATCHER self -- @param DetectedItem - -- @return #number, Core.CommandCenter#REPORT + -- @return #number, Tasking.CommandCenter#REPORT function TASK_A2A_DISPATCHER:GetPlayerFriendliesNearBy( DetectedItem ) local DetectedSet = DetectedItem.Set diff --git a/Moose Development/Moose/Tasking/Task_CARGO.lua b/Moose Development/Moose/Tasking/Task_CARGO.lua index 0bb782526..2c6c8ed3d 100644 --- a/Moose Development/Moose/Tasking/Task_CARGO.lua +++ b/Moose Development/Moose/Tasking/Task_CARGO.lua @@ -5,7 +5,7 @@ -- * TASK_CARGO is the **base class** for: -- -- * @{Tasking.Task_Cargo_Transport#TASK_CARGO_TRANSPORT} --- * @{Tasking.Task_CARGO_CSAR#TASK_CARGO_CSAR} +-- * @{Tasking.Task_Cargo_CSAR#TASK_CARGO_CSAR} -- -- -- === @@ -14,7 +14,7 @@ -- -- Test missions can be located on the main GITHUB site. -- --- [FlightControl-Master/MOOSE_MISSIONS/TAD - Task Dispatching/CGO - Cargo Dispatching/](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/TAD%20-%20Task%20Dispatching/CGO%20-%20Cargo%20Dispatching) +-- [FlightControl-Master/MOOSE_MISSIONS/TAD - Task Dispatching/CGO - Cargo Dispatching/](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/TAD%20-%20Task%20Dispatching/CGO%20-%20Cargo%20Task%20Dispatching) -- -- === -- @@ -34,7 +34,7 @@ -- The following TASK_CARGO_ classes are important, as they implement the CONCRETE tasks: -- -- * @{Tasking.Task_Cargo_Transport#TASK_CARGO_TRANSPORT}: Defines a task for a human player to transport a set of cargo between various zones. --- * @{Tasking.Task_CARGO_CSAR#TASK_CARGO_CSAR}: Defines a task for a human player to Search and Rescue wounded pilots. +-- * @{Tasking.Task_Cargo_CSAR#TASK_CARGO_CSAR}: Defines a task for a human player to Search and Rescue wounded pilots. -- -- However! The menu system and basic usage of the TASK_CARGO classes is explained in the @{#TASK_CARGO} class description. -- So please browse further below to understand how to use it from a player perspective! @@ -49,7 +49,7 @@ -- Once the task is assigned to the player and accepted by the player, the player will obtain -- an extra **Cargo (Radio) Menu** that contains the CARGO objects that need to be transported. -- --- Each @{Cargo.Cargo} object has a certain state: +-- Each @{Tasking.Task_CARGO#TASK_CARGO} object has a certain state: -- -- * **UnLoaded**: The cargo is located within the battlefield. It may still need to be transported. -- * **Loaded**: The cargo is loaded within a Carrier. This can be your air unit, or another air unit, or even a vehicle. @@ -298,8 +298,7 @@ -- -- When you are within the range of the deploy zone (can be also a polygon!), a message is communicated by HQ that you have arrived within the zone! -- --- The routing messages are formulated in the coordinate format that is currently active as configured in your settings profile. --- ![Task_Types](../Tasking/Task_Cargo_Settings.JPG) +-- The routing messages are formulated in the coordinate format that is currently active as configured in your settings profile. -- Use the **Settings Menu** to select the coordinate format that you would like to use for location determination. -- -- #### Unboard Cargo. @@ -391,12 +390,12 @@ -- - @{Tasking.Task_CARGO#TASK_CARGO_TRANSPORT}: Documents the specific methods how to handle the cargo transportation tasking from a mission designer perspective. -- - @{Tasking.Task_CARGO#TASK_CARGO_CSAR}: Documents the specific methods how to handle the cargo CSAR tasking from a mission designer perspective. -- - -- - -- # 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** @@ -448,7 +447,7 @@ do -- TASK_CARGO -- -- ## 2.2) Handle TASK_CARGO Events ... -- - -- The TASK_CARGO classes define @{Cargo} transport tasks, + -- The TASK_CARGO classes define Cargo transport tasks, -- based on the tasking capabilities defined in @{Tasking.Task#TASK}. -- -- ### 2.2.1) Boarding events. @@ -515,7 +514,7 @@ do -- TASK_CARGO -- @param #string Event -- @param #string To -- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that Deployed the cargo. You can use this to retrieve the PlayerName etc. - -- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status. + -- @param Cargo.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status. -- @param Core.Zone#ZONE DeployZone The zone where the Cargo got Deployed or UnBoarded. -- @return #boolean @@ -526,7 +525,7 @@ do -- TASK_CARGO -- @param #string Event -- @param #string To -- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that Deployed the cargo. You can use this to retrieve the PlayerName etc. - -- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status. + -- @param Cargo.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status. -- @param Core.Zone#ZONE DeployZone The zone where the Cargo got Deployed or UnBoarded. -- @usage -- @@ -568,7 +567,7 @@ do -- TASK_CARGO -- @param #string Event -- @param #string To -- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that PickedUp the cargo. You can use this to retrieve the PlayerName etc. - -- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status. + -- @param Cargo.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status. -- @return #boolean --- CargoPickedUp Handler OnAfter for TASK_CARGO @@ -578,7 +577,7 @@ do -- TASK_CARGO -- @param #string Event -- @param #string To -- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that PickedUp the cargo. You can use this to retrieve the PlayerName etc. - -- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status. + -- @param Cargo.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status. local Fsm = self:GetUnitProcess() @@ -844,7 +843,7 @@ do -- TASK_CARGO -- @param From -- @param Event -- @param To - -- @param Core.Cargo#CARGO Cargo + -- @param Cargo.Cargo#CARGO Cargo function Fsm:onafterRouteToPickup( TaskUnit, Task, From, Event, To, Cargo ) self:F( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } ) diff --git a/Moose Development/Moose/Tasking/Task_Capture_Dispatcher.lua b/Moose Development/Moose/Tasking/Task_Capture_Dispatcher.lua index 1cf999b8c..be2086a2f 100644 --- a/Moose Development/Moose/Tasking/Task_Capture_Dispatcher.lua +++ b/Moose Development/Moose/Tasking/Task_Capture_Dispatcher.lua @@ -45,12 +45,12 @@ -- * Switch between metric and imperial measurement system. -- * Switch between coordinate formats used in messages: BR, BRA, LL DMS, LL DDM, MGRS. -- * Various other options. - -- - -- # 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** @@ -128,7 +128,7 @@ do -- TASK_CAPTURE_DISPATCHER -- -- ## 2.2. Create a set of player groups. -- - -- What is also needed, is to have a set of @{Core.Group}s defined that contains the clients of the players. + -- What is also needed, is to have a set of @{Wrapper.Group}s defined that contains the clients of the players. -- -- -- Allocate the player slots, which must be aircraft (airplanes or helicopters), that can be manned by players. -- -- We use the method FilterPrefixes to filter those player groups that have client slots, as defined in the mission editor. @@ -245,7 +245,7 @@ do -- TASK_CAPTURE_DISPATCHER -- @param #string TaskPrefix (optional) The prefix of the capture zone task. -- If no TaskPrefix is given, then "Capture" will be used as the TaskPrefix. -- The TaskPrefix will be appended with a . + a number of 3 digits, if the TaskPrefix already exists in the task collection. - -- @param Functional.CaptureZoneCoalition#ZONE_CAPTURE_COALITION CaptureZone The zone of the coalition to be captured as the task goal. + -- @param Functional.ZoneCaptureCoalition#ZONE_CAPTURE_COALITION CaptureZone The zone of the coalition to be captured as the task goal. -- @param #string Briefing The briefing of the task to be shown to the player. -- @return Tasking.Task_Capture_Zone#TASK_CAPTURE_ZONE -- @usage diff --git a/Moose Development/Moose/Tasking/Task_Cargo_CSAR.lua b/Moose Development/Moose/Tasking/Task_Cargo_CSAR.lua index 290ebc7f3..f0c14b227 100644 --- a/Moose Development/Moose/Tasking/Task_Cargo_CSAR.lua +++ b/Moose Development/Moose/Tasking/Task_Cargo_CSAR.lua @@ -52,12 +52,12 @@ -- -- Enjoy! -- FC - -- - -- # 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** @@ -73,7 +73,7 @@ do -- TASK_CARGO_CSAR --- @type TASK_CARGO_CSAR - -- @extends Tasking.Task_Cargo#TASK_CARGO + -- @extends Tasking.Task_CARGO#TASK_CARGO --- Orchestrates the task for players to execute CSAR for downed pilots. -- @@ -137,7 +137,7 @@ do -- TASK_CARGO_CSAR -- -- The cargoset "CargoSet" will embed all defined cargo of type "Pilots" (prefix) into its set. -- local CargoGroup = CARGO_GROUP:New( PilotGroup, "Pilots", "Downed Pilot", 500 ) -- - -- What is also needed, is to have a set of @{Core.Group}s defined that contains the clients of the players. + -- What is also needed, is to have a set of @{Wrapper.Group}s defined that contains the clients of the players. -- -- -- Allocate the Transport, which are the helicopter to retrieve the pilot, that can be manned by players. -- local GroupSet = SET_GROUP:New():FilterPrefixes( "Transport" ):FilterStart() @@ -301,7 +301,7 @@ do -- TASK_CARGO_CSAR -- @param #string Event The Event string. -- @param #string To The To State string. -- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that PickedUp the cargo. You can use this to retrieve the PlayerName etc. - -- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status. + -- @param Cargo.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status. --- OnAfter Transition Handler for Event CargoDeployed. -- @function [parent=#TASK_CARGO_CSAR] OnAfterCargoDeployed @@ -310,7 +310,7 @@ do -- TASK_CARGO_CSAR -- @param #string Event The Event string. -- @param #string To The To State string. -- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that Deployed the cargo. You can use this to retrieve the PlayerName etc. - -- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status. + -- @param Cargo.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status. -- @param Core.Zone#ZONE DeployZone The zone where the Cargo got Deployed or UnBoarded. local Fsm = self:GetUnitProcess() @@ -318,7 +318,7 @@ do -- TASK_CARGO_CSAR local CargoReport = REPORT:New( "Rescue a downed pilot from the following position:") SetCargo:ForEachCargo( - --- @param Core.Cargo#CARGO Cargo + --- @param Cargo.Cargo#CARGO Cargo function( Cargo ) local CargoType = Cargo:GetType() local CargoName = Cargo:GetName() @@ -358,7 +358,7 @@ do -- TASK_CARGO_CSAR -- Loop the CargoSet (so evaluate each Cargo in the SET_CARGO ). for CargoID, CargoData in pairs( Set ) do - local Cargo = CargoData -- Core.Cargo#CARGO + local Cargo = CargoData -- Cargo.Cargo#CARGO self:F( { Cargo = Cargo:GetName(), CargoDeployed = Cargo:IsDeployed() } ) diff --git a/Moose Development/Moose/Tasking/Task_Cargo_Dispatcher.lua b/Moose Development/Moose/Tasking/Task_Cargo_Dispatcher.lua index fd1ed2075..d60318573 100644 --- a/Moose Development/Moose/Tasking/Task_Cargo_Dispatcher.lua +++ b/Moose Development/Moose/Tasking/Task_Cargo_Dispatcher.lua @@ -52,12 +52,12 @@ -- * Switch between coordinate formats used in messages: BR, BRA, LL DMS, LL DDM, MGRS. -- * Different settings modes for A2G and A2A operations. -- * Various other options. - -- - -- # 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** @@ -144,7 +144,7 @@ do -- TASK_CARGO_DISPATCHER -- -- Note that the name of the cargo is "Engineer Team 1". -- local CargoGroup = CARGO_GROUP:New( PilotGroup, "Workmaterials", "Engineer Team 1", 500 ) -- - -- What is also needed, is to have a set of @{Core.Group}s defined that contains the clients of the players. + -- What is also needed, is to have a set of @{Wrapper.Group}s defined that contains the clients of the players. -- -- -- Allocate the Transport, which are the helicopters to retrieve the pilot, that can be manned by players. -- -- The name of these helicopter groups containing one client begins with "Transport", as modelled within the mission editor. @@ -214,7 +214,7 @@ do -- TASK_CARGO_DISPATCHER -- -- The method will create a new CSAR task, and will generate the pilots cargo itself, at the specified coordinate. -- - -- What is first needed, is to have a set of @{Core.Group}s defined that contains the clients of the players. + -- What is first needed, is to have a set of @{Wrapper.Group}s defined that contains the clients of the players. -- -- -- Allocate the Transport, which are the helicopter to retrieve the pilot, that can be manned by players. -- local GroupSet = SET_GROUP:New():FilterPrefixes( "Transport" ):FilterStart() @@ -570,7 +570,7 @@ do -- TASK_CARGO_DISPATCHER -- @param #string CSARTaskPrefix (optional) The prefix of the CSAR task. -- @param Core.Point#COORDINATE CSARCoordinate The coordinate where a downed pilot will be spawned. -- @param #number CSARHeading The heading of the pilot in degrees. - -- @param DCSCountry#Country CSARCountry The country ID of the pilot that will be spawned. + -- @param #DCSCountry CSARCountry The country ID of the pilot that will be spawned. -- @param #string CSARBriefing The briefing of the CSAR task. -- @return #string The CSAR Task Name as a string. The Task Name is the main key and is shown in the task list of the Mission Tasking menu. -- @usage @@ -686,7 +686,7 @@ do -- TASK_CARGO_DISPATCHER -- @param #string TaskPrefix (optional) The prefix of the transport task. -- This prefix will be appended with a . + a number of 3 digits. -- If no TaskPrefix is given, then "Transport" will be used as the prefix. - -- @param Core.SetCargo#SET_CARGO SetCargo The SetCargo to be transported. + -- @param Core.Set#SET_CARGO SetCargo The SetCargo to be transported. -- @param #string Briefing The briefing of the task transport to be shown to the player. -- @param #boolean Silent If true don't send a message that a new task is available. -- @return Tasking.Task_Cargo_Transport#TASK_CARGO_TRANSPORT diff --git a/Moose Development/Moose/Tasking/Task_Cargo_Transport.lua b/Moose Development/Moose/Tasking/Task_Cargo_Transport.lua index bfe066d10..6f8137c6a 100644 --- a/Moose Development/Moose/Tasking/Task_Cargo_Transport.lua +++ b/Moose Development/Moose/Tasking/Task_Cargo_Transport.lua @@ -41,12 +41,12 @@ -- * Switch between coordinate formats used in messages: BR, BRA, LL DMS, LL DDM, MGRS. -- * Different settings modes for A2G and A2A operations. -- * Various other options. - -- - -- # 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 +-- -- === -- -- Please read through the #Tasking.Task_Cargo process to understand the mechanisms of tasking and cargo tasking and handling. @@ -123,7 +123,7 @@ do -- TASK_CARGO_TRANSPORT -- -- The cargoset "CargoSet" will embed all defined cargo of type "Pilots" (prefix) into its set. -- local CargoGroup = CARGO_GROUP:New( PilotGroup, "Cargo", "Engineer Team 1", 500 ) -- - -- What is also needed, is to have a set of Core.Groups defined that contains the clients of the players. + -- What is also needed, is to have a set of @{Wrapper.Group}s defined that contains the clients of the players. -- -- -- Allocate the Transport, which are the helicopter to retrieve the pilot, that can be manned by players. -- local GroupSet = SET_GROUP:New():FilterPrefixes( "Transport" ):FilterStart() diff --git a/Moose Development/Moose/Tasking/Task_Manager.lua b/Moose Development/Moose/Tasking/Task_Manager.lua index 82f3fceac..127b455ad 100644 --- a/Moose Development/Moose/Tasking/Task_Manager.lua +++ b/Moose Development/Moose/Tasking/Task_Manager.lua @@ -23,12 +23,12 @@ -- If an ad-hoc report is requested, use the method @{Tasking.Task_Manager#TASK_MANAGER#ManageTasks}(). -- -- The default task management interval is every 60 seconds. - -- - -- # 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 diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 76a51bc04..28af788ab 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -100,7 +100,10 @@ CALLSIGN={ Texaco=1, Arco=2, Shell=3, - }, + Navy_One=4, + Mauler=5, + Bloodhound=6, + }, -- JTAC JTAC={ Axeman=1, @@ -224,7 +227,7 @@ UTILS = { -- @return #boolean UTILS.IsInstanceOf = function( object, className ) -- Is className NOT a string ? - if not type( className ) == 'string' then + if type( className ) ~= 'string' then -- Is className a Moose class ? if type( className ) == 'table' and className.IsInstanceOf ~= nil then @@ -406,7 +409,7 @@ function UTILS._OneLineSerialize(tbl) elseif type(val) == 'nil' then -- won't ever happen, right? tbl_str[#tbl_str + 1] = 'nil, ' elseif type(val) == 'table' then - --tbl_str[#tbl_str + 1] = UTILS._OneLineSerialize(val) + --tbl_str[#tbl_str + 1] = UTILS.TableShow(tbl,loc,indent,tableshow_tbls) --tbl_str[#tbl_str + 1] = ', ' --I think this is right, I just added it else --log:warn('Unable to serialize value type $1 at index $2', mist.utils.basicSerialize(type(val)), tostring(ind)) @@ -2496,7 +2499,7 @@ function UTILS.CheckFileExists(Path,Filename) -- Check io module is available. if not io then - BASE:E("ERROR: io not desanitized. Can't save current state.") + BASE:E("ERROR: io not desanitized.") return false end diff --git a/Moose Development/Moose/Wrapper/Airbase.lua b/Moose Development/Moose/Wrapper/Airbase.lua index 4cdf88092..e26fe7584 100644 --- a/Moose Development/Moose/Wrapper/Airbase.lua +++ b/Moose Development/Moose/Wrapper/Airbase.lua @@ -62,7 +62,7 @@ -- -- The DCS Airbase APIs are used extensively within MOOSE. The AIRBASE class has for each DCS Airbase API a corresponding method. -- To be able to distinguish easily in your code the difference between a AIRBASE API call and a DCS Airbase API call, --- the first letter of the method is also capitalized. So, by example, the DCS Airbase method @{DCSWrapper.Airbase#Airbase.getName}() +-- the first letter of the method is also capitalized. So, by example, the DCS Airbase method DCSWrapper.Airbase#Airbase.getName() -- is implemented in the AIRBASE class as @{#AIRBASE.GetName}(). -- -- @field #AIRBASE AIRBASE diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 4012528ca..d603a3511 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -62,6 +62,7 @@ -- * @{#CONTROLLABLE.TaskLandAtZone}: (AIR) Land the controllable at a @{Core.Zone#ZONE_RADIUS). -- * @{#CONTROLLABLE.TaskOrbitCircle}: (AIR) Orbit at the current position of the first unit of the controllable at a specified altitude. -- * @{#CONTROLLABLE.TaskOrbitCircleAtVec2}: (AIR) Orbit at a specified position at a specified altitude during a specified duration with a specified speed. +-- * @{#CONTROLLABLE.TaskStrafing}: (AIR) Strafe a point Vec2 with onboard weapons. -- * @{#CONTROLLABLE.TaskRefueling}: (AIR) Refueling from the nearest tanker. No parameters. -- * @{#CONTROLLABLE.TaskRecoveryTanker}: (AIR) Set group to act as recovery tanker for a naval group. -- * @{#CONTROLLABLE.TaskRoute}: (AIR + GROUND) Return a Mission task to follow a given route defined by Points. @@ -98,7 +99,7 @@ -- This method can also be used to **embed a function call when a certain waypoint has been reached**. -- See below the **Tasks at Waypoints** section. -- --- Demonstration Mission: [GRP-502 - Route at waypoint to random point](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/release-2-2-pre/GRP - Group Commands/GRP-502 - Route at waypoint to random point) +-- Demonstration Mission: [GRP-502 - Route at waypoint to random point](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/GRP%20-%20Group%20Commands/GRP-502%20-%20Route%20at%20waypoint%20to%20random%20point) -- -- ## 2.5) Tasks at Waypoints -- @@ -488,7 +489,7 @@ end --- Return a Combo Task taking an array of Tasks. -- @param #CONTROLLABLE self --- @param DCS#TaskArray DCSTasks Array of @{DCSTasking.Task#Task} +-- @param DCS#TaskArray DCSTasks Array of DCSTasking.Task#Task -- @return DCS#Task function CONTROLLABLE:TaskCombo( DCSTasks ) @@ -909,6 +910,30 @@ function CONTROLLABLE:CommandEPLRS( SwitchOnOff, Delay ) return self end +--- Set unlimited fuel. See [DCS command Unlimited Fuel](https://wiki.hoggitworld.com/view/DCS_command_setUnlimitedFuel). +-- @param #CONTROLLABLE self +-- @param #boolean OnOff Set unlimited fuel on = true or off = false. +-- @param #number Delay (Optional) Set the option only after x seconds. +-- @return #CONTROLLABLE self +function CONTROLLABLE:CommandSetUnlimitedFuel(OnOff, Delay) + + local CommandSetFuel = { + id = 'SetUnlimitedFuel', + params = { + value = OnOff + } +} + + if Delay and Delay > 0 then + SCHEDULER:New( nil, self.CommandSetUnlimitedFuel, { self, OnOff }, Delay ) + else + self:SetCommand( CommandSetFuel ) + end + + return self +end + + --- Set radio frequency. See [DCS command EPLRS](https://wiki.hoggitworld.com/view/DCS_command_setFrequency) -- @param #CONTROLLABLE self -- @param #number Frequency Radio frequency in MHz. @@ -1073,6 +1098,42 @@ function CONTROLLABLE:TaskBombing( Vec2, GroupAttack, WeaponExpend, AttackQty, D return DCSTask end +--- (AIR) Strafe the point on the ground. +-- @param #CONTROLLABLE self +-- @param DCS#Vec2 Vec2 2D-coordinates of the point to deliver strafing at. +-- @param #number AttackQty (optional) This parameter limits maximal quantity of attack. The aircraft/controllable will not make more attack than allowed even if the target controllable not destroyed and the aircraft/controllable still have ammo. If not defined the aircraft/controllable will attack target until it will be destroyed or until the aircraft/controllable will run out of ammo. +-- @param #number Length (optional) Length of the strafing area. +-- @param #number WeaponType (optional) The WeaponType. WeaponType is a number associated with a [corresponding weapons flags](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) +-- @param DCS#AI.Task.WeaponExpend WeaponExpend (optional) Determines how much ammunition will be released at each attack. If parameter is not defined the unit / controllable will choose expend on its own discretion, e.g. AI.Task.WeaponExpend.ALL. +-- @param DCS#Azimuth Direction (optional) Desired ingress direction from the target to the attacking aircraft. Controllable/aircraft will make its attacks from the direction. Of course if there is no way to attack from the direction due the terrain controllable/aircraft will choose another direction. +-- @param #boolean GroupAttack (optional) If true, all units in the group will attack the Unit when found. +-- @return DCS#Task The DCS task structure. +-- @usage +-- local attacker = GROUP:FindByName("Aerial-1") +-- local attackVec2 = ZONE:New("Strafe Attack"):GetVec2() +-- -- Attack with any cannons = 805306368, 4 runs, strafe a field of 200 meters +-- local task = attacker:TaskStrafing(attackVec2,4,200,805306368,AI.Task.WeaponExpend.ALL) +-- attacker:SetTask(task,2) +function CONTROLLABLE:TaskStrafing( Vec2, AttackQty, Length, WeaponType, WeaponExpend, Direction, GroupAttack ) + + local DCSTask = { + id = 'Strafing', + params = { + point = Vec2, -- req + weaponType = WeaponType or 1073741822, + expend = WeaponExpend or "Auto", + attackQty = AttackQty or 1, -- req + attackQtyLimit = AttackQty >1 and true or false, + direction = Direction and math.rad(Direction) or 0, + directionEnabled = Direction and true or false, + groupAttack = GroupAttack or false, + length = Length, + } +} + + return DCSTask +end + --- (AIR) Attacking the map object (building, structure, etc). -- @param #CONTROLLABLE self -- @param DCS#Vec2 Vec2 2D-coordinates of the point to deliver weapon at. @@ -1094,7 +1155,6 @@ function CONTROLLABLE:TaskAttackMapObject( Vec2, GroupAttack, WeaponExpend, Atta groupAttack = GroupAttack or false, expend = WeaponExpend or "Auto", attackQtyLimit = AttackQty and true or false, - attackQty = AttackQty, directionEnabled = Direction and true or false, direction = Direction and math.rad(Direction) or 0, altitudeEnabled = Altitude and true or false, @@ -2167,7 +2227,7 @@ do -- Patrol methods -- @return #CONTROLLABLE function CONTROLLABLE:PatrolZones( ZoneList, Speed, Formation, DelayMin, DelayMax ) - if not type( ZoneList ) == "table" then + if type( ZoneList ) ~= "table" then ZoneList = { ZoneList } end @@ -2679,7 +2739,7 @@ do -- Route methods -- @param Core.Zone#ZONE Zone The zone where to route to. -- @param #boolean Randomize Defines whether to target point gets randomized within the Zone. -- @param #number Speed The speed in m/s. Default is 5.555 m/s = 20 km/h. - -- @param Base#FORMATION Formation The formation string. + -- @param Core.Base#FORMATION Formation The formation string. function CONTROLLABLE:TaskRouteToZone( Zone, Randomize, Speed, Formation ) self:F2( Zone ) @@ -2739,7 +2799,7 @@ do -- Route methods -- @param #CONTROLLABLE self -- @param DCS#Vec2 Vec2 The Vec2 where to route to. -- @param #number Speed The speed in m/s. Default is 5.555 m/s = 20 km/h. - -- @param Base#FORMATION Formation The formation string. + -- @param Core.Base#FORMATION Formation The formation string. function CONTROLLABLE:TaskRouteToVec2( Vec2, Speed, Formation ) local DCSControllable = self:GetDCSObject() @@ -5269,3 +5329,54 @@ function CONTROLLABLE:TaskAerobaticsBarrelRoll(TaskAerobatics,Repeats,InitAltitu return TaskAerobatics end + +--- [Air] Make an airplane or helicopter patrol between two points in a racetrack - resulting in a much tighter track around the start and end points. +-- @param #CONTROLLABLE self +-- @param Core.Point#COORDINATE Point1 Start point. +-- @param Core.Point#COORDINATE Point2 End point. +-- @param #number Altitude (Optional) Altitude in meters. Defaults to the altitude of the coordinate. +-- @param #number Speed (Optional) Speed in kph. Defaults to 500 kph. +-- @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). +-- @param #boolean AGL (Optional) If true, set altitude to above ground level (AGL), not above sea level (ASL). +-- @param #number Delay (Optional) Set the task after delay seconds only. +-- @return #CONTROLLABLE self +function CONTROLLABLE:PatrolRaceTrack(Point1, Point2, Altitude, Speed, Formation, AGL, Delay) + + local PatrolGroup = self -- Wrapper.Group#GROUP + + if not self:IsInstanceOf( "GROUP" ) then + PatrolGroup = self:GetGroup() -- Wrapper.Group#GROUP + end + + local delay = Delay or 1 + + self:F( { PatrolGroup = PatrolGroup:GetName() } ) + + if PatrolGroup:IsAir() then + if Formation then + PatrolGroup:SetOption(AI.Option.Air.id.FORMATION,Formation) -- https://wiki.hoggitworld.com/view/DCS_option_formation + end + + local FromCoord = PatrolGroup:GetCoordinate() + local ToCoord = Point1:GetCoordinate() + + -- Calculate the new Route + if Altitude then + local asl = true + if AGL then asl = false end + FromCoord:SetAltitude(Altitude, asl) + ToCoord:SetAltitude(Altitude, asl) + end + + -- Create a "air waypoint", which is a "point" structure that can be given as a parameter to a Task + local Route = {} + Route[#Route + 1] = FromCoord:WaypointAir( AltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed, true, nil, DCSTasks, description, timeReFuAr ) + Route[#Route + 1] = ToCoord:WaypointAir( AltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed, true, nil, DCSTasks, description, timeReFuAr ) + + local TaskRouteToZone = PatrolGroup:TaskFunction( "CONTROLLABLE.PatrolRaceTrack", Point2, Point1, Altitude, Speed, Formation, Delay ) + PatrolGroup:SetTaskWaypoint( Route[#Route], TaskRouteToZone ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone. + PatrolGroup:Route( Route, Delay ) -- Move after delay seconds to the Route. See the Route method for details. + end + + return self +end diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 07a32f676..7d674819b 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -30,7 +30,7 @@ -- -- ### Contributions: -- --- * [**Entropy**](https://forums.eagle.ru/member.php?u=111471), **Afinegan**: Came up with the requirement for AIOnOff(). +-- * **Entropy**, **Afinegan**: Came up with the requirement for AIOnOff(). -- -- === -- @@ -305,6 +305,8 @@ function GROUP:GetDCSObject() if DCSGroup then return DCSGroup + else + env.error("ERROR: Could not get DCS group object!") end return nil @@ -1870,7 +1872,7 @@ function GROUP:InitModex(modex) return self end ---- Respawn the @{Wrapper.Group} at a @{Point}. +--- Respawn the @{Wrapper.Group} at a @{Core.Point}. -- The method will setup the new group template according the Init(Respawn) settings provided for the group. -- These settings can be provided by calling the relevant Init...() methods of the Group. -- diff --git a/Moose Development/Moose/Wrapper/Marker.lua b/Moose Development/Moose/Wrapper/Marker.lua index 4bb7f9c7b..9d138341c 100644 --- a/Moose Development/Moose/Wrapper/Marker.lua +++ b/Moose Development/Moose/Wrapper/Marker.lua @@ -32,8 +32,6 @@ -- -- === -- --- ![Banner Image](..\Presentations\MARKER\Marker_Main.jpg) --- -- # The MARKER Class Idea -- -- The MARKER class simplifies creating, updating and removing of markers on the F10 map. diff --git a/Moose Development/Moose/Wrapper/Positionable.lua b/Moose Development/Moose/Wrapper/Positionable.lua index 57e50c7be..f181cbd23 100644 --- a/Moose Development/Moose/Wrapper/Positionable.lua +++ b/Moose Development/Moose/Wrapper/Positionable.lua @@ -1684,7 +1684,7 @@ do -- Cargo --- Add cargo. -- @param #POSITIONABLE self - -- @param Core.Cargo#CARGO Cargo + -- @param Cargo.Cargo#CARGO Cargo -- @return #POSITIONABLE function POSITIONABLE:AddCargo( Cargo ) self.__.Cargo[Cargo] = Cargo @@ -1700,7 +1700,7 @@ do -- Cargo --- Remove cargo. -- @param #POSITIONABLE self - -- @param Core.Cargo#CARGO Cargo + -- @param Cargo.Cargo#CARGO Cargo -- @return #POSITIONABLE function POSITIONABLE:RemoveCargo( Cargo ) self.__.Cargo[Cargo] = nil @@ -1709,7 +1709,7 @@ do -- Cargo --- Returns if carrier has given cargo. -- @param #POSITIONABLE self - -- @return Core.Cargo#CARGO Cargo + -- @return Cargo.Cargo#CARGO Cargo function POSITIONABLE:HasCargo( Cargo ) return self.__.Cargo[Cargo] end @@ -1733,7 +1733,7 @@ do -- Cargo --- Get cargo item count. -- @param #POSITIONABLE self - -- @return Core.Cargo#CARGO Cargo + -- @return Cargo.Cargo#CARGO Cargo function POSITIONABLE:CargoItemCount() local ItemCount = 0 for CargoName, Cargo in pairs( self.__.Cargo ) do diff --git a/Moose Development/Moose/Wrapper/Storage.lua b/Moose Development/Moose/Wrapper/Storage.lua index be07bb477..4ffc505da 100644 --- a/Moose Development/Moose/Wrapper/Storage.lua +++ b/Moose Development/Moose/Wrapper/Storage.lua @@ -8,7 +8,7 @@ -- -- ## Example Missions: -- --- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Wrapper%20-%20Storage). +-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Wrapper/Storage). -- -- === -- diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index cd6769fc2..0fc411ebd 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -20,8 +20,8 @@ -- @module Wrapper.Unit -- @image Wrapper_Unit.JPG - ---- @type UNIT +--- +-- @type UNIT -- @field #string ClassName Name of the class. -- @field #string UnitName Name of the unit. -- @field #string GroupName Name of the group the unit belongs to. @@ -561,7 +561,7 @@ end --- Check if the unit is a tanker. Also retrieves the refuelling system (boom or probe) if applicable. -- @param #UNIT self --- @return #boolean If true, unit is refuelable (checks for the attribute "Refuelable"). +-- @return #boolean If true, unit is a tanker (checks for the attribute "Tankers"). -- @return #number Refueling system (if any): 0=boom, 1=probe. function UNIT:IsTanker() self:F2( self.UnitName ) @@ -582,7 +582,7 @@ function UNIT:IsTanker() -- Some hard coded data as this is not in the descriptors... if typename=="IL-78M" then system=1 --probe - elseif typename=="KC130" then + elseif typename=="KC130" or typename=="KC130J" then system=1 --probe elseif typename=="KC135BDA" then system=1 --probe @@ -590,6 +590,10 @@ function UNIT:IsTanker() system=1 --probe elseif typename=="S-3B Tanker" then system=1 --probe + elseif typename=="KC_10_Extender" then + system=1 --probe + elseif typename=="KC_10_Extender_D" then + system=0 --boom end end diff --git a/Moose Development/Moose/Wrapper/Weapon.lua b/Moose Development/Moose/Wrapper/Weapon.lua index 3e6e98092..6f56ceb99 100644 --- a/Moose Development/Moose/Wrapper/Weapon.lua +++ b/Moose Development/Moose/Wrapper/Weapon.lua @@ -14,7 +14,7 @@ -- -- ## Example Missions: -- --- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Wrapper%20-%20Weapon). +-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/WRAPPER%20-%20Weapon). -- -- === -- diff --git a/Moose Development/docs-header.html b/Moose Development/docs-header.html new file mode 100644 index 000000000..e559ffff1 --- /dev/null +++ b/Moose Development/docs-header.html @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Moose Development/docs-header.py b/Moose Development/docs-header.py new file mode 100644 index 000000000..72dfc6f28 --- /dev/null +++ b/Moose Development/docs-header.py @@ -0,0 +1,26 @@ +# import required module +from pathlib import Path +import os + +# assign directory +directory = '.' + +print( "Replacing head tag in all html files" ) + +# Read template file +with open( os.path.dirname(__file__) + '/docs-header.html', 'r') as file: + newhead = file.read() + +# iterate over files in +# that directory +files = Path(directory).glob('*.html') +for file in files: + # print(file) + with open(file, 'r') as fileread: + filedata = fileread.read() + # Replace the target string + filedata = filedata.replace( '', newhead ) + + # Write the file out again + with open(file, 'w') as filewrite: + filewrite.write(filedata) diff --git a/Moose Setup/Moose_Create.lua b/Moose Setup/Moose_Create.lua index 4b3e635ec..0bfde46ac 100644 --- a/Moose Setup/Moose_Create.lua +++ b/Moose Setup/Moose_Create.lua @@ -55,6 +55,8 @@ local MooseSourcesFile = assert(io.open( PathConvert(MooseModulesFilePath), "r" local MooseSource = MooseSourcesFile:read("*l") while( MooseSource ) do + -- Remove Windows line endings. Can occur when using act + MooseSource = string.gsub(MooseSource, "\r", "") if MooseSource ~= "" then MooseSource = string.match( MooseSource, "Scripts/Moose/(.+)'" ) diff --git a/README.md b/README.md index aec3cbd3a..7205da476 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build status](https://ci.appveyor.com/api/projects/status/1y8nfmx7lwsn33tt?svg=true)](https://ci.appveyor.com/project/Applevangelist/MOOSE) +[![Moose-Includes](https://github.com/FlightControl-Master/MOOSE/actions/workflows/build-includes.yml/badge.svg?branch=master)](https://github.com/FlightControl-Master/MOOSE/actions/workflows/build-includes.yml) # MOOSE framework diff --git a/docker/build-docs/Dockerfile b/docker/build-docs/Dockerfile new file mode 100644 index 000000000..6fd7007ff --- /dev/null +++ b/docker/build-docs/Dockerfile @@ -0,0 +1,13 @@ +FROM nickblah/lua:5.1.5-luarocks-ubuntu + +RUN apt-get -qq update +RUN apt-get -qq install tree +RUN apt-get -qq install build-essential +RUN apt-get -qq install git +RUN luarocks install markdown 0.32-2 +RUN luarocks install penlight 1.11.0-1 +RUN luarocks install metalua-compiler 0.7.3-1 +RUN luarocks install metalua-parser 0.7.3-2 +RUN luarocks install checks +COPY start.sh /start.sh +RUN chmod +x /start.sh diff --git a/docker/build-docs/docker-compose.yml b/docker/build-docs/docker-compose.yml new file mode 100644 index 000000000..8ca5680e4 --- /dev/null +++ b/docker/build-docs/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3.5" + +services: + lua: + image: moose/build-docs + build: + context: . + dockerfile: Dockerfile + container_name: moose-build-docs + volumes: + - ../../:/moose + stdin_open: true + tty: true + command: /bin/bash -c /start.sh diff --git a/docker/build-docs/start.sh b/docker/build-docs/start.sh new file mode 100644 index 000000000..4773540be --- /dev/null +++ b/docker/build-docs/start.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +# Prepare environment +cd /moose/ +mkdir -p build/tools +mkdir -p build/doc + +# Checkout luadocumentor +cd /moose/build/tools +if [ ! -f /moose/build/tools/luadocumentor/luadocumentor.lua ] +then + git clone --branch patch-1 --single-branch https://github.com/Applevangelist/luadocumentor.git +fi + +# Run luadocumentor +cd /moose/build/tools/luadocumentor +lua luadocumentor.lua -d /moose/build/doc '/moose/Moose Development/Moose' + +# Copy generated files in the MOOSE_DOCS repo if it is already there +if [ -d /moose/build/MOOSE_DOCS/Documentation ]; then + rm -rf /moose/build/MOOSE_DOCS/Documentation + mkdir -p /moose/build/MOOSE_DOCS/Documentation + cp /moose/build/doc/* /moose/build/MOOSE_DOCS/Documentation/ +fi diff --git a/docker/build-includes/Dockerfile b/docker/build-includes/Dockerfile new file mode 100644 index 000000000..2c72a7996 --- /dev/null +++ b/docker/build-includes/Dockerfile @@ -0,0 +1,10 @@ +FROM nickblah/lua:5.3-luarocks-ubuntu + +RUN apt-get -qq update +RUN apt-get -qq install tree +RUN apt-get -qq install build-essential +RUN apt-get -qq install git +RUN luarocks install luasrcdiet +RUN luarocks install luacheck +COPY start.sh /start.sh +RUN chmod +x /start.sh diff --git a/docker/build-includes/docker-compose.yml b/docker/build-includes/docker-compose.yml new file mode 100644 index 000000000..e994882fc --- /dev/null +++ b/docker/build-includes/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3.5" + +services: + moose-build-includes: + image: moose/build-includes + build: + context: . + dockerfile: Dockerfile + container_name: moose-build-includes + volumes: + - ../../:/moose + stdin_open: true + tty: true + command: /bin/bash -c /start.sh diff --git a/docker/build-includes/start.sh b/docker/build-includes/start.sh new file mode 100644 index 000000000..10b29231e --- /dev/null +++ b/docker/build-includes/start.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Prepare environment +cd /moose/ +mkdir -p build/result/Moose_Include_Dynamic +mkdir -p build/result/Moose_Include_Static + +GIT_SHA=$(git rev-parse HEAD) +GIT_SHA=$(echo $GIT_SHA|tr -d '\n') +COMMIT_TIME=$(date +%Y-%m-%dT%H:%M:%S) + +# Create Includes +lua "./Moose Setup/Moose_Create.lua" S "$COMMIT_TIME-$GIT_SHA" "./Moose Development/Moose" "./Moose Setup" "./build/result/Moose_Include_Static" +lua "./Moose Setup/Moose_Create.lua" D "$COMMIT_TIME-$GIT_SHA" "./Moose Development/Moose" "./Moose Setup" "./build/result/Moose_Include_Dynamic" + +# Create Moose_.lua +luasrcdiet --basic --opt-emptylines ./build/result/Moose_Include_Static/Moose.lua -o ./build/result/Moose_Include_Static/Moose_.lua + +# Run luacheck +luacheck --std=lua51c --config=.luacheckrc -gurasqq "Moose Development/Moose" diff --git a/docker/gh-pages-check/Dockerfile b/docker/gh-pages-check/Dockerfile new file mode 100644 index 000000000..282c600dd --- /dev/null +++ b/docker/gh-pages-check/Dockerfile @@ -0,0 +1,4 @@ +FROM node:latest + +WORKDIR /usr/app +RUN npm install linkinator \ No newline at end of file diff --git a/docker/gh-pages-check/docker-compose.yml b/docker/gh-pages-check/docker-compose.yml new file mode 100644 index 000000000..30035ba8e --- /dev/null +++ b/docker/gh-pages-check/docker-compose.yml @@ -0,0 +1,17 @@ +version: "3.5" + +services: + moose-gh-pages-checks: + image: moose/gh-pages-checks + #image: node:latest + #image: joskfg/np + build: + context: . + dockerfile: Dockerfile + container_name: moose-gh-pages-checks + volumes: + - .:/moose + stdin_open: true + tty: true + #command: /bin/bash -c /moose/start.sh + command: npx linkinator https://flightcontrol-master.github.io/MOOSE/ diff --git a/docker/gh-pages/Dockerfile b/docker/gh-pages/Dockerfile new file mode 100644 index 000000000..a499513b2 --- /dev/null +++ b/docker/gh-pages/Dockerfile @@ -0,0 +1,12 @@ +FROM ruby:2.7 + +ENV LC_ALL C.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US.UTF-8 + +WORKDIR /usr/src/app + +COPY Gemfile just-the-docs.gemspec ./ +RUN gem install bundler && bundle install + +EXPOSE 4000 diff --git a/docker/gh-pages/docker-compose.yml b/docker/gh-pages/docker-compose.yml new file mode 100644 index 000000000..26e978667 --- /dev/null +++ b/docker/gh-pages/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3.5" + +services: + jekyll: + build: + context: ../../docs + dockerfile: ./Dockerfile + ports: + - 4000:4000 + volumes: + - ../../docs:/usr/src/app + stdin_open: true + tty: true + command: bundle exec jekyll serve -H 0.0.0.0 -t --force_polling diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000..44a974e25 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,11 @@ +# Copied from https://github.com/github/gitignore/blob/main/Jekyll.gitignore +# Ignore metadata generated by Jekyll +_site/ +.sass-cache/ +.jekyll-cache/ +.jekyll-metadata + +# Ignore folders generated by Bundler +.bundle/ +vendor/ +Gemfile.lock diff --git a/docs/Dockerfile b/docs/Dockerfile new file mode 100644 index 000000000..a499513b2 --- /dev/null +++ b/docs/Dockerfile @@ -0,0 +1,12 @@ +FROM ruby:2.7 + +ENV LC_ALL C.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US.UTF-8 + +WORKDIR /usr/src/app + +COPY Gemfile just-the-docs.gemspec ./ +RUN gem install bundler && bundle install + +EXPOSE 4000 diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 000000000..c6d33204b --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,7 @@ +source "https://rubygems.org" +gem "github-pages", group: :jekyll_plugins +gem "jekyll" +gem "json" +gem "just-the-docs" + +gem "webrick", group: :development diff --git a/docs/LICENSE b/docs/LICENSE new file mode 100644 index 000000000..7d510d02f --- /dev/null +++ b/docs/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 just-the-docs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 000000000..f40d6a2bb --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,36 @@ +baseurl: "" +url: "https://flightcontrol-master.github.io" +repository: FlightControl-Master/MOOSE +title: MOOSE +description: MOOSE is a Mission Object Oriented Scripting Environment for mission designers in DCS World +theme: just-the-docs +color_scheme: moose + +gh_edit_link: false +gh_edit_link_text: "Edit this page on GitHub" +gh_edit_repository: https://github.com/FlightControl-Master/MOOSE +gh_edit_branch: master +gh_edit_source: docs +gh_edit_view_mode: edit + +callouts_level: quiet # or loud +callouts: + highlight: + color: grey-dk + important: + title: Important + color: red + new: + title: New + color: grey-lt + note: + title: Note + color: green + warning: + title: Warning + color: yellow +callouts_opacity: 0.4 + +aux_links: + GitHub: https://github.com/FlightControl-Master/MOOSE + Discord: https://discord.gg/aQtjcR94Qf diff --git a/docs/_sass/color_schemes/moose.scss b/docs/_sass/color_schemes/moose.scss new file mode 100644 index 000000000..12e58bad8 --- /dev/null +++ b/docs/_sass/color_schemes/moose.scss @@ -0,0 +1,5 @@ +@import "./color_schemes/dark"; + +$green-300: #0d441b; +$red-300: #440d0d; +$grey-dk-300: #adadad; diff --git a/docs/buildsystem/build-docs.md b/docs/buildsystem/build-docs.md new file mode 100644 index 000000000..3ad52c993 --- /dev/null +++ b/docs/buildsystem/build-docs.md @@ -0,0 +1,73 @@ +--- +parent: Build system +nav_order: 2 +--- + +# Build class documentation + +The documentation of all classes are included in the code as comments. +This kind of documentation process is called [LuaDoc]. But we build the +html files for the documentation with [LuaDocumentor]. It is a tool +similar to [LuaDoc], but with some additional features the Moose team +decided to use. + +{: .important } +> The team created also some modifications, which are not part of the +> official [LuaDocumentor] tool. So we use the code in the git repository +> [Applevangelist/luadocumentor] in the branch `patch-1`. + +There are two git repositories which are used to save the generated +documentation: + +- [MOOSE_DOCS] is the repository for the `master` branch of [MOOSE] + - A configured GitHub Pages job will deploy the result to:
+ +- [MOOSE_DOCS_DEVELOP] is the repository for the `develop` branch of [MOOSE] + - A configured GitHub Pages job will deploy the result to:
+ + +Main build steps to create the class documentation are defined in [.github/workflows/build-docs.yml]: + +- Checkout of the git repository [MOOSE]. +- Create output folders. +- Checkout of the git repository [Applevangelist/luadocumentor] with + branch `patch-1` into a subdirectory. +- Update the Linux system software. +- Install needed tools: + - [tree] - A tool to output a tree view of a folder structure. + - [lua] - Package to run [Lua] scripts. This time [Lua] 5.1, + because it matches the DCS environment. + - [LuaRocks] - This is the package manager for Lua modules. + - [markdown] - Dependency for [LuaDocumentor] + - [penlight] - Dependency for [LuaDocumentor] + - [metalua-compiler] - Dependency for [LuaDocumentor] + - [metalua-parser] - Dependency for [metalua-compiler] + - [checks] - Dependency for [metalua-parser] + +- Run the build steps: + - Run `luadocumentor.lua` to create the html files. + +- Deploy build results: + - Checkout [MOOSE_DOCS] or [MOOSE_DOCS_DEVELOP] git repository in a subdirectory. + - Use the matching git repository for the branch of [MOOSE]. + - `master` -> [MOOSE_DOCS]. + - `develop` -> [MOOSE_DOCS_DEVELOP]. + - Use a `TOKEN` for checkout, so a `push` is possible later on. + - Copy build result to `MOOSE_DOCS` folder. + - Push results to the target repository. + +[tree]: https://wiki.ubuntuusers.de/tree/ +[LuaDoc]: https://keplerproject.github.io/luadoc/ +[LuaDocumentor]: https://luarocks.org/modules/luarocks/luadocumentor +[Applevangelist/luadocumentor]: https://github.com/Applevangelist/luadocumentor/tree/patch-1 +[markdown]: https://luarocks.org/modules/mpeterv/markdown +[penlight]: https://luarocks.org/modules/tieske/penlight +[metalua-compiler]: https://luarocks.org/modules/luarocks/metalua-compiler +[metalua-parser]: https://luarocks.org/modules/luarocks/metalua-parser +[checks]: https://luarocks.org/modules/fab13n/checks +[MOOSE]: https://github.com/FlightControl-Master/MOOSE +[MOOSE_DOCS]: https://github.com/FlightControl-Master/MOOSE_DOCS +[MOOSE_DOCS_DEVELOP]: https://github.com/FlightControl-Master/MOOSE_DOCS_DEVELOP +[Lua]: https://www.lua.org/ +[LuaRocks]: https://luarocks.org/ +[.github/workflows/build-docs.yml]: https://github.com/FlightControl-Master/MOOSE/blob/master/.github/workflows/build-docs.yml diff --git a/docs/buildsystem/build-includes.md b/docs/buildsystem/build-includes.md new file mode 100644 index 000000000..bdd683a22 --- /dev/null +++ b/docs/buildsystem/build-includes.md @@ -0,0 +1,45 @@ +--- +parent: Build system +nav_order: 1 +--- + +# Build include files + +Main build steps to create the include files are defined in [.github/workflows/build-includes.yml]: + +- Checkout of the git repository [MOOSE]. +- Create output folders. +- Update the Linux system software. +- Install needed tools: + - [tree] - A tool to output a tree view of a folder structure. + - [lua5.3] - Package to run [Lua] scripts. Version 5.3 is needed, because we + need liblua5.3-dev for [LuaSrcDiet]. + - [LuaRocks] - LuaRocks is the package manager for Lua modules. + - liblua5.3-dev - Header file of [Lua] needed for [LuaSrcDiet] to work. + - [LuaSrcDiet] - To compress the [Lua] code and create `Moose_.lua`. + - [LuaCheck] - This is a static code analyzer and a linter for [Lua]. + +- Run the build steps: + - Run `./Moose Setup/Moose_Create.lua` to create `Moose.lua`. + - Run `./Moose Setup/Moose_Create.lua` to create dynamic `Moose.lua` to + load individual Lua class files used by Moose developers. + - Run [LuaSrcDiet] to compress the [Lua] code and create `Moose_.lua` + - Run [LuaCheck] to find errors in the code. Warnings are ignored, because + there are a lot of warnings, which cannot be resolved by the Moose team. + +- Deploy build results: + - Checkout [MOOSE_INCLUDE] git repository in a subdirectory. + - Use the same branch used to checkout [MOOSE] git repository. + - Use a `TOKEN` for checkout, so a `push` is possible later on. + - Copy build result to `MOOSE_INCLUDE` folder + - Push results to [MOOSE_INCLUDE] repository + +[.github/workflows/build-includes.yml]: https://github.com/FlightControl-Master/MOOSE/blob/master/.github/workflows/build-includes.yml +[tree]: https://wiki.ubuntuusers.de/tree/ +[lua5.3]: https://www.lua.org/manual/5.3/ +[LuaRocks]: https://luarocks.org/ +[LuaCheck]: https://github.com/mpeterv/luacheck +[MOOSE]: https://github.com/FlightControl-Master/MOOSE +[MOOSE_INCLUDE]: https://github.com/FlightControl-Master/MOOSE_INCLUDE +[LuaSrcDiet]: https://github.com/jirutka/luasrcdiet +[Lua]: https://www.lua.org/ diff --git a/docs/buildsystem/gh-pages.md b/docs/buildsystem/gh-pages.md new file mode 100644 index 000000000..94ed78fa9 --- /dev/null +++ b/docs/buildsystem/gh-pages.md @@ -0,0 +1,51 @@ +--- +parent: Build system +nav_order: 3 +--- + +# Build GitHub Pages + +This documentation is created by [GitHub Pages]. The source files are +stored in the repository [MOOSE] in the subfolder `docs`. +We use [Just the Docs], which is a modern, highly customizable, and responsive +[Jekyll] theme for documentation. + +{: .note } +> The class documentation is created by its own [build] and is not the scope for this page! + +The build steps to create this documentation are defined in [.github/workflows/gh-pages.yml]. + +It is divided into two jobs: +- build: + - Only changes to in the subfolder `docs` or `gh-pages.yml` will trigger a build. + - Checkout of the git repository [MOOSE]. + - Setup [Ruby] version 3.1, which is needed by [Jekyll]. + - Run action [configure-pages]. + - Build with [Jekyll]. + - Run action [upload-pages-artifact]. +- deploy: + - Run action [deploy-pages]. + +# Preview of this documentation + +When enhancing this documentation it is very useful to see a 1on1 preview of the pages. +This can be displayed as follows: + +- You need a working installation of [Docker]. +- Go to the `docs` subfolder. +- Run `docker compose up`. +- Open a browser with the following URL: `http://127.0.0.1:4000/`. +- After a change of the [Markdown] files, wait some seconds and press F5 in the browser. + +[GitHub Pages]: https://pages.github.com/ +[MOOSE]: https://github.com/FlightControl-Master/MOOSE +[Just the Docs]: https://github.com/just-the-docs/just-the-docs +[Jekyll]: https://jekyllrb.com/ +[Ruby]: https://www.ruby-lang.org/en/ +[build]: build-docs.md +[.github/workflows/gh-pages.yml]: https://github.com/FlightControl-Master/MOOSE/blob/master/.github/workflows/gh-pages.yml +[configure-pages]: https://github.com/actions/configure-pages/ +[upload-pages-artifact]: https://github.com/actions/upload-pages-artifact +[deploy-pages]: https://github.com/actions/deploy-pages/ +[Docker]: https://www.docker.com/ +[Markdown]: https://www.markdownguide.org/ diff --git a/docs/buildsystem/index.md b/docs/buildsystem/index.md new file mode 100644 index 000000000..1dec95fed --- /dev/null +++ b/docs/buildsystem/index.md @@ -0,0 +1,58 @@ +--- +has_children: true +nav_order: 3 +--- + +# Build system + +{: .note } +> This documentation is not needed for end users. Only the people of the +> development team, who must maintain the build system need to read this. + +In this document we want to describe our build system for MOOSE. +MOOSE consists of multiple [Lua] files. Each class is stored in its own file. +This is needed for MOOSE developers to maintain clarity. +For users this is not practical, because they want to include the whole framework +as a single file into their missions. + +Because of this the build will collect all needed files and merge them together +in one file with the name `Moose.lua`. It includes also all comments and the +class documentation. Because of this its size is about 6-7 MB. + +To reduce the size of the file and make mission files smaller, the Moose team +decided to create a version without all comments and documentation. This file +is named `Moose_.lua`. It is created by a tool with the name [LuaSrcDiet]. + +Both files will be called static includes. In other programming languages includes +are dependencies. For Moose it is easier to memorize, that these files must be +included in your mission to use Moose. It is an static approach because you need +to add it once and it is only read from inside of the mission file after that. +A dynamic approach is to load all the single class files on each mission start +from the hard disk. But this is more for advanced Moose users and Moose developers. + +## Details + +In the past [AppVeyor] was used to run the build on a Windows system. +We decided to migrate this build to [GitHub Actions]. Installation of +dependencies was not stable on Windows with [GitHub Actions]. So we switched +to Ubuntu Linux. + +### GitHub Actions yml files + +The build configuration is stored in the folder `.github/workflows`. You will find +multiple files in this directory: + +- [build-docs.yml] - Job definition to generate the class documentation +- [build-includes.yml] - Job definition to build the static includes +- [gh-pages.yml] - Job to build this documentation page + +We decided to use different files for each job for separation of duties and easier +maintenance. + +[Lua]: https://www.lua.org/ +[LuaSrcDiet]: https://github.com/jirutka/luasrcdiet +[AppVeyor]: https://www.appveyor.com/ +[GitHub Actions]: https://docs.github.com/en/actions +[build-docs.yml]: build-docs.md +[build-includes.yml]: build-includes.md +[gh-pages.yml]: gh-pages.md diff --git a/docs/buildsystem/local-test.md b/docs/buildsystem/local-test.md new file mode 100644 index 000000000..98d39fc5a --- /dev/null +++ b/docs/buildsystem/local-test.md @@ -0,0 +1,49 @@ +--- +parent: Build system +nav_order: 4 +--- + +# Run builds locally + +When creating or enhancing [GitHub Actions] builds it is a problem to test the +build. After each change you need to commit and check the build result. This +leads to a lot of unnecessary commits. + +Therefor it is needed to run the build locally on the developer PC. The tool +which enabled this is [act]. It uses [Docker] to create a build runner and +executes the [GitHub Actions] build with it. + +[act] can by installed by [Chocolatey] by this single command: `choco install act-cli`. + +We use the `Medium Docker Image` for our MOOSE builds to work properly. +Unfortunately the docker images used by [act] are not as up to date as the +images used by [GitHub Actions]. So we needed to add a build step with +`sudo apt-get -qq update`. + +The build jobs needs `TOKENS` to run properly. So you have to create a PAT +([Personal Access Token]). A classic Token with read rights is enough to run +the build, as long as don't want to push the results. + +{: .important } +> The push step is only executed if the variable `FORCE_PUSH` with value `true` is set. +> - This is only needed if the push step itself must be change and tested! +> - Add parameter `--var FORCE_PUSH=true` to your [act] commando. +> - You and your PAT needs write access to the target repos, too. + +Save your PAT in the file `.secrets` in the main folder +of the MOOSE repository. This file is added to `.gitignore`, so it is not +recognized by git for commits. Add the following line to `.secrets`: + +``` +BOT_TOKEN= +``` + +To run the builds use these commands: +- `act push -W .github/workflows/build-includes.yml` +- `act push -W .github/workflows/build-docs.yml` + +[GitHub Actions]: https://docs.github.com/en/actions +[act]: https://github.com/nektos/act +[Docker]: https://www.docker.com/ +[Chocolatey]: https://community.chocolatey.org/ +[Personal Access Token]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens diff --git a/docs/docker-compose.yml b/docs/docker-compose.yml new file mode 100644 index 000000000..6901f39a7 --- /dev/null +++ b/docs/docker-compose.yml @@ -0,0 +1,13 @@ +version: "3.5" + +services: + jekyll: + build: + context: ./ + ports: + - 4000:4000 + volumes: + - .:/usr/src/app + stdin_open: true + tty: true + command: bundle exec jekyll serve -H 0.0.0.0 -t --force_polling diff --git a/docs/favicon.ico b/docs/favicon.ico new file mode 100644 index 000000000..9d06e6489 Binary files /dev/null and b/docs/favicon.ico differ diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..bd3525f15 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,68 @@ +--- +title: Overview +nav_order: 1 +layout: home +--- + +[![Moose-Includes](https://github.com/FlightControl-Master/MOOSE/actions/workflows/build-includes.yml/badge.svg?branch=master)](https://github.com/FlightControl-Master/MOOSE/actions/workflows/build-includes.yml)   +[![Moose-Docs](https://github.com/FlightControl-Master/MOOSE/actions/workflows/build-docs.yml/badge.svg?branch=master)](https://github.com/FlightControl-Master/MOOSE/actions/workflows/build-docs.yml) + +# MOOSE framework + +MOOSE is a **M**ission **O**bject **O**riented **S**cripting **E**nvironment for mission designers in [DCS World]. +It allows to quickly setup complex missions using pre-scripted scenarios using the available classes within the MOOSE Framework. +MOOSE is written in [Lua] which is a small and fast programming language, which is embedded in [DCS World]. + +## Goal of MOOSE + +The goal of MOOSE is to allow mission designers to enhance their scripting with mission orchestration objects, +which can be instantiated from defined classes within the framework. This will allow to write mission scripts with +minimal code embedded. Of course, the richness of the framework will determine the richness of the misson scenarios. +The MOOSE is a service that is produced while being consumed. It will evolve further as more classes are developed +for the framework and as more users are using it. +MOOSE is not a one-man show, it is a collaborative effort and meant to evolve within a growing community around the framework. +Within the community, key users will start supporting, documenting, explaining and even creating new classes for the framework. +It is the ambition to grow this framework as a de-facto standard for mission designers to use. + +## Two branches - Choose wisely + +In [DCS World] there is a `Stable` version and an `OpenBeta`. New features are released to the `OpenBeta` first and applied to `Stable` later. +People who choose to use `OpenBeta` can use the newest featuest and module, but accept the risk of bugs and unstable updates. +In MOOSE there is a `master` branch, which is comparable to the `Stable` version. +And there is the `development` branch, which is more like the `OpenBeta`. +New modules (called classes in [Lua], like [OPS.Auftrag]) will only available in the `development` branch. + +Releases are the most stable approach to use MOOSE. +From time to time the current state of the `master` branch is used to create release. +A release gets a spefific version number and will not be changed later on. + +## Documentation + +Documentation on the MOOSE class hierarchy will be automatically generated from [LuaDoc] comments inside of the source code of MOOOSE. +You can find the results on these websites: + +- Stable `master` branch: +- `develop` branch: + +## YouTube Tutorials + +There are different tutorial playlists available on YouTube: + +- AnyTimeBaby (Pene) has kindly created a [tutorial series for MOOSE](https://youtube.com/playlist?list=PLLkY2GByvtC2ME0Q9wrKRDE6qnXJYV3iT) + with various videos that you can watch. +- FlightControl (initiator of the project) has created a lot of [videos](https://www.youtube.com/@flightcontrol5350/featured) on how to use MOOSE. + They are a little bit outdated, but they still contain a lot of valuable information. + +## MOOSE on Discord + +MOOSE has a living community of users, beta testers and contributors. +The gathering point is a service provided by [Discord]. +If you want to join this community, just click the link below and you'll be on board in no time. + +- [Moose for DCS Discord server](https://discord.gg/aQtjcR94Qf) + +[DCS World]: https://www.digitalcombatsimulator.com/de/ +[Lua]: https://www.lua.org/ +[LuaDoc]: https://keplerproject.github.io/luadoc/ +[Ops.Auftrag]: https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Ops.Auftrag.html +[Discord]: https://discord.com/ diff --git a/docs/just-the-docs.gemspec b/docs/just-the-docs.gemspec new file mode 100644 index 000000000..851ac0aba --- /dev/null +++ b/docs/just-the-docs.gemspec @@ -0,0 +1,26 @@ +# coding: utf-8 + +Gem::Specification.new do |spec| + spec.name = "just-the-docs" + spec.version = "0.4.1" + spec.authors = ["Patrick Marsceill", "Matthew Wang"] + spec.email = ["patrick.marsceill@gmail.com", "matt@matthewwang.me"] + + spec.summary = %q{A modern, highly customizable, and responsive Jekyll theme for documentation with built-in search.} + spec.homepage = "https://github.com/just-the-docs/just-the-docs" + spec.license = "MIT" + spec.metadata = { + "bug_tracker_uri" => "https://github.com/just-the-docs/just-the-docs/issues", + "changelog_uri" => "https://github.com/just-the-docs/just-the-docs/blob/main/CHANGELOG.md", + "documentation_uri" => "https://just-the-docs.github.io/just-the-docs/", + "source_code_uri" => "https://github.com/just-the-docs/just-the-docs", + } + + spec.files = `git ls-files -z ':!:*.jpg' ':!:*.png'`.split("\x0").select { |f| f.match(%r{^(assets|bin|_layouts|_includes|lib|Rakefile|_sass|LICENSE|README|CHANGELOG|favicon)}i) } + spec.executables << 'just-the-docs' + + spec.add_development_dependency "bundler", ">= 2.3.5" + spec.add_runtime_dependency "jekyll", ">= 3.8.5" + spec.add_runtime_dependency "jekyll-seo-tag", ">= 2.0" + spec.add_runtime_dependency "rake", ">= 12.3.1" +end diff --git a/docs/repositories.md b/docs/repositories.md new file mode 100644 index 000000000..f7e89b744 --- /dev/null +++ b/docs/repositories.md @@ -0,0 +1,43 @@ +--- +title: Repositories +nav_order: 2 +--- + +# MOOSE Repositories + +The underlying picture documents the different repositories in the MOOSE framework. +The white ones are edited and are the source of the framework. +The red ones contain generated artefacts. See further the explanation for each repository. + +![Graphic](https://raw.githubusercontent.com/FlightControl-Master/MOOSE_DOCS/master/Configuration/Master.png) + +## [MOOSE](https://github.com/FlightControl-Master/MOOSE) - For development and static documentation + +This repository contains the source lua code of the MOOSE framework. +Also the source files for this documentation are included in this repository. + +## [MOOSE_INCLUDE](https://github.com/FlightControl-Master/MOOSE_INCLUDE) - For users (provides generated files) + +This repository contains the `Moose.lua` and `Moose\_.lua` file to be included within your missions. +Note that the `Moose\_.lua` is technically the same as `Moose.lua`, but without any commentary or unnecessary whitespace in it. +You only need to load **one** of those files at the beginning of your mission. + +## [MOOSE_DOCS](https://github.com/FlightControl-Master/MOOSE_DOCS) - Only to generate documentation website + +This repository contains the generated documentation and pictures and other references. +The generated documentation is reflected in html and is published at: +- Stable `master` branch: +- `develop` branch: + +## [MOOSE_MISSIONS](https://github.com/FlightControl-Master/MOOSE_MISSIONS) - For users (provides demo missions) + +This repository contains all the demonstration missions in packed format (*.miz), +and can be used without any further setup in DCS WORLD. + +## [MOOSE_MISSIONS_DYNAMIC](https://github.com/FlightControl-Master/MOOSE_MISSIONS_DYNAMIC) - Outdated + +This repository will be removed in future. + +## [MOOSE_MISSIONS_UNPACKED](https://github.com/FlightControl-Master/MOOSE_MISSIONS_UNPACKED) - Outdated + +This repository will be removed in future.