mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 22:56:30 -10:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
017c502894 |
No files matched your search
@@ -1,6 +1,14 @@
|
||||
|
||||
cmake/ @asarium
|
||||
|
||||
ci/ @asarium @z64555
|
||||
|
||||
code/executor/ @asarium
|
||||
|
||||
code/scpui/ @asarium
|
||||
|
||||
code/scripting/ @asarium
|
||||
|
||||
code/controlconfig/ @z64555
|
||||
|
||||
code/model/modelanimation*.* @bmagnu
|
||||
@@ -6,7 +6,7 @@ on:
|
||||
- 'nightly_*'
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.12
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
@@ -15,8 +15,23 @@ jobs:
|
||||
configuration: [FastDebug, Release]
|
||||
name: Linux
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-8a6bbbe
|
||||
steps:
|
||||
- name: Cache Qt
|
||||
id: cache-qt-lin
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
@@ -25,7 +40,6 @@ jobs:
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: gcc-5
|
||||
ENABLE_QTFRED: OFF
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
@@ -45,7 +59,7 @@ jobs:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/generate_appimage.sh $GITHUB_WORKSPACE/build/install
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: linux-${{ matrix.configuration }}
|
||||
path: ${{ github.workspace }}/build/install/*.AppImage
|
||||
@@ -61,12 +75,12 @@ jobs:
|
||||
submodules: true
|
||||
fetch-depth: '0'
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: linux-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linux-FastDebug
|
||||
path: builds
|
||||
@@ -95,36 +109,31 @@ jobs:
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
# - name: Cache Qt
|
||||
# id: cache-qt-win
|
||||
# uses: actions/cache@v1
|
||||
# with:
|
||||
# path: ${{ github.workspace }}/../Qt
|
||||
# key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
|
||||
# - name: Install Qt (32 bit)
|
||||
# uses: jurplel/install-qt-action@v2
|
||||
# if: ${{ matrix.arch == 'Win32' }}
|
||||
# with:
|
||||
# version: ${{ env.QT_VERSION }}
|
||||
# dir: ${{ github.workspace }}/..
|
||||
# arch: win32_msvc2017
|
||||
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
# aqtversion: ==0.8
|
||||
# - name: Install Qt (64 bit)
|
||||
# uses: jurplel/install-qt-action@v2
|
||||
# if: ${{ matrix.arch == 'x64' }}
|
||||
# with:
|
||||
# version: ${{ env.QT_VERSION }}
|
||||
# dir: ${{ github.workspace }}/..
|
||||
# arch: win64_msvc2017_64
|
||||
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
# aqtversion: ==0.8
|
||||
- name: Prepare Vulkan SDK
|
||||
uses: humbletim/[email protected]
|
||||
- name: Cache Qt
|
||||
id: cache-qt-win
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
vulkan-query-version: 1.3.204.0
|
||||
vulkan-components: Vulkan-Headers, Vulkan-Loader
|
||||
vulkan-use-cache: true
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt (32 bit)
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.arch == 'Win32' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win32_msvc2017
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
- name: Install Qt (64 bit)
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.arch == 'x64' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win64_msvc2017_64
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
@@ -135,19 +144,11 @@ jobs:
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
if [ "$ARCHITECTURE" = "Win32" ]; then
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_QTFRED=OFF -DFSO_BUILD_TESTS=ON \
|
||||
-DFSO_INSTALL_DEBUG_FILES="ON" -DFSO_BUILD_WITH_VULKAN="OFF" -A "$ARCHITECTURE" \
|
||||
-G "Visual Studio 16 2019" -T "v142" ..
|
||||
else
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_QTFRED=OFF -DFSO_BUILD_TESTS=ON \
|
||||
-DFSO_INSTALL_DEBUG_FILES="ON" -A "$ARCHITECTURE" \
|
||||
-G "Visual Studio 16 2019" -T "v142" ..
|
||||
fi
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_QTFRED=ON -DFSO_BUILD_TESTS=ON \
|
||||
-DFSO_INSTALL_DEBUG_FILES="ON" -A "$ARCHITECTURE" \
|
||||
-G "Visual Studio 16 2019" -T "v142" ..
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
env:
|
||||
@@ -164,7 +165,7 @@ jobs:
|
||||
shell: bash
|
||||
run: ./bin/$CONFIGURATION/unittests --gtest_shuffle
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: windows-${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: ${{ github.workspace }}/build/install/*
|
||||
@@ -184,12 +185,12 @@ jobs:
|
||||
submodules: true
|
||||
fetch-depth: '0'
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: windows-Release-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: windows-FastDebug-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: builds
|
||||
@@ -215,36 +216,30 @@ jobs:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
compiler: [clang]
|
||||
arch: [x86_64, arm64]
|
||||
arch: [x86_64]
|
||||
name: Mac
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
# - name: Cache Qt
|
||||
# id: cache-qt-mac
|
||||
# uses: actions/cache@v1
|
||||
# with:
|
||||
# path: ${{ github.workspace }}/../Qt
|
||||
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
# - name: Install Qt
|
||||
# uses: jurplel/install-qt-action@v2
|
||||
# with:
|
||||
# version: ${{ env.QT_VERSION }}
|
||||
# dir: ${{ github.workspace }}/..
|
||||
# cached: ${{ steps.cache-qt-mac.outputs.cache-hit }}
|
||||
# setup-python: 'false'
|
||||
# aqtversion: ==1.1.3
|
||||
# py7zrversion: '==0.19.*'
|
||||
- name: Cache Qt
|
||||
id: cache-qt-mac
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-mac.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
- name: Prepare Vulkan SDK
|
||||
uses: humbletim/[email protected]
|
||||
with:
|
||||
vulkan-query-version: 1.3.204.0
|
||||
vulkan-components: Vulkan-Headers, Vulkan-Loader
|
||||
vulkan-use-cache: true
|
||||
- name: Set up test version
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -257,7 +252,6 @@ jobs:
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
ARCHITECTURE: ${{ matrix.arch }}
|
||||
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
|
||||
ENABLE_QTFRED: OFF
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
@@ -266,27 +260,21 @@ jobs:
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
ARCH: ${{ matrix.arch }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Package build result
|
||||
working-directory: ./build/bin
|
||||
# Use GNU tar here (part of runner image) to avoid weird corruption bug with bsdtar
|
||||
# Ref: https://github.com/actions/runner-images/issues/2619
|
||||
run: gtar -cvzf macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz *.app
|
||||
working-directory: ./build
|
||||
run: cd bin && tar -cvzf macos-build.tar *.app
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: mac-${{ matrix.configuration }}-${{ matrix.arch }}
|
||||
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz
|
||||
name: mac-${{ matrix.configuration }}
|
||||
path: ${{ github.workspace }}/build/bin/macos-build.tar
|
||||
mac_zip:
|
||||
name: Build Mac distribution zip
|
||||
needs: build_mac
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x86_64, arm64]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
name: Checkout
|
||||
@@ -295,24 +283,17 @@ jobs:
|
||||
fetch-depth: '0'
|
||||
ref: '${{ github.ref }}'
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: mac-Release-${{ matrix.arch }}
|
||||
name: mac-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: mac-FastDebug-${{ matrix.arch }}
|
||||
name: mac-FastDebug
|
||||
path: builds
|
||||
- name: Unpack builds
|
||||
working-directory: ./builds
|
||||
run: |
|
||||
tar -xvzf macos-build-Release-${{ matrix.arch }}.tgz
|
||||
tar -xvzf macos-build-FastDebug-${{ matrix.arch }}.tgz
|
||||
- name: Create Distribution package
|
||||
working-directory: ./builds
|
||||
env:
|
||||
ARCH: ${{ matrix.arch }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Mac
|
||||
- name: Upload result package
|
||||
working-directory: ./builds
|
||||
|
||||
@@ -6,7 +6,7 @@ on:
|
||||
- 'release_*'
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.12
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
jobs:
|
||||
create_release:
|
||||
@@ -44,19 +44,59 @@ jobs:
|
||||
name: Linux
|
||||
needs: create_release # Don't run this job until create_release is done and successful
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-8a6bbbe
|
||||
steps:
|
||||
- name: Cache Qt
|
||||
id: cache-qt-lin
|
||||
uses: actions/cache@v1
|
||||
# cache the Qt directory so we don't have to reinstall it every time
|
||||
# cache.inputs:
|
||||
# path - A list of files, directories, and wildcard patterns to cache and restore. See @actions/glob for supported patterns.
|
||||
# key - An explicit key for restoring and saving the cache
|
||||
# restore-keys - An ordered list of keys to use for restoring the cache if no cache hit occurred for key
|
||||
# cache.outputs:
|
||||
# cache-hit true when an exact match was found for the key, false otherwise.
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
# installs Qt in the action workflow
|
||||
# install-qt-action.inputs:
|
||||
# version desired qt version to install
|
||||
# host Host platform of Qt, default to platform used by runs-on
|
||||
# target target platform of Qt, default to desktop
|
||||
# arch target architecture of Qt, only used for windows or android builds
|
||||
# dir root dir Qt will be installed to
|
||||
# install-deps if true, auto-install dependencies on linux. Default true
|
||||
# modules whitespace delimited list string of additional addon modules to install
|
||||
# archives whitespace delimited list string of Qt archives to install
|
||||
# cached if true, Don't download Qt but set ENVARs; use with cache.outputs.cache-hit
|
||||
# setup-python Set to false to skip using setup-python to find/download a valid python version
|
||||
# set-env if true, set ENVARs; default = false
|
||||
# aqtversion version of aqtinstall to use; default = 2.0.0
|
||||
# py7zrversion version of py7zr to use; default = 0.16.1
|
||||
# extra additional arguments to pass to aqinstall
|
||||
# ENVARS set:
|
||||
# Qt5_DIR / Qt6_DIR
|
||||
# Qt bin dir appended to PATH
|
||||
# QT_PLUGIN_PATH, QML2_IMPORT_PATH, PKG_CONFIG_PATH, LD_LIBRARY_PATH
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
# checks-out your repository under $GITHUB_WORKSPACE, so your workflow can access it.
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true # `true` to checkout submodules, `recursive` to recursively checkout submodules
|
||||
ref: '${{ github.ref }}'
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: gcc-5
|
||||
ENABLE_QTFRED: OFF
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
@@ -76,7 +116,7 @@ jobs:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/generate_appimage.sh $GITHUB_WORKSPACE/build/install
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v2
|
||||
# Upload the url file for use with other runners
|
||||
# upload-artifact.inputs:
|
||||
# if-no-files-found=warn What to do if path fails to find any files.
|
||||
@@ -100,16 +140,15 @@ jobs:
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: '0' # value 0 to fetch all history and tags for all branches
|
||||
ref: '${{ github.ref }}'
|
||||
- name: Download Release builds
|
||||
# Grab the release builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linux-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
# Grab the debug builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linux-FastDebug
|
||||
path: builds
|
||||
@@ -120,7 +159,7 @@ jobs:
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Linux
|
||||
- name: Upload result package
|
||||
# Stash the result to artifact filespace
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ steps.generate_package.outputs.package_name }}
|
||||
path: ${{ steps.generate_package.outputs.package_path }}
|
||||
@@ -147,40 +186,34 @@ jobs:
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
ref: '${{ github.ref }}'
|
||||
# - name: Cache Qt
|
||||
# # Cache Qt
|
||||
# id: cache-qt-win
|
||||
# uses: actions/cache@v1
|
||||
# with:
|
||||
# path: ${{ github.workspace }}/../Qt
|
||||
# key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
|
||||
# - name: Install Qt (32 bit)
|
||||
# # Install Qt 32bit if matrix.arch == Win32
|
||||
# uses: jurplel/install-qt-action@v2
|
||||
# if: ${{ matrix.arch == 'Win32' }}
|
||||
# with:
|
||||
# version: ${{ env.QT_VERSION }}
|
||||
# dir: ${{ github.workspace }}/..
|
||||
# arch: win32_msvc2017
|
||||
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
# aqtversion: ==0.8
|
||||
# - name: Install Qt (64 bit)
|
||||
# # Install Qt 64bit if matrix.arch == x64
|
||||
# uses: jurplel/install-qt-action@v2
|
||||
# if: ${{ matrix.arch == 'x64' }}
|
||||
# with:
|
||||
# version: ${{ env.QT_VERSION }}
|
||||
# dir: ${{ github.workspace }}/..
|
||||
# arch: win64_msvc2017_64
|
||||
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
# aqtversion: ==0.8
|
||||
- name: Prepare Vulkan SDK
|
||||
uses: humbletim/[email protected]
|
||||
- name: Cache Qt
|
||||
# Cache Qt
|
||||
id: cache-qt-win
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
vulkan-query-version: 1.3.204.0
|
||||
vulkan-components: Vulkan-Headers, Vulkan-Loader
|
||||
vulkan-use-cache: true
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt (32 bit)
|
||||
# Install Qt 32bit if matrix.arch == Win32
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.arch == 'Win32' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win32_msvc2017
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
- name: Install Qt (64 bit)
|
||||
# Install Qt 64bit if matrix.arch == x64
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.arch == 'x64' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win64_msvc2017_64
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
@@ -191,19 +224,11 @@ jobs:
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
if [ "$ARCHITECTURE" = "Win32" ]; then
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_QTFRED=OFF -DFSO_BUILD_TESTS=ON \
|
||||
-DFSO_INSTALL_DEBUG_FILES="ON" -DFSO_BUILD_WITH_VULKAN="OFF" -A "$ARCHITECTURE" \
|
||||
-G "Visual Studio 16 2019" -T "v142" ..
|
||||
else
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_QTFRED=OFF -DFSO_BUILD_TESTS=ON \
|
||||
-DFSO_INSTALL_DEBUG_FILES="ON" -A "$ARCHITECTURE" \
|
||||
-G "Visual Studio 16 2019" -T "v142" ..
|
||||
fi
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_QTFRED=ON -DFSO_BUILD_TESTS=ON \
|
||||
-DFSO_INSTALL_DEBUG_FILES="ON" -A "$ARCHITECTURE" \
|
||||
-G "Visual Studio 16 2019" -T "v142" ..
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
env:
|
||||
@@ -220,7 +245,7 @@ jobs:
|
||||
shell: bash
|
||||
run: ./bin/$CONFIGURATION/unittests --gtest_shuffle
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: windows-${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: ${{ github.workspace }}/build/install/*
|
||||
@@ -242,15 +267,15 @@ jobs:
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: '0'
|
||||
ref: '${{ github.ref }}'
|
||||
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: windows-Release-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: builds
|
||||
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: windows-FastDebug-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: builds
|
||||
@@ -265,13 +290,13 @@ jobs:
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Windows
|
||||
|
||||
- name: Upload result package
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ steps.generate_package.outputs.package_name }}
|
||||
path: ${{ steps.generate_package.outputs.package_path }}
|
||||
|
||||
- name: Upload debug package
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ steps.generate_package.outputs.debug_name }}
|
||||
path: ${{ steps.generate_package.outputs.debug_path }}
|
||||
@@ -285,125 +310,11 @@ jobs:
|
||||
${{ steps.generate_package.outputs.package_path }}
|
||||
${{ steps.generate_package.outputs.debug_path }}
|
||||
|
||||
build_mac:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
compiler: [clang]
|
||||
arch: [x86_64, arm64]
|
||||
name: Mac
|
||||
needs: create_release
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
# - name: Cache Qt
|
||||
# id: cache-qt-mac
|
||||
# uses: actions/cache@v1
|
||||
# with:
|
||||
# path: ${{ github.workspace }}/../Qt
|
||||
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
# - name: Install Qt
|
||||
# uses: jurplel/install-qt-action@v2
|
||||
# with:
|
||||
# version: ${{ env.QT_VERSION }}
|
||||
# dir: ${{ github.workspace }}/..
|
||||
# cached: ${{ steps.cache-qt-mac.outputs.cache-hit }}
|
||||
# setup-python: 'false'
|
||||
# aqtversion: ==1.1.3
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
ref: '${{ github.ref }}'
|
||||
- name: Prepare Vulkan SDK
|
||||
uses: humbletim/[email protected]
|
||||
with:
|
||||
vulkan-query-version: 1.3.204.0
|
||||
vulkan-components: Vulkan-Headers, Vulkan-Loader
|
||||
vulkan-use-cache: true
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
ARCHITECTURE: ${{ matrix.arch }}
|
||||
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
|
||||
ENABLE_QTFRED: OFF
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja all
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
ARCH: ${{ matrix.arch }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Package build result
|
||||
working-directory: ./build/bin
|
||||
# Use GNU tar here (part of runner image) to avoid weird corruption bug with bsdtar
|
||||
# Ref: https://github.com/actions/runner-images/issues/2619
|
||||
run: gtar -cvzf macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz *.app
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: mac-${{ matrix.configuration }}-${{ matrix.arch }}
|
||||
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz
|
||||
mac_zip:
|
||||
name: Build Mac distribution zip
|
||||
needs: build_mac
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x86_64, arm64]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: '0'
|
||||
ref: '${{ github.ref }}'
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: mac-Release-${{ matrix.arch }}
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: mac-FastDebug-${{ matrix.arch }}
|
||||
path: builds
|
||||
- name: Unpack builds
|
||||
working-directory: ./builds
|
||||
run: |
|
||||
tar -xvzf macos-build-Release-${{ matrix.arch }}.tgz
|
||||
tar -xvzf macos-build-FastDebug-${{ matrix.arch }}.tgz
|
||||
- name: Create Distribution package
|
||||
id: generate_package
|
||||
working-directory: ./builds
|
||||
env:
|
||||
ARCH: ${{ matrix.arch }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Mac
|
||||
- name: Upload result package
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ steps.generate_package.outputs.package_name }}
|
||||
path: ${{ steps.generate_package.outputs.package_path }}
|
||||
- name: Publish result package
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
files: ${{ steps.generate_package.outputs.package_path }}
|
||||
|
||||
post_build:
|
||||
name: Post builds to Nebula and Forum
|
||||
needs: [linux_zip, windows_zip, mac_zip]
|
||||
needs: [linux_zip, windows_zip]
|
||||
uses: ./.github/workflows/post-build-release.yaml
|
||||
with:
|
||||
linux_result: ${{ needs.linux_zip.result }}
|
||||
windows_result: ${{ needs.windows_zip.result }}
|
||||
mac_result: ${{ needs.mac_zip.result }}
|
||||
releaseTag: ${{ github.ref_name }}
|
||||
secrets: inherit
|
||||
@@ -6,7 +6,7 @@ on:
|
||||
- 'test/*'
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.12
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
@@ -15,8 +15,23 @@ jobs:
|
||||
configuration: [FastDebug, Release]
|
||||
name: Linux
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-8a6bbbe
|
||||
steps:
|
||||
- name: Cache Qt
|
||||
id: cache-qt-lin
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
@@ -31,7 +46,6 @@ jobs:
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: gcc-5
|
||||
ENABLE_QTFRED: OFF
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
@@ -51,7 +65,7 @@ jobs:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/generate_appimage.sh $GITHUB_WORKSPACE/build/install
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: linux-${{ matrix.configuration }}
|
||||
path: ${{ github.workspace }}/build/install/*.AppImage
|
||||
@@ -68,12 +82,12 @@ jobs:
|
||||
fetch-depth: '0'
|
||||
ref: '${{ github.ref }}'
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: linux-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linux-FastDebug
|
||||
path: builds
|
||||
@@ -108,36 +122,31 @@ jobs:
|
||||
[[ "${{ github.ref }}" =~ ^refs\/heads\/test\/(.*)$ ]]
|
||||
# Override the revision string so that the builds are named correctly
|
||||
echo "set(FSO_VERSION_REVISION_STR ${BASH_REMATCH[1]})" > "version_override.cmake"
|
||||
# - name: Cache Qt
|
||||
# id: cache-qt-win
|
||||
# uses: actions/cache@v1
|
||||
# with:
|
||||
# path: ${{ github.workspace }}/../Qt
|
||||
# key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
|
||||
# - name: Install Qt (32 bit)
|
||||
# uses: jurplel/install-qt-action@v2
|
||||
# if: ${{ matrix.arch == 'Win32' }}
|
||||
# with:
|
||||
# version: ${{ env.QT_VERSION }}
|
||||
# dir: ${{ github.workspace }}/..
|
||||
# arch: win32_msvc2017
|
||||
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
# aqtversion: ==0.8
|
||||
# - name: Install Qt (64 bit)
|
||||
# uses: jurplel/install-qt-action@v2
|
||||
# if: ${{ matrix.arch == 'x64' }}
|
||||
# with:
|
||||
# version: ${{ env.QT_VERSION }}
|
||||
# dir: ${{ github.workspace }}/..
|
||||
# arch: win64_msvc2017_64
|
||||
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
# aqtversion: ==0.8
|
||||
- name: Prepare Vulkan SDK
|
||||
uses: humbletim/[email protected]
|
||||
- name: Cache Qt
|
||||
id: cache-qt-win
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
vulkan-query-version: 1.3.204.0
|
||||
vulkan-components: Vulkan-Headers, Vulkan-Loader
|
||||
vulkan-use-cache: true
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt (32 bit)
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.arch == 'Win32' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win32_msvc2017
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
- name: Install Qt (64 bit)
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.arch == 'x64' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win64_msvc2017_64
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
@@ -148,19 +157,11 @@ jobs:
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
if [ "$ARCHITECTURE" = "Win32" ]; then
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_QTFRED=OFF -DFSO_BUILD_TESTS=ON \
|
||||
-DFSO_INSTALL_DEBUG_FILES="ON" -DFSO_BUILD_WITH_VULKAN="OFF" -A "$ARCHITECTURE" \
|
||||
-G "Visual Studio 16 2019" -T "v142" ..
|
||||
else
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_QTFRED=OFF -DFSO_BUILD_TESTS=ON \
|
||||
-DFSO_INSTALL_DEBUG_FILES="ON" -A "$ARCHITECTURE" \
|
||||
-G "Visual Studio 16 2019" -T "v142" ..
|
||||
fi
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_QTFRED=ON -DFSO_BUILD_TESTS=ON \
|
||||
-DFSO_INSTALL_DEBUG_FILES="ON" -A "$ARCHITECTURE" \
|
||||
-G "Visual Studio 16 2019" -T "v142" ..
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
env:
|
||||
@@ -177,7 +178,7 @@ jobs:
|
||||
shell: bash
|
||||
run: ./bin/$CONFIGURATION/unittests --gtest_shuffle
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: windows-${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: ${{ github.workspace }}/build/install/*
|
||||
@@ -198,12 +199,12 @@ jobs:
|
||||
fetch-depth: '0'
|
||||
ref: '${{ github.ref }}'
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: windows-Release-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: windows-FastDebug-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: builds
|
||||
@@ -229,36 +230,30 @@ jobs:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
compiler: [clang]
|
||||
arch: [x86_64, arm64]
|
||||
arch: [x86_64]
|
||||
name: Mac
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
# - name: Cache Qt
|
||||
# id: cache-qt-mac
|
||||
# uses: actions/cache@v1
|
||||
# with:
|
||||
# path: ${{ github.workspace }}/../Qt
|
||||
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
# - name: Install Qt
|
||||
# uses: jurplel/install-qt-action@v2
|
||||
# with:
|
||||
# version: ${{ env.QT_VERSION }}
|
||||
# dir: ${{ github.workspace }}/..
|
||||
# cached: ${{ steps.cache-qt-mac.outputs.cache-hit }}
|
||||
# setup-python: 'false'
|
||||
# aqtversion: ==1.1.3
|
||||
# py7zrversion: '==0.19.*'
|
||||
- name: Cache Qt
|
||||
id: cache-qt-mac
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-mac.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
- name: Prepare Vulkan SDK
|
||||
uses: humbletim/[email protected]
|
||||
with:
|
||||
vulkan-query-version: 1.3.204.0
|
||||
vulkan-components: Vulkan-Headers, Vulkan-Loader
|
||||
vulkan-use-cache: true
|
||||
- name: Set up test version
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -270,7 +265,6 @@ jobs:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
ARCHITECTURE: ${{ matrix.arch }}
|
||||
ENABLE_QTFRED: OFF
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
@@ -279,27 +273,21 @@ jobs:
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
ARCH: ${{ matrix.arch }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Package build result
|
||||
working-directory: ./build/bin
|
||||
# Use GNU tar here (part of runner image) to avoid weird corruption bug with bsdtar
|
||||
# Ref: https://github.com/actions/runner-images/issues/2619
|
||||
run: gtar -cvzf macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz *.app
|
||||
working-directory: ./build
|
||||
run: cd bin && tar -cvzf macos-build.tar *.app
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: mac-${{ matrix.configuration }}-${{ matrix.arch }}
|
||||
path: ${{ github.workspace }}/build/bin/macos-build-${{ matrix.configuration }}-${{ matrix.arch }}.tgz
|
||||
name: mac-${{ matrix.configuration }}
|
||||
path: ${{ github.workspace }}/build/bin/macos-build.tar
|
||||
mac_zip:
|
||||
name: Build Mac distribution zip
|
||||
needs: build_mac
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x86_64, arm64]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
name: Checkout
|
||||
@@ -308,24 +296,17 @@ jobs:
|
||||
fetch-depth: '0'
|
||||
ref: '${{ github.ref }}'
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: mac-Release-${{ matrix.arch }}
|
||||
name: mac-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: mac-FastDebug-${{ matrix.arch }}
|
||||
name: mac-FastDebug
|
||||
path: builds
|
||||
- name: Unpack builds
|
||||
working-directory: ./builds
|
||||
run: |
|
||||
tar -xvzf macos-build-Release-${{ matrix.arch }}.tgz
|
||||
tar -xvzf macos-build-FastDebug-${{ matrix.arch }}.tgz
|
||||
- name: Create Distribution package
|
||||
working-directory: ./builds
|
||||
env:
|
||||
ARCH: ${{ matrix.arch }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Mac
|
||||
- name: Upload result package
|
||||
working-directory: ./builds
|
||||
|
||||
@@ -6,27 +6,42 @@ on:
|
||||
- master
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.12
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
compiler: [gcc-5, gcc-13, clang-16]
|
||||
compiler: [gcc-5, gcc-10]
|
||||
cmake_options: [""]
|
||||
include:
|
||||
# Also include configurations that check if the code compiles without the graphics backends
|
||||
- configuration: Debug
|
||||
compiler: gcc-13
|
||||
compiler: gcc-10
|
||||
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
|
||||
- configuration: Release
|
||||
compiler: gcc-13
|
||||
compiler: gcc-10
|
||||
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
|
||||
name: Linux
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-8a6bbbe
|
||||
steps:
|
||||
- name: Cache Qt
|
||||
id: cache-qt-lin
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
@@ -35,22 +50,13 @@ jobs:
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}
|
||||
- name: Configure ccache
|
||||
run: |
|
||||
ccache --set-config=sloppiness=pch_defines,time_macros
|
||||
ccache -p
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
|
||||
CCACHE_PATH: /usr/local/bin/ccache
|
||||
ENABLE_QTFRED: ON
|
||||
Qt5_DIR: /qt/${{ env.QT_VERSION }}/gcc_64/lib/cmake/Qt5
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja -k 20 all
|
||||
- name: Show CCache statistics
|
||||
run: ccache --show-stats
|
||||
@@ -10,9 +10,6 @@ on:
|
||||
windows_result: # job.result
|
||||
required: true
|
||||
type: string
|
||||
mac_result: # job.result
|
||||
required: true
|
||||
type: string
|
||||
releaseTag:
|
||||
required: true
|
||||
type: string
|
||||
@@ -58,15 +55,6 @@ jobs:
|
||||
env:
|
||||
LINUX_RESULT: ${{ inputs.linux_result }}
|
||||
WINDOWS_RESULT: ${{ inputs.windows_result }}
|
||||
MAC_RESULT: ${{ inputs.mac_result }}
|
||||
GITHUB_REPO: ${{ github.repository }} # repo this workflow was called from
|
||||
INDIEGAMES_USER: ${{ secrets.INDIEGAMES_USER }}
|
||||
INDIEGAMES_SSHPASS: ${{ secrets.INDIEGAMES_PASSWORD }}
|
||||
NEBULA_USER: ${{ secrets.NEBULA_USER }}
|
||||
NEBULA_PASSWORD: ${{ secrets.NEBULA_PASSWORD }}
|
||||
HLP_API: ${{ secrets.HLP_API }}
|
||||
HLP_KEY: ${{ secrets.HLP_KEY }}
|
||||
RELEASE_TAG: ${{ inputs.releaseTag }}
|
||||
run: python ci/post/main.py release
|
||||
|
||||
- name: Post Builds (Manual trigger)
|
||||
@@ -75,8 +63,7 @@ jobs:
|
||||
env:
|
||||
LINUX_RESULT: success
|
||||
WINDOWS_RESULT: success
|
||||
MAC_RESULT: success
|
||||
run: |
|
||||
echo "releaseTag= ${{ env.RELEASE_TAG }}"
|
||||
echo "repository= ${{ github.repository }}"
|
||||
python ci/post/main.py release
|
||||
python ci/post/main.py release
|
||||
@@ -3,27 +3,42 @@ name: Check a pull request
|
||||
on: [pull_request]
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.12
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
compiler: [gcc-5, gcc-13, clang-16]
|
||||
compiler: [gcc-5, gcc-10, clang-9]
|
||||
cmake_options: [""]
|
||||
include:
|
||||
# Also include configurations that check if the code compiles without the graphics backends
|
||||
- configuration: Debug
|
||||
compiler: gcc-13
|
||||
compiler: gcc-10
|
||||
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
|
||||
- configuration: Release
|
||||
compiler: gcc-13
|
||||
compiler: gcc-10
|
||||
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
|
||||
name: Linux
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-8a6bbbe
|
||||
steps:
|
||||
- name: Cache Qt
|
||||
id: cache-qt-lin
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
@@ -33,18 +48,12 @@ jobs:
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}
|
||||
save: false # Caches are created by a separate job and only restored for PRs
|
||||
verbose: 1
|
||||
- name: Configure ccache
|
||||
run: ccache --set-config=sloppiness=pch_defines,time_macros
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
|
||||
CCACHE_PATH: /usr/local/bin/ccache
|
||||
ENABLE_QTFRED: ON
|
||||
Qt5_DIR: /qt/${{ env.QT_VERSION }}/gcc_64/lib/cmake/Qt5
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
@@ -55,8 +64,6 @@ jobs:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Show CCache statistics
|
||||
run: ccache --show-stats
|
||||
- name: Run Clang Tidy
|
||||
# Clang-tidy reuses the precompiled headers so this only makes sense for the clang compilers
|
||||
if: startsWith(matrix.compiler, 'clang-')
|
||||
@@ -82,36 +89,31 @@ jobs:
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
# - name: Cache Qt
|
||||
# id: cache-qt-win
|
||||
# uses: actions/cache@v1
|
||||
# with:
|
||||
# path: ${{ github.workspace }}/../Qt
|
||||
# key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
|
||||
# - name: Install Qt (32 bit)
|
||||
# uses: jurplel/install-qt-action@v2
|
||||
# if: ${{ matrix.compiler == 'MSVC' && matrix.arch == 'Win32' }}
|
||||
# with:
|
||||
# version: ${{ env.QT_VERSION }}
|
||||
# dir: ${{ github.workspace }}/..
|
||||
# arch: win32_msvc2017
|
||||
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
# aqtversion: ==0.8
|
||||
# - name: Install Qt (64 bit)
|
||||
# uses: jurplel/install-qt-action@v2
|
||||
# if: ${{ matrix.compiler == 'MSVC' && matrix.arch == 'x64' }}
|
||||
# with:
|
||||
# version: ${{ env.QT_VERSION }}
|
||||
# dir: ${{ github.workspace }}/..
|
||||
# arch: win64_msvc2017_64
|
||||
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
# aqtversion: ==0.8
|
||||
- name: Prepare Vulkan SDK
|
||||
uses: humbletim/[email protected]
|
||||
- name: Cache Qt
|
||||
id: cache-qt-win
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
vulkan-query-version: 1.3.204.0
|
||||
vulkan-components: Vulkan-Headers, Vulkan-Loader
|
||||
vulkan-use-cache: true
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt (32 bit)
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.compiler == 'MSVC' && matrix.arch == 'Win32' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win32_msvc2017
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
- name: Install Qt (64 bit)
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.compiler == 'MSVC' && matrix.arch == 'x64' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win64_msvc2017_64
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
@@ -123,23 +125,12 @@ jobs:
|
||||
cd build
|
||||
|
||||
if [ "$COMPILER" = "MinGW" ]; then
|
||||
if [ "$ARCHITECTURE" = "Win32" ]; then
|
||||
cmake -DFSO_USE_SPEECH="OFF" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
|
||||
-DFSO_BUILD_FRED2="OFF" -DFSO_BUILD_WITH_VULKAN="OFF" -DCMAKE_BUILD_TYPE=$CONFIGURATION -G "Ninja" ..
|
||||
else
|
||||
cmake -DFSO_USE_SPEECH="OFF" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
|
||||
-DFSO_BUILD_FRED2="OFF" -DCMAKE_BUILD_TYPE=$CONFIGURATION -G "Ninja" ..
|
||||
fi
|
||||
cmake -DFSO_USE_SPEECH="OFF" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
|
||||
-DFSO_BUILD_FRED2="OFF" -DCMAKE_BUILD_TYPE=$CONFIGURATION -G "Ninja" ..
|
||||
else
|
||||
if [ "$ARCHITECTURE" = "Win32" ]; then
|
||||
cmake -DFSO_USE_SPEECH="ON" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
|
||||
-DMSVC_SIMD_INSTRUCTIONS=SSE2 -DFSO_BUILD_FRED2="ON" -DFSO_BUILD_WITH_VULKAN="OFF" -G "Visual Studio 16 2019" \
|
||||
-DFSO_BUILD_QTFRED=OFF -T "v142" -A "$ARCHITECTURE" ..
|
||||
else
|
||||
cmake -DFSO_USE_SPEECH="ON" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
|
||||
-DMSVC_SIMD_INSTRUCTIONS=SSE2 -DFSO_BUILD_FRED2="ON" -G "Visual Studio 16 2019" \
|
||||
-DFSO_BUILD_QTFRED=OFF -T "v142" -A "$ARCHITECTURE" ..
|
||||
fi
|
||||
cmake -DFSO_USE_SPEECH="ON" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
|
||||
-DMSVC_SIMD_INSTRUCTIONS=SSE2 -DFSO_BUILD_FRED2="ON" -G "Visual Studio 16 2019" \
|
||||
-DFSO_BUILD_QTFRED=ON -T "v142" -A "$ARCHITECTURE" ..
|
||||
fi
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
@@ -171,26 +162,26 @@ jobs:
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
compiler: [clang]
|
||||
arch: [x86_64, arm64]
|
||||
arch: [x86_64]
|
||||
cmake_options: [""]
|
||||
name: Mac
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
# - name: Cache Qt
|
||||
# id: cache-qt-mac
|
||||
# uses: actions/cache@v1
|
||||
# with:
|
||||
# path: ${{ github.workspace }}/../Qt
|
||||
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
# - name: Install Qt
|
||||
# uses: jurplel/install-qt-action@v2
|
||||
# with:
|
||||
# version: ${{ env.QT_VERSION }}
|
||||
# dir: ${{ github.workspace }}/..
|
||||
# cached: ${{ steps.cache-qt-mac.outputs.cache-hit }}
|
||||
# setup-python: 'false'
|
||||
# aqtversion: ==1.1.3
|
||||
# py7zrversion: '==0.19.*'
|
||||
- name: Cache Qt
|
||||
id: cache-qt-mac
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-mac.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
@@ -199,21 +190,14 @@ jobs:
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}-${{ matrix.arch }}
|
||||
save: false # Caches are created by a separate job and only restored for PRs
|
||||
- name: Prepare Vulkan SDK
|
||||
uses: humbletim/[email protected]
|
||||
with:
|
||||
vulkan-query-version: 1.3.204.0
|
||||
vulkan-components: Vulkan-Headers, Vulkan-Loader
|
||||
vulkan-use-cache: true
|
||||
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
ARCHITECTURE: ${{ matrix.arch }}
|
||||
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
|
||||
ENABLE_QTFRED: OFF
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
@@ -222,7 +206,6 @@ jobs:
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
ARCH: ${{ matrix.arch }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Run Clang Tidy
|
||||
@@ -233,4 +216,4 @@ jobs:
|
||||
if: startsWith(matrix.compiler, 'clang-')
|
||||
uses: asarium/clang-tidy-action@v1
|
||||
with:
|
||||
fixesFile: clang-fixes.yaml
|
||||
fixesFile: clang-fixes.yaml
|
||||
@@ -1,68 +0,0 @@
|
||||
name: Weekly Coverity Scan for Freespace Open
|
||||
# adapted from code by "albert-github" on the doxygen repository
|
||||
# many thanks for figuring this out first so it could be less painful for us!
|
||||
|
||||
#This mode is for testing
|
||||
on: [push, pull_request]
|
||||
|
||||
# In production, push on a specific schedule
|
||||
#on:
|
||||
# schedule:
|
||||
# - cron: "5 0 * * 5" # Run once per a week on Friday morning (midnight UTC, 4 AM EST), to avoid Coverity's submission limits
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.12
|
||||
coverity_email: [email protected]
|
||||
coverity_token: ${{ secrets.COVERITY_TOKEN }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build FSO With Coverity Wrapper
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-5ac6f70
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- { name: "GCC on ubuntu", os: ubuntu-latest, build_type: "Release" }
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive # `true` to checkout submodules, `recursive` to recursively checkout submodules
|
||||
|
||||
# pipe results of wget to a log file because it's very verbose and rarely fails
|
||||
- name: Install Coverity
|
||||
run: |
|
||||
wget -o wgetlog.txt -q https://scan.coverity.com/download/cxx/linux64 --post-data "token=${{ env.coverity_token }}&project=scp-fs2open/fs2open.github.com" -O coverity_tool.tgz
|
||||
mkdir cov-scan
|
||||
tar ax -f coverity_tool.tgz --strip-components=1 -C cov-scan
|
||||
|
||||
- name: Setup Environment
|
||||
run: |
|
||||
echo "$(pwd)/cov-scan/bin" >> $GITHUB_PATH
|
||||
echo "NPROC=$(getconf _NPROCESSORS_ONLN)" >> $GITHUB_ENV
|
||||
|
||||
- name: Configure CMake for FSO
|
||||
env:
|
||||
CONFIGURATION: Release
|
||||
compiler: gcc-5
|
||||
ENABLE_QTFRED: OFF
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
|
||||
- name: Build FSO with Coverity Wrapper
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: Release
|
||||
run: cov-build --dir cov-int ninja -k 20 all
|
||||
|
||||
- name: Compress Results
|
||||
working-directory: ./build
|
||||
run: tar zcf cov-scan.tgz cov-int
|
||||
|
||||
#Comment this out when testing to keep from running into upload limits
|
||||
- name: Upload to Coverity
|
||||
run: |
|
||||
cd build
|
||||
curl --form token=${{ env.coverity_token }} --form email=${{ env.coverity_email }} --form [email protected] --form version="$(git rev-parse HEAD)" --form description="Automatic GHA scan" 'https://scan.coverity.com/builds?project=scp-fs2open/fs2open.github.com'
|
||||
@@ -250,7 +250,6 @@ documentation/doxygen/*
|
||||
projects/*
|
||||
/.vs
|
||||
CMakeSettings.json
|
||||
CMakePresets.json
|
||||
|
||||
# Weird files created by Linux
|
||||
.fuse_hidden*
|
||||
|
||||
@@ -4,4 +4,3 @@
|
||||
[submodule "lib/libRocket"]
|
||||
path = lib/libRocket
|
||||
url = https://github.com/asarium/libRocket.git
|
||||
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
language: bash
|
||||
sudo: required
|
||||
dist: xenial
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/cmake-3.8
|
||||
- $HOME/.ccache
|
||||
- $HOME/curl_cache
|
||||
addons:
|
||||
apt:
|
||||
packages: &global_deps
|
||||
- ninja-build
|
||||
- libopenal-dev
|
||||
- libreadline6-dev
|
||||
- libpng12-dev
|
||||
- libjpeg62-dev
|
||||
- liblua5.1-0-dev
|
||||
- libjansson-dev
|
||||
- libsdl2-dev
|
||||
- libfreetype6-dev
|
||||
- qt57base
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "scp-fs2open/fs2open.github.com"
|
||||
notification_email: [email protected]
|
||||
build_command: "ci/travis/script.sh"
|
||||
# must match TRAVIS_BRANCH check below
|
||||
branch_pattern: coverity_scan
|
||||
env:
|
||||
global:
|
||||
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||
# via the "travis encrypt" command using the project repo's public key
|
||||
# also note that fork's don't get access to secure keys
|
||||
# you have to test using a branch in the main repo
|
||||
- secure: "C3wF967ZeliwwP1vC12EMIBOaC568n26Z/cPnwzn317ve59DWH3YSfPZVgvt08GzmaXITGGsJvPB+qxfGoKvQzYE4O1B73q81RpUe5pB3IhF+ThQ91VfQZIRJR5xEGJaLINUlHTTZGX5jxlkVO9wAcauVj/s3b8sQ3dvUZauPvk="
|
||||
# These declarations set INDIEGAMES_USER and INDIEGAMES_PASSWORD for uploading nightly builds to the indiegames server
|
||||
- secure: "lUuRu8XIi8MKNf1ebOfyC4iVEpPyASojJIDWXRo2bNqEF4ILAljXdkVeXeN6H5yKCHD52cxCNTtyePIG/o3p3QEuGSVud9bDS3D7LaQicLETGGrsw3l07U49gF2OKHXGopg0MzBbZUU9QmhoFTAe8t6PV9NDuEayYCheqvTqjZg="
|
||||
- secure: "E/DHLYcPK/hBUqxBYYlUqp5sjgvIqY5A0qRHyQ4bmjsB+WB/Xx71bGCSiF7hk6lTxar1ZI1i5RAXXh9AIvNVaYAIdEOlCP+q3gvwCYuc5naZEKmkxlUCf0oEL4O9Fye93A/3VkFHuBdC1TGPYYf69m4W5r4367wWO9dPRIdWpJA="
|
||||
# These declarations set DATACORDER_USER and DATACORDER_PASSWORD
|
||||
- secure: "dpBH/dDN3bmU/NFlh+2v9isNx9wX0ocoRy+W+kBXRH32sosUGp26REhMqgVRpBNP5oxPBU8ic5bEogxAYWCB+0xUygBbkxAwyMPgoA34s0OXdTCY/ofw14ni8qqV2Ffy7fQJbP/jkMURyiMHx3kBTxNv3YjxKJqLnOuOMlQLpT8="
|
||||
- secure: "tLMRBD1Ufp5iKNwlqPDVbbuczgusaXNoBJyAnPATpJq2YwlkW4j3PqP9rW5vd85+52xam2EOP20w9PoBR5J6FLdiXRu4Lf7yCEhSHFAgowVqQj8QcJpPlyXr90bM4emFGrGqpdxVwxyQ5AFhKwLuEZKsI14GYLN+UMEwpNCMing="
|
||||
deploy:
|
||||
- provider: releases
|
||||
api_key:
|
||||
secure: "q619+eQTe7lv8UVphK4OIzU8Jw84KBbVkuprN2sWIubRcV3IbZr2+WahJoUMt+nyhiy3YjDYtstO2ZgkxupwnZgwGUBVIiD1c4SPuyy+HTjNMOtiVsEUHT2hf+xPAemWpTlK5HcwhMmHAOh6rt6dEj57QOg0gcmGiwD/tCbEriA="
|
||||
skip_cleanup: true
|
||||
file_glob: true
|
||||
file: "/tmp/builds/*"
|
||||
on:
|
||||
condition: '"$RELEASE_BUILD" == true'
|
||||
tags: true
|
||||
|
||||
- provider: script
|
||||
script: bash ci/travis/ftp_deploy.sh
|
||||
on:
|
||||
condition: '"$NIGHTLY_BUILD" == true'
|
||||
tags: true
|
||||
|
||||
- provider: script
|
||||
skip_cleanup: true
|
||||
script: bash ci/travis/ftp_deploy.sh
|
||||
on:
|
||||
condition: $TEST_BUILD = true
|
||||
all_branches: true
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# note that gcc Debug MUST be 1st for Coverity
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=gcc-5 CXX=g++-5
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-xenial'
|
||||
packages:
|
||||
- *global_deps
|
||||
- g++-5
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=gcc-9 CXX=g++-9
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-xenial'
|
||||
packages:
|
||||
- g++-9
|
||||
- *global_deps
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=clang-9 CXX=clang++-9 CMAKE_OPTIONS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-xenial'
|
||||
packages:
|
||||
- *global_deps
|
||||
- g++-9
|
||||
script:
|
||||
- ./ci/travis/script.sh
|
||||
- ./ci/travis/clang_tidy.sh
|
||||
- os: osx
|
||||
env: CONFIGURATION="Debug"
|
||||
|
||||
- os: windows
|
||||
env: CONFIGURATION="Debug" CMAKE_TOOLSET=v141 CMAKE_GENERATOR="Visual Studio 15 2017"
|
||||
- os: windows
|
||||
env: CONFIGURATION="Debug" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
|
||||
|
||||
- os: linux
|
||||
env: CONFIGURATION="Release" CC=gcc-5 CXX=g++-5
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-xenial'
|
||||
packages:
|
||||
- *global_deps
|
||||
- g++-5
|
||||
- os: linux
|
||||
env: CONFIGURATION="Release" CC=gcc-9 CXX=g++-9
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-xenial'
|
||||
packages:
|
||||
- g++-9
|
||||
- *global_deps
|
||||
- os: linux
|
||||
env: CONFIGURATION="Release" CC=clang-9 CXX=clang++-9 CMAKE_OPTIONS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-xenial'
|
||||
packages:
|
||||
- *global_deps
|
||||
- g++-9
|
||||
script:
|
||||
- ./ci/travis/script.sh
|
||||
- ./ci/travis/clang_tidy.sh
|
||||
- os: osx
|
||||
env: CONFIGURATION="Release"
|
||||
|
||||
- os: windows
|
||||
env: CONFIGURATION="Release" CMAKE_TOOLSET=v141 CMAKE_GENERATOR="Visual Studio 15 2017"
|
||||
- os: windows
|
||||
env: CONFIGURATION="Release" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
|
||||
# There is a GCC compiler bug with MinGW that causes compilation failures on Windows at the moment
|
||||
allow_failures:
|
||||
- os: windows
|
||||
env: CONFIGURATION="Debug" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
|
||||
- os: windows
|
||||
env: CONFIGURATION="Release" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
|
||||
fast_finish: true
|
||||
|
||||
before_install:
|
||||
# ugly hack; if running a coverity scan abort all except the 1st build
|
||||
# see note re gcc compiler above needing to be 1st
|
||||
# also note that branch_pattern & the TRAVIS_BRANCH check must match
|
||||
# unfortunately COVERITY_SCAN_BRANCH isn't defined until later in the
|
||||
# build process
|
||||
- if ([[ "${TRAVIS_JOB_NUMBER##*.}" != "1" ]] && [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]]); then false ; fi
|
||||
- source "./ci/travis/check_release.sh"
|
||||
- "./ci/travis/before_install.sh"
|
||||
install:
|
||||
- if [ "$TRAVIS_OS_NAME" = "windows" ]; then export PATH="/c/Program Files/CMake/bin":$PATH; fi
|
||||
- "./ci/travis/install.sh"
|
||||
- export PATH=$HOME/cmake-3.6/bin:$PATH
|
||||
before_script:
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then QT_ENV_SCRIPT=$(find /opt -name 'qt*-env.sh'); source $QT_ENV_SCRIPT; fi
|
||||
- "./ci/travis/before_script.sh"
|
||||
script:
|
||||
- if [ "$BUILD_DEPLOYMENT" = true ] ; then ./ci/travis/release.sh ; else ./ci/travis/script.sh ; fi
|
||||
+17
-18
@@ -39,14 +39,22 @@ endif(NOT CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES)
|
||||
# Override standard CMake configurations
|
||||
set(CMAKE_CONFIGURATION_TYPES Debug Release FastDebug CACHE STRING "Available configurations" FORCE)
|
||||
|
||||
set(FSO_LANGUAGES C CXX)
|
||||
PROJECT(FS2_Open)
|
||||
|
||||
if(APPLE)
|
||||
set(FSO_LANGUAGES ${FSO_LANGUAGES} OBJC OBJCXX)
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
# Currently only GCC support ccache properly without generating additional warnings
|
||||
# Enable ccache on Mac even for clang
|
||||
if(CCACHE_PROGRAM AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR APPLE))
|
||||
if(NOT CMAKE_C_COMPILER_LAUNCHER)
|
||||
message(STATUS "Using ccache for C compilation: ${CCACHE_PROGRAM}")
|
||||
SET(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
|
||||
endif()
|
||||
if(NOT CMAKE_CXX_COMPILER_LAUNCHER)
|
||||
message(STATUS "Using ccache for C++ compilation: ${CCACHE_PROGRAM}")
|
||||
SET(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
PROJECT(FS2_Open LANGUAGES ${FSO_LANGUAGES})
|
||||
|
||||
IF(CMAKE_CROSSCOMPILING)
|
||||
SET(IMPORT_EXE_DIR "IMPORT_EXE_DIR-NOTFOUND" CACHE FILEPATH "Required for a cross compiling build, point to binary directory of a cmake build for the real OS")
|
||||
INCLUDE(${IMPORT_EXE_DIR}/ImportExecutables.cmake)
|
||||
@@ -75,11 +83,9 @@ IF(RESET_INSTALL_PREFIX)
|
||||
ENDIF(NOT $ENV{FS2PATH} STREQUAL "")
|
||||
ENDIF(RESET_INSTALL_PREFIX)
|
||||
|
||||
IF(WIN32 OR APPLE)
|
||||
OPTION(FSO_USE_SPEECH "Use text-to-speach libraries" ON)
|
||||
ENDIF(WIN32 OR APPLE)
|
||||
|
||||
IF (WIN32)
|
||||
OPTION(FSO_USE_SPEECH "Use Windows specific text-to-speach libraries" ON)
|
||||
|
||||
OPTION(FSO_USE_VOICEREC "Enable voice recognition support" ON)
|
||||
|
||||
OPTION(FSO_BUILD_FRED2 "Build FRED2 binary" ON)
|
||||
@@ -123,11 +129,8 @@ option(FSO_RELEASE_LOGGING "Enable logging output for release builds" OFF)
|
||||
OPTION(FSO_BUILD_WITH_FFMPEG "Enable the usage of FFmpeg for sound and custscenes" ON)
|
||||
|
||||
OPTION(FSO_BUILD_WITH_OPENGL "Enable compilation of the OpenGL renderer" ON)
|
||||
OPTION(FSO_BUILD_WITH_OPENGL_DEBUG "Enables debug option for OpenGL" OFF)
|
||||
|
||||
OPTION(FSO_BUILD_WITH_VULKAN "Enable compilation of the Vulkan renderer" OFF)
|
||||
|
||||
OPTION(FSO_BUILD_WITH_OPENXR_DEBUG "Enables debug option for OpenXR" OFF)
|
||||
OPTION(FSO_BUILD_WITH_VULKAN "Enable compilation of the Vulkan renderer" ON)
|
||||
|
||||
MARK_AS_ADVANCED(FORCE FSO_CMAKE_DEBUG)
|
||||
MARK_AS_ADVANCED(FORCE FSO_BUILD_INCLUDED_LIBS)
|
||||
@@ -140,9 +143,7 @@ mark_as_advanced(FORCE ENABLE_COTIRE)
|
||||
mark_as_advanced(FORCE FSO_RELEASE_LOGGING)
|
||||
mark_as_advanced(FORCE FSO_BUILD_WITH_FFMPEG)
|
||||
mark_as_advanced(FORCE FSO_BUILD_WITH_OPENGL)
|
||||
mark_as_advanced(FORCE FSO_BUILD_WITH_OPENGL_DEBUG)
|
||||
mark_as_advanced(FORCE FSO_BUILD_WITH_VULKAN)
|
||||
mark_as_advanced(FORCE FSO_BUILD_WITH_OPENXR_DEBUG)
|
||||
|
||||
# Include cotire file from https://github.com/sakra/cotire/
|
||||
include(cotire)
|
||||
@@ -207,10 +208,8 @@ include(package)
|
||||
include(doxygen)
|
||||
|
||||
# Print used options to log
|
||||
IF(WIN32 OR APPLE)
|
||||
message(STATUS "Using text to speech: ${FSO_USE_SPEECH}")
|
||||
ENDIF()
|
||||
IF (WIN32)
|
||||
message(STATUS "Using text to speech: ${FSO_USE_SPEECH}")
|
||||
message(STATUS "Using voice recogition: ${FSO_USE_VOICEREC}")
|
||||
message(STATUS "Building FRED2: ${FSO_BUILD_FRED2}")
|
||||
elseif(UNIX)
|
||||
|
||||
-179
@@ -3,185 +3,6 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [23.2.0] - 2023-06-16
|
||||
### Changes
|
||||
|
||||
<details><summary> <b>Big Feature: MSAA</b> </summary>
|
||||
|
||||
> The return of a long forgotten feature, with optimizations and improvements
|
||||
> Noticeable reduction to artifacts caused by subpixel geometry and glinting.
|
||||
</details>
|
||||
|
||||
<details><summary> <b>Big Feature: SCPUI</b> </summary>
|
||||
|
||||
> A modernized approach to defining menus in FS
|
||||
> Tired of having your Menus in FSO be at a resolution of potato? Use SCPUI to have them rendered from Fake-HTML to the actual screensize as opposed to a prebuilt graphics!
|
||||
> Tired of being limited to whatever people in the SCP hardcoded in for buttons? Use SCPUI to define buttons and all other manner of shenanigans as Lua-code just as you like.
|
||||
> Tired of needing to replace a bajillion interface graphics to reskin FSO? Use SCPUI, and especially Mjn's existing collection of Lua, CSS, Fake-HTML and images, and you only need to replace about 250 graphics.
|
||||
</details>
|
||||
|
||||
<details><summary> <b>Big Feature: Localized Volumetric Nebulae</b> </summary>
|
||||
|
||||
> Allows specifying a POF as the "hull" of a nebula, which will be rendered using ray marching
|
||||
> Further details can be found on the [GitHub Pull Request](https://github.com/scp-fs2open/fs2open.github.com/pull/5231)
|
||||
> Note: As this is a new feature, many improvements and optimizations remain to be made
|
||||
> Adapted from Andrew Schneider's 2015 SIGGRAPH talk "The real-time volumetric cloudscapes of Horizon: Zero Dawn"
|
||||
</details>
|
||||
|
||||
<details><summary>Game: </summary>
|
||||
|
||||
- Per bank autoaim
|
||||
</details>
|
||||
|
||||
<details><summary>Animation: </summary>
|
||||
|
||||
- Fix CTD on bad legacy animation data
|
||||
- Add proper time wrapping for Animations
|
||||
- Actually handle a mssing `Fade_anim` properly
|
||||
</details>
|
||||
|
||||
<details><summary>Controls: </summary>
|
||||
|
||||
- Organize and map additional keys to librocket
|
||||
- Catch when SDL fails to open a joystick that is enumerated by the OS
|
||||
</details>
|
||||
|
||||
<details><summary>FRED: </summary>
|
||||
|
||||
- Add SpaceMouse support
|
||||
- Add pre-parse enums support
|
||||
- Add music player to FRED
|
||||
- Enhanced SEXP comments
|
||||
- FRED Dialog for Volumetrics
|
||||
- QoL improvements to Object Editor
|
||||
- Add FRED support for the "required weapon" feature
|
||||
- SEXP Tree search and filter
|
||||
</details>
|
||||
|
||||
<details><summary>QtFRED: </summary>
|
||||
|
||||
- Campaign Editor
|
||||
- Add SpaceMouse support
|
||||
- Make 'player starts in chase view' a toggle
|
||||
</details>
|
||||
|
||||
<details><summary>Graphics: </summary>
|
||||
|
||||
- "The other great shader flag removal effort"
|
||||
- Enhance handling of motion debris
|
||||
- Expose texture filtering as a built-in option
|
||||
- Improved particle culling and performance
|
||||
- Optimized trail renderer
|
||||
- Beam Particles
|
||||
- Multiple lighting profiles
|
||||
- Use volume particles for poofs
|
||||
- Optimize for simple trails
|
||||
- Kink shamed the laser bitmaps
|
||||
</details>
|
||||
|
||||
<details><summary>HUD: </summary>
|
||||
|
||||
- Flag to apply HUD shudder to chase view
|
||||
- Add missing HUD gauges
|
||||
- Explicitly do not split lines when making the message log
|
||||
</details>
|
||||
|
||||
<details><summary>Localization: </summary>
|
||||
|
||||
- Add some XSTR entries
|
||||
</details>
|
||||
|
||||
<details><summary>Modding: </summary>
|
||||
|
||||
- Mapify built-in strings
|
||||
- Allow `gameplay_profiles.tbl` to be an alias of `ai_profiles.tbl`
|
||||
- Modular rank table
|
||||
- Toggle auto-assigning personas
|
||||
- Add some parameters for corkscrew starting angle
|
||||
- Add clip planes to `game_settings.tbl`
|
||||
- Add `+Use ship` as a Template
|
||||
- Modular messages table
|
||||
- Add arbitrary curves support
|
||||
- Traitor overrides
|
||||
- Add support for loose lz4 compressed files
|
||||
- Add per-species warp effects
|
||||
</details>
|
||||
|
||||
<details><summary>Models: </summary>
|
||||
|
||||
- Fix submodel sanity check
|
||||
- Fix techroom modelnum references
|
||||
- Adjust movement sanity checks to account for more situations
|
||||
- Modular POF Features 2
|
||||
- Add fov values to .pof models
|
||||
- Add a Translation Moveable
|
||||
- Remove model octants
|
||||
- Fix glowpoints on animated submodels
|
||||
- Update type_flags when dock name changes
|
||||
- Add additional checks for Animation List handling of nonexistent polymodel instances
|
||||
- Virtual POFs: Modify Subsystems
|
||||
- Validate chunk size to avoid alignment crash and add align skip flag
|
||||
</details>
|
||||
|
||||
<details><summary>Multiplayer: </summary>
|
||||
|
||||
- Generic Lua Multiplayer RPC
|
||||
</details>
|
||||
|
||||
<details><summary>Performance: </summary>
|
||||
|
||||
- Increase sound update rate
|
||||
- Add `line of sight` as an optional AI override
|
||||
</details>
|
||||
|
||||
<details><summary>SEXPs: </summary>
|
||||
|
||||
- `turret-fired-since`, returns `true` if the specified turret has fired in the last `N` milliseconds
|
||||
- `is-ship-emp-active`, returns `true` if the specified ship or list of ships is currently under an EMP effect
|
||||
- `turret-has-primary` and `turret-has-secondary`, returns `true` if the specified turret contains the specified weapon
|
||||
- `has-armor-type`, returns `true` if the specified ship or subsystem has the specified armor type
|
||||
- `OPF_ANY_HUD_GAUGE` and `OPF_EVENT_NAME`, new Lua SEXP parameters
|
||||
- Enhance Dynamic SEXPs with parent parameters
|
||||
- Add "afterburn hard" AI goal flag
|
||||
</details>
|
||||
|
||||
<details><summary>Scripting: </summary>
|
||||
|
||||
- Add option to deprecate hooks
|
||||
- Get audiostream duration in float seconds
|
||||
- Lua method to check if the game has focus
|
||||
- `On warp complete` hook
|
||||
- Allow Lua to set the Discord presence to custom strings
|
||||
- Add virtvars for goal satisfaction and score
|
||||
- Allow scripts to read and add LuaEnums
|
||||
- Funcs and virtvars for SCPUI pause screen
|
||||
- Expose pausing weapon sounds
|
||||
- Make collision_group_id accessible to parse objects
|
||||
- Pass shortcut key character to Lua as a hook variable
|
||||
- Lua method to free all loaded models
|
||||
- `On Asteroid Created` hook
|
||||
- SCPUI methods required for handling closeup briefing icons
|
||||
- Expose some Nebula settings to Lua
|
||||
- SCPUI mission log
|
||||
- SCPUI APIsfor the Game Help UI, medals access, and control config
|
||||
- Force expand wings instead of toggle for SCPUI
|
||||
- Add misc. validity checks
|
||||
- Convert hotkey types to enum
|
||||
- Finalize SCPUI API
|
||||
- Blocking `On Frame` executor
|
||||
- SCPUI Hud Config API
|
||||
- Configurable restriction for ships that accept Lua player orders
|
||||
- Add `ship::isPlayer()`
|
||||
- Lua access to default countermeasures class
|
||||
- Flag to check if a ship or weapon class is player allowed
|
||||
- Add hooks for comm menu opening/closing
|
||||
</details>
|
||||
|
||||
<details><summary>Technical: </summary>
|
||||
|
||||
- Improve CFLAGS handling
|
||||
</details>
|
||||
|
||||
## [22.2.0] - 2022-08-06
|
||||
|
||||
```
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
FreeSpace2 *S*ource *C*ode *P*roject
|
||||
==
|
||||
[](https://travis-ci.org/scp-fs2open/fs2open.github.com)
|
||||
[](https://ci.appveyor.com/project/SirKnightly/fs2open-github-com/branch/master)
|
||||
[](https://scan.coverity.com/projects/870)
|
||||
|
||||
Building
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
version: 1.0.0.{build}
|
||||
image: Visual Studio 2015
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
clone_depth: 10
|
||||
environment:
|
||||
matrix:
|
||||
- BuildID: 0
|
||||
CMAKE_GENERATOR: Visual Studio 14 2015
|
||||
PlatformToolset: v140
|
||||
QT_DIR: C:\Qt\5.9\msvc2015
|
||||
- BuildID: 1
|
||||
CMAKE_GENERATOR: Visual Studio 14 2015 Win64
|
||||
PlatformToolset: v140
|
||||
QT_DIR: C:\Qt\5.9\msvc2015_64
|
||||
before_build:
|
||||
- git submodule update --init --recursive
|
||||
build_script:
|
||||
- ps: . $Env:APPVEYOR_BUILD_FOLDER/ci/appveyor/build.ps1
|
||||
test_script:
|
||||
- ps: . $Env:APPVEYOR_BUILD_FOLDER/ci/appveyor/test.ps1
|
||||
|
||||
deploy:
|
||||
- provider: GitHub
|
||||
auth_token:
|
||||
secure: h55Scpy+3vmo1Yb7WlSIGA4d9DRnsbzUYc2LYsQdByQHZHbqrqjBpicH0D2FFLEO
|
||||
on:
|
||||
ReleaseBuild: true # deploy on release push only
|
||||
|
||||
- provider: FTP
|
||||
protocol: sftp
|
||||
host: scp.indiegames.us
|
||||
username:
|
||||
secure: SFivQZfatqWHXK1ijYK3GQ==
|
||||
password:
|
||||
secure: q6Zk/412o1ri+NEya1dl1Q==
|
||||
folder: public_html/builds/nightly/$(VersionName)
|
||||
on:
|
||||
NightlyBuild: true # deploy on nightly push only
|
||||
|
||||
- provider: FTP
|
||||
protocol: sftp
|
||||
host: porphyrion.feralhosting.com
|
||||
username:
|
||||
secure: 36+bVD8eJgI0BVbi7TZ4zQ==
|
||||
password:
|
||||
secure: CrzmDVca8AGG08iWPA1gOD4Ge06+wJ3rcBagBGclwYQ=
|
||||
folder: www/datacorder.porphyrion.feralhosting.com/public_html/builds/nightly/$(VersionName)
|
||||
on:
|
||||
NightlyBuild: true # deploy on nightly push only
|
||||
|
||||
- provider: FTP
|
||||
protocol: sftp
|
||||
host: porphyrion.feralhosting.com
|
||||
username:
|
||||
secure: 36+bVD8eJgI0BVbi7TZ4zQ==
|
||||
password:
|
||||
secure: CrzmDVca8AGG08iWPA1gOD4Ge06+wJ3rcBagBGclwYQ=
|
||||
folder: www/datacorder.porphyrion.feralhosting.com/public_html/builds/test/$(VersionName)
|
||||
on:
|
||||
TestBuild: true # deploy on test build push only
|
||||
@@ -0,0 +1,164 @@
|
||||
|
||||
class BuildConfig {
|
||||
[string]$Generator
|
||||
[string]$PackageType
|
||||
[string]$Toolset
|
||||
[string]$SimdType
|
||||
[string]$QtDir
|
||||
[Bool]$SourcePackage
|
||||
}
|
||||
|
||||
$NightlyConfigurations = @(
|
||||
# [BuildConfig]@{
|
||||
# Generator="Visual Studio 14 2015 Win64";
|
||||
# PackageType="Win64";
|
||||
# Toolset="v140";
|
||||
# SimdType="SSE2";
|
||||
# QtDir="C:\Qt\5.9\msvc2015_64";
|
||||
# SourcePackage=$false;
|
||||
# },
|
||||
# [BuildConfig]@{
|
||||
# Generator="Visual Studio 14 2015";
|
||||
# PackageType="Win32";
|
||||
# Toolset="v140";
|
||||
# SimdType="SSE2";
|
||||
# QtDir="C:\Qt\5.9\msvc2015";
|
||||
# SourcePackage=$false;
|
||||
# }
|
||||
)
|
||||
$ReleaseConfigurations = @(
|
||||
# [BuildConfig]@{
|
||||
# Generator="Visual Studio 14 2015";
|
||||
# PackageType="Win32";
|
||||
# Toolset="v140";
|
||||
# SimdType="SSE2";
|
||||
# QtDir="C:\Qt\5.9\msvc2015";
|
||||
# SourcePackage=$true;
|
||||
# }
|
||||
# [BuildConfig]@{
|
||||
# Generator="Visual Studio 14 2015";
|
||||
# PackageType="Win32-AVX";
|
||||
# Toolset="v140";
|
||||
# SimdType="AVX";
|
||||
# QtDir="C:\Qt\5.9\msvc2015";
|
||||
# SourcePackage=$false;
|
||||
# }
|
||||
# [BuildConfig]@{
|
||||
# Generator="Visual Studio 14 2015 Win64";
|
||||
# PackageType="Win64";
|
||||
# Toolset="v140";
|
||||
# SimdType="SSE2";
|
||||
# QtDir="C:\Qt\5.9\msvc2015_64";
|
||||
# SourcePackage=$false;
|
||||
# }
|
||||
# [BuildConfig]@{
|
||||
# Generator="Visual Studio 14 2015 Win64";
|
||||
# PackageType="Win64-AVX";
|
||||
# Toolset="v140";
|
||||
# SimdType="AVX";
|
||||
# QtDir="C:\Qt\5.9\msvc2015_64";
|
||||
# SourcePackage=$false;
|
||||
# }
|
||||
)
|
||||
|
||||
$BuildConfigurations = $null
|
||||
|
||||
# Default values
|
||||
$ReleaseBuild = $false
|
||||
$NightlyBuild = $false
|
||||
$TestBuild = $false
|
||||
|
||||
# Set to true to test either the release or the nightly part of this script
|
||||
$ReleaseTest = $false
|
||||
$NightlyTest = $false
|
||||
$TestBuildTest = $false
|
||||
|
||||
if ($ReleaseTest -Or ([System.Convert]::ToBoolean($env:APPVEYOR_REPO_TAG) -And ("$env:APPVEYOR_REPO_TAG_NAME" -match "^release_(.*)"))) {
|
||||
# Tag matches
|
||||
$ReleaseBuild = $true
|
||||
$PackageName = "fs2_open_$($matches[1])"
|
||||
$BuildConfigurations = $ReleaseConfigurations
|
||||
}
|
||||
|
||||
if ($NightlyTest -Or ([System.Convert]::ToBoolean($env:APPVEYOR_REPO_TAG) -And ("$env:APPVEYOR_REPO_TAG_NAME" -match "^nightly_(.*)"))) {
|
||||
# Tag matches
|
||||
$NightlyBuild = $true
|
||||
$PackageName = "nightly_$($matches[1])"
|
||||
Set-AppveyorBuildVariable 'VersionName' "$($matches[1])"
|
||||
$BuildConfigurations = $NightlyConfigurations
|
||||
}
|
||||
|
||||
if ($TestBuildTest -Or ([System.Convert]::ToInt32($env:APPVEYOR_PULL_REQUEST_NUMBER) -le 0 -And ("$env:APPVEYOR_REPO_BRANCH" -match "^test\/(.*)"))) {
|
||||
# Tag matches
|
||||
$TestBuild = $true
|
||||
$PackageName = "test_$($matches[1])"
|
||||
Set-AppveyorBuildVariable 'VersionName' "$($matches[1])"
|
||||
$BuildConfigurations = $NightlyConfigurations
|
||||
|
||||
# Override the revision string so that the builds are named correctly
|
||||
[System.IO.File]::WriteAllLines("$env:APPVEYOR_BUILD_FOLDER/version_override.cmake", "set(FSO_VERSION_REVISION_STR $env:VersionName)")
|
||||
}
|
||||
|
||||
# Multiply by 2 so that we can add 0 or 1 for debug or release Configs
|
||||
$buildID = [convert]::ToInt32($env:BuildID) * 2
|
||||
if ($Env:Configuration -eq "Release") {
|
||||
$buildID = $buildID + 1
|
||||
}
|
||||
|
||||
$DeployBuild = $false
|
||||
if ($ReleaseBuild -Or $NightlyBuild -Or $TestBuild) {
|
||||
$DeployBuild = $true
|
||||
}
|
||||
|
||||
Set-AppveyorBuildVariable 'ReleaseBuild' "$ReleaseBuild"
|
||||
Set-AppveyorBuildVariable 'NightlyBuild' "$NightlyBuild"
|
||||
Set-AppveyorBuildVariable 'TestBuild' "$TestBuild"
|
||||
|
||||
New-Item build -type directory
|
||||
Set-Location -Path build
|
||||
|
||||
if ($DeployBuild) {
|
||||
# Release build
|
||||
if ($buildID -ge $BuildConfigurations.Length) {
|
||||
# Not needed
|
||||
exit 0
|
||||
}
|
||||
|
||||
$buildConfig = $BuildConfigurations[$buildID]
|
||||
|
||||
if ($buildConfig.SourcePackage -eq $True) {
|
||||
7z a -xr'!.git' "$($PackageName)-source-Win.zip" "$env:APPVEYOR_BUILD_FOLDER"
|
||||
Push-AppveyorArtifact "$($PackageName)-source-Win.zip"
|
||||
}
|
||||
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$env:APPVEYOR_BUILD_FOLDER/../install" -DFSO_USE_SPEECH="ON" `
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$($buildConfig.SimdType)" `
|
||||
-DQT5_INSTALL_ROOT="$($buildConfig.QtDir)" -DFSO_BUILD_QTFRED=ON `
|
||||
-DFSO_INSTALL_DEBUG_FILES="ON" `
|
||||
-G "$($buildConfig.Generator)" -T "$($buildConfig.Toolset)" ..
|
||||
|
||||
$Configs = @("Release", "FastDebug")
|
||||
foreach ($config in $Configs) {
|
||||
cmake --build . --config "$config" --target INSTALL -- /verbosity:minimal
|
||||
if (! ($?)) {
|
||||
Add-AppveyorMessage "A release build failed!"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
7z a -xr'!*.pdb' "$($PackageName)-builds-$($buildConfig.PackageType).zip" "$env:APPVEYOR_BUILD_FOLDER/../install/*"
|
||||
Push-AppveyorArtifact "$($PackageName)-builds-$($buildConfig.PackageType).zip"
|
||||
|
||||
7z a "$($PackageName)-debug-$($buildConfig.PackageType).7z" "$env:APPVEYOR_BUILD_FOLDER/../install/*.pdb"
|
||||
Push-AppveyorArtifact "$($PackageName)-debug-$($buildConfig.PackageType).7z"
|
||||
} else {
|
||||
cmake -DFSO_USE_SPEECH="ON" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="ON" -DFSO_BUILD_TESTS="ON" -DMSVC_SIMD_INSTRUCTIONS=SSE2 `
|
||||
-DFSO_BUILD_QTFRED=ON -DQT5_INSTALL_ROOT="$env:QT_DIR" -DFSO_BUILD_FRED2="ON" `
|
||||
-G "$Env:CMAKE_GENERATOR" -T "$Env:PlatformToolset" ..
|
||||
|
||||
cmake --build . --config "$Env:CONFIGURATION" -- /verbosity:minimal
|
||||
|
||||
if (! ($?)) {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
if ([System.Convert]::ToBoolean($env:ReleaseBuild) -Or [System.Convert]::ToBoolean($env:NightlyBuild) -Or [System.Convert]::ToBoolean($env:TestBuild)) {
|
||||
# Skip tests for deployment
|
||||
exit 0
|
||||
} else {
|
||||
write "Running unit tests..."
|
||||
# Run unit tests
|
||||
&"$pwd\bin\$Env:CONFIGURATION\unittests.exe" --gtest_shuffle 2>&1
|
||||
|
||||
if (! ($?)) {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
+11
-22
@@ -4,24 +4,24 @@ if [ "$COMPILER" = "gcc-5" ]; then
|
||||
export CC=gcc-5
|
||||
export CXX=g++-5
|
||||
fi
|
||||
if [ "$COMPILER" = "gcc-13" ]; then
|
||||
export CC=gcc-13
|
||||
export CXX=g++-13
|
||||
if [ "$COMPILER" = "gcc-10" ]; then
|
||||
export CC=gcc-10
|
||||
export CXX=g++-10
|
||||
fi
|
||||
if [ "$COMPILER" = "clang-16" ]; then
|
||||
export CC=clang-16
|
||||
export CXX=clang++-16
|
||||
if [ "$COMPILER" = "clang-9" ]; then
|
||||
# Work around bug in clang that uses the wrong installation directory: https://bugs.llvm.org/show_bug.cgi?id=47460
|
||||
export CC=$(readlink -f $(which clang-9))
|
||||
export CXX=$(readlink -f $(which clang++-9))
|
||||
fi
|
||||
|
||||
LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH
|
||||
if [ "$RUNNER_OS" = "macOS" ]; then
|
||||
CXXFLAGS="-mtune=generic -pipe -Wno-unknown-pragmas"
|
||||
CFLAGS="-mtune=generic -pipe -Wno-unknown-pragmas"
|
||||
# TODO: Vulkan support is disabled on MacOS due to issues with the test suite not linking correctly
|
||||
PLATFORM_CMAKE_OPTIONS="-DFSO_BUILD_WITH_VULKAN=OFF"
|
||||
PLATFORM_CMAKE_OPTIONS=""
|
||||
export CMAKE_OSX_ARCHITECTURES="$ARCHITECTURE"
|
||||
else
|
||||
CXXFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas -static-libstdc++"
|
||||
CXXFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
CFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
PLATFORM_CMAKE_OPTIONS="-DFSO_BUILD_APPIMAGE=ON"
|
||||
fi
|
||||
@@ -29,13 +29,6 @@ fi
|
||||
CMAKE_OPTIONS="$JOB_CMAKE_OPTIONS"
|
||||
if [[ "$COMPILER" =~ ^clang.*$ ]]; then
|
||||
CMAKE_OPTIONS="$CMAKE_OPTIONS -DCLANG_USE_LIBCXX=ON"
|
||||
# force clang to silently allow -static-libstdc++ flag
|
||||
CXXFLAGS="$CXXFLAGS -Qunused-arguments"
|
||||
fi
|
||||
|
||||
if [ ! "$CCACHE_PATH" = "" ]; then
|
||||
echo "Using ccache at $CCACHE_PATH"
|
||||
CMAKE_OPTIONS="$CMAKE_OPTIONS -DCMAKE_C_COMPILER_LAUNCHER=$CCACHE_PATH -DCMAKE_CXX_COMPILER_LAUNCHER=$CCACHE_PATH"
|
||||
fi
|
||||
|
||||
mkdir build
|
||||
@@ -48,11 +41,7 @@ export LD_LIBRARY_PATH
|
||||
if [ "$RUNNER_OS" = "macOS" ]; then
|
||||
brew install ninja
|
||||
fi
|
||||
|
||||
# CMAKE_JOB_POOLS and CMAKE_JOB_POOL_LINK ensure that when using ninja, link operations are done sequentially
|
||||
# we have some build rules that do not play nice with parallel invocation and that fixes these issues
|
||||
|
||||
cmake -G Ninja -DFSO_FATAL_WARNINGS=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON $CMAKE_OPTIONS $PLATFORM_CMAKE_OPTIONS \
|
||||
-DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DCMAKE_BUILD_TYPE=$CONFIGURATION \
|
||||
-DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFSO_BUILD_QTFRED=${ENABLE_QTFRED:-OFF} \
|
||||
-DSHADERS_ENABLE_COMPILATION=ON -DCMAKE_JOB_POOLS=link=1 -DCMAKE_JOB_POOL_LINK=link ..
|
||||
-DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFSO_BUILD_QTFRED=ON \
|
||||
-DSHADERS_ENABLE_COMPILATION=ON ..
|
||||
@@ -10,27 +10,27 @@ source $HERE/dist_functions.sh
|
||||
if [ "$OS" = "Linux" ]; then
|
||||
tar -cvzf "$(get_package_name)-builds-Linux.tar.gz" *
|
||||
|
||||
echo "package_path=$(pwd)/$(get_package_name)-builds-Linux.tar.gz" >> $GITHUB_OUTPUT
|
||||
echo "package_name=$(get_package_name)-builds-Linux.tar.gz" >> $GITHUB_OUTPUT
|
||||
echo "package_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-Linux.tar.gz")" >> $GITHUB_OUTPUT
|
||||
echo "::set-output name=package_path::$(pwd)/$(get_package_name)-builds-Linux.tar.gz"
|
||||
echo "::set-output name=package_name::$(get_package_name)-builds-Linux.tar.gz"
|
||||
echo "::set-output name=package_mime::$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-Linux.tar.gz")"
|
||||
elif [ "$OS" = "Windows" ]; then
|
||||
7z a -xr'!*.pdb' "$(get_package_name)-builds-$ARCH-$SIMD.zip" "*"
|
||||
|
||||
echo "package_path=$(pwd)/$(get_package_name)-builds-$ARCH-$SIMD.zip" >> $GITHUB_OUTPUT
|
||||
echo "package_name=$(get_package_name)-builds-$ARCH-$SIMD.zip" >> $GITHUB_OUTPUT
|
||||
echo "package_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-$ARCH-$SIMD.zip")" >> $GITHUB_OUTPUT
|
||||
echo "::set-output name=package_path::$(pwd)/$(get_package_name)-builds-$ARCH-$SIMD.zip"
|
||||
echo "::set-output name=package_name::$(get_package_name)-builds-$ARCH-$SIMD.zip"
|
||||
echo "::set-output name=package_mime::$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-$ARCH-$SIMD.zip")"
|
||||
|
||||
7z a "$(get_package_name)-debug-$ARCH-$SIMD.7z" "*.pdb"
|
||||
|
||||
echo "debug_path=$(pwd)/$(get_package_name)-debug-$ARCH-$SIMD.7z" >> $GITHUB_OUTPUT
|
||||
echo "debug_name=$(get_package_name)-debug-$ARCH-$SIMD.7z" >> $GITHUB_OUTPUT
|
||||
echo "debug_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-debug-$ARCH-$SIMD.7z")" >> $GITHUB_OUTPUT
|
||||
echo "::set-output name=debug_path::$(pwd)/$(get_package_name)-debug-$ARCH-$SIMD.7z"
|
||||
echo "::set-output name=debug_name::$(get_package_name)-debug-$ARCH-$SIMD.7z"
|
||||
echo "::set-output name=debug_mime::$(file -b --mime-type "$(pwd)/$(get_package_name)-debug-$ARCH-$SIMD.7z")"
|
||||
elif [ "$OS" = "Mac" ]; then
|
||||
tar -cvzf "$(get_package_name)-builds-Mac-$ARCH.tar.gz" *.app
|
||||
tar -cvzf "$(get_package_name)-builds-Mac.tar.gz" *
|
||||
|
||||
echo "package_path=$(pwd)/$(get_package_name)-builds-Mac-$ARCH.tar.gz" >> $GITHUB_OUTPUT
|
||||
echo "package_name=$(get_package_name)-builds-Mac-$ARCH.tar.gz" >> $GITHUB_OUTPUT
|
||||
echo "package_mime=$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-Mac-$ARCH.tar.gz")" >> $GITHUB_OUTPUT
|
||||
echo "::set-output name=package_path::$(pwd)/$(get_package_name)-builds-Mac.tar.gz"
|
||||
echo "::set-output name=package_name::$(get_package_name)-builds-Mac.tar.gz"
|
||||
echo "::set-output name=package_mime::$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-Mac.tar.gz")"
|
||||
else
|
||||
echo "Invalid OS: $OS"
|
||||
fi
|
||||
@@ -5,13 +5,6 @@ HERE=$(dirname "$SCRIPT")
|
||||
|
||||
export LD_LIBRARY_PATH=$(pwd)/bin/lib:$LD_LIBRARY_PATH
|
||||
|
||||
# if on mac and building for architecture that doesn't match host
|
||||
# then unittests will fail so we just need to skip it (for now)
|
||||
if [ "$RUNNER_OS" = "macOS" ] && [ "$ARCH" != "$(uname -m)" ]; then
|
||||
echo "Skipping tests due to architecture mismatch!"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$CONFIGURATION" = "Debug"] && [[ "$RUNNER_OS" != "macOS" ]] ; then
|
||||
valgrind --leak-check=full --error-exitcode=1 --gen-suppressions=all \
|
||||
--suppressions="$HERE/valgrind.supp" ./bin/unittests --gtest_shuffle
|
||||
|
||||
@@ -10,21 +10,11 @@ HERE=$(dirname "$SCRIPT")
|
||||
source $HERE/dist_functions.sh
|
||||
|
||||
if [ "$UPLOAD_TYPE" = "nightly" ]; then
|
||||
any_success=false
|
||||
if SSHPASS=$INDIEGAMES_SSHPASS upload_files_to_sftp "$INDIEGAMES_USER@scp.indiegames.us" "public_html/builds/nightly"; then
|
||||
any_success=true
|
||||
fi
|
||||
SSHPASS=$INDIEGAMES_SSHPASS upload_files_to_sftp "$INDIEGAMES_USER@scp.indiegames.us" "public_html/builds/nightly"
|
||||
|
||||
if SSHPASS=$DATACORDER_SSHPASS upload_files_to_sftp "$DATACORDER_USER@perses.feralhosting.com" "www/datacorder.perses.feralhosting.com/public_html/builds/nightly"; then
|
||||
any_success=true
|
||||
fi
|
||||
|
||||
if [ "$any_success" = "false" ]; then
|
||||
echo "All uploads failed"
|
||||
exit 1
|
||||
fi
|
||||
SSHPASS=$DATACORDER_SSHPASS upload_files_to_sftp "$DATACORDER_USER@porphyrion.feralhosting.com" "www/datacorder.porphyrion.feralhosting.com/public_html/builds/nightly"
|
||||
elif [ "$UPLOAD_TYPE" = "test" ]; then
|
||||
SSHPASS=$DATACORDER_SSHPASS upload_files_to_sftp "$DATACORDER_USER@perses.feralhosting.com" "www/datacorder.perses.feralhosting.com/public_html/builds/test"
|
||||
SSHPASS=$DATACORDER_SSHPASS upload_files_to_sftp "$DATACORDER_USER@porphyrion.feralhosting.com" "www/datacorder.porphyrion.feralhosting.com/public_html/builds/test"
|
||||
else
|
||||
echo "Unknown upload type $UPLOAD_TYPE"
|
||||
exit 1
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ class ForumAPI:
|
||||
"body": content
|
||||
})
|
||||
|
||||
if resp.status_code != 200:
|
||||
if resp.text != "OK":
|
||||
print("Post failed! Response: %s" %resp.text)
|
||||
|
||||
return resp.json()
|
||||
|
||||
+3
-7
@@ -19,7 +19,7 @@
|
||||
# HLP_API:
|
||||
# HLP_KEY:
|
||||
|
||||
# LINUX_RESULT: bool, if the linux builds were successfully uploaded
|
||||
# LINUX_RESULT: bool, if the linux builds were sucessfully uploaded
|
||||
# WINDOWS_RESULT: bool, if the windows builds were successfully uploaded
|
||||
|
||||
import sys
|
||||
@@ -137,8 +137,8 @@ def main():
|
||||
"pass": os.environ["INDIEGAMES_SSHPASS"],
|
||||
"path": "public_html/builds/{type}/{version}/",
|
||||
"mirrors": (
|
||||
"https://perses.feralhosting.com/datacorder/builds/{type}/{version}/{file}",
|
||||
"https://scp.indiegames.us/builds/{type}/{version}/{file}",
|
||||
"https://porphyrion.feralhosting.com/datacorder/builds/{type}/{version}/{file}",
|
||||
"http://scp.indiegames.us/builds/{type}/{version}/{file}",
|
||||
),
|
||||
},
|
||||
"nebula": {
|
||||
@@ -260,10 +260,6 @@ def main():
|
||||
if "Linux" not in groups.keys():
|
||||
print("ERROR: No Linux builds were detected!")
|
||||
sys.exit(1)
|
||||
|
||||
if "Mac" not in groups.keys():
|
||||
print("ERROR: No Mac builds were detected!")
|
||||
sys.exit(1)
|
||||
|
||||
# z64: What dose this do???
|
||||
# print(installer.render_installer_config(version, groups, config))
|
||||
|
||||
+19
-30
@@ -7,14 +7,6 @@ import requests
|
||||
from file_list import ReleaseFile
|
||||
from util import retry_multi, GLOBAL_TIMEOUT
|
||||
|
||||
LINUX_KEY = "Linux"
|
||||
MACOSX_X64_KEY = "Mac-x86_64"
|
||||
MACOSX_ARM64_KEY = "Mac-arm64"
|
||||
WIN32_SSE2_KEY = "Win32-SSE2"
|
||||
WIN64_SSE2_KEY = "Win64-SSE2"
|
||||
WIN32_AVX_KEY = "Win32-AVX"
|
||||
WIN64_AVX_KEY = "Win64-AVX"
|
||||
|
||||
metadata = {
|
||||
'type': 'engine',
|
||||
'title': 'FSO',
|
||||
@@ -34,30 +26,28 @@ metadata = {
|
||||
}
|
||||
|
||||
platforms = {
|
||||
LINUX_KEY: 'linux',
|
||||
MACOSX_X64_KEY: 'macosx',
|
||||
MACOSX_ARM64_KEY: 'macosx',
|
||||
WIN32_SSE2_KEY: 'windows',
|
||||
WIN64_SSE2_KEY: 'windows',
|
||||
WIN32_AVX_KEY: 'windows',
|
||||
WIN64_AVX_KEY: 'windows'
|
||||
'Linux': 'linux',
|
||||
'MacOSX': 'macosx',
|
||||
'Win32-SSE2': 'windows',
|
||||
'Win64-SSE2': 'windows',
|
||||
'Win32-AVX': 'windows',
|
||||
'Win64-AVX': 'windows'
|
||||
}
|
||||
|
||||
envs = {
|
||||
LINUX_KEY: 'linux && x86_64', # Linux only has 64bit builds
|
||||
MACOSX_X64_KEY: 'macosx && x86_64',
|
||||
MACOSX_ARM64_KEY: 'macosx && arm64',
|
||||
WIN32_SSE2_KEY: 'windows',
|
||||
WIN64_SSE2_KEY: 'windows && x86_64',
|
||||
WIN32_AVX_KEY: 'windows && avx',
|
||||
WIN64_AVX_KEY: 'windows && avx && x86_64'
|
||||
'Linux': 'linux && x86_64', # Linux only has 64bit builds
|
||||
'MacOSX': 'macosx',
|
||||
'Win32-SSE2': 'windows',
|
||||
'Win64-SSE2': 'windows && x86_64',
|
||||
'Win32-AVX': 'windows && avx',
|
||||
'Win64-AVX': 'windows && avx && x86_64'
|
||||
}
|
||||
|
||||
subdirs = {
|
||||
WIN32_SSE2_KEY: 'x86',
|
||||
WIN64_SSE2_KEY: 'x64',
|
||||
WIN32_AVX_KEY: 'x86_avx',
|
||||
WIN64_AVX_KEY: 'x64_avx'
|
||||
'Win32-SSE2': 'x86',
|
||||
'Win64-SSE2': 'x64',
|
||||
'Win32-AVX': 'x86_avx',
|
||||
'Win64-AVX': 'x64_avx'
|
||||
}
|
||||
|
||||
|
||||
@@ -113,7 +103,7 @@ def render_nebula_release(version, stability, files, config):
|
||||
'filename': dest_fn
|
||||
})
|
||||
|
||||
if group == LINUX_KEY and fn.endswith('.AppImage'):
|
||||
if group == 'Linux' and fn.endswith('.AppImage'):
|
||||
if 'qtfred' in fn:
|
||||
if '-FASTDBG' in fn:
|
||||
label = 'QtFRED Debug'
|
||||
@@ -138,7 +128,7 @@ def render_nebula_release(version, stability, files, config):
|
||||
'label': label,
|
||||
'properties': props,
|
||||
})
|
||||
elif group.startswith('Mac') and fn.startswith(os.path.basename(fn) + '.app/'):
|
||||
elif group == 'MacOSX' and fn.startswith(os.path.basename(fn) + '.app/'):
|
||||
if 'qtfred' in fn:
|
||||
if '-FASTDBG' in fn:
|
||||
label = 'QtFRED Debug'
|
||||
@@ -151,8 +141,7 @@ def render_nebula_release(version, stability, files, config):
|
||||
label = None
|
||||
|
||||
props = {
|
||||
"arm64": "arm64" in fn,
|
||||
"x64": "x64" in fn,
|
||||
"x64": True, # All Mac builds are 64-bit
|
||||
"sse2": True, # There are no forced options on mac but 64-bit always implies SSE2 so we set that here
|
||||
"avx": False,
|
||||
"avx2": False,
|
||||
|
||||
+13
-21
@@ -9,20 +9,20 @@ PLACEHOLDER
|
||||
|
||||
Deprecations are a mechanism in FSO where a certain feature or aspect of the engine has changed or is no longer supported. Since this would normally break existing mods we have the mod table feature "[tt]$Target Version:[/tt]" with which a mod can specify what version of FSO it was developed with. The features listed above will be removed or changed when the target version of a mod is at least the version released in this post.
|
||||
|
||||
[size=5pt]Previous [url=https://www.hard-light.net/forums/index.php?topic=98682.0]23.0.0 Release Thread[/url][/size]
|
||||
[size=5pt]Previous [url=https://www.hard-light.net/forums/index.php?topic=97293.0]21.0 Release Thread[/url][/size]
|
||||
|
||||
Launchers, if you don't have one already:
|
||||
[b]All platforms: [/b] For every day use, we recommend [url=https://www.hard-light.net/forums/index.php?topic=94068.0]Knossos[/url], an integrated solution for downloading and launching mods.
|
||||
|
||||
[hidden=Alternative Launchers]
|
||||
Cross-platform: [url=https://www.hard-light.net/forums/index.php?topic=89162]wxLauncher 0.12.x Test Build[/url] (ongoing project for a unified launcher, you should upgrade to the latest RC/test build if you have not yet)
|
||||
Cross-platform: [url=http://www.hard-light.net/forums/index.php?topic=89162]wxLauncher 0.12.x Test Build[/url] (ongoing project for a unified launcher, you should upgrade to the latest RC/test build if you have not yet)
|
||||
[b]Important:[/b] For best compatibility with FSO 3.8 and later you should use at least wxLauncher 0.12.
|
||||
|
||||
Windows: [url=http://scp.fsmods.net/builds/Launcher55g.zip]Launcher 5.5g[/url] ([url=https://scp.indiegames.us/builds/Launcher55g.zip]Mirror[/url]) ([url=https://www.mediafire.com/?wdvzn7hhhzh418m]Mirror[/url]) Not compatible with Windows 8+, use wxLauncher above
|
||||
OS X: Soulstorm's [url=https://www.hard-light.net/forums/index.php/topic,51391.0.html]OS X Launcher 3.0[/url]
|
||||
Linux: [url=https://www.hard-light.net/forums/index.php/topic,53206.0.html]YAL[/url] or [url=https://www.hard-light.net/wiki/index.php/Fs2_open_on_Linux/Graphics_Settings]by hand[/url] or whatever you can figure out.[/hidden]
|
||||
Windows: [url=http://scp.fsmods.net/files/Launcher55g.zip]Launcher 5.5g[/url] ([url=http://scp.indiegames.us/builds/Launcher55g.zip]Mirror[/url]) ([url=http://www.mediafire.com/?wdvzn7hhhzh418m]Mirror[/url]) Not compatible with Windows 8+, use wxLauncher above
|
||||
OS X: Soulstorm's [url=http://www.hard-light.net/forums/index.php/topic,51391.0.html]OS X Launcher 3.0[/url]
|
||||
Linux: [url=http://www.hard-light.net/forums/index.php/topic,53206.0.html]YAL[/url] or [url=http://www.hard-light.net/wiki/index.php/Fs2_open_on_Linux/Graphics_Settings]by hand[/url] or whatever you can figure out.[/hidden]
|
||||
|
||||
[img]https://scp.indiegames.us/img/windows-icon.png[/img] [color=green][size=12pt]Windows (32/64-bit)[/size][/color]
|
||||
[img]http://scp.indiegames.us/img/windows-icon.png[/img] [color=green][size=12pt]Windows (32/64-bit)[/size][/color]
|
||||
[size=8pt]Compiled using GitHub Actions on Windows Server 2019 (10.0.17763), Visual Studio Enterprise 2019[/size]
|
||||
|
||||
[b]64-bit:[/b] ${build(groups["Win64"].mainFile)}
|
||||
@@ -40,37 +40,29 @@ Linux: [url=https://www.hard-light.net/forums/index.php/topic,53206.0.html]YAL[
|
||||
[size=8pt]This one is based on the AVX Optimizations from the MSVC Compiler.[/size]
|
||||
|
||||
[b]What are those SSE, SSE2 and AVX builds I keep seeing everywhere?[/b]
|
||||
[url=https://www.hard-light.net/forums/index.php?topic=65628.0]Your answer is in this topic.[/url]
|
||||
[url=http://www.hard-light.net/forums/index.php?topic=65628.0]Your answer is in this topic.[/url]
|
||||
Don't want to deal with that? Use [url=https://www.hard-light.net/forums/index.php?topic=94068.0]Knossos[/url] and it will download the best build specifically for your PC!
|
||||
[/hidden]
|
||||
|
||||
[img]https://scp.indiegames.us/img/linux-icon.png[/img] [color=green][size=12pt]Linux 64-bit[/size][/color]
|
||||
[img]http://scp.indiegames.us/img/linux-icon.png[/img] [color=green][size=12pt]Linux 64-bit[/size][/color]
|
||||
[size=8pt]Compiled with Ubuntu 16.04 LTS 64-bit, GCC 5[/size]
|
||||
${build(groups["Linux"].mainFile)}
|
||||
|
||||
These builds use a mechanism called [url=https://appimage.org/]AppImage[/url] which should allow these builds to run on most Linux distributions. However, we recommend that you compile your own builds which will result in less issues.
|
||||
These builds use a mechanism called [url=http://appimage.org/]AppImage[/url] which should allow these builds to run on most Linux distributions. However, we recommend that you compile your own builds which will result in less issues.
|
||||
Alternatively, if there is a package in your software repository then you should use that. If you are the maintainer of such a package for a distribution then let us know and we will include that here.
|
||||
|
||||
|
||||
[img]https://scp.indiegames.us/img/mac-icon.png[/img] [color=green][size=12pt]macOS[/size][/color]
|
||||
[size=8pt]macOS 10.9+[/size]
|
||||
[b]Intel (64-bit):[/b] ${build(groups["Mac"].subFiles["x86_64"])}
|
||||
[b]Apple Silicon:[/b] ${build(groups["Mac"].subFiles["arm64"])}
|
||||
|
||||
These builds are not signed and so by default will fail to launch. To run them simply right-click on the app, click open, then click open again on the security confirmation dialog. You should only have to do this once for each app.
|
||||
If running the game through Knossos or Knossos.NET this step should not be necessary.
|
||||
|
||||
[size=8pt][color=red][b]NOTE:[/b][/color] macOS builds currently have limited support and may exhibit issues not present on other platforms.[/size]
|
||||
|
||||
[img]http://scp.indiegames.us/img/mac-icon.png[/img] [color=green][size=12pt]OS X[/size][/color]
|
||||
[b][color=red]Not available[/color][/b] We recently lost access to our Mac CI environment which we usually used for compiling these builds so for the time being, there will be no builds for this OS.
|
||||
|
||||
[hidden=TrackIR Users]
|
||||
[size=12pt]Important!![/size]
|
||||
An external DLL is required for FSO to use TrackIR functions. The following DLL is simply unpacked in to your main FreeSpace2 root dir.
|
||||
TrackIR is only supported on Windows.
|
||||
[url=https://www.mediafire.com/download.php?4zw024zrh44etse]TrackIR SCP DLL[/url] ([url=http://scp.fsmods.net/builds/scptrackir.zip]Mirror[/url]) ([url=https://scp.indiegames.us/builds/scptrackir.zip]Mirror[/url])[/hidden]
|
||||
[url=http://www.mediafire.com/download.php?4zw024zrh44etse]TrackIR SCP DLL[/url] ([url=http://scp.fsmods.net/builds/scptrackir.zip]Mirror[/url]) ([url=http://scp.indiegames.us/builds/scptrackir.zip]Mirror[/url])[/hidden]
|
||||
|
||||
Known issues:
|
||||
[list]
|
||||
[li][url=https://github.com/scp-fs2open/fs2open.github.com/issues]Github issues[/url] and [url=https://github.com/scp-fs2open/fs2open.github.com/pulls]pending pull requests[/url][/li]
|
||||
[li]See the list of [url=https://github.com/scp-fs2open/fs2open.github.com/projects/8]bugs ranked by priority[/url][/li]
|
||||
[li]See the list of [url=http://scp.indiegames.us/mantis/search.php?project_id=1&status_id%5B%5D=10&status_id%5B%5D=20&status_id%5B%5D=30&status_id%5B%5D=40&status_id%5B%5D=50&priority_id%5B%5D=40&priority_id%5B%5D=50&priority_id%5B%5D=60&sticky_issues=on&sortby=last_updated&dir=DESC&per_page=200&hide_status_id=-2]Fix for next release[/url] bugs - mark a bug as an elevated priority (high, urgent, immediate) to get it included in that filter.[/li]
|
||||
[/list]
|
||||
@@ -1,3 +1,3 @@
|
||||
Mako==1.2.2
|
||||
requests==2.31.0
|
||||
Mako==1.1.5
|
||||
requests==2.26.0
|
||||
semantic-version==2.8.5
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -ex
|
||||
|
||||
if [ "$NIGHTLY_BUILD" = true ]; then
|
||||
echo "Generating bintray config..."
|
||||
sed -e "s/\$VERSION_NAME/$VERSION_NAME/" ci/bintray.template.json > ci/bintray.json
|
||||
fi
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -ex
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
sudo add-apt-repository -y "ppa:msulikowski/valgrind" # For fixing a bug with valgrind 3.11 which does not recognize the rdrand instruction
|
||||
|
||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
|
||||
sudo add-apt-repository -y 'deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
|
||||
|
||||
sudo apt-get -yq update
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
# Nothing to do here
|
||||
:
|
||||
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
# Nothing to do here
|
||||
:
|
||||
fi
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
mkdir -p /tmp/builds
|
||||
if [ "$RELEASE_BUILD" = true ]; then
|
||||
# Package the source code in release builds
|
||||
PARENT_DIR="$(basename "$PWD")"
|
||||
(cd .. && tar -czvf /tmp/builds/$PACKAGE_NAME-source-Unix.tar.gz --exclude-vcs "$PARENT_DIR")
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
CXXFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
CFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
|
||||
export CXXFLAGS
|
||||
export CFLAGS
|
||||
CMAKE="cmake -G Ninja -DFSO_FATAL_WARNINGS=ON $CMAKE_OPTIONS"
|
||||
if [ "$BUILD_DEPLOYMENT" = true ]; then
|
||||
for config in $BUILD_CONFIGS
|
||||
do
|
||||
mkdir -p $config
|
||||
cd $config
|
||||
eval $CMAKE -DFSO_INSTALL_DEBUG_FILES=ON -DCMAKE_BUILD_TYPE=$config -DCMAKE_INSTALL_PREFIX="/tmp/release/$config" \
|
||||
-DFSO_BUILD_APPIMAGE=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_QTFRED=OFF ../..
|
||||
cd ..
|
||||
done
|
||||
else
|
||||
eval $CMAKE -DCMAKE_BUILD_TYPE=$CONFIGURATION -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFSO_BUILD_QTFRED=ON ..
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
if [ "$BUILD_DEPLOYMENT" = true ]; then
|
||||
cmake -G "Xcode" -DFSO_FATAL_WARNINGS=ON -DFSO_INSTALL_DEBUG_FILES=ON -DCMAKE_INSTALL_PREFIX="/tmp/release" ..
|
||||
else
|
||||
cmake -G "Xcode" $CMAKE_OPTIONS ..
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
if [ "$CMAKE_GENERATOR" = "Ninja" ]; then
|
||||
cmake -DFSO_USE_SPEECH="OFF" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
|
||||
-DFSO_BUILD_FRED2="OFF" -G "$CMAKE_GENERATOR" ..
|
||||
else
|
||||
cmake -DFSO_USE_SPEECH="ON" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
|
||||
-DMSVC_SIMD_INSTRUCTIONS=SSE2 -DFSO_BUILD_FRED2="ON" -G "$CMAKE_GENERATOR" -T "$CMAKE_TOOLSET" ..
|
||||
fi
|
||||
fi
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
RELEASE_BUILD=false
|
||||
NIGHTLY_BUILD=false
|
||||
TEST_BUILD=false
|
||||
|
||||
BUILD_DEPLOYMENT=false
|
||||
BUILD_CONFIGS="Release FastDebug"
|
||||
VERSION_NAME=""
|
||||
PACKAGE_NAME=""
|
||||
|
||||
RELEASE_PATTERN="^release_(.*)$"
|
||||
NIGHTLY_PATTERN="^nightly_(.*)$"
|
||||
TEST_BUILD_PATTERN="^test\/(.*)$"
|
||||
|
||||
# These are for testing
|
||||
NIGHTLY_TEST=false
|
||||
RELEASE_TEST=false
|
||||
TEST_BUILD_TEST=false
|
||||
|
||||
if [ "$RELEASE_TEST" = true ] || [[ "$TRAVIS_TAG" =~ $RELEASE_PATTERN ]]; then
|
||||
echo "This is a release tag!";
|
||||
RELEASE_BUILD=true;
|
||||
PACKAGE_NAME="fs2_open_${BASH_REMATCH[1]}";
|
||||
fi
|
||||
if [ "$NIGHTLY_TEST" = true ] || [[ "$TRAVIS_TAG" =~ $NIGHTLY_PATTERN ]]; then
|
||||
echo "This is a nightly tag!";
|
||||
NIGHTLY_BUILD=true;
|
||||
VERSION_NAME="${BASH_REMATCH[1]}";
|
||||
PACKAGE_NAME="nightly_${BASH_REMATCH[1]}";
|
||||
fi
|
||||
if [ "$TEST_BUILD_TEST" = true ] || [[ "$TRAVIS_PULL_REQUEST" == "false" && "$TRAVIS_BRANCH" =~ $TEST_BUILD_PATTERN ]]; then
|
||||
echo "This is a test build branch!";
|
||||
TEST_BUILD=true;
|
||||
if [ "$TEST_BUILD_TEST" = true ]; then
|
||||
VERSION_NAME="test";
|
||||
PACKAGE_NAME="test_test";
|
||||
else
|
||||
VERSION_NAME="${BASH_REMATCH[1]}";
|
||||
PACKAGE_NAME="test_${BASH_REMATCH[1]}";
|
||||
fi
|
||||
|
||||
# Override the revision string so that the builds are named correctly
|
||||
echo "set(FSO_VERSION_REVISION_STR $VERSION_NAME)" > "$TRAVIS_BUILD_DIR/version_override.cmake"
|
||||
fi
|
||||
|
||||
if ([ "$RELEASE_BUILD" = true ] || [ "$NIGHTLY_BUILD" = true ] || [ "$TEST_BUILD" = true ]); then
|
||||
BUILD_DEPLOYMENT=true;
|
||||
fi
|
||||
|
||||
if [ "$BUILD_DEPLOYMENT" = true ]; then
|
||||
if ([ "$TRAVIS_OS_NAME" = "linux" ] && (! [[ "$CC" =~ ^gcc-5.*$ ]])); then
|
||||
echo "Skipping non-release compiler";
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
if ([[ "$CONFIGURATION" == "Debug" ]]); then
|
||||
echo "Skipping non-release configuration";
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
echo "Skipping non-release platform"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
export RELEASE_BUILD
|
||||
export NIGHTLY_BUILD
|
||||
export TEST_BUILD
|
||||
export BUILD_DEPLOYMENT
|
||||
export BUILD_CONFIGS
|
||||
export VERSION_NAME
|
||||
export PACKAGE_NAME
|
||||
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
if [[ ! "$(curl -V)" == *"sftp"* ]]; then
|
||||
# Before
|
||||
echo "Before:"
|
||||
curl -V
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
|
||||
if [ -f ~/curl_cache/curl*.deb ]; then
|
||||
cd ~/curl_cache
|
||||
sudo dpkg -i libcurl3*.deb
|
||||
sudo dpkg -i curl*.deb
|
||||
else
|
||||
# Since the Travis CI people are not capable of enabling SSH/SCP support for their libcurl we need to build that manually...
|
||||
# These commands are based on the tutorial from here: http://zeroset.mnim.org/2013/03/14/sftp-support-for-curl-in-ubuntu-12-10-quantal-quetzal-and-later/
|
||||
mkdir /tmp/curl
|
||||
cd /tmp/curl
|
||||
sudo apt-get update
|
||||
sudo apt-get install build-essential debhelper libssh2-1-dev libgnutls-dev libidn11-dev libkrb5-dev libldap2-dev libnss3-dev librtmp-dev libtool openssh-server quilt
|
||||
apt-get source curl
|
||||
sudo apt-get build-dep curl
|
||||
|
||||
cd curl-*
|
||||
export DEB_BUILD_OPTIONS="nocheck"
|
||||
sudo dpkg-buildpackage -uc -us -j"$(grep -c ^processor /proc/cpuinfo)"
|
||||
|
||||
cd ..
|
||||
dpkg -l | grep curl
|
||||
ls -al
|
||||
|
||||
if [ ! -d ~/curl_cache ]; then
|
||||
mkdir ~/curl_cache
|
||||
fi
|
||||
|
||||
cp libcurl3*.deb curl*.deb ~/curl_cache
|
||||
|
||||
sudo dpkg -i libcurl3*.deb
|
||||
sudo dpkg -i curl*.deb
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
brew install libssh2
|
||||
|
||||
if [ -d ~/curl_cache/curl ]; then
|
||||
cd ~/curl_cache/curl
|
||||
sudo make install
|
||||
else
|
||||
mkdir /tmp/curl
|
||||
cd /tmp/curl
|
||||
|
||||
curl -LO "https://curl.haxx.se/download/curl-7.64.0.tar.bz2"
|
||||
tar -xjf curl-7.64.0.tar.bz2
|
||||
|
||||
cd curl-7.64.0
|
||||
./configure --disable-debug --disable-dependency-tracking --disable-silent-rules --with-libssh2 --with-darwinssl --without-ca-bundle --without-ca-path
|
||||
make -j"$(sysctl hw.logicalcpu | cut -d " " -f 2)"
|
||||
|
||||
if [ ! -d ~/curl_cache ]; then
|
||||
mkdir ~/curl_cache
|
||||
fi
|
||||
|
||||
cp -a . ~/curl_cache/curl
|
||||
sudo make install
|
||||
fi
|
||||
export PATH=/usr/local/bin:$PATH
|
||||
fi
|
||||
|
||||
# After
|
||||
echo "After:"
|
||||
curl -V
|
||||
fi
|
||||
|
||||
cd /tmp/builds
|
||||
|
||||
for file in *; do
|
||||
if [ "$TEST_BUILD" = true ]; then
|
||||
# Upload to datacorder
|
||||
curl -k "sftp://porphyrion.feralhosting.com/www/datacorder.porphyrion.feralhosting.com/public_html/builds/test/$VERSION_NAME/" --user "$DATACORDER_USER:$DATACORDER_PASSWORD" -T "$file" --ftp-create-dirs
|
||||
else
|
||||
# Upload to indiegames
|
||||
curl -k "sftp://scp.indiegames.us/~/public_html/builds/nightly/$VERSION_NAME/" --user "$INDIEGAMES_USER:$INDIEGAMES_PASSWORD" -T "$file" --ftp-create-dirs
|
||||
|
||||
# Upload to datacorder
|
||||
curl -k "sftp://porphyrion.feralhosting.com/~/www/datacorder.porphyrion.feralhosting.com/public_html/builds/nightly/$VERSION_NAME/" --user "$DATACORDER_USER:$DATACORDER_PASSWORD" -T "$file" --ftp-create-dirs
|
||||
fi
|
||||
done
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
FILENAME=
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
if [ ! -d "$HOME/cmake-3.8/bin" ]; then
|
||||
# If the cache does not currently contain CMake then download and install it
|
||||
mkdir -p $HOME/cmake-3.8/
|
||||
|
||||
wget -O /tmp/cmake.tar.gz --no-check-certificate https://cmake.org/files/v3.8/cmake-3.8.2-Linux-x86_64.tar.gz
|
||||
tar -xzf /tmp/cmake.tar.gz -C $HOME/cmake-3.8/ --strip-components=1
|
||||
fi
|
||||
export PATH=$HOME/cmake-3.8/bin:$PATH
|
||||
|
||||
cd $HOME
|
||||
|
||||
if [ "${BUILD_DEPLOYMENT}" = true ]; then
|
||||
wget -O appimagetool -c "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" # (64-bit)
|
||||
chmod a+x ./appimagetool
|
||||
|
||||
wget -O linuxdeployqt -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" # (64-bit)
|
||||
chmod a+x ./linuxdeployqt
|
||||
fi
|
||||
|
||||
sudo apt-get -yq install valgrind
|
||||
|
||||
if [[ "$CC" = "clang-9" ]]; then
|
||||
sudo apt-get -yq install clang-9 clang-tidy-9
|
||||
fi
|
||||
|
||||
if [[ "$CC" = "clang-4.0" ]]; then
|
||||
# Fix a header bug present in ubuntu...
|
||||
sudo ln -s /usr/include/libcxxabi/__cxxabi_config.h /usr/include/c++/v1/__cxxabi_config.h
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
gem install xcpretty
|
||||
|
||||
brew update
|
||||
brew outdated cmake || brew upgrade cmake
|
||||
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
choco install mingw ninja
|
||||
fi
|
||||
|
||||
cmake --version
|
||||
Executable
+68
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -ex
|
||||
mkdir -p /tmp/builds
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
cd build
|
||||
for config in $BUILD_CONFIGS
|
||||
do
|
||||
cd "$config"
|
||||
|
||||
# Compile all targets
|
||||
ninja all
|
||||
|
||||
# Install Freespace2 targets
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/fso -DCOMPONENT=Unspecified -P cmake_install.cmake
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/fso -DCOMPONENT=Freespace2 -P cmake_install.cmake
|
||||
|
||||
# We need to be a bit creative for determining the AppImage name since we don't want to hard-code the name
|
||||
FILENAME="$(find /tmp/release/$config/fso/bin -name 'fs2_open_*' -type f -printf "%f\n").AppImage"
|
||||
$HOME/appimagetool -n /tmp/release/$config/fso "/tmp/release/$config/fso/$FILENAME"
|
||||
|
||||
: <<'END'
|
||||
# Install qtFRED targets
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/qtfred/usr -DCOMPONENT=Unspecified -P cmake_install.cmake
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/qtfred/usr -DCOMPONENT=qtFRED -P cmake_install.cmake
|
||||
|
||||
PREV="$(pwd)"
|
||||
cd /tmp/release/$config/qtfred
|
||||
|
||||
unset QTDIR; unset QT_PLUGIN_PATH; unset LD_LIBRARY_PATH
|
||||
$HOME/linuxdeployqt usr/qtfred.desktop -bundle-non-qt-libs
|
||||
# Move our AppRun script to the right location
|
||||
mv usr/AppRun AppRun
|
||||
|
||||
echo "Embed newer libstdc++ for distros that don't come with it (ubuntu 14.04)";
|
||||
mkdir -p usr/optional/; mkdir -p usr/optional/libstdc++/;
|
||||
cp /usr/lib/x86_64-linux-gnu/libstdc++.so.6 ./usr/optional/libstdc++/;
|
||||
|
||||
$HOME/appimagetool -n . "$(find /tmp/release/$config/qtfred/usr/bin -name 'qtfred_*' -type f -printf "%f\n").AppImage"
|
||||
|
||||
cd "$PREV"
|
||||
END
|
||||
|
||||
cd ..
|
||||
done
|
||||
|
||||
cp `find /tmp/release -name '*.AppImage' -print` /tmp/release
|
||||
(cd /tmp/release && tar -cvzf /tmp/builds/$PACKAGE_NAME-builds-Linux.tar.gz *.AppImage)
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
cd build
|
||||
|
||||
for config in $BUILD_CONFIGS
|
||||
do
|
||||
cmake --build . --config "$config" --target install | tee build.log \
|
||||
| xcpretty
|
||||
XCODE_RET=${PIPESTATUS[0]}
|
||||
if [ "$XCODE_RET" -ne "0" ]; then
|
||||
tar -cvzf build.log.tar.gz build.log
|
||||
curl --upload-file build.log.tar.gz "https://transfer.sh/build.log.tar.gz"
|
||||
exit $XCODE_RET
|
||||
fi
|
||||
done
|
||||
|
||||
ls -al /tmp/release
|
||||
|
||||
(cd /tmp/release && tar -cvzf /tmp/builds/$PACKAGE_NAME-builds-MacOSX.tar.gz *)
|
||||
fi
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -e
|
||||
|
||||
cd build
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
ninja -k 20 all
|
||||
|
||||
if [ "$CONFIGURATION" = "Debug" ]; then
|
||||
valgrind --leak-check=full --error-exitcode=1 --gen-suppressions=all \
|
||||
--suppressions="$TRAVIS_BUILD_DIR/ci/travis/valgrind.supp" ./bin/unittests --gtest_shuffle
|
||||
else
|
||||
./bin/unittests --gtest_shuffle
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
cmake --build . --config "$CONFIGURATION" | tee build.log | xcpretty
|
||||
XCODE_RET=${PIPESTATUS[0]}
|
||||
if [ "$XCODE_RET" -ne "0" ]; then
|
||||
tar -cvzf build.log.tar.gz build.log
|
||||
curl --upload-file build.log.tar.gz "https://keep.sh"
|
||||
exit $XCODE_RET
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
if [ "$CMAKE_GENERATOR" = "Ninja" ]; then
|
||||
cmake --build . --config "$CONFIGURATION"
|
||||
else
|
||||
cmake --build . --config "$CONFIGURATION" -- /verbosity:minimal
|
||||
fi
|
||||
fi
|
||||
@@ -1,16 +0,0 @@
|
||||
buildType:
|
||||
default: release
|
||||
description: R
|
||||
choices:
|
||||
release:
|
||||
short: Release
|
||||
long: Release builds
|
||||
buildType: Release
|
||||
fastDebug:
|
||||
short: FastDebug
|
||||
long: Debug with optimizations
|
||||
buildType: FastDebug
|
||||
debug:
|
||||
short: Debug
|
||||
long: Debug without optimizations
|
||||
buildType: Debug
|
||||
@@ -9,8 +9,6 @@ if (WIN32)
|
||||
if (NOT HAVE_SAPI_H)
|
||||
message(SEND_ERROR "sapi.h could not be found on your platform. Please disable speech support.")
|
||||
endif()
|
||||
elseif(APPLE)
|
||||
# it should just work
|
||||
else()
|
||||
message(SEND_ERROR "Text to Speech is not supported on this platform!")
|
||||
endif()
|
||||
|
||||
@@ -7,9 +7,3 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
else()
|
||||
set(IS_64BIT FALSE)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64|ARM64)")
|
||||
set(IS_ARM64 TRUE)
|
||||
else()
|
||||
set(IS_ARM64 FALSE)
|
||||
endif()
|
||||
@@ -22,14 +22,6 @@ SET(LIBRAY_DESTINATION "../Frameworks")
|
||||
|
||||
set(PLATFORM_MAC TRUE CACHE INTERNAL "" FORCE)
|
||||
|
||||
# Maybe override arm64 setting if we are compiling for different architecture
|
||||
# If not specified, or if it's a universal build, then this should do nothing
|
||||
if(CMAKE_OSX_ARCHITECTURES MATCHES "arm64")
|
||||
set(IS_ARM64 TRUE)
|
||||
elseif(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
|
||||
set(IS_ARM64 FALSE)
|
||||
endif()
|
||||
|
||||
# Generate and don't strip debug symbols
|
||||
# These settings don't seem to generate debug symbols for code and Freespace2
|
||||
# so those settings are set manually in code and Freespace2's CMakeLists.txt files
|
||||
|
||||
@@ -10,7 +10,6 @@ SET(WIN32_LIBS
|
||||
winmm
|
||||
ws2_32
|
||||
psapi
|
||||
shlwapi
|
||||
)
|
||||
|
||||
IF (MINGW)
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#cmakedefine SCP_HAVE_STD_MAX_ALIGN_T
|
||||
|
||||
#cmakedefine01 IS_64BIT
|
||||
#cmakedefine01 IS_ARM64
|
||||
|
||||
#cmakedefine01 SCP_HAVE_STRCASECMP
|
||||
#cmakedefine01 SCP_HAVE_STRNCASECMP
|
||||
|
||||
@@ -4,7 +4,7 @@ MESSAGE(STATUS "Doing configuration specific to Apple Clang...")
|
||||
# TODO: Actually add Mac specific flags here...
|
||||
|
||||
# Suppress specific warning
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fsigned-char -Wno-unknown-pragmas")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -funroll-loops -fsigned-char -Wno-unknown-pragmas")
|
||||
|
||||
# Omit "conversion from string literal to 'char *' is deprecated" warnings.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-write-strings")
|
||||
@@ -13,6 +13,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated -Wno-char-subscripts")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -Wno-unused-variable -Wno-unused-parameter")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-Wno-unused-variable")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g -Wshadow")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Wextra -Wshadow -Wno-unused-parameter")
|
||||
+10
-31
@@ -33,7 +33,7 @@ set(COMPILER_FLAGS "")
|
||||
_enable_extra_compiler_warnings_flags()
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} ${_flags}")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -fsigned-char -Wno-unknown-pragmas")
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -funroll-loops -fsigned-char -Wno-unknown-pragmas")
|
||||
|
||||
# Omit "argument unused during compilation" when clang is used with ccache.
|
||||
if(${CMAKE_CXX_COMPILER} MATCHES "ccache")
|
||||
@@ -83,41 +83,20 @@ if(SUPPORTS_SHIFT_NEGATIVE_VALUE)
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-shift-negative-value")
|
||||
endif()
|
||||
|
||||
# Check if there is a user-set optimisation flag
|
||||
string(REGEX MATCH "-O[a-zA-Z|0-9]+" CXX_OPT_FLAG ${CXX_BASE_FLAGS})
|
||||
string(REGEX MATCH "-O[a-zA-Z|0-9]+" C_OPT_FLAG ${C_BASE_FLAGS})
|
||||
set(COMPILER_FLAGS_RELEASE "-O2 -Wno-unused-variable -Wno-unused-parameter")
|
||||
|
||||
# If no user-set opt flag, set -O2 and -Og
|
||||
if ("${CXX_OPT_FLAG}" STREQUAL "")
|
||||
set(CXX_OPT_FLAG_RELEASE "-O2")
|
||||
set(CXX_OPT_FLAG_DEBUG "-Og")
|
||||
else()
|
||||
set(CXX_OPT_FLAG_RELEASE "${CXX_OPT_FLAG}")
|
||||
set(CXX_OPT_FLAG_DEBUG "${CXX_OPT_FLAG}")
|
||||
endif()
|
||||
if ("${C_OPT_FLAG}" STREQUAL "")
|
||||
set(C_OPT_FLAG_RELEASE "-O2")
|
||||
set(C_OPT_FLAG_DEBUG "-Og")
|
||||
else()
|
||||
set(C_OPT_FLAG_RELEASE "${C_OPT_FLAG}")
|
||||
set(C_OPT_FLAG_DEBUG "${C_OPT_FLAG}")
|
||||
endif()
|
||||
set(COMPILER_FLAGS_DEBUG "-O0 -g -Wshadow")
|
||||
|
||||
set(CXX_FLAGS_RELEASE "${CXX_OPT_FLAG_RELEASE} -Wno-unused-variable -Wno-unused-parameter")
|
||||
set(C_FLAGS_RELEASE "${C_OPT_FLAG_RELEASE} -Wno-unused-variable -Wno-unused-parameter")
|
||||
|
||||
set(CXX_FLAGS_DEBUG "${CXX_OPT_FLAG_DEBUG} -g -Wshadow")
|
||||
set(C_FLAGS_DEBUG "${C_OPT_FLAG_DEBUG} -g -Wshadow")
|
||||
|
||||
# Always use the base flags and add our compiler flags at the back
|
||||
# Always use the base flags and add our compiler flags at the bacl
|
||||
set(CMAKE_CXX_FLAGS "${CXX_BASE_FLAGS} ${COMPILER_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${C_BASE_FLAGS} ${COMPILER_FLAGS}")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE ${CXX_FLAGS_RELEASE})
|
||||
set(CMAKE_C_FLAGS_RELEASE ${C_FLAGS_RELEASE})
|
||||
set(CMAKE_CXX_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
|
||||
set(CMAKE_C_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
set(CMAKE_C_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG ${CXX_FLAGS_DEBUG})
|
||||
set(CMAKE_C_FLAGS_DEBUG ${C_FLAGS_DEBUG})
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "")
|
||||
|
||||
@@ -141,7 +120,7 @@ if (FSO_FATAL_WARNINGS)
|
||||
target_compile_options(compiler INTERFACE "-Werror")
|
||||
endif()
|
||||
|
||||
# Always define this to make sure that the fixed-width format macros are available
|
||||
# Always define this to make sure that the fixed width format macros are available
|
||||
target_compile_definitions(compiler INTERFACE __STDC_FORMAT_MACROS)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR MINGW)
|
||||
|
||||
@@ -45,7 +45,7 @@ endif()
|
||||
_enable_extra_compiler_warnings_flags()
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} ${_flags}")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -fsigned-char -Wno-unknown-pragmas")
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -funroll-loops -fsigned-char -Wno-unknown-pragmas")
|
||||
|
||||
if (NOT GCC_INCREMENTAL_LINKING)
|
||||
# Place each function and data in its own section so the linker can
|
||||
@@ -113,41 +113,19 @@ if(SUPPORTS_STRINGOP_TRUNCATION)
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-stringop-overflow")
|
||||
endif()
|
||||
|
||||
# Check if there is a user-set optimisation flag
|
||||
string(REGEX MATCH "-O[a-zA-Z|0-9]+" CXX_OPT_FLAG ${CXX_BASE_FLAGS})
|
||||
string(REGEX MATCH "-O[a-zA-Z|0-9]+" C_OPT_FLAG ${C_BASE_FLAGS})
|
||||
set(COMPILER_FLAGS_RELEASE "-O2 -Wno-unused-variable -Wno-unused-but-set-variable -Wno-array-bounds -Wno-empty-body -Wno-clobbered -Wno-unused-parameter")
|
||||
|
||||
# If no user-set opt flag, set -O2 and -Og
|
||||
if ("${CXX_OPT_FLAG}" STREQUAL "")
|
||||
set(CXX_OPT_FLAG_RELEASE "-O2")
|
||||
set(CXX_OPT_FLAG_DEBUG "-Og")
|
||||
else()
|
||||
set(CXX_OPT_FLAG_RELEASE "${CXX_OPT_FLAG}")
|
||||
set(CXX_OPT_FLAG_DEBUG "${CXX_OPT_FLAG}")
|
||||
endif()
|
||||
if ("${C_OPT_FLAG}" STREQUAL "")
|
||||
set(C_OPT_FLAG_RELEASE "-O2")
|
||||
set(C_OPT_FLAG_DEBUG "-Og")
|
||||
else()
|
||||
set(C_OPT_FLAG_RELEASE "${C_OPT_FLAG}")
|
||||
set(C_OPT_FLAG_DEBUG "${C_OPT_FLAG}")
|
||||
endif()
|
||||
|
||||
set(CXX_FLAGS_RELEASE "${CXX_OPT_FLAG_RELEASE} -Wno-unused-variable -Wno-unused-but-set-variable -Wno-array-bounds -Wno-empty-body -Wno-clobbered -Wno-unused-parameter")
|
||||
set(C_FLAGS_RELEASE "${C_OPT_FLAG_RELEASE} -Wno-unused-variable -Wno-unused-but-set-variable -Wno-array-bounds -Wno-empty-body -Wno-clobbered -Wno-unused-parameter")
|
||||
|
||||
set(CXX_FLAGS_DEBUG "${CXX_OPT_FLAG_DEBUG} -g -Wshadow")
|
||||
set(C_FLAGS_DEBUG "${C_OPT_FLAG_DEBUG} -g -Wshadow")
|
||||
set(COMPILER_FLAGS_DEBUG "-O0 -g -Wshadow")
|
||||
|
||||
# Always use the base flags and add our compiler flags at the back
|
||||
set(CMAKE_CXX_FLAGS "${CXX_BASE_FLAGS} ${COMPILER_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${C_BASE_FLAGS} ${COMPILER_FLAGS}")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE ${CXX_FLAGS_RELEASE})
|
||||
set(CMAKE_C_FLAGS_RELEASE ${C_FLAGS_RELEASE})
|
||||
set(CMAKE_CXX_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
|
||||
set(CMAKE_C_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG ${CXX_FLAGS_DEBUG})
|
||||
set(CMAKE_C_FLAGS_DEBUG ${C_FLAGS_DEBUG})
|
||||
set(CMAKE_CXX_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
set(CMAKE_C_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${LINKER_FLAGS}")
|
||||
|
||||
@@ -187,7 +165,7 @@ if (FSO_FATAL_WARNINGS)
|
||||
target_compile_options(compiler INTERFACE "-Werror")
|
||||
endif()
|
||||
|
||||
# Always define this to make sure that the fixed-width format macros are available
|
||||
# Always define this to make sure that the fixed width format macros are available
|
||||
target_compile_definitions(compiler INTERFACE __STDC_FORMAT_MACROS=1)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR MINGW)
|
||||
|
||||
+17
-30
@@ -67,43 +67,30 @@ ENDIF(EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${FILE}\")
|
||||
ENDFUNCTION(EP_CHECK_FILE_EXISTS)
|
||||
|
||||
MACRO(COPY_FILE_TO_TARGET _target _file)
|
||||
if (IS_DIRECTORY "${_file}")
|
||||
get_filename_component(_dirName "${_file}" NAME)
|
||||
if (PLATFORM_MAC AND ("${_file}" MATCHES ".framework$"))
|
||||
# This is stupid, but it preserves symlinks, unlike copy_directory_if_different.
|
||||
# Otherwise we end up creating duplicate files in the copied framework.
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET ${_target} POST_BUILD
|
||||
COMMAND rsync -rlq "${_file}" "$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}"
|
||||
COMMENT "copying '${_file}'..."
|
||||
VERBATIM
|
||||
)
|
||||
else()
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET ${_target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different "${_file}" "$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}/${_dirName}"
|
||||
COMMENT "copying '${_file}'..."
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
if(UNIX)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET ${_target} POST_BUILD
|
||||
COMMAND cp -a "${_file}" "$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}/"
|
||||
COMMENT "copying '${_file}'..."
|
||||
)
|
||||
else()
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET ${_target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_file}" "$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}/"
|
||||
COMMENT "copying '${_file}'..."
|
||||
VERBATIM
|
||||
TARGET ${_target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_file}" "$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}/"
|
||||
COMMENT "copying '${_file}'..."
|
||||
)
|
||||
endif()
|
||||
endmacro(COPY_FILE_TO_TARGET)
|
||||
|
||||
MACRO(COPY_FILES_TO_TARGET _target)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET ${_target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}/"
|
||||
COMMENT "Creating '$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}/'..."
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET ${_target} POST_BUILD
|
||||
COMMAND mkdir -p "$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}/"
|
||||
COMMENT "Creating '$<TARGET_FILE_DIR:${_target}>/${LIBRAY_DESTINATION}/'..."
|
||||
)
|
||||
endif()
|
||||
|
||||
FOREACH(file IN LISTS TARGET_COPY_FILES)
|
||||
COPY_FILE_TO_TARGET("${_target}" "${file}")
|
||||
ENDFOREACH(file)
|
||||
|
||||
+3
-5
@@ -6,8 +6,8 @@ if (EXISTS "${PROJECT_SOURCE_DIR}/version_override.cmake")
|
||||
include("${PROJECT_SOURCE_DIR}/version_override.cmake")
|
||||
endif()
|
||||
|
||||
set_if_not_defined(FSO_VERSION_MAJOR 23)
|
||||
set_if_not_defined(FSO_VERSION_MINOR 3)
|
||||
set_if_not_defined(FSO_VERSION_MAJOR 22)
|
||||
set_if_not_defined(FSO_VERSION_MINOR 1)
|
||||
set_if_not_defined(FSO_VERSION_BUILD 0)
|
||||
|
||||
# A numeric revision e.g. the CI build number
|
||||
@@ -35,9 +35,7 @@ ELSE()
|
||||
SET(FSO_BINARY_SUFFIX "${FSO_VERSION_MAJOR}_${FSO_VERSION_MINOR}_${FSO_VERSION_BUILD}_${FSO_VERSION_REVISION_STR}")
|
||||
ENDIF()
|
||||
|
||||
IF(IS_ARM64)
|
||||
SET(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}_arm64")
|
||||
ELSEIF(IS_64BIT)
|
||||
IF(IS_64BIT)
|
||||
# This is a 64-bit builds
|
||||
SET(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}_x64")
|
||||
ENDIF()
|
||||
|
||||
+5
-36
@@ -20,13 +20,6 @@ TARGET_INCLUDE_DIRECTORIES(code PUBLIC ${GENERATED_SOURCE_DIR}/code)
|
||||
|
||||
if (FSO_BUILD_WITH_OPENGL)
|
||||
target_link_libraries(code PUBLIC OpenGL)
|
||||
if(FSO_BUILD_WITH_OPENGL_DEBUG)
|
||||
add_definitions(-DFS_OPENGL_DEBUG)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(FSO_BUILD_WITH_OPENXR_DEBUG)
|
||||
add_definitions(-DFS_OPENXR_DEBUG)
|
||||
endif()
|
||||
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC openal)
|
||||
@@ -54,6 +47,10 @@ target_link_libraries(code PUBLIC libRocket)
|
||||
|
||||
target_link_libraries(code PUBLIC pcp)
|
||||
|
||||
if (FSO_BUILD_WITH_VULKAN)
|
||||
target_link_libraries(code PUBLIC vulkan-hpp)
|
||||
endif()
|
||||
|
||||
target_link_libraries(code PUBLIC parsers)
|
||||
|
||||
target_link_libraries(code PUBLIC mdns)
|
||||
@@ -71,25 +68,6 @@ target_link_libraries(code PUBLIC variant)
|
||||
|
||||
target_link_libraries(code PUBLIC any)
|
||||
|
||||
target_link_libraries(code PUBLIC optional)
|
||||
|
||||
target_link_libraries(code PUBLIC anl)
|
||||
|
||||
target_link_libraries(code PUBLIC hidapi::hidapi)
|
||||
|
||||
target_link_libraries(code PUBLIC imgui)
|
||||
|
||||
IF(NOT APPLE)
|
||||
target_link_libraries(code PUBLIC OpenXR::openxr_loader)
|
||||
target_include_directories(code PUBLIC OpenXR::Headers)
|
||||
ENDIF()
|
||||
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
# On Linux, we need to access X11 window data.
|
||||
# On Windows, SDL already provides everything, so no need to do anything
|
||||
find_package(X11)
|
||||
target_link_libraries(code PUBLIC ${X11_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
# Headers for standalone "gui" on UNIX
|
||||
IF(UNIX)
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ${MONGOOSE_LIBS})
|
||||
@@ -112,16 +90,7 @@ if (FSO_BUILD_WITH_OPENGL)
|
||||
target_compile_definitions(code PUBLIC WITH_OPENGL)
|
||||
endif()
|
||||
if (FSO_BUILD_WITH_VULKAN)
|
||||
find_package(Vulkan REQUIRED)
|
||||
if (Vulkan_FOUND)
|
||||
target_compile_definitions(code PUBLIC WITH_VULKAN)
|
||||
target_link_libraries(code PRIVATE Vulkan::Vulkan)
|
||||
|
||||
target_compile_definitions(code PUBLIC WITH_VULKAN VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1 VK_NO_PROTOTYPES)
|
||||
else()
|
||||
message(WARNING "FSO_BUILD_WITH_VULKAN was set, but the package was unable to be found. Forcing OFF.")
|
||||
set(FSO_BUILD_WITH_VULKAN OFF CACHE BOOL "Enable compilation of the Vulkan renderer" FORCE)
|
||||
endif()
|
||||
target_compile_definitions(code PUBLIC WITH_VULKAN)
|
||||
endif()
|
||||
|
||||
include(shaders.cmake)
|
||||
|
||||
@@ -18,7 +18,7 @@ struct ProgramLocals {
|
||||
matrix localOrient = vmd_identity_matrix;
|
||||
int hostSubobject = -1;
|
||||
|
||||
TIMESTAMP waitTimestamp = TIMESTAMP::invalid();
|
||||
int waitTimestamp = 0;
|
||||
|
||||
expression::ProgramVariables variables;
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ WaitAction::~WaitAction() = default;
|
||||
|
||||
ActionResult WaitAction::execute(actions::ProgramLocals& locals) const
|
||||
{
|
||||
if (!locals.waitTimestamp.isValid()) {
|
||||
if (!timestamp_valid(locals.waitTimestamp)) {
|
||||
auto waitTime = _waitTimeExpression.execute(locals.variables);
|
||||
|
||||
// Catch errors in the expression
|
||||
@@ -28,7 +28,7 @@ ActionResult WaitAction::execute(actions::ProgramLocals& locals) const
|
||||
waitTime = 0.001f;
|
||||
}
|
||||
|
||||
locals.waitTimestamp = _timestamp(fl2i(waitTime * MILLISECONDS_PER_SECOND));
|
||||
locals.waitTimestamp = timestamp(fl2i(waitTime * TIMESTAMP_FREQUENCY));
|
||||
}
|
||||
if (!timestamp_elapsed(locals.waitTimestamp)) {
|
||||
// Wait until the timestamp is elapsed
|
||||
@@ -36,7 +36,7 @@ ActionResult WaitAction::execute(actions::ProgramLocals& locals) const
|
||||
}
|
||||
// Timestamp is elapsed. The timestamp is elapsed so that timestamp_valid above returns false for the next wait
|
||||
// action
|
||||
locals.waitTimestamp = TIMESTAMP::invalid();
|
||||
locals.waitTimestamp = 0;
|
||||
return ActionResult::Finished;
|
||||
}
|
||||
std::unique_ptr<Action> WaitAction::clone() const
|
||||
|
||||
@@ -52,6 +52,34 @@ void ai_free_slot(int ai_index)
|
||||
Ai_info[ai_index].shipnum = -1;
|
||||
}
|
||||
|
||||
int get_wingnum(int objnum)
|
||||
{
|
||||
int shipnum, ai_index;
|
||||
|
||||
shipnum = Objects[objnum].instance;
|
||||
|
||||
ai_index = Ships[shipnum].ai_index;
|
||||
|
||||
return Ai_info[ai_index].wing;
|
||||
}
|
||||
|
||||
void set_wingnum(int objnum, int wingnum)
|
||||
{
|
||||
int shipnum, ai_index;
|
||||
|
||||
Assert(Objects[objnum].type == OBJ_SHIP);
|
||||
|
||||
shipnum = Objects[objnum].instance;
|
||||
|
||||
Assert((shipnum >= 0) && (shipnum < MAX_SHIPS));
|
||||
|
||||
ai_index = Ships[shipnum].ai_index;
|
||||
|
||||
Assert( (ai_index >= 0) && (ai_index < MAX_AI_INFO) );
|
||||
|
||||
Ai_info[ai_index].wing = wingnum;
|
||||
}
|
||||
|
||||
const char *ai_get_goal_target_name(const char *name, int *index)
|
||||
{
|
||||
Assertion(name != nullptr && index != nullptr, "Arguments cannot be null!");
|
||||
|
||||
+82
-29
@@ -12,7 +12,6 @@
|
||||
#ifndef _AI_H
|
||||
#define _AI_H
|
||||
|
||||
#include "ai/aigoals.h"
|
||||
#include "ai/ai_profiles.h"
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
@@ -34,14 +33,8 @@ typedef struct ai_flag_name {
|
||||
char flag_name[TOKEN_LENGTH];
|
||||
} ai_flag_name;
|
||||
|
||||
typedef struct ai_flag_description {
|
||||
AI::AI_Flags flag;
|
||||
SCP_string flag_desc;
|
||||
} ai_flag_description;
|
||||
|
||||
#define MAX_AI_FLAG_NAMES 2
|
||||
extern ai_flag_name Ai_flag_names[];
|
||||
extern ai_flag_description Ai_flag_descriptions[];
|
||||
extern const int Num_ai_flag_names;
|
||||
|
||||
// dock_orient_and_approach() modes.
|
||||
#define DOA_APPROACH 1 // Approach the current point on the path (aip->path_cur)
|
||||
@@ -56,6 +49,24 @@ extern const int Num_ai_flag_names;
|
||||
#define AIDO_DOCK_NOW 2 // Immediately move into dock position. For ships that start mission docked.
|
||||
#define AIDO_UNDOCK 3 // Set goal of undocking with object.
|
||||
|
||||
// Submodes for seeking safety.
|
||||
#define AISS_1 41 // Pick a spot to fly to.
|
||||
#define AISS_2 42 // Flying to spot.
|
||||
#define AISS_3 43 // Gotten near spot, fly about there.
|
||||
#define AISS_1a 44 // Pick a new nearby spot because we are endangered, then go to AISS_2
|
||||
|
||||
#define MAX_AI_GOALS 5
|
||||
|
||||
// types of ai goals -- tyese types will help us to determination on which goals should
|
||||
// have priority over others (i.e. when a player issues a goal to a wing, then a seperate
|
||||
// goal to a ship in that wing). We would probably use this type in conjunction with
|
||||
// goal priority to establish which goal to follow
|
||||
#define AIG_TYPE_EVENT_SHIP 1 // from mission event direct to ship
|
||||
#define AIG_TYPE_EVENT_WING 2 // from mission event direct to wing
|
||||
#define AIG_TYPE_PLAYER_SHIP 3 // from player direct to ship
|
||||
#define AIG_TYPE_PLAYER_WING 4 // from player direct to wing
|
||||
#define AIG_TYPE_DYNAMIC 5 // created on the fly
|
||||
|
||||
// Flags to ai_turn_towards_vector().
|
||||
#define AITTV_FAST (1<<0) // Turn fast, not slowed down based on skill level.
|
||||
#define AITTV_VIA_SEXP (1<<1) // Goober5000 - via sexp
|
||||
@@ -65,7 +76,39 @@ extern const int Num_ai_flag_names;
|
||||
|
||||
#define KAMIKAZE_HULL_ON_DEATH -1000.0f // Hull strength ship gets set to if it crash-dies.
|
||||
|
||||
// individual AI modes aka AI behaviors
|
||||
// structure for AI goals
|
||||
typedef struct ai_goal {
|
||||
int signature; // Unique identifier. All goals ever created (per mission) have a unique signature.
|
||||
int ai_mode; // one of the AIM_* modes for this goal
|
||||
int ai_submode; // maybe need a submode
|
||||
int type; // one of the AIG_TYPE_* values above
|
||||
flagset<AI::Goal_Flags> flags; // one of the AIGF_* values above
|
||||
fix time; // time at which this goal was issued.
|
||||
int priority; // how important is this goal -- number 0 - 100
|
||||
|
||||
const char *target_name; // name of the thing that this goal acts upon
|
||||
int target_name_index; // index of goal_target_name in Goal_target_names[][]
|
||||
waypoint_list *wp_list; // waypoints that this ship might fly.
|
||||
int target_instance; // instance of thing this ship might be chasing (currently only used for weapons; note, not the same as objnum!)
|
||||
int target_signature; // signature of object this ship might be chasing (currently only used for weapons; paired with above value to confirm target)
|
||||
|
||||
// unions for docking stuff.
|
||||
// (AIGF_DOCKER_INDEX_VALID and AIGF_DOCKEE_INDEX_VALID tell us to use indexes; otherwise we use names)
|
||||
// these are the dockpoints used on the docker and dockee ships, not the ships themselves
|
||||
union {
|
||||
const char *name;
|
||||
int index;
|
||||
} docker;
|
||||
|
||||
union {
|
||||
const char *name;
|
||||
int index;
|
||||
} dockee;
|
||||
|
||||
object_ship_wing_point_team lua_ai_target;
|
||||
|
||||
} ai_goal;
|
||||
|
||||
#define AIM_CHASE 0
|
||||
#define AIM_EVADE 1
|
||||
#define AIM_GET_BEHIND 2 // This mode is not actually implemented.
|
||||
@@ -87,7 +130,7 @@ extern const int Num_ai_flag_names;
|
||||
#define AIM_BAY_DEPART 18 // Departing to a fighter bay, following path to do so
|
||||
#define AIM_SENTRYGUN 19 // AI mode for sentry guns only (floating turrets)
|
||||
#define AIM_WARP_OUT 20 // Commence warp out sequence. Point in legal direction. Then call John's code.
|
||||
#define AIM_FLY_TO_SHIP 21 // Rendezvous with a ship. Like stay-near, but non-perpetual.
|
||||
#define AIM_FLY_TO_SHIP 21 // [Kazan] Fly to a ship, doesn't matter if it's hostile or friendly -- for Autopilot usage
|
||||
#define AIM_LUA 22 // Generic Lua-based AI mode
|
||||
|
||||
#define MAX_AI_BEHAVIORS 23 // Number of AIM_xxxx types
|
||||
@@ -95,7 +138,8 @@ extern const int Num_ai_flag_names;
|
||||
#define MAX_WAYPOINTS_PER_LIST 20
|
||||
#define MAX_ENEMY_DISTANCE 2500.0f // Maximum distance from which a ship will pursue an enemy.
|
||||
|
||||
#define MAX_AI_GOALS 5
|
||||
#define AI_GOAL_NONE -1
|
||||
|
||||
#define AI_ACTIVE_GOAL_DYNAMIC 999
|
||||
|
||||
typedef struct ai_class {
|
||||
@@ -180,12 +224,6 @@ typedef struct ai_class {
|
||||
#define AIS_UNDOCK_3 33
|
||||
#define AIS_UNDOCK_4 34
|
||||
|
||||
// Submodes for seeking safety.
|
||||
#define AISS_1 41 // Pick a spot to fly to.
|
||||
#define AISS_2 42 // Flying to spot.
|
||||
#define AISS_3 43 // Gotten near spot, fly about there.
|
||||
#define AISS_1a 44 // Pick a new nearby spot because we are endangered, then go to AISS_2. (Not implemented.)
|
||||
|
||||
// Submodes for Guard behavior
|
||||
#define AIS_GUARD_PATROL 101
|
||||
#define AIS_GUARD_ATTACK 102
|
||||
@@ -239,7 +277,10 @@ extern pnode *Ppfp; // Free pointer in path points.
|
||||
typedef struct ai_info {
|
||||
flagset<AI::AI_Flags> ai_flags; // Special flags for AI behavior.
|
||||
int shipnum; // Ship using this slot, -1 means none.
|
||||
int type; //
|
||||
int wing; // Member of what wing? -1 means none.
|
||||
|
||||
int behavior; // AI behavior; vestigial field from early development of FS1
|
||||
int mode;
|
||||
int previous_mode;
|
||||
int mode_time; // timestamp at which current mode elapses.
|
||||
@@ -277,7 +318,7 @@ typedef struct ai_info {
|
||||
|
||||
// Probably become obsolete, to be replaced by path_start, path_cur, etc.
|
||||
waypoint_list *wp_list; // waypoint list being followed
|
||||
int wp_index; // waypoint index in list
|
||||
size_t wp_index; // waypoint index in list
|
||||
int wp_flags; // waypoint flags, see WPF_xxxx
|
||||
int waypoint_speed_cap; // -1 no cap, otherwise cap - changed to int by Goober5000
|
||||
|
||||
@@ -307,7 +348,6 @@ typedef struct ai_info {
|
||||
fix submode_start_time; // time at which we entered the current submode
|
||||
int submode_parm0; // parameter specific to current submode
|
||||
int submode_parm1; // SUSHI: Another optional parameter
|
||||
float submode_float0; // Goober5000: a float parameter
|
||||
fix next_predict_pos_time; // Next time to predict position.
|
||||
|
||||
int next_dynamic_path_check_time; //ETP: Time of next path check in ai_new_maybe_reposition_attack_subsys
|
||||
@@ -373,6 +413,11 @@ typedef struct ai_info {
|
||||
float ai_turret_max_aim_update_delay;
|
||||
flagset<AI::Profile_Flags> ai_profile_flags; //Holds AI_Profiles flags (possibly overriden by AI class) that actually apply to AI
|
||||
|
||||
|
||||
union {
|
||||
float stay_near_distance; // Distance to stay within for AIM_STAY_NEAR mode.
|
||||
};
|
||||
|
||||
ship_subsys* targeted_subsys; // Targeted subobject on current target. NULL if none;
|
||||
ship_subsys* last_subsys_target; // last known subsystem target
|
||||
int targeted_subsys_parent; // Parent objnum of subobject, not necessarily targeted
|
||||
@@ -459,12 +504,9 @@ typedef struct ai_info {
|
||||
int multilock_check_timestamp; // when to check for multilock next
|
||||
SCP_vector<std::pair<int, ship_subsys*>> ai_missile_locks_firing; // a list of missile locks (locked objnum, locked subsys) the ai is currently firing
|
||||
|
||||
ai_lua_parameters lua_ai_target;
|
||||
object_ship_wing_point_team lua_ai_target;
|
||||
} ai_info;
|
||||
|
||||
int ai_maybe_autoscale(int absolute_index = -1);
|
||||
int ai_get_autoscale_index(int absolute_index = -1);
|
||||
|
||||
// Goober5000
|
||||
typedef struct {
|
||||
vec3d docker_point;
|
||||
@@ -489,6 +531,11 @@ typedef struct {
|
||||
|
||||
extern int Mission_all_attack; // !0 means all teams attack all teams.
|
||||
|
||||
extern void update_ai_info_for_hit(int hitter_obj, int hit_obj);
|
||||
extern void ai_frame_all(void);
|
||||
|
||||
extern int find_guard_obj(void);
|
||||
|
||||
extern ai_info Ai_info[];
|
||||
extern ai_info *Player_ai;
|
||||
|
||||
@@ -499,6 +546,7 @@ extern int Num_ai_classes;
|
||||
extern int Ai_firing_enabled;
|
||||
|
||||
extern const char *Skill_level_names(int skill_level, int translate = 1);
|
||||
extern int Ai_goal_signature;
|
||||
|
||||
extern control_info AI_ci;
|
||||
|
||||
@@ -522,6 +570,9 @@ void ai_object_init(object * obj, int ai_index);
|
||||
// Called once a frame
|
||||
void ai_process( object * obj, int ai_index, float frametime );
|
||||
|
||||
int get_wingnum(int objnum);
|
||||
|
||||
void set_wingnum(int objnum, int wingnum);
|
||||
const char *ai_get_goal_target_name(const char *name, int *index);
|
||||
void ai_clear_goal_target_names();
|
||||
|
||||
@@ -533,11 +584,11 @@ extern void ai_ignore_wing(object *ignorer, int wingnum);
|
||||
extern void ai_dock_with_object(object *docker, int docker_index, object *dockee, int dockee_index, int dock_type);
|
||||
extern void ai_stay_still(object *still_objp, vec3d *view_pos);
|
||||
extern void ai_do_default_behavior(object *obj);
|
||||
extern void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags, int start_index);
|
||||
extern void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags);
|
||||
extern void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hit_normal);
|
||||
extern void ai_ship_destroy(int shipnum);
|
||||
extern vec3d ai_get_acc_limit(vec3d* vel_limit, const object* objp);
|
||||
extern void ai_turn_towards_vector(const vec3d *dest, object *objp, const vec3d *slide_vec, const vec3d *rel_pos, float bank_override, int flags, const vec3d *rvec = nullptr, const vec3d* turnrate_mod = nullptr);
|
||||
extern void ai_turn_towards_vector(vec3d *dest, object *objp, vec3d *slide_vec, vec3d *rel_pos, float bank_override, int flags, vec3d *rvec = nullptr, vec3d* turnrate_mod = nullptr);
|
||||
extern void init_ai_object(int objnum);
|
||||
extern void ai_init(void); // Call this one to parse ai.tbl.
|
||||
extern void ai_level_init(void); // Call before each level to reset AI
|
||||
@@ -560,7 +611,7 @@ extern void ai_attack_wing(object *attacker, int wingnum);
|
||||
extern void ai_deathroll_start(object *ship_obj);
|
||||
extern int set_target_objnum(ai_info *aip, int objnum);
|
||||
extern void ai_form_on_wing(object *objp, object *goal_objp);
|
||||
extern void ai_do_stay_near(object *objp, object *other_obj, float dist, int additional_data);
|
||||
extern void ai_do_stay_near(object *objp, object *other_obj, float dist);
|
||||
extern ship_subsys *set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, int parent_objnum);
|
||||
extern void ai_rearm_repair( object *objp, int docker_index, object *goal_objp, int dockee_index );
|
||||
extern void ai_add_rearm_goal( object *requester_objp, object *support_objp );
|
||||
@@ -589,8 +640,6 @@ extern int ai_fire_primary_weapon(object *objp); //changed to return weather it
|
||||
extern int ai_fire_secondary_weapon(object *objp);
|
||||
extern float ai_get_weapon_dist(ship_weapon *swp);
|
||||
extern void turn_towards_point(object *objp, vec3d *point, vec3d *slide_vec, float bank_override, matrix* target_orient = nullptr, int flags = 0);
|
||||
extern bool ai_willing_to_afterburn_hard(ai_info* aip);
|
||||
extern void ai_afterburn_hard(object* objp, ai_info* aip);
|
||||
extern int ai_maybe_fire_afterburner(object *objp, ai_info *aip);
|
||||
extern void set_predicted_enemy_pos(vec3d *predicted_enemy_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, ai_info *aip);
|
||||
|
||||
@@ -620,6 +669,10 @@ int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float ra
|
||||
// moved to header file by Goober5000
|
||||
void ai_announce_ship_dying(object *dying_objp);
|
||||
|
||||
// added by kazan
|
||||
void ai_start_fly_to_ship(object *objp, int shipnum);
|
||||
void ai_fly_to_ship();
|
||||
|
||||
//Moved declaration here for player ship -WMC
|
||||
void ai_process_subobjects(int objnum);
|
||||
|
||||
@@ -634,6 +687,6 @@ void do_random_sidethrust(ai_info *aip, ship_info *sip);
|
||||
void ai_formation_object_recalculate_slotnums(int form_objnum, int exiting_objnum = -1);
|
||||
|
||||
|
||||
bool test_line_of_sight(vec3d* from, vec3d* to, std::unordered_set<const object*>&& excluded_objects = {}, float threshold = 10.0f, bool test_for_shields = false, bool test_for_hull = true, float* first_intersect_dist = nullptr, object** first_intersect_obj = nullptr);
|
||||
bool test_line_of_sight(vec3d* from, vec3d* to, std::unordered_set<const object*>&& excluded_objects = {}, float threshold = 10.0f, bool test_for_shields = false, bool test_for_hull = true, float* first_intersect_dist = nullptr);
|
||||
|
||||
#endif
|
||||
+4
-17
@@ -45,9 +45,7 @@ namespace AI {
|
||||
Purge, // purge this goal next time we process
|
||||
Goals_purged, // this goal has already caused other goals to get purged
|
||||
Depart_sound_played,// Goober5000 - replacement for AL's hack ;)
|
||||
Target_own_team, // this attack goal is allowed to target friendlies
|
||||
Afterburn_hard, // afterburn as hard as possible to the goal
|
||||
Waypoints_in_reverse, // decrement instead of increment
|
||||
Target_own_team,
|
||||
|
||||
NUM_VALUES
|
||||
};
|
||||
@@ -123,7 +121,7 @@ namespace AI {
|
||||
Smart_shield_management,
|
||||
Smart_subsystem_targeting_for_turrets,
|
||||
Strict_turret_tagged_only_targeting,
|
||||
Support_dont_add_primaries, //Prevents support ship from equipping new primary as requested in https://scp.indiegames.us/mantis/view.php?id=3198
|
||||
Support_dont_add_primaries, //Prevents support ship from equipping new primary as requested in http://scp.indiegames.us/mantis/view.php?id=3198
|
||||
Turrets_ignore_target_radius,
|
||||
Use_actual_primary_range,
|
||||
Use_subsystem_path_point_radii,
|
||||
@@ -132,9 +130,8 @@ namespace AI {
|
||||
Use_only_single_fov_for_turrets,
|
||||
No_turning_directional_bias,
|
||||
Use_axial_turnrate_differences,
|
||||
All_nonshielded_ships_can_manage_ets,
|
||||
Fightercraft_nonshielded_ships_can_manage_ets,
|
||||
Ships_playing_dead_dont_manage_ets,
|
||||
all_nonshielded_ships_can_manage_ets,
|
||||
fightercraft_nonshielded_ships_can_manage_ets,
|
||||
Better_collision_avoidance,
|
||||
Require_exact_los,
|
||||
Improved_missile_avoidance,
|
||||
@@ -148,16 +145,6 @@ namespace AI {
|
||||
Prevent_negative_turret_ammo,
|
||||
Fix_keep_safe_distance,
|
||||
Ignore_aspect_when_leading,
|
||||
Fix_good_rearm_time_bug,
|
||||
No_continuous_turn_on_attack,
|
||||
Fixed_removing_play_dead_order,
|
||||
Disable_bay_emerge_timeout,
|
||||
Adjusted_AI_class_autoscale,
|
||||
Carry_shield_difficulty_scaling_bug,
|
||||
Whackable_debris,
|
||||
Whackable_asteroids,
|
||||
Dynamic_goals_afterburn_hard,
|
||||
Hudsquadmsg_tactical_disarm_disable,
|
||||
|
||||
NUM_VALUES
|
||||
};
|
||||
|
||||
+11
-62
@@ -223,9 +223,6 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
if (optional_string("$Player Subsys Damage Factor:") || optional_string("$AI Damage Reduction to Player Subsys:"))
|
||||
parse_float_list(profile->subsys_damage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Damage Inflicted Factor:"))
|
||||
parse_float_list(profile->player_damage_inflicted_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
// represented in fractions of F1_0
|
||||
if (optional_string("$Predict Position Delay:"))
|
||||
{
|
||||
@@ -258,7 +255,7 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
if (optional_string("$Glide Attack Percent:")) {
|
||||
parse_float_list(profile->glide_attack_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it between 0 and 1.0
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->glide_attack_percent[i] < 0.0f || profile->glide_attack_percent[i] > 100.0f) {
|
||||
@@ -271,7 +268,7 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
if (optional_string("$Circle Strafe Percent:")) {
|
||||
parse_float_list(profile->circle_strafe_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it between 0 and 1.0
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->circle_strafe_percent[i] < 0.0f || profile->circle_strafe_percent[i] > 100.0f) {
|
||||
@@ -284,7 +281,7 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
if (optional_string("$Glide Strafe Percent:")) {
|
||||
parse_float_list(profile->glide_strafe_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it between 0 and 1.0
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->glide_strafe_percent[i] < 0.0f || profile->glide_strafe_percent[i] > 100.0f) {
|
||||
@@ -297,7 +294,7 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
if (optional_string("$Random Sidethrust Percent:")) {
|
||||
parse_float_list(profile->random_sidethrust_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it between 0 and 1.0
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->random_sidethrust_percent[i] < 0.0f || profile->random_sidethrust_percent[i] > 100.0f) {
|
||||
@@ -549,20 +546,16 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
mprintf(("Warning: \"$ships with no shields can manage ETS\" flag is deprecated in favor of \"$any ship with no shields can manage ETS\"\n"));
|
||||
bool temp;
|
||||
stuff_boolean(&temp);
|
||||
profile->flags.set(AI::Profile_Flags::All_nonshielded_ships_can_manage_ets, temp);
|
||||
profile->flags.set(AI::Profile_Flags::all_nonshielded_ships_can_manage_ets, temp);
|
||||
}
|
||||
|
||||
// ----------
|
||||
|
||||
set_flag(profile, "$no directional bias for missile and ship turning:", AI::Profile_Flags::No_turning_directional_bias);
|
||||
set_flag(profile, "$no directional bias for missile and ship turning:", AI::Profile_Flags::No_turning_directional_bias);
|
||||
|
||||
set_flag(profile, "$respect ship axial turnrate differences:", AI::Profile_Flags::Use_axial_turnrate_differences);
|
||||
|
||||
set_flag(profile, "$any ship with no shields can manage ETS:", AI::Profile_Flags::All_nonshielded_ships_can_manage_ets);
|
||||
set_flag(profile, "$any ship with no shields can manage ETS:", AI::Profile_Flags::all_nonshielded_ships_can_manage_ets);
|
||||
|
||||
set_flag(profile, "$fighters/bombers with no shields can manage ETS:", AI::Profile_Flags::Fightercraft_nonshielded_ships_can_manage_ets);
|
||||
|
||||
set_flag(profile, "$ships playing dead don't manage ETS:", AI::Profile_Flags::Ships_playing_dead_dont_manage_ets);
|
||||
set_flag(profile, "$fighters/bombers with no shields can manage ETS:", AI::Profile_Flags::fightercraft_nonshielded_ships_can_manage_ets);
|
||||
|
||||
set_flag(profile, "$better combat collision avoidance for fightercraft:", AI::Profile_Flags::Better_collision_avoidance);
|
||||
|
||||
@@ -607,25 +600,6 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
set_flag(profile, "$AI ignores aspect lock for leading:", AI::Profile_Flags::Ignore_aspect_when_leading);
|
||||
|
||||
set_flag(profile, "$fix good-rearm-time bug:", AI::Profile_Flags::Fix_good_rearm_time_bug);
|
||||
|
||||
set_flag(profile, "$no continuous turn on attack:", AI::Profile_Flags::No_continuous_turn_on_attack);
|
||||
|
||||
set_flag(profile, "$remove-goal properly removes play-dead order:", AI::Profile_Flags::Fixed_removing_play_dead_order);
|
||||
|
||||
set_flag(profile, "$bay arrivals not time limited:", AI::Profile_Flags::Disable_bay_emerge_timeout);
|
||||
|
||||
set_flag(profile, "$use adjusted AI class autoscale:", AI::Profile_Flags::Adjusted_AI_class_autoscale);
|
||||
|
||||
set_flag(profile, "$carry shield difficulty scaling bug:", AI::Profile_Flags::Carry_shield_difficulty_scaling_bug);
|
||||
|
||||
set_flag(profile, "$debris affected by physics whacks:", AI::Profile_Flags::Whackable_debris);
|
||||
|
||||
set_flag(profile, "$asteroids affected by physics whacks:", AI::Profile_Flags::Whackable_asteroids);
|
||||
|
||||
set_flag(profile, "$dynamic goals afterburn hard:", AI::Profile_Flags::Dynamic_goals_afterburn_hard);
|
||||
|
||||
set_flag(profile, "$hud squad messages use tactical disarm/disable:", AI::Profile_Flags::Hudsquadmsg_tactical_disarm_disable);
|
||||
|
||||
// if we've been through once already and are at the same place, force a move
|
||||
if (saved_Mp && (saved_Mp == Mp))
|
||||
@@ -668,21 +642,12 @@ void ai_profiles_init()
|
||||
// init retail entry first
|
||||
parse_ai_profiles_tbl(NULL);
|
||||
|
||||
// Allow mission_profiles.tbl to be a alias of ai_profiles.tbl, but only load one or the other.
|
||||
// mission_profiles.tbl would be newer so assume intended, but print to the log to be sure - Mjn
|
||||
char filename[MAX_FILENAME_LEN] = "ai_profiles.tbl";
|
||||
if (cf_exists_full("mission_profiles.tbl", CF_TYPE_TABLES)) {
|
||||
mprintf(("mission_profiles.tbl was found! Using that instead of ai_profiles.tbl...\n"));
|
||||
strcpy_s(filename, "mission_profiles.tbl");
|
||||
}
|
||||
|
||||
// now parse the supplied table (if any)
|
||||
if (cf_exists_full(filename, CF_TYPE_TABLES))
|
||||
parse_ai_profiles_tbl(filename);
|
||||
if (cf_exists_full("ai_profiles.tbl", CF_TYPE_TABLES))
|
||||
parse_ai_profiles_tbl("ai_profiles.tbl");
|
||||
|
||||
// parse any modular tables
|
||||
parse_modular_table("*-aip.tbm", parse_ai_profiles_tbl);
|
||||
parse_modular_table("*-msp.tbm", parse_ai_profiles_tbl);
|
||||
|
||||
// set default if specified
|
||||
temp = ai_profile_lookup(Default_profile_name);
|
||||
@@ -736,7 +701,6 @@ void ai_profile_t::reset()
|
||||
shield_energy_scale[i] = 0;
|
||||
afterburner_recharge_scale[i] = 0;
|
||||
player_damage_scale[i] = 0;
|
||||
player_damage_inflicted_scale[i] = 0;
|
||||
|
||||
subsys_damage_scale[i] = 0;
|
||||
beam_friendly_damage_cap[i] = 0;
|
||||
@@ -786,7 +750,7 @@ void ai_profile_t::reset()
|
||||
flags.set(AI::Profile_Flags::Fix_ai_path_order_bug);
|
||||
flags.set(AI::Profile_Flags::Aspect_invulnerability_fix);
|
||||
flags.set(AI::Profile_Flags::Use_actual_primary_range);
|
||||
flags.set(AI::Profile_Flags::Fightercraft_nonshielded_ships_can_manage_ets);
|
||||
flags.set(AI::Profile_Flags::fightercraft_nonshielded_ships_can_manage_ets);
|
||||
}
|
||||
// this flag has been enabled ever since 3.7.2
|
||||
if (mod_supports_version(3, 7, 2)) {
|
||||
@@ -796,10 +760,6 @@ void ai_profile_t::reset()
|
||||
if (mod_supports_version(3, 6, 10)) {
|
||||
flags.set(AI::Profile_Flags::Reset_last_hit_target_time_for_player_hits);
|
||||
}
|
||||
// backwards compatible flag for a bug accidentally introduced during this time
|
||||
if (mod_supports_version(3, 6, 14) && !mod_supports_version(23, 1, 0)) {
|
||||
flags.set(AI::Profile_Flags::Carry_shield_difficulty_scaling_bug);
|
||||
}
|
||||
if (mod_supports_version(21, 4, 0)) {
|
||||
flags.set(AI::Profile_Flags::Fixed_ship_weapon_collision);
|
||||
}
|
||||
@@ -808,15 +768,4 @@ void ai_profile_t::reset()
|
||||
flags.set(AI::Profile_Flags::Prevent_negative_turret_ammo);
|
||||
flags.set(AI::Profile_Flags::Fix_keep_safe_distance);
|
||||
}
|
||||
if (mod_supports_version(23, 0, 0)) {
|
||||
flags.set(AI::Profile_Flags::Fix_good_rearm_time_bug);
|
||||
flags.set(AI::Profile_Flags::No_continuous_turn_on_attack);
|
||||
flags.set(AI::Profile_Flags::Fixed_removing_play_dead_order);
|
||||
}
|
||||
if (mod_supports_version(23, 2, 0)) {
|
||||
flags.set(AI::Profile_Flags::Ships_playing_dead_dont_manage_ets);
|
||||
}
|
||||
if (mod_supports_version(23, 4, 0)) {
|
||||
flags.set(AI::Profile_Flags::Hudsquadmsg_tactical_disarm_disable);
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
#define AI_RANGE_AWARE_SEC_SEL_MODE_RETAIL 0
|
||||
#define AI_RANGE_AWARE_SEC_SEL_MODE_AWARE 1
|
||||
|
||||
#define MAX_AI_PROFILES 8
|
||||
#define MAX_AI_PROFILES 5
|
||||
|
||||
class ai_profile_t {
|
||||
public:
|
||||
@@ -53,7 +53,6 @@ public:
|
||||
float shield_energy_scale[NUM_SKILL_LEVELS]; // shield energy available
|
||||
float afterburner_recharge_scale[NUM_SKILL_LEVELS]; // speed of afterburner recharge
|
||||
float player_damage_scale[NUM_SKILL_LEVELS]; // damage applied to the player
|
||||
float player_damage_inflicted_scale[NUM_SKILL_LEVELS]; // damage applied by the player
|
||||
|
||||
float subsys_damage_scale[NUM_SKILL_LEVELS]; // damage applied to a player subsystem
|
||||
float beam_friendly_damage_cap[NUM_SKILL_LEVELS]; // damage cap values for friendly beam fire
|
||||
|
||||
+83
-100
@@ -67,6 +67,7 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check=1);
|
||||
void ai_big_strafe_position();
|
||||
static int ai_big_strafe_maybe_retreat(const vec3d *target_pos);
|
||||
|
||||
extern int model_which_octant_distant_many( vec3d *pnt, int model_num,matrix *model_orient, vec3d * model_pos, polymodel **pm, int *octs);
|
||||
extern void compute_desired_rvec(vec3d *rvec, vec3d *goal_pos, vec3d *cur_pos);
|
||||
extern void big_ship_collide_recover_start(object *objp, object *big_objp, vec3d *collision_normal);
|
||||
|
||||
@@ -82,9 +83,10 @@ void ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec,
|
||||
vec3d result_point, best_point;
|
||||
vec3d rel_point;
|
||||
int num_tries;
|
||||
int i;
|
||||
model_octant *octp;
|
||||
polymodel *pm;
|
||||
int i, q, octs[4];
|
||||
ship_info *sip = &Ship_info[Ships[objp->instance].ship_info_index];
|
||||
polymodel* pm = model_get(sip->model_num);
|
||||
model_subsystem *tp = NULL;
|
||||
if (ss != NULL)
|
||||
tp = ss->system_info;
|
||||
@@ -92,53 +94,63 @@ void ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec,
|
||||
best_point = objp->pos;
|
||||
nearest_dist = weapon_travel_dist;
|
||||
|
||||
// attempt anywhere from 16 to 4 times, more if we're closer
|
||||
model_which_octant_distant_many(attacker_objp_pos, sip->model_num, &objp->orient, &objp->pos, &pm, octs);
|
||||
|
||||
num_tries = (int) (vm_vec_dist(&objp->pos, attacker_objp_pos)/objp->radius);
|
||||
|
||||
if (num_tries >= 4)
|
||||
num_tries = 1;
|
||||
else
|
||||
num_tries = (4 - num_tries) * 4;
|
||||
num_tries = 4 - num_tries;
|
||||
|
||||
vm_vec_zero(local_attack_point);
|
||||
// Index #0 is best one.
|
||||
if ( pm->octants[octs[0]].verts ) {
|
||||
*local_attack_point = *pm->octants[octs[0]].verts[0]; // Set just in case it doesn't get set below.
|
||||
} else {
|
||||
vm_vec_zero(local_attack_point);
|
||||
}
|
||||
|
||||
auto collision_tree = model_get_bsp_collision_tree(pm->submodel[pm->detail[0]].collision_tree_index);
|
||||
for (q=0; q<4; q++) {
|
||||
octp = &pm->octants[octs[q]];
|
||||
if (octp->nverts > 0) {
|
||||
|
||||
if (!collision_tree->poly_centers.empty()) {
|
||||
int num_polies = (int)collision_tree->poly_centers.size();
|
||||
if (num_tries > octp->nverts)
|
||||
num_tries = octp->nverts;
|
||||
|
||||
if (num_tries > num_polies)
|
||||
num_tries = num_polies;
|
||||
if (num_tries > octp->nverts)
|
||||
num_tries = octp->nverts;
|
||||
|
||||
for (i=0; i<num_tries; i++) {
|
||||
int index;
|
||||
float dist, dot;
|
||||
vec3d v2p;
|
||||
for (i=0; i<num_tries; i++) {
|
||||
int index;
|
||||
float dist, dot;
|
||||
vec3d v2p;
|
||||
|
||||
index = (int) (frand() * num_polies);
|
||||
index = (int) (frand() * (octp->nverts));
|
||||
|
||||
rel_point = collision_tree->poly_centers[index];
|
||||
vm_vec_unrotate(&result_point, &rel_point, &objp->orient);
|
||||
vm_vec_add2(&result_point, &objp->pos);
|
||||
rel_point = *octp->verts[index];
|
||||
vm_vec_unrotate(&result_point, &rel_point, &objp->orient);
|
||||
vm_vec_add2(&result_point, &objp->pos);
|
||||
|
||||
dist = vm_vec_normalized_dir(&v2p, &result_point, attacker_objp_pos);
|
||||
bool in_fov = false;
|
||||
dist = vm_vec_normalized_dir(&v2p, &result_point, attacker_objp_pos);
|
||||
bool in_fov = false;
|
||||
|
||||
dot = vm_vec_dot(&v2p, attacker_objp_fvec);
|
||||
if (tp == NULL) {
|
||||
if (dot > fov)
|
||||
in_fov = true;
|
||||
} else {
|
||||
in_fov = turret_fov_test(ss, attacker_objp_fvec, &v2p);
|
||||
}
|
||||
dot = vm_vec_dot(&v2p, attacker_objp_fvec);
|
||||
if (tp == NULL) {
|
||||
if (dot > fov)
|
||||
in_fov = true;
|
||||
} else {
|
||||
in_fov = turret_fov_test(ss, attacker_objp_fvec, &v2p);
|
||||
}
|
||||
|
||||
if (in_fov) {
|
||||
if (dist < nearest_dist) {
|
||||
nearest_dist = dist;
|
||||
best_point = result_point;
|
||||
*local_attack_point = rel_point;
|
||||
Assert( !vm_is_vec_nan(local_attack_point) );
|
||||
if (dot > (1.0f + fov)/2.0f) // If this point is quite good, quit searching for a better one.
|
||||
goto done_1;
|
||||
if (in_fov) {
|
||||
if (dist < nearest_dist) {
|
||||
nearest_dist = dist;
|
||||
best_point = result_point;
|
||||
*local_attack_point = rel_point;
|
||||
Assert( !vm_is_vec_nan(local_attack_point) );
|
||||
if (dot > (1.0f + fov)/2.0f) // If this point is quite good, quit searching for a better one.
|
||||
goto done_1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,6 +174,8 @@ done_1:
|
||||
}
|
||||
|
||||
mc_info mc;
|
||||
mc_info_init(&mc);
|
||||
|
||||
mc.model_instance_num = Ships[objp->instance].model_instance_num;
|
||||
mc.model_num = sip->model_num;
|
||||
mc.orient = &objp->orient;
|
||||
@@ -535,10 +549,11 @@ bool ai_new_maybe_reposition_attack_subsys() {
|
||||
|
||||
// get world pos of eye (stored in geye)
|
||||
ep = &(pm->view_positions[Ships[Pl_objp->instance].current_viewpoint]);
|
||||
model_local_to_global_point(&geye, &ep->pnt, pm, 0, &Pl_objp->orient, &Pl_objp->pos);
|
||||
model_local_to_global_point(&geye, &ep->pnt, pm->id, 0, &Pl_objp->orient, &Pl_objp->pos);
|
||||
|
||||
// get world pos of subsystem
|
||||
get_subsystem_pos(&gsubpos, target_objp, aip->targeted_subsys);
|
||||
vm_vec_unrotate(&gsubpos, &aip->targeted_subsys->system_info->pnt, &En_objp->orient);
|
||||
vm_vec_add2(&gsubpos, &En_objp->pos);
|
||||
|
||||
// you're in sight! shoot it!
|
||||
if (ship_subsystem_in_sight(En_objp, aip->targeted_subsys, &geye, &gsubpos, 0))
|
||||
@@ -546,7 +561,6 @@ bool ai_new_maybe_reposition_attack_subsys() {
|
||||
|
||||
// not in sight, gotta get there
|
||||
vec3d* good_pos = nullptr;
|
||||
vec3d world_goal_pos;
|
||||
// For performance reasons we only recheck once a second, otherwise we reuse the last found target.
|
||||
if (timestamp_elapsed(aip->next_dynamic_path_check_time)) {
|
||||
vec3d tgt2pl = Pl_objp->pos - target_objp->pos;
|
||||
@@ -568,6 +582,7 @@ bool ai_new_maybe_reposition_attack_subsys() {
|
||||
vm_rot_point_around_line(&goal_pos, &tgt2pl, angle2goal, &vmd_zero_vector, &cross);
|
||||
|
||||
// then scale in (or out) towards our subsys
|
||||
vec3d world_goal_pos;
|
||||
float new_radius = ((subsys_dist - pl_dist) * (angle2goal / angle2subsys)) + pl_dist;
|
||||
vm_vec_copy_scale(&world_goal_pos, &goal_pos, new_radius / pl_dist);
|
||||
world_goal_pos += target_objp->pos;
|
||||
@@ -603,7 +618,6 @@ bool ai_new_maybe_reposition_attack_subsys() {
|
||||
else
|
||||
good_pos = &world_goal_pos;
|
||||
aip->next_dynamic_path_check_time = timestamp( AI_DYNAMIC_PATH_RECHECK_DELAY );
|
||||
aip->last_dynamic_path_goal = *good_pos;
|
||||
|
||||
}
|
||||
else{ //Not enough time has passed till recheck.
|
||||
@@ -617,17 +631,15 @@ bool ai_new_maybe_reposition_attack_subsys() {
|
||||
accelerate_ship(aip, subsys_distance > 200.0f ? 1.0f : subsys_distance / 200.0f);
|
||||
|
||||
if (!(Ships[Pl_objp->instance].flags[Ship::Ship_Flags::Afterburner_locked])) {
|
||||
if (ai_willing_to_afterburn_hard(aip) && subsys_distance > 1000.0f)
|
||||
ai_afterburn_hard(Pl_objp, aip);
|
||||
else if (subsys_distance > 300.0f) {
|
||||
if (subsys_distance > 300.0f) {
|
||||
if (ai_maybe_fire_afterburner(Pl_objp, aip)) {
|
||||
afterburners_start(Pl_objp);
|
||||
aip->afterburner_stop_time = Missiontime + 2 * F1_0;
|
||||
}
|
||||
}
|
||||
} else
|
||||
afterburners_stop(Pl_objp);
|
||||
|
||||
else
|
||||
afterburners_stop(Pl_objp);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
@@ -649,17 +661,16 @@ int ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
|
||||
// are near
|
||||
if ( sip->is_small_ship() ) {
|
||||
if ( timestamp_elapsed(aip->scan_for_enemy_timestamp) ) {
|
||||
ship_obj *so;
|
||||
object *test_objp;
|
||||
ship *test_sp;
|
||||
float dist_squared;
|
||||
|
||||
aip->scan_for_enemy_timestamp = timestamp(SCAN_FIGHTERS_INTERVAL);
|
||||
// iterate through ships, and see if any fighter/bomber from opposite team are near
|
||||
for (auto so: list_range(&Ship_obj_list)) {
|
||||
so = GET_FIRST(&Ship_obj_list);
|
||||
while( so != END_OF_LIST(&Ship_obj_list) ) {
|
||||
test_objp = &Objects[so->objnum];
|
||||
if (test_objp->flags[Object::Object_Flags::Should_be_dead])
|
||||
continue;
|
||||
|
||||
test_sp = &Ships[test_objp->instance];
|
||||
|
||||
if ( iff_x_attacks_y(Ships[Pl_objp->instance].team, test_sp->team) ) {
|
||||
@@ -670,6 +681,7 @@ int ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
|
||||
}
|
||||
}
|
||||
}
|
||||
so = GET_NEXT(so);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -694,9 +706,6 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
if (Pl_objp->phys_info.speed < 3.0f) {
|
||||
object *objp;
|
||||
for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
|
||||
if (objp->flags[Object::Object_Flags::Should_be_dead])
|
||||
continue;
|
||||
|
||||
if ((objp->type == OBJ_WEAPON) && (iff_x_attacks_y(Ships[Pl_objp->instance].team, Weapons[objp->instance].team)))
|
||||
if (Weapon_info[Weapons[objp->instance].weapon_info_index].subtype == WP_LASER) {
|
||||
vec3d in_vec;
|
||||
@@ -747,7 +756,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
if (ai_new_maybe_reposition_attack_subsys())
|
||||
return;
|
||||
} else if ( ai_big_maybe_follow_subsys_path() ) {
|
||||
if ((Pl_objp->phys_info.flags & PF_AFTERBURNER_ON) && !(aip->ai_flags[AI::AI_Flags::Kamikaze]) && !ai_willing_to_afterburn_hard(aip)) {
|
||||
if ((Pl_objp->phys_info.flags & PF_AFTERBURNER_ON) && !(aip->ai_flags[AI::AI_Flags::Kamikaze])) {
|
||||
afterburners_stop(Pl_objp);
|
||||
}
|
||||
return;
|
||||
@@ -839,9 +848,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
} else {
|
||||
accelerate_ship(aip, accel);
|
||||
|
||||
if (ai_willing_to_afterburn_hard(aip) && accel > 0.99f && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked])) {
|
||||
ai_afterburn_hard(Pl_objp, aip);
|
||||
} else if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (accel > 0.95f)) {
|
||||
if ((aip->ai_flags[AI::AI_Flags::Free_afterburner_use] || aip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use]) && !(shipp->flags[Ship::Ship_Flags::Afterburner_locked]) && (accel > 0.95f)) {
|
||||
if (ai_maybe_fire_afterburner(Pl_objp, aip)) {
|
||||
afterburners_start(Pl_objp);
|
||||
aip->afterburner_stop_time = Missiontime + 3*F1_0;
|
||||
@@ -860,9 +867,9 @@ void ai_big_chase_ct()
|
||||
ai_chase_ct();
|
||||
}
|
||||
|
||||
extern bool ai_select_secondary_weapon(object *objp, ship_weapon *swp, int priority1 = -1, int priority2 = -1);
|
||||
extern void ai_select_secondary_weapon(object *objp, ship_weapon *swp, int priority1 = -1, int priority2 = -1);
|
||||
extern float set_secondary_fire_delay(ai_info *aip, ship *shipp, weapon_info *swip, bool burst);
|
||||
extern bool ai_choose_secondary_weapon(object *objp, ai_info *aip, object *en_objp);
|
||||
extern void ai_choose_secondary_weapon(object *objp, ai_info *aip, object *en_objp);
|
||||
extern int maybe_avoid_big_ship(object *objp, object *ignore_objp, ai_info *aip, vec3d *goal_point, float delta_time, float time_scale = 1.f);
|
||||
|
||||
extern void maybe_cheat_fire_synaptic(object *objp);
|
||||
@@ -893,7 +900,7 @@ static void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy)
|
||||
|
||||
// Chance of hitting ship is based on dot product of firing ship's forward vector with vector to ship
|
||||
// and also the size of the target relative to distance to target.
|
||||
if (dot_to_enemy > std::max(0.5f, 0.90f + aip->ai_accuracy / 10.0f - En_objp->radius / std::max(1.0f, dist_to_enemy))) {
|
||||
if (dot_to_enemy > MAX(0.5f, 0.90f + aip->ai_accuracy/10.0f - En_objp->radius/MAX(1.0f,dist_to_enemy))) {
|
||||
|
||||
ship *temp_shipp;
|
||||
temp_shipp = &Ships[Pl_objp->instance];
|
||||
@@ -913,13 +920,13 @@ static void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy)
|
||||
}
|
||||
|
||||
if (tswp->num_secondary_banks > 0) {
|
||||
if (!(En_objp->flags[Object::Object_Flags::Protected]) || (aip->goals[0].ai_mode & (AI_GOAL_DISABLE_SHIP | AI_GOAL_DISABLE_SHIP_TACTICAL | AI_GOAL_DISARM_SHIP | AI_GOAL_DISARM_SHIP_TACTICAL))) {
|
||||
bool valid_secondary = ai_choose_secondary_weapon(Pl_objp, aip, En_objp);
|
||||
if (!(En_objp->flags[Object::Object_Flags::Protected]) || (aip->goals[0].ai_mode & (AI_GOAL_DISABLE_SHIP | AI_GOAL_DISARM_SHIP))) {
|
||||
ai_choose_secondary_weapon(Pl_objp, aip, En_objp);
|
||||
int current_bank = tswp->current_secondary_bank;
|
||||
if (current_bank > -1 && valid_secondary) {
|
||||
if (current_bank > -1) {
|
||||
weapon_info *swip = &Weapon_info[tswp->secondary_bank_weapons[current_bank]];
|
||||
|
||||
if(!(En_objp->flags[Object::Object_Flags::Protected]) || ((aip->goals[0].ai_mode & (AI_GOAL_DISABLE_SHIP | AI_GOAL_DISABLE_SHIP_TACTICAL | AI_GOAL_DISARM_SHIP | AI_GOAL_DISARM_SHIP_TACTICAL)) && swip->wi_flags[Weapon::Info_Flags::Puncture] )) { //override lockdown on protected ships when using anti subsystem weapons - Valathil
|
||||
if(!(En_objp->flags[Object::Object_Flags::Protected]) || ((aip->goals[0].ai_mode & (AI_GOAL_DISABLE_SHIP | AI_GOAL_DISARM_SHIP)) && swip->wi_flags[Weapon::Info_Flags::Puncture] )) { //override lockdown on protected ships when using anti subsystem weapons - Valathil
|
||||
// If ship is protected and very low on hits, don't fire missiles.
|
||||
if (!(En_objp->flags[Object::Object_Flags::Protected]) || (En_objp->hull_strength > 10*swip->damage)) {
|
||||
if (aip->ai_flags[AI::AI_Flags::Unload_secondaries]) {
|
||||
@@ -1012,8 +1019,6 @@ void ai_big_switch_to_chase_mode(ai_info *aip)
|
||||
aip->submode_start_time = Missiontime;
|
||||
}
|
||||
|
||||
extern weapon_info* ai_get_weapon(ship_weapon* swp);
|
||||
|
||||
// Make object Pl_objp chase object En_objp, which is a big ship, not a small ship.
|
||||
void ai_big_chase()
|
||||
{
|
||||
@@ -1033,38 +1038,16 @@ void ai_big_chase()
|
||||
player_pos = Pl_objp->pos;
|
||||
ai_big_pick_attack_point(En_objp, Pl_objp, &enemy_pos, 0.8f);
|
||||
|
||||
weapon_info* wip = ai_get_weapon(&shipp->weapons);
|
||||
bool ballistic_aiming = !IS_VEC_NULL(&The_mission.gravity) && wip->gravity_const != 0.0f;
|
||||
bool valid_ballistic_trajectory = true;
|
||||
// Compute the predicted position of the center of the ship, then add the delta to the goal pos.
|
||||
if (En_objp->phys_info.speed > 3.0f) {
|
||||
set_predicted_enemy_pos(&predicted_enemy_pos, Pl_objp, &En_objp->pos, &En_objp->phys_info.vel, aip);
|
||||
vm_vec_add2(&enemy_pos, &predicted_enemy_pos);
|
||||
vm_vec_sub2(&enemy_pos, &En_objp->pos);
|
||||
} else
|
||||
predicted_enemy_pos = En_objp->pos;
|
||||
|
||||
if (!ballistic_aiming) {
|
||||
// Compute the predicted position of the center of the ship, then add the delta to the goal pos.
|
||||
if (En_objp->phys_info.speed > 3.0f) {
|
||||
set_predicted_enemy_pos(&predicted_enemy_pos, Pl_objp, &En_objp->pos, &En_objp->phys_info.vel, aip);
|
||||
vm_vec_add2(&enemy_pos, &predicted_enemy_pos);
|
||||
vm_vec_sub2(&enemy_pos, &En_objp->pos);
|
||||
} else
|
||||
predicted_enemy_pos = En_objp->pos;
|
||||
|
||||
if (aip->targeted_subsys != NULL) {
|
||||
get_subsystem_pos(&enemy_pos, En_objp, aip->targeted_subsys);
|
||||
}
|
||||
} else {
|
||||
if (aip->targeted_subsys != NULL) {
|
||||
get_subsystem_pos(&enemy_pos, En_objp, aip->targeted_subsys);
|
||||
}
|
||||
|
||||
vec3d gravity = The_mission.gravity * wip->gravity_const;
|
||||
vec3d target;
|
||||
valid_ballistic_trajectory =
|
||||
physics_lead_ballistic_trajectory(&player_pos, &enemy_pos, &En_objp->phys_info.vel, wip->max_speed, &gravity, &target);
|
||||
|
||||
if (valid_ballistic_trajectory) {
|
||||
enemy_pos = Pl_objp->pos + target * vm_vec_dist(&Pl_objp->pos, &enemy_pos);
|
||||
predicted_enemy_pos = enemy_pos;
|
||||
} else {
|
||||
set_predicted_enemy_pos(&predicted_enemy_pos, Pl_objp, &En_objp->pos, &En_objp->phys_info.vel, aip);
|
||||
}
|
||||
if (aip->targeted_subsys != NULL) {
|
||||
get_subsystem_pos(&enemy_pos, En_objp, aip->targeted_subsys);
|
||||
}
|
||||
|
||||
dist_to_enemy = vm_vec_normalized_dir(&vec_to_enemy, &enemy_pos, &player_pos); // - En_objp->radius;
|
||||
@@ -1095,7 +1078,7 @@ void ai_big_chase()
|
||||
// If just acquired target, or target is not in reasonable cone, don't refine believed enemy position.
|
||||
if ((dot_to_enemy < 0.25f) || (aip->target_time < 1.0f) || (aip->ai_flags[AI::AI_Flags::Seek_lock])) {
|
||||
update_aspect_lock_information(aip, &vec_to_enemy, dist_to_enemy - En_objp->radius, En_objp->radius);
|
||||
} else if (aip->targeted_subsys != NULL && !ballistic_aiming) {
|
||||
} else if (aip->targeted_subsys != NULL) {
|
||||
Assert(aip->targeted_subsys != NULL);
|
||||
get_subsystem_pos(&enemy_pos, En_objp, aip->targeted_subsys);
|
||||
vm_vec_add2(&enemy_pos, &predicted_enemy_pos);
|
||||
@@ -1127,7 +1110,7 @@ void ai_big_chase()
|
||||
}
|
||||
}
|
||||
|
||||
if (!aip->ai_profile_flags[AI::Profile_Flags::No_continuous_turn_on_attack] && aip->target_time < 2.0f)
|
||||
if (aip->target_time < 2.0f)
|
||||
if ((dot_to_enemy < 0.9f) || (dist_to_enemy > 300.0f)) {
|
||||
aip->submode = SM_CONTINUOUS_TURN;
|
||||
aip->submode_start_time = Missiontime - fl2f(2.75f); // This backdated start time allows immediate switchout.
|
||||
@@ -1335,7 +1318,7 @@ void ai_big_chase()
|
||||
// I noticed AI ships firing inappropriately when following a path near a big ship.
|
||||
// TODO: investigate why ships fire (and aren't close to hitting ship) when following a path near
|
||||
// a big ship
|
||||
if (aip->mode != AIM_EVADE && aip->path_start == -1 && (!ballistic_aiming || valid_ballistic_trajectory)) {
|
||||
if (aip->mode != AIM_EVADE && aip->path_start == -1 ) {
|
||||
ai_big_maybe_fire_weapons(dist_to_enemy, dot_to_enemy);
|
||||
} else {
|
||||
if (flFrametime < 1.0f)
|
||||
@@ -1841,7 +1824,7 @@ void ai_big_strafe()
|
||||
|
||||
/*
|
||||
if ( aip->goal_objnum != aip->target_objnum ) {
|
||||
UNREACHABLE("The goal objnum does not match the target objnum in ai_big_strafe(), please report to the SCP!"); // what is going on here? - Get Alan
|
||||
Int3(); // what is going on here? - Get Alan
|
||||
aip->mode = AIM_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
+610
-1041
File diff suppressed because it is too large.
Load diff
+267
-379
File diff suppressed because it is too large.
Load diff
+10
-74
@@ -12,30 +12,16 @@
|
||||
#ifndef _AIGOALS_H
|
||||
#define _AIGOALS_H
|
||||
|
||||
#include "ai/ai_flags.h"
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "parse/sexp.h"
|
||||
#include "scripting/lua/LuaTypes.h"
|
||||
#include "scripting/lua/LuaValue.h"
|
||||
|
||||
struct wing;
|
||||
struct ai_info;
|
||||
struct ai_goal;
|
||||
|
||||
// macros for goals which get set via sexpressions in the mission code
|
||||
|
||||
// types of ai goals -- tyese types will help us to determination on which goals should
|
||||
// have priority over others (i.e. when a player issues a goal to a wing, then a seperate
|
||||
// goal to a ship in that wing). We would probably use this type in conjunction with
|
||||
// goal priority to establish which goal to follow
|
||||
#define AIG_TYPE_EVENT_SHIP 1 // from mission event direct to ship
|
||||
#define AIG_TYPE_EVENT_WING 2 // from mission event direct to wing
|
||||
#define AIG_TYPE_PLAYER_SHIP 3 // from player direct to ship
|
||||
#define AIG_TYPE_PLAYER_WING 4 // from player direct to wing
|
||||
#define AIG_TYPE_DYNAMIC 5 // created on the fly
|
||||
|
||||
#define AI_GOAL_NONE -1
|
||||
|
||||
// IMPORTANT! If you add a new AI_GOAL_x define, be sure to update the functions
|
||||
// ai_update_goal_references() and query_referenced_in_ai_goals() or else risk breaking
|
||||
// Fred. If the goal you add doesn't have a target (such as chase_any), then you don't have
|
||||
@@ -73,17 +59,15 @@ struct ai_info;
|
||||
#define AI_GOAL_FLY_TO_SHIP (1<<23) // 0x00800000
|
||||
#define AI_GOAL_IGNORE_NEW (1<<24) // 0x01000000
|
||||
#define AI_GOAL_CHASE_SHIP_CLASS (1<<25) // 0x02000000
|
||||
#define AI_GOAL_PLAY_DEAD_PERSISTENT (1<<26) // 0x04000000
|
||||
#define AI_GOAL_LUA (1<<27) // 0x08000000
|
||||
#define AI_GOAL_DISARM_SHIP_TACTICAL (1<<28) // 0x10000000
|
||||
#define AI_GOAL_DISABLE_SHIP_TACTICAL (1<<29) // 0x20000000
|
||||
#define AI_GOAL_PLAY_DEAD_PERSISTENT (1<<26) // 0x03000000
|
||||
#define AI_GOAL_LUA (1<<27) // 0x04000000
|
||||
|
||||
// now the masks for ship types
|
||||
|
||||
// Goober5000: added AI_GOAL_STAY_NEAR_SHIP and AI_GOAL_KEEP_SAFE_DISTANCE as valid for fighters
|
||||
//WMC - Don't need these anymore. Whee!
|
||||
/*
|
||||
#define AI_GOAL_ACCEPT_FIGHTER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_CHASE | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_WARP | AI_GOAL_DESTROY_SUBSYSTEM | AI_GOAL_CHASE_WING | AI_GOAL_GUARD | AI_GOAL_DISABLE_SHIP | AI_GOAL_DISABLE_SHIP_TACTICAL | AI_GOAL_DISARM_SHIP | AI_GOAL_DISARM_SHIP_TACTICAL | AI_GOAL_CHASE_ANY | AI_GOAL_IGNORE | AI_GOAL_IGNORE_NEW | AI_GOAL_GUARD_WING | AI_GOAL_EVADE_SHIP | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD | AI_GOAL_PLAY_DEAD_PERSISTENT | AI_GOAL_STAY_NEAR_SHIP | AI_GOAL_KEEP_SAFE_DISTANCE )
|
||||
#define AI_GOAL_ACCEPT_FIGHTER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_CHASE | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_WARP | AI_GOAL_DESTROY_SUBSYSTEM | AI_GOAL_CHASE_WING | AI_GOAL_GUARD | AI_GOAL_DISABLE_SHIP | AI_GOAL_DISARM_SHIP | AI_GOAL_CHASE_ANY | AI_GOAL_IGNORE | AI_GOAL_IGNORE_NEW | AI_GOAL_GUARD_WING | AI_GOAL_EVADE_SHIP | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD | AI_GOAL_PLAY_DEAD_PERSISTENT | AI_GOAL_STAY_NEAR_SHIP | AI_GOAL_KEEP_SAFE_DISTANCE )
|
||||
#define AI_GOAL_ACCEPT_BOMBER ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FIGHTER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_STEALTH ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_ACCEPT_FIGHTER | AI_GOAL_STAY_NEAR_SHIP )
|
||||
#define AI_GOAL_ACCEPT_TRANSPORT ( AI_GOAL_FLY_TO_SHIP | AI_GOAL_CHASE | AI_GOAL_CHASE_WING | AI_GOAL_DOCK | AI_GOAL_WAYPOINTS | AI_GOAL_WAYPOINTS_ONCE | AI_GOAL_WARP | AI_GOAL_UNDOCK | AI_GOAL_STAY_STILL | AI_GOAL_PLAY_DEAD | AI_GOAL_PLAY_DEAD_PERSISTENT | AI_GOAL_STAY_NEAR_SHIP )
|
||||
@@ -102,51 +86,6 @@ struct ai_info;
|
||||
|
||||
enum class ai_achievability { ACHIEVABLE, NOT_ACHIEVABLE, NOT_KNOWN, SATISFIED };
|
||||
|
||||
struct ai_lua_parameters {
|
||||
object_ship_wing_point_team target;
|
||||
luacpp::LuaValueList arguments;
|
||||
};
|
||||
|
||||
// structure for AI goals
|
||||
typedef struct ai_goal {
|
||||
int signature; // Unique identifier. All goals ever created (per mission) have a unique signature.
|
||||
int ai_mode; // one of the AIM_* modes for this goal
|
||||
int ai_submode; // maybe need a submode
|
||||
int type; // one of the AIG_TYPE_* values above
|
||||
flagset<AI::Goal_Flags> flags; // one of the AIGF_* values above
|
||||
fix time; // time at which this goal was issued.
|
||||
int priority; // how important is this goal -- number 0 - 100
|
||||
|
||||
const char *target_name; // name of the thing that this goal acts upon
|
||||
int target_name_index; // index of goal_target_name in Goal_target_names[][]
|
||||
waypoint_list *wp_list; // waypoints that this ship might fly.
|
||||
int target_instance; // instance of thing this ship might be chasing (currently only used for weapons; note, not the same as objnum!)
|
||||
int target_signature; // signature of object this ship might be chasing (currently only used for weapons; paired with above value to confirm target)
|
||||
|
||||
// extra goal-specific data
|
||||
int int_data;
|
||||
float float_data;
|
||||
|
||||
// unions for docking stuff.
|
||||
// (AIGF_DOCKER_INDEX_VALID and AIGF_DOCKEE_INDEX_VALID tell us to use indexes; otherwise we use names)
|
||||
// these are the dockpoints used on the docker and dockee ships, not the ships themselves
|
||||
union {
|
||||
const char *name;
|
||||
int index;
|
||||
} docker;
|
||||
|
||||
union {
|
||||
const char *name;
|
||||
int index;
|
||||
} dockee;
|
||||
|
||||
ai_lua_parameters lua_ai_target;
|
||||
|
||||
} ai_goal;
|
||||
|
||||
extern void ai_goal_reset(ai_goal *aigp, bool adding_goal = false, int ai_mode = AI_GOAL_NONE, int ai_submode = -1, int type = -1);
|
||||
|
||||
|
||||
typedef flag_def_list ai_goal_list;
|
||||
|
||||
extern ai_goal_list Ai_goal_names[];
|
||||
@@ -157,9 +96,6 @@ extern char Ai_dock_names[MAX_AI_DOCK_NAMES][NAME_LENGTH];
|
||||
|
||||
extern const char *Ai_goal_text(int goal, int submode);
|
||||
|
||||
// every goal in a mission gets a unique signature
|
||||
extern int Ai_goal_signature;
|
||||
|
||||
// extern function definitions
|
||||
extern void ai_post_process_mission();
|
||||
extern void ai_maybe_add_form_goal( wing *wingp );
|
||||
@@ -168,17 +104,17 @@ extern void ai_process_mission_orders( int objnum, ai_info *aip );
|
||||
extern int ai_goal_num(ai_goal *goals);
|
||||
|
||||
// adds goals to ships/wing through sexpressions
|
||||
extern void ai_add_ship_goal_scripting(int mode, int submode, int priority, const char *shipname, ai_info *aip);
|
||||
extern void ai_add_ship_goal_scripting(int mode, int submode, int priority, char *shipname, ai_info *aip);
|
||||
extern void ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip );
|
||||
extern void ai_add_wing_goal_sexp( int sexp, int type, wing *wingp );
|
||||
extern void ai_add_goal_sub_sexp( int sexp, int type, ai_info *aip, ai_goal *aigp, const char *actor_name);
|
||||
extern void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name);
|
||||
|
||||
extern int ai_remove_goal_sexp_sub( int sexp, ai_goal* aigp );
|
||||
extern void ai_remove_wing_goal_sexp( int sexp, wing *wingp );
|
||||
|
||||
// adds goals to ships/sings through player orders
|
||||
extern void ai_add_ship_goal_player(int type, int mode, int submode, const char* shipname, ai_info* aip, const ai_lua_parameters& lua_target = { object_ship_wing_point_team(), luacpp::LuaValueList{} });
|
||||
extern void ai_add_wing_goal_player(int type, int mode, int submode, const char* shipname, int wingnum, const ai_lua_parameters& lua_target = { object_ship_wing_point_team(), luacpp::LuaValueList{} });
|
||||
extern void ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip, const object_ship_wing_point_team& lua_target = object_ship_wing_point_team());
|
||||
extern void ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, int wingnum, const object_ship_wing_point_team& lua_target = object_ship_wing_point_team());
|
||||
|
||||
extern void ai_remove_ship_goal( ai_info *aip, int index );
|
||||
extern void ai_clear_ship_goals( ai_info *aip );
|
||||
@@ -189,8 +125,8 @@ extern void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip );
|
||||
extern void ai_mission_goal_complete( ai_info *aip );
|
||||
extern void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp );
|
||||
|
||||
extern void ai_update_goal_references(ai_goal *goals, sexp_ref_type type, const char *old_name, const char *new_name);
|
||||
extern bool query_referenced_in_ai_goals(ai_goal *goals, sexp_ref_type type, const char *name);
|
||||
extern void ai_update_goal_references(ai_goal *goals, int type, const char *old_name, const char *new_name);
|
||||
extern int query_referenced_in_ai_goals(ai_goal *goals, int type, const char *name);
|
||||
extern char *ai_add_dock_name(const char *str);
|
||||
|
||||
extern int ai_query_goal_valid( int ship, int ai_goal_type );
|
||||
|
||||
+73
-248
@@ -18,9 +18,9 @@ void ai_lua_add_mode(int sexp_op, const ai_mode_lua& mode) {
|
||||
}
|
||||
|
||||
bool ai_lua_add_order(int sexp_op, player_order_lua order) {
|
||||
Player_orders.emplace_back(order.parseText, order.displayText, -1, sexp_op);
|
||||
Player_orders.emplace_back(vm_strdup(order.parseText.c_str()), vm_strdup(order.displayText.c_str()), -1, sexp_op);
|
||||
Player_orders.back().localize();
|
||||
|
||||
|
||||
Lua_player_orders.emplace(sexp_op, std::move(order));
|
||||
|
||||
return true;
|
||||
@@ -48,140 +48,6 @@ const player_order_lua* ai_lua_find_player_order(int sexp_op) {
|
||||
return &aiLuaOrder->second;
|
||||
}
|
||||
|
||||
int ai_lua_get_num_general_orders() {
|
||||
int count = 0;
|
||||
|
||||
for (const auto& order : Lua_player_orders) {
|
||||
if (order.second.generalOrder) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
SCP_vector<SCP_string> ai_lua_get_general_order_categories(bool enabled_only)
|
||||
{
|
||||
SCP_vector<SCP_string> list;
|
||||
|
||||
for (const auto& order : Lua_player_orders) {
|
||||
const SCP_string &cat = order.second.category;
|
||||
|
||||
// If it's not a general order then move on
|
||||
if (!order.second.generalOrder) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the order is not enabled then move on
|
||||
if (enabled_only && !order.second.cur_enabled) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Assertion((cat.length() > 0), "Lua general orders category name must be longer than 0 characters!");
|
||||
|
||||
for (size_t i = 0; i <= list.size(); i++) {
|
||||
|
||||
// reached the end of the list, so add it
|
||||
if (i == list.size()) {
|
||||
list.push_back(cat);
|
||||
break;
|
||||
}
|
||||
|
||||
// if it's already in the list then don't add it
|
||||
if (cat == list[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
// Provides a list of general orders for mission saving. You can only get one kind
|
||||
// of list at a time. If onlyEnabled and onlyValid are both true, for example, you will get
|
||||
// a list of onlyEnabled orders. If you need a list of enabled orders that are also valid, you'll
|
||||
// need to get both lists separately and compare.
|
||||
SCP_vector<SCP_string> ai_lua_get_general_orders(bool onlyEnabled, bool onlyValid, const SCP_string& category)
|
||||
{
|
||||
SCP_vector<SCP_string> list;
|
||||
|
||||
for (const auto& order : Lua_player_orders) {
|
||||
if (order.second.generalOrder) {
|
||||
bool add = false;
|
||||
|
||||
// All general orders
|
||||
if (!onlyEnabled && !onlyValid && category.empty()) {
|
||||
add = true;
|
||||
} else {
|
||||
|
||||
// Only enabled orders
|
||||
if (onlyEnabled && order.second.cur_enabled) {
|
||||
add = true;
|
||||
|
||||
// Only valid orders
|
||||
} else if (onlyValid && order.second.cur_valid) {
|
||||
add = true;
|
||||
|
||||
// Only orders that match the category requested
|
||||
} else if ((!category.empty()) && (order.second.category == category)) {
|
||||
add = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (add) {
|
||||
list.push_back(order.second.parseText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
int ai_lua_find_general_order_id(const SCP_string& name) {
|
||||
for (const auto& order : Lua_player_orders) {
|
||||
if (order.second.parseText == name) {
|
||||
return order.first;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ai_lua_enable_general_order(int sexp_op, bool enable) {
|
||||
auto aiLuaOrder = Lua_player_orders.find(sexp_op);
|
||||
|
||||
if (aiLuaOrder == Lua_player_orders.end())
|
||||
return;
|
||||
else
|
||||
aiLuaOrder->second.cur_enabled = enable;
|
||||
}
|
||||
|
||||
void ai_lua_validate_general_order(int sexp_op, bool validity)
|
||||
{
|
||||
auto aiLuaOrder = Lua_player_orders.find(sexp_op);
|
||||
|
||||
if (aiLuaOrder == Lua_player_orders.end())
|
||||
return;
|
||||
else
|
||||
aiLuaOrder->second.cur_valid = validity;
|
||||
}
|
||||
|
||||
void ai_lua_reset_general_orders() {
|
||||
for (const auto& order : Lua_player_orders) {
|
||||
ai_lua_enable_general_order(order.first, false);
|
||||
ai_lua_validate_general_order(order.first, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool ai_lua_is_general_order(int sexp_op) {
|
||||
auto aiLuaOrder = Lua_player_orders.find(sexp_op);
|
||||
|
||||
if (aiLuaOrder == Lua_player_orders.end())
|
||||
return false;
|
||||
|
||||
return aiLuaOrder->second.generalOrder;
|
||||
}
|
||||
|
||||
void run_ai_lua_action(const luacpp::LuaFunction& action, const ai_mode_lua& lua_ai, ai_info* aip) {
|
||||
if (!action.isValid()) {
|
||||
Error(LOCATION,
|
||||
@@ -190,28 +56,16 @@ void run_ai_lua_action(const luacpp::LuaFunction& action, const ai_mode_lua& lua
|
||||
}
|
||||
|
||||
luacpp::LuaValueList luaParameters;
|
||||
if (aip->shipnum >= 0){
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_AI_Helper.Set(object_h(&Objects[Ships[aip->shipnum].objnum]))));
|
||||
} else {
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_AI_Helper.Set(object_h())));
|
||||
}
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_AI_Helper.Set(object_h(&Objects[Ships[aip->shipnum].objnum]))));
|
||||
if (lua_ai.needsTarget) {
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_OSWPT.Set(aip->lua_ai_target.target)));
|
||||
}
|
||||
for (const auto& additionalParam : aip->lua_ai_target.arguments) {
|
||||
luaParameters.push_back(additionalParam);
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_OSWPT.Set(aip->lua_ai_target)));
|
||||
}
|
||||
|
||||
auto retVals = action.call(Script_system.GetLuaSession(), luaParameters);
|
||||
|
||||
if (!retVals.empty() && retVals[0].getValueType() == luacpp::ValueType::BOOLEAN) {
|
||||
if (retVals[0].getValue<bool>()) {
|
||||
|
||||
// If we don't have a ship then it's a general order and we have nothing else to do
|
||||
if (aip->shipnum >= 0) {
|
||||
ai_mission_goal_complete(aip);
|
||||
}
|
||||
}
|
||||
if (retVals[0].getValue<bool>())
|
||||
ai_mission_goal_complete(aip);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,10 +74,14 @@ void ai_lua(ai_info* aip){
|
||||
|
||||
const auto& lua_ai = Lua_ai_modes.at(aip->submode);
|
||||
|
||||
const auto& lua_ai_sexp = lua_ai.sexp;
|
||||
const auto& action = lua_ai_sexp.getAction();
|
||||
auto dynamicSEXP = sexp::get_dynamic_sexp(aip->submode);
|
||||
|
||||
run_ai_lua_action(action, lua_ai, aip);
|
||||
if (dynamicSEXP != nullptr && typeid(*dynamicSEXP) == typeid(sexp::LuaAISEXP)) {
|
||||
auto lua_ai_sexp = static_cast<sexp::LuaAISEXP*>(dynamicSEXP);
|
||||
const auto& action = lua_ai_sexp->getActionFrame();
|
||||
|
||||
run_ai_lua_action(action, lua_ai, aip);
|
||||
}
|
||||
}
|
||||
|
||||
void ai_lua_start(ai_goal* aigp, object* objp){
|
||||
@@ -240,30 +98,15 @@ void ai_lua_start(ai_goal* aigp, object* objp){
|
||||
|
||||
const auto& lua_ai = Lua_ai_modes.at(aigp->ai_submode);
|
||||
|
||||
const auto& lua_ai_sexp = lua_ai.sexp;
|
||||
const auto& action = lua_ai_sexp.getActionEnter();
|
||||
auto dynamicSEXP = sexp::get_dynamic_sexp(aigp->ai_submode);
|
||||
|
||||
run_ai_lua_action(action, lua_ai, aip);
|
||||
}
|
||||
if (dynamicSEXP != nullptr && typeid(*dynamicSEXP) == typeid(sexp::LuaAISEXP)) {
|
||||
auto lua_ai_sexp = static_cast<sexp::LuaAISEXP*>(dynamicSEXP);
|
||||
const auto& action = lua_ai_sexp->getActionEnter();
|
||||
|
||||
// For sending general orders that don't run on a ship.
|
||||
// Essentially just runs arbitrary lua script when the command is called
|
||||
void ai_lua_start_general(int lua_sexp_id, int target_objnum)
|
||||
{
|
||||
//Create a dummy aip to pass the target data
|
||||
ai_info aip;
|
||||
aip.shipnum = -1;
|
||||
|
||||
if (target_objnum >= 0 && Objects[target_objnum].type == OBJ_SHIP) {
|
||||
aip.lua_ai_target = {object_ship_wing_point_team(&Ships[Objects[target_objnum].instance]), {}};
|
||||
run_ai_lua_action(action, lua_ai, aip);
|
||||
}
|
||||
|
||||
const auto& lua_ai = ai_lua_find_mode(lua_sexp_id);
|
||||
|
||||
const auto& lua_ai_sexp = lua_ai->sexp;
|
||||
const auto& action = lua_ai_sexp.getActionEnter();
|
||||
|
||||
run_ai_lua_action(action, *lua_ai, &aip);
|
||||
}
|
||||
|
||||
bool ai_lua_is_valid_target_intrinsic(int sexp_op, int target_objnum, ship* self) {
|
||||
@@ -296,32 +139,36 @@ bool ai_lua_is_valid_target_intrinsic(int sexp_op, int target_objnum, ship* self
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ai_lua_is_valid_target_lua(const ai_mode_lua& mode, int target_objnum, ship* self) {
|
||||
bool ai_lua_is_valid_target_lua(const ai_mode_lua& mode, int sexp_op, int target_objnum, ship* self) {
|
||||
auto dynamicSEXP = sexp::get_dynamic_sexp(sexp_op);
|
||||
|
||||
const auto& action = mode.sexp.getTargetRestrict();
|
||||
if (dynamicSEXP != nullptr && typeid(*dynamicSEXP) == typeid(sexp::LuaAISEXP)) {
|
||||
auto lua_ai_sexp = static_cast<sexp::LuaAISEXP*>(dynamicSEXP);
|
||||
const auto& action = lua_ai_sexp->getTargetRestrict();
|
||||
|
||||
if (!action.isValid())
|
||||
return true;
|
||||
if (!action.isValid())
|
||||
return true;
|
||||
|
||||
luacpp::LuaValueList luaParameters;
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_Ship.Set(object_h(&Objects[self->objnum]))));
|
||||
if (mode.needsTarget) {
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_OSWPT.Set(object_ship_wing_point_team(&Ships[Objects[target_objnum].instance]))));
|
||||
}
|
||||
luacpp::LuaValueList luaParameters;
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_Ship.Set(object_h(&Objects[self->objnum]))));
|
||||
if (mode.needsTarget) {
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_OSWPT.Set(object_ship_wing_point_team(&Ships[Objects[target_objnum].instance]))));
|
||||
}
|
||||
|
||||
auto retVals = action.call(Script_system.GetLuaSession(), luaParameters);
|
||||
auto retVals = action.call(Script_system.GetLuaSession(), luaParameters);
|
||||
|
||||
if (!retVals.empty() && retVals[0].getValueType() == luacpp::ValueType::BOOLEAN) {
|
||||
return retVals[0].getValue<bool>();
|
||||
}
|
||||
else {
|
||||
Error(LOCATION, "LuaAI target restriction function did not return a valid boolean!");
|
||||
if (!retVals.empty() && retVals[0].getValueType() == luacpp::ValueType::BOOLEAN) {
|
||||
return retVals[0].getValue<bool>();
|
||||
}
|
||||
else {
|
||||
Error(LOCATION, "LuaAI target restriction function did not return a valid boolean!");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ai_lua_is_valid_target(int sexp_op, int target_objnum, ship* self, size_t order) {
|
||||
bool ai_lua_is_valid_target(int sexp_op, int target_objnum, ship* self) {
|
||||
const ai_mode_lua& mode = *ai_lua_find_mode(sexp_op);
|
||||
|
||||
//All targetless AI modes are fine
|
||||
@@ -337,77 +184,55 @@ bool ai_lua_is_valid_target(int sexp_op, int target_objnum, ship* self, size_t o
|
||||
|
||||
if (!ai_lua_is_valid_target_intrinsic(sexp_op, target_objnum, self))
|
||||
return false;
|
||||
|
||||
// check if this order can be issued against the target
|
||||
ship *shipp = &Ships[Objects[target_objnum].instance];
|
||||
if (shipp->orders_allowed_against.find(order) == shipp->orders_allowed_against.end()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//If we haven't bailed yet, query the custom callback
|
||||
return ai_lua_is_valid_target_lua(mode, target_objnum, self);
|
||||
}
|
||||
|
||||
bool ai_lua_is_valid_ship(int sexp_op, bool isWing, ship* self)
|
||||
{
|
||||
const player_order_lua& order = *ai_lua_find_player_order(sexp_op);
|
||||
|
||||
switch (order.shipRestrictions) {
|
||||
case player_order_lua::ship_restrictions::ANY:
|
||||
return true;
|
||||
case player_order_lua::ship_restrictions::WING:
|
||||
return isWing;
|
||||
case player_order_lua::ship_restrictions::IN_PLAYER_WING:
|
||||
return self->wingnum != -1 && Ships[Player_obj->instance].wingnum == self->wingnum;
|
||||
case player_order_lua::ship_restrictions::PLAYER_WING:
|
||||
return isWing && self->wingnum != -1 && Ships[Player_obj->instance].wingnum == self->wingnum;
|
||||
}
|
||||
|
||||
return false;
|
||||
return ai_lua_is_valid_target_lua(mode, sexp_op, target_objnum, self);
|
||||
}
|
||||
|
||||
ai_achievability ai_lua_is_achievable(const ai_goal* aigp, int objnum){
|
||||
const auto& lua_ai = Lua_ai_modes.at(aigp->ai_submode);
|
||||
|
||||
const auto& action = lua_ai.sexp.getAchievable();
|
||||
auto dynamicSEXP = sexp::get_dynamic_sexp(aigp->ai_submode);
|
||||
|
||||
if (!action.isValid())
|
||||
return ai_achievability::ACHIEVABLE;
|
||||
if (dynamicSEXP != nullptr && typeid(*dynamicSEXP) == typeid(sexp::LuaAISEXP)) {
|
||||
auto lua_ai_sexp = static_cast<sexp::LuaAISEXP*>(dynamicSEXP);
|
||||
const auto& action = lua_ai_sexp->getAchievable();
|
||||
|
||||
luacpp::LuaValueList luaParameters;
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_Ship.Set(object_h(&Objects[objnum]))));
|
||||
if (lua_ai.needsTarget) {
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_OSWPT.Set(aigp->lua_ai_target.target)));
|
||||
}
|
||||
for (const auto& additionalParam : aigp->lua_ai_target.arguments) {
|
||||
luaParameters.push_back(additionalParam);
|
||||
}
|
||||
|
||||
auto retVals = action.call(Script_system.GetLuaSession(), luaParameters);
|
||||
|
||||
if (!retVals.empty() && retVals[0].getValueType() == luacpp::ValueType::USERDATA) {
|
||||
scripting::api::enum_h enumData;
|
||||
retVals[0].getValue(scripting::api::l_Enum.Get(&enumData));
|
||||
if (!enumData.IsValid()) {
|
||||
Error(LOCATION, "LuaAI SEXP achievability hook returned an invalid avilability enum.");
|
||||
if (!action.isValid())
|
||||
return ai_achievability::ACHIEVABLE;
|
||||
|
||||
luacpp::LuaValueList luaParameters;
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_Ship.Set(object_h(&Objects[objnum]))));
|
||||
if (lua_ai.needsTarget) {
|
||||
luaParameters.push_back(luacpp::LuaValue::createValue(action.getLuaState(), scripting::api::l_OSWPT.Set(aigp->lua_ai_target)));
|
||||
}
|
||||
|
||||
switch (enumData.index) {
|
||||
case scripting::api::LE_LUAAI_ACHIEVABLE:
|
||||
return ai_achievability::ACHIEVABLE;
|
||||
case scripting::api::LE_LUAAI_NOT_YET_ACHIEVABLE:
|
||||
return ai_achievability::NOT_KNOWN;
|
||||
case scripting::api::LE_LUAAI_UNACHIEVABLE:
|
||||
return ai_achievability::NOT_ACHIEVABLE;
|
||||
default:
|
||||
Error(LOCATION, "LuaAI SEXP achievability hook returned an invalid avilability enum.");
|
||||
return ai_achievability::ACHIEVABLE;
|
||||
auto retVals = action.call(Script_system.GetLuaSession(), luaParameters);
|
||||
|
||||
if (!retVals.empty() && retVals[0].getValueType() == luacpp::ValueType::USERDATA) {
|
||||
scripting::api::enum_h enumData;
|
||||
retVals[0].getValue(scripting::api::l_Enum.Get(&enumData));
|
||||
if (!enumData.IsValid()) {
|
||||
Error(LOCATION, "LuaAI SEXP achievability hook returned an invalid avilability enum.");
|
||||
return ai_achievability::ACHIEVABLE;
|
||||
}
|
||||
|
||||
switch (enumData.index) {
|
||||
case scripting::api::LE_LUAAI_ACHIEVABLE:
|
||||
return ai_achievability::ACHIEVABLE;
|
||||
case scripting::api::LE_LUAAI_NOT_YET_ACHIEVABLE:
|
||||
return ai_achievability::NOT_KNOWN;
|
||||
case scripting::api::LE_LUAAI_UNACHIEVABLE:
|
||||
return ai_achievability::NOT_ACHIEVABLE;
|
||||
default:
|
||||
Error(LOCATION, "LuaAI SEXP achievability hook returned an invalid avilability enum.");
|
||||
return ai_achievability::ACHIEVABLE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Error(LOCATION, "LuaAI SEXP achievability hook did not return any avilability enum!");
|
||||
}
|
||||
}
|
||||
else {
|
||||
Error(LOCATION, "LuaAI SEXP achievability hook did not return any avilability enum!");
|
||||
}
|
||||
|
||||
return ai_achievability::ACHIEVABLE;
|
||||
|
||||
+1
-21
@@ -4,13 +4,9 @@
|
||||
#include "ai/aigoals.h"
|
||||
#include "mission/missionmessage.h"
|
||||
#include "ship/ship.h"
|
||||
#include "parse/sexp.h"
|
||||
#include "globalincs/globals.h"
|
||||
|
||||
namespace sexp { class LuaAISEXP; }
|
||||
|
||||
struct ai_mode_lua {
|
||||
const sexp::LuaAISEXP& sexp;
|
||||
bool needsTarget;
|
||||
const char* hudText;
|
||||
};
|
||||
@@ -19,31 +15,15 @@ struct player_order_lua {
|
||||
int ai_message = MESSAGE_YESSIR;
|
||||
SCP_string parseText = "";
|
||||
SCP_string displayText = "";
|
||||
bool generalOrder = false;
|
||||
SCP_string category = "";
|
||||
bool cur_enabled = false;
|
||||
bool cur_valid = false;
|
||||
enum class target_restrictions : int { TARGET_ALLIES, TARGET_ALL, TARGET_OWN, TARGET_ENEMIES, TARGET_SAME_WING, TARGET_PLAYER_WING, TARGET_ALL_CAPS, TARGET_ALLIED_CAPS, TARGET_ENEMY_CAPS, TARGET_NOT_SELF } targetRestrictions = target_restrictions::TARGET_ALL;
|
||||
enum class ship_restrictions : int { ANY, WING, IN_PLAYER_WING, PLAYER_WING } shipRestrictions = ship_restrictions::ANY;
|
||||
};
|
||||
|
||||
|
||||
void ai_lua_add_mode(int sexp_op, const ai_mode_lua& mode);
|
||||
bool ai_lua_add_order(int sexp_op, player_order_lua order);
|
||||
bool ai_lua_has_mode(int sexp_op);
|
||||
const ai_mode_lua* ai_lua_find_mode(int sexp_op);
|
||||
const player_order_lua* ai_lua_find_player_order(int sexp_op);
|
||||
SCP_vector<SCP_string> ai_lua_get_general_order_categories(bool enabled_only = true);
|
||||
int ai_lua_get_num_general_orders();
|
||||
SCP_vector<SCP_string> ai_lua_get_general_orders(bool onlyEnabled = false, bool onlyValid = false, const SCP_string& category = "");
|
||||
int ai_lua_find_general_order_id(const SCP_string& name);
|
||||
void ai_lua_enable_general_order(int sexp_op, bool enable);
|
||||
void ai_lua_validate_general_order(int sexp_op, bool validity);
|
||||
void ai_lua_reset_general_orders();
|
||||
bool ai_lua_is_general_order(int sexp_op);
|
||||
void ai_lua(ai_info* aip);
|
||||
void ai_lua_start(ai_goal* aigp, object* objp);
|
||||
void ai_lua_start_general(int lua_sexp_id, int target_objnum);
|
||||
bool ai_lua_is_valid_target(int sexp_op, int target_objnum, ship* self, size_t order);
|
||||
bool ai_lua_is_valid_ship(int sexp_op, bool isWing, ship* self);
|
||||
bool ai_lua_is_valid_target(int sexp_op, int target_objnum, ship* self);
|
||||
ai_achievability ai_lua_is_achievable(const ai_goal* aigp, int objnum);
|
||||
+97
-175
@@ -14,7 +14,6 @@
|
||||
#include "network/multi.h"
|
||||
#include "network/multimsgs.h"
|
||||
#include "object/objectdock.h"
|
||||
#include "scripting/global_hooks.h"
|
||||
#include "scripting/scripting.h"
|
||||
#include "render/3d.h"
|
||||
#include "ship/ship.h"
|
||||
@@ -58,43 +57,35 @@ const char *Turret_target_order_names[NUM_TURRET_ORDER_TYPES] = {
|
||||
#define EEOF_BIG_ONLY (1<<0) // turret fires only at big and huge ships
|
||||
#define EEOF_SMALL_ONLY (1<<1) // turret fires only at small ships
|
||||
#define EEOF_TAGGED_ONLY (1<<2) // turret fires only at tagged ships
|
||||
|
||||
#define EEOF_BEAM (1<<3) // turret is a beam
|
||||
#define EEOF_FLAK (1<<4) // turret is flak
|
||||
#define EEOF_LASER (1<<5) // turret is a laser
|
||||
#define EEOF_MISSILE (1<<6) // turret is a missile
|
||||
|
||||
const char* Turret_valid_types[NUM_TURRET_TYPES] = {
|
||||
"Beam",
|
||||
"Flak",
|
||||
"Laser",
|
||||
"Missile",
|
||||
};
|
||||
|
||||
typedef struct eval_enemy_obj_struct {
|
||||
int turret_parent_objnum = -1; // parent of turret
|
||||
float weapon_travel_dist = 0.0f; // max targeting range of turret weapon
|
||||
int enemy_team_mask = 0;
|
||||
bool weapon_system_ok = false; // is the weapon subsystem of turret ship ok
|
||||
int eeo_flags = 0;
|
||||
int turret_parent_objnum; // parent of turret
|
||||
float weapon_travel_dist; // max targeting range of turret weapon
|
||||
int enemy_team_mask;
|
||||
int weapon_system_ok; // is the weapon subsystem of turret ship ok
|
||||
int eeo_flags;
|
||||
|
||||
const vec3d *tpos = nullptr;
|
||||
const vec3d *tvec = nullptr;
|
||||
const ship_subsys *turret_subsys = nullptr;
|
||||
int current_enemy = -1;
|
||||
vec3d *tpos;
|
||||
vec3d *tvec;
|
||||
ship_subsys *turret_subsys;
|
||||
int current_enemy;
|
||||
|
||||
|
||||
float nearest_attacker_dist = 99999.0f; // nearest ship
|
||||
int nearest_attacker_objnum = -1;
|
||||
float nearest_attacker_dist; // nearest ship
|
||||
int nearest_attacker_objnum;
|
||||
|
||||
float nearest_homing_bomb_dist = 99999.0f; // nearest homing bomb
|
||||
int nearest_homing_bomb_objnum = -1;
|
||||
float nearest_homing_bomb_dist; // nearest homing bomb
|
||||
int nearest_homing_bomb_objnum;
|
||||
|
||||
float nearest_bomb_dist = 99999.0f; // nearest non-homing bomb
|
||||
int nearest_bomb_objnum = -1;
|
||||
float nearest_bomb_dist; // nearest non-homing bomb
|
||||
int nearest_bomb_objnum;
|
||||
|
||||
float nearest_dist = 99999.0f; // nearest ship attacking this turret
|
||||
int nearest_objnum = -1;
|
||||
float nearest_dist; // nearest ship attacking this turret
|
||||
int nearest_objnum;
|
||||
} eval_enemy_obj_struct;
|
||||
|
||||
// the current world orientation of the turret matrix, corresponding to its fvec and uvec defined in the model
|
||||
@@ -120,7 +111,7 @@ void turret_instance_find_world_orient(matrix* out_mat, int model_instance_num,
|
||||
*
|
||||
* @return 1 if objp is in fov of the specified turret. Otherwise return 0.
|
||||
*/
|
||||
bool object_in_turret_fov(const object *objp, const ship_subsys *ss, const vec3d *tvec, const vec3d *tpos, float dist)
|
||||
bool object_in_turret_fov(object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, float dist)
|
||||
{
|
||||
vec3d v2e;
|
||||
float size_mod;
|
||||
@@ -215,7 +206,7 @@ int turret_select_best_weapon(ship_subsys *turret, object * /*target*/)
|
||||
/**
|
||||
* Returns true if all weapons in swp have the specified flag
|
||||
*/
|
||||
bool all_turret_weapons_have_flags(const ship_weapon *swp, flagset<Weapon::Info_Flags> flags)
|
||||
bool all_turret_weapons_have_flags(ship_weapon *swp, flagset<Weapon::Info_Flags> flags)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < swp->num_primary_banks; i++)
|
||||
@@ -232,7 +223,7 @@ bool all_turret_weapons_have_flags(const ship_weapon *swp, flagset<Weapon::Info_
|
||||
return true;
|
||||
}
|
||||
|
||||
bool all_turret_weapons_have_flags(const ship_weapon *swp, Weapon::Info_Flags flags)
|
||||
bool all_turret_weapons_have_flags(ship_weapon *swp, Weapon::Info_Flags flags)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < swp->num_primary_banks; i++)
|
||||
@@ -253,7 +244,7 @@ bool all_turret_weapons_have_flags(const ship_weapon *swp, Weapon::Info_Flags fl
|
||||
* Returns true if any of the weapons in swp have flags
|
||||
*
|
||||
*/
|
||||
bool turret_weapon_has_flags(const ship_weapon *swp, Weapon::Info_Flags flags)
|
||||
bool turret_weapon_has_flags(ship_weapon *swp, Weapon::Info_Flags flags)
|
||||
{
|
||||
Assert(swp != NULL);
|
||||
|
||||
@@ -279,7 +270,7 @@ bool turret_weapon_has_flags(const ship_weapon *swp, Weapon::Info_Flags flags)
|
||||
/**
|
||||
* Just gloms all the flags from all the weapons into one variable. More efficient if all you need to do is test for the existence of a flag.
|
||||
*/
|
||||
flagset<Weapon::Info_Flags> turret_weapon_aggregate_flags(const ship_weapon *swp)
|
||||
flagset<Weapon::Info_Flags> turret_weapon_aggregate_flags(ship_weapon *swp)
|
||||
{
|
||||
Assert(swp != NULL);
|
||||
|
||||
@@ -307,7 +298,7 @@ flagset<Weapon::Info_Flags> turret_weapon_aggregate_flags(const ship_weapon *swp
|
||||
* @note It might be a little faster to optimize based on WP_LASER should only appear in primaries
|
||||
* and WP_MISSILE in secondaries. but in the interest of future coding I leave it like this.
|
||||
*/
|
||||
bool turret_weapon_has_subtype(const ship_weapon *swp, int subtype)
|
||||
bool turret_weapon_has_subtype(ship_weapon *swp, int subtype)
|
||||
{
|
||||
Assert(swp != NULL);
|
||||
|
||||
@@ -492,7 +483,7 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
{
|
||||
object *turret_parent_obj = &Objects[eeo->turret_parent_objnum];
|
||||
ship *shipp;
|
||||
auto ss = eeo->turret_subsys;
|
||||
ship_subsys *ss = eeo->turret_subsys;
|
||||
float dist, dist_comp;
|
||||
bool turret_has_no_target = false;
|
||||
|
||||
@@ -772,6 +763,9 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
*/
|
||||
int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag, bool flak_flag, bool laser_flag, bool missile_flag)
|
||||
{
|
||||
//float weapon_travel_dist;
|
||||
int weapon_system_ok;
|
||||
object *objp;
|
||||
eval_enemy_obj_struct eeo;
|
||||
ship_weapon *swp = &turret_subsys->weapons;
|
||||
|
||||
@@ -786,7 +780,10 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
|
||||
// weapon_travel_dist=wip->lssm_lock_range;
|
||||
|
||||
// Set flag based on strength of weapons subsystem. If weapons subsystem is destroyed, don't let turrets fire at bombs
|
||||
bool weapon_system_ok = !ship_subsystems_blown(&Ships[Objects[turret_parent_objnum].instance], SUBSYSTEM_WEAPONS);
|
||||
weapon_system_ok = 0;
|
||||
if ( ship_get_subsystem_strength( &Ships[Objects[turret_parent_objnum].instance], SUBSYSTEM_WEAPONS ) > 0 ) {
|
||||
weapon_system_ok = 1;
|
||||
}
|
||||
|
||||
// Initialize eeo struct.
|
||||
eeo.turret_parent_objnum = turret_parent_objnum;
|
||||
@@ -818,6 +815,18 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
|
||||
eeo.tvec = tvec;
|
||||
eeo.turret_subsys = turret_subsys;
|
||||
|
||||
eeo.nearest_attacker_dist = 99999.0f;
|
||||
eeo.nearest_attacker_objnum = -1;
|
||||
|
||||
eeo.nearest_homing_bomb_dist = 99999.0f;
|
||||
eeo.nearest_homing_bomb_objnum = -1;
|
||||
|
||||
eeo.nearest_bomb_dist = 99999.0f;
|
||||
eeo.nearest_bomb_objnum = -1;
|
||||
|
||||
eeo.nearest_dist = 99999.0f;
|
||||
eeo.nearest_objnum = -1;
|
||||
|
||||
// here goes the new targeting priority setting
|
||||
int n_tgt_priorities;
|
||||
int priority_weapon_idx = -1;
|
||||
@@ -853,10 +862,9 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
|
||||
int n_w_classes = (int)tt->weapon_class.size();
|
||||
|
||||
bool found_something;
|
||||
for (auto ptr: list_range(&obj_used_list)) {
|
||||
if (ptr->flags[Object::Object_Flags::Should_be_dead])
|
||||
continue;
|
||||
|
||||
object *ptr = GET_FIRST(&obj_used_list);
|
||||
|
||||
while (ptr != END_OF_LIST(&obj_used_list)) {
|
||||
found_something = false;
|
||||
|
||||
if(tt->obj_type > -1 && (ptr->type == tt->obj_type)) {
|
||||
@@ -907,10 +915,15 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
|
||||
if(!(found_something)) {
|
||||
//we didnt find this object within this priority group
|
||||
//skip to next without evaluating the object as target
|
||||
ptr = GET_NEXT(ptr);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
evaluate_obj_as_target(ptr, &eeo);
|
||||
|
||||
ptr = GET_NEXT(ptr);
|
||||
}
|
||||
|
||||
//homing weapon entry...
|
||||
@@ -981,10 +994,8 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
|
||||
{
|
||||
// Missile_obj_list
|
||||
for( mo = GET_FIRST(&Missile_obj_list); mo != END_OF_LIST(&Missile_obj_list); mo = GET_NEXT(mo) ) {
|
||||
auto objp = &Objects[mo->objnum];
|
||||
if (objp->flags[Object::Object_Flags::Should_be_dead])
|
||||
continue;
|
||||
|
||||
objp = &Objects[mo->objnum];
|
||||
|
||||
Assert(objp->type == OBJ_WEAPON);
|
||||
if ((Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags[Weapon::Info_Flags::Bomb]) || (Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags[Weapon::Info_Flags::Turret_Interceptable]))
|
||||
{
|
||||
@@ -1004,9 +1015,7 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
|
||||
//Return if a ship is found
|
||||
// Ship_used_list
|
||||
for ( so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so) ) {
|
||||
auto objp = &Objects[so->objnum];
|
||||
if (objp->flags[Object::Object_Flags::Should_be_dead])
|
||||
continue;
|
||||
objp = &Objects[so->objnum];
|
||||
evaluate_obj_as_target(objp, &eeo);
|
||||
}
|
||||
|
||||
@@ -1034,9 +1043,7 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
|
||||
if ( !all_turret_weapons_have_flags(swp, tmp_flagset) ) {
|
||||
// Asteroid_obj_list
|
||||
for ( ao = GET_FIRST(&Asteroid_obj_list); ao != END_OF_LIST(&Asteroid_obj_list); ao = GET_NEXT(ao) ) {
|
||||
auto objp = &Objects[ao->objnum];
|
||||
if (objp->flags[Object::Object_Flags::Should_be_dead])
|
||||
continue;
|
||||
objp = &Objects[ao->objnum];
|
||||
evaluate_obj_as_target(objp, &eeo);
|
||||
}
|
||||
|
||||
@@ -1047,7 +1054,7 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE("Invalid target type of %d sent to get_nearest_turret_objnum. Please report to the SCP!", turret_subsys->turret_targeting_order[i]);
|
||||
Int3(); //Means invalid number passed.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1087,7 +1094,7 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
|
||||
ai_info *aip = &Ai_info[Ships[Objects[objnum].instance].ai_index];
|
||||
sip = &Ship_info[Ships[Objects[objnum].instance].ship_info_index];
|
||||
|
||||
if ((sip->class_type >= 0) && (Ship_types[sip->class_type].flags[Ship::Type_Info_Flags::Turret_tgt_ship_tgt]) && (aip->target_objnum != -1)) {
|
||||
if ((Ship_types[sip->class_type].flags[Ship::Type_Info_Flags::Turret_tgt_ship_tgt]) && (aip->target_objnum != -1)) {
|
||||
int target_objnum = aip->target_objnum;
|
||||
|
||||
if (Objects[target_objnum].signature == aip->target_signature) {
|
||||
@@ -1154,9 +1161,9 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
|
||||
Assert( !((Objects[enemy_objnum].flags[Object::Object_Flags::Flak_protected]) && flak_flag) );
|
||||
Assert( !((Objects[enemy_objnum].flags[Object::Object_Flags::Laser_protected]) && laser_flag) );
|
||||
Assert( !((Objects[enemy_objnum].flags[Object::Object_Flags::Missile_protected]) && missile_flag) );
|
||||
Assertion(!Objects[enemy_objnum].flags[Object::Object_Flags::Protected], "find_turret_enemy selected an object of type %d %s that is protected, please report to the SCP!", Objects[enemy_objnum].type, Objects[enemy_objnum].type == OBJ_SHIP ? Ships[Objects[enemy_objnum].instance].ship_name : "");
|
||||
|
||||
if ( Objects[enemy_objnum].flags[Object::Object_Flags::Protected] ) {
|
||||
Int3();
|
||||
enemy_objnum = aip->target_objnum;
|
||||
}
|
||||
}
|
||||
@@ -1312,7 +1319,7 @@ int aifft_rotate_turret(object *objp, ship *shipp, ship_subsys *ss, object *lep,
|
||||
|
||||
if (ss->turret_enemy_objnum != -1) {
|
||||
model_subsystem *tp = ss->system_info;
|
||||
vec3d gun_pos, gun_vec, target_vel;
|
||||
vec3d gun_pos, gun_vec, target_moving_direction;
|
||||
//float weapon_speed;
|
||||
float weapon_system_strength;
|
||||
//HACK HACK HACK -WMC
|
||||
@@ -1350,34 +1357,14 @@ int aifft_rotate_turret(object *objp, ship *shipp, ship_subsys *ss, object *lep,
|
||||
}
|
||||
}
|
||||
|
||||
target_vel = ss->last_aim_enemy_vel;
|
||||
target_moving_direction = ss->last_aim_enemy_vel;
|
||||
|
||||
//Try to guess where the enemy will be, and store that spot in predicted_enemy_pos
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Use_additive_weapon_velocity]) {
|
||||
vm_vec_scale_sub2(&target_vel, &objp->phys_info.vel, wip->vel_inherit_amount);
|
||||
vm_vec_scale_sub2(&target_moving_direction, &objp->phys_info.vel, wip->vel_inherit_amount);
|
||||
}
|
||||
|
||||
if (tp->flags[Model::Subsystem_Flags::Turret_distant_firepoint] || Always_use_distant_firepoints) {
|
||||
//The firing point of this turret is so far away from the its center that we should consider this for firing calculations
|
||||
//This will do the enemy position prediction based on their relative position and speed to the firing point, not the turret center.
|
||||
vec3d temp;
|
||||
ship_get_global_turret_gun_info(objp, ss, &gun_pos, &temp, 1, nullptr);
|
||||
}
|
||||
|
||||
if (IS_VEC_NULL(&The_mission.gravity) || wip->gravity_const == 0.0f)
|
||||
set_predicted_enemy_pos_turret(predicted_enemy_pos, &gun_pos, objp, &enemy_point, &target_vel, wip->max_speed, ss->turret_time_enemy_in_range * (weapon_system_strength + 1.0f)/2.0f);
|
||||
else {
|
||||
vec3d shoot_vec;
|
||||
vec3d gravity_vec = The_mission.gravity * wip->gravity_const;
|
||||
if (physics_lead_ballistic_trajectory(&gun_pos, &enemy_point, &target_vel, wip->max_speed, &gravity_vec, &shoot_vec)) {
|
||||
*predicted_enemy_pos = gun_pos + shoot_vec * 1000.0f;
|
||||
} else {
|
||||
if ((ss->system_info->flags[Model::Subsystem_Flags::Turret_reset_idle]) && (timestamp_elapsed(ss->rotation_timestamp))) {
|
||||
ret_val = model_rotate_gun(objp, pm, pmi, ss, predicted_enemy_pos, true);
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
}
|
||||
set_predicted_enemy_pos_turret(predicted_enemy_pos, &gun_pos, objp, &enemy_point, &target_moving_direction, wip->max_speed, ss->turret_time_enemy_in_range * (weapon_system_strength + 1.0f)/2.0f);
|
||||
|
||||
//Mess with the turret's accuracy if the weapon system is damaged.
|
||||
if (weapon_system_strength < Weapon_SS_Threshold_Turret_Inaccuracy) {
|
||||
@@ -1562,7 +1549,7 @@ ship_subsys *aifft_find_turret_subsys(object *objp, ship_subsys *ssp, object *en
|
||||
if(stride <= 0){
|
||||
stride = 1;
|
||||
}
|
||||
int offset = Random::next((aifft_list_size % stride) + 1); // returns an offset in [0, size % stride] inclusive
|
||||
int offset = (int)frand_range(0.0f, (float)(aifft_list_size % stride));
|
||||
int idx;
|
||||
float dot_fov_modifier = 0.0f;
|
||||
|
||||
@@ -1656,21 +1643,11 @@ void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsy
|
||||
if (wip->wi_flags[Weapon::Info_Flags::Flak]) {
|
||||
wait *= aip->ai_ship_fire_delay_scale_friendly * 0.5f;
|
||||
if (aip->ai_class_autoscale)
|
||||
{
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Adjusted_AI_class_autoscale])
|
||||
wait += (ai_get_autoscale_index(Num_ai_classes) - ai_get_autoscale_index(aip->ai_class) - 1) * 40.0f;
|
||||
else
|
||||
wait += (Num_ai_classes - aip->ai_class - 1) * 40.0f;
|
||||
}
|
||||
wait += (Num_ai_classes - aip->ai_class - 1) * 40.0f;
|
||||
} else {
|
||||
wait *= aip->ai_ship_fire_delay_scale_friendly;
|
||||
if (aip->ai_class_autoscale)
|
||||
{
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Adjusted_AI_class_autoscale])
|
||||
wait += (ai_get_autoscale_index(Num_ai_classes) - ai_get_autoscale_index(aip->ai_class) - 1) * 100.0f;
|
||||
else
|
||||
wait += (Num_ai_classes - aip->ai_class - 1) * 100.0f;
|
||||
}
|
||||
wait += (Num_ai_classes - aip->ai_class - 1) * 100.0f;
|
||||
}
|
||||
} else {
|
||||
// flak guns need to fire more rapidly
|
||||
@@ -1681,23 +1658,13 @@ void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsy
|
||||
wait *= aip->ai_ship_fire_delay_scale_hostile * 0.5f;
|
||||
}
|
||||
if (aip->ai_class_autoscale)
|
||||
{
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Adjusted_AI_class_autoscale])
|
||||
wait += (ai_get_autoscale_index(Num_ai_classes) - ai_get_autoscale_index(aip->ai_class) - 1) * 40.0f;
|
||||
else
|
||||
wait += (Num_ai_classes - aip->ai_class - 1) * 40.0f;
|
||||
}
|
||||
wait += (Num_ai_classes - aip->ai_class - 1) * 40.0f;
|
||||
|
||||
} else if (wip->wi_flags[Weapon::Info_Flags::Huge]) {
|
||||
// make huge weapons fire independently of team
|
||||
wait *= aip->ai_ship_fire_delay_scale_friendly;
|
||||
if (aip->ai_class_autoscale)
|
||||
{
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Adjusted_AI_class_autoscale])
|
||||
wait += (ai_get_autoscale_index(Num_ai_classes) - ai_get_autoscale_index(aip->ai_class) - 1) * 100.0f;
|
||||
else
|
||||
wait += (Num_ai_classes - aip->ai_class - 1) * 100.0f;
|
||||
}
|
||||
wait += (Num_ai_classes - aip->ai_class - 1) * 100.0f;
|
||||
} else {
|
||||
// give team friendly an advantage
|
||||
if (Ships[aip->shipnum].team == Player_ship->team) {
|
||||
@@ -1706,12 +1673,7 @@ void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsy
|
||||
wait *= aip->ai_ship_fire_delay_scale_hostile;
|
||||
}
|
||||
if (aip->ai_class_autoscale)
|
||||
{
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Adjusted_AI_class_autoscale])
|
||||
wait += (ai_get_autoscale_index(Num_ai_classes) - ai_get_autoscale_index(aip->ai_class) - 1) * 100.0f;
|
||||
else
|
||||
wait += (Num_ai_classes - aip->ai_class - 1) * 100.0f;
|
||||
}
|
||||
wait += (Num_ai_classes - aip->ai_class - 1) * 100.0f;
|
||||
}
|
||||
}
|
||||
// vary wait time +/- 10%
|
||||
@@ -1755,7 +1717,7 @@ void turret_update_enemy_in_range(ship_subsys *turret, float seconds)
|
||||
/**
|
||||
* Fire a weapon from a turret
|
||||
*/
|
||||
bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *firing_vec, vec3d *predicted_pos = nullptr, float flak_range_override = 100.0f, bool play_sound = true)
|
||||
bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *firing_vec, vec3d *predicted_pos = nullptr, float flak_range_override = 100.0f)
|
||||
{
|
||||
matrix turret_orient;
|
||||
int weapon_objnum;
|
||||
@@ -1879,15 +1841,11 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
|
||||
parent_ship->last_fired_turret = turret;
|
||||
turret->last_fired_weapon_info_index = turret_weapon_class;
|
||||
turret->turret_last_fired = _timestamp();
|
||||
|
||||
if (scripting::hooks::OnTurretFired->isActive()) {
|
||||
scripting::hooks::OnTurretFired->run(scripting::hooks::WeaponUsedConditions{ parent_ship , turret_enemy_objp, SCP_vector<int>{ turret_weapon_class }, true },
|
||||
scripting::hook_param_list(
|
||||
scripting::hook_param("Ship", 'o', &Objects[parent_objnum]),
|
||||
scripting::hook_param("Beam", 'o', objp),
|
||||
scripting::hook_param("Target", 'o', turret_enemy_objp)
|
||||
));
|
||||
if (Script_system.IsActiveAction(CHA_ONTURRETFIRED)) {
|
||||
Script_system.SetHookObjects(4, "Ship", &Objects[parent_objnum], "Weapon", nullptr, "Beam", objp, "Target", turret_enemy_objp);
|
||||
Script_system.RunCondition(CHA_ONTURRETFIRED, &Objects[parent_objnum], objp);
|
||||
Script_system.RemHookVars({"Ship", "Weapon", "Beam", "Target"});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2022,19 +1980,15 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
|
||||
parent_ship->last_fired_turret = turret;
|
||||
turret->last_fired_weapon_info_index = wp->weapon_info_index;
|
||||
turret->turret_last_fired = _timestamp();
|
||||
|
||||
wp->target_num = turret->turret_enemy_objnum;
|
||||
// AL 1-6-97: Store pointer to turret subsystem
|
||||
wp->turret_subsys = turret;
|
||||
|
||||
if (scripting::hooks::OnTurretFired->isActive()) {
|
||||
scripting::hooks::OnTurretFired->run(scripting::hooks::WeaponUsedConditions{ parent_ship , turret_enemy_objp, SCP_vector<int>{ turret_weapon_class }, wip->subtype == WP_LASER },
|
||||
scripting::hook_param_list(
|
||||
scripting::hook_param("Ship", 'o', &Objects[parent_objnum]),
|
||||
scripting::hook_param("Weapon", 'o', objp),
|
||||
scripting::hook_param("Target", 'o', turret_enemy_objp)
|
||||
));
|
||||
if (Script_system.IsActiveAction(CHA_ONTURRETFIRED)) {
|
||||
Script_system.SetHookObjects(4, "Ship", &Objects[parent_objnum], "Weapon", objp, "Beam", nullptr, "Target", turret_enemy_objp);
|
||||
Script_system.RunCondition(CHA_ONTURRETFIRED, &Objects[parent_objnum], objp);
|
||||
Script_system.RemHookVars({"Ship", "Weapon", "Beam", "Target"});
|
||||
}
|
||||
|
||||
// if the gun is a flak gun
|
||||
@@ -2072,7 +2026,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
}
|
||||
}
|
||||
|
||||
if ( play_sound && wip->launch_snd.isValid() ) {
|
||||
if ( wip->launch_snd.isValid() ) {
|
||||
// Don't play turret firing sound if turret sits on player ship... it gets annoying.
|
||||
if ( parent_objnum != OBJ_INDEX(Player_obj) || (turret->flags[Ship::Subsystem_Flags::Play_sound_for_player]) ) {
|
||||
snd_play_3d( gamesnd_get_game_sound(wip->launch_snd), turret_pos, &View_position );
|
||||
@@ -2098,8 +2052,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
turret->flags.set(Ship::Subsystem_Flags::Has_fired); //set has fired flag for scriptng - nuke
|
||||
|
||||
//Fire animation stuff
|
||||
Ship_info[parent_ship->ship_info_index].animations.get(model_get_instance(parent_ship->model_instance_num), animation::ModelAnimationTriggerType::TurretFired, animation::anim_name_from_subsys(turret->system_info))
|
||||
.start(animation::ModelAnimationDirection::FWD, true);
|
||||
Ship_info[parent_ship->ship_info_index].animations.start(model_get_instance(parent_ship->model_instance_num), animation::ModelAnimationTriggerType::TurretFired, animation::anim_name_from_subsys(turret->system_info), animation::ModelAnimationDirection::FWD, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2149,19 +2102,11 @@ void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
|
||||
|
||||
Ships[Objects[tsi->parent_objnum].instance].last_fired_turret = tsi->turret;
|
||||
tsi->turret->last_fired_weapon_info_index = tsi->weapon_class;
|
||||
tsi->turret->turret_last_fired = _timestamp();
|
||||
|
||||
if (scripting::hooks::OnTurretFired->isActive()) {
|
||||
scripting::hooks::OnTurretFired->run(scripting::hooks::WeaponUsedConditions{
|
||||
&Ships[Objects[tsi->parent_objnum].instance],
|
||||
&Objects[tsi->turret->turret_enemy_objnum],
|
||||
SCP_vector<int>{ tsi->weapon_class }, Weapon_info[tsi->weapon_class].subtype == WP_LASER
|
||||
},
|
||||
scripting::hook_param_list(
|
||||
scripting::hook_param("Ship", 'o', &Objects[tsi->parent_objnum]),
|
||||
scripting::hook_param("Weapon", 'o', &Objects[weapon_objnum]),
|
||||
scripting::hook_param("Target", 'o', &Objects[tsi->turret->turret_enemy_objnum])
|
||||
));
|
||||
if (Script_system.IsActiveAction(CHA_ONTURRETFIRED)) {
|
||||
Script_system.SetHookObjects(4, "Ship", &Objects[tsi->parent_objnum], "Weapon", &Objects[weapon_objnum], "Beam", nullptr, "Target", &Objects[tsi->turret->turret_enemy_objnum]);
|
||||
Script_system.RunCondition(CHA_ONTURRETFIRED, &Objects[tsi->parent_objnum], &Objects[weapon_objnum]);
|
||||
Script_system.RemHookVars({"Ship", "Weapon", "Beam", "Target"});
|
||||
}
|
||||
|
||||
// muzzle flash?
|
||||
@@ -2289,12 +2234,6 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
// Rotate the turret even if time hasn't elapsed, since it needs to turn to face its target.
|
||||
int use_angles = aifft_rotate_turret(objp, shipp, ss, lep, &predicted_enemy_pos, &gvec);
|
||||
|
||||
// Multiplayer clients are now able to try to track their targets and also reset to their idle positions.
|
||||
// But everything after this point is turret firing, so we need to bail here.
|
||||
if (MULTIPLAYER_CLIENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((tp->flags[Model::Subsystem_Flags::Fire_on_target]) && (ss->points_to_target >= 0.0f))
|
||||
{
|
||||
// value probably needs tweaking... could perhaps be made into table option?
|
||||
@@ -2399,15 +2338,6 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
}
|
||||
}
|
||||
|
||||
// If the barrel of this turret is long, we shouldn't try to fire if the enemy is under the gun.
|
||||
// Note that this isn't the same thing as min_range, which is unrelated to barrel length.
|
||||
if (tp->flags[Model::Subsystem_Flags::Turret_distant_firepoint] || Always_use_distant_firepoints) {
|
||||
vec3d fpoint, fvec;
|
||||
ship_get_global_turret_gun_info(objp, ss, &fpoint, &fvec, use_angles, &predicted_enemy_pos);
|
||||
auto barrel_length = vm_vec_dist(&fpoint, &gpos);
|
||||
if (dist_to_enemy < barrel_length) continue;
|
||||
}
|
||||
|
||||
// Don't try to fire beyond weapon_limit_range (or within min range)
|
||||
if (dist_to_enemy < weapon_min_range || dist_to_enemy > weapon_firing_range) {
|
||||
// it's possible another weapon is in range, but if not,
|
||||
@@ -2596,9 +2526,7 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
bool in_fov = turret_fov_test(ss, &gvec, &v2e);
|
||||
bool something_was_ok_to_fire = false;
|
||||
|
||||
// the only reason predicted_enemy_pos might be zero, while everything else is valid is if
|
||||
// its a ballistic trajectory with no valid path
|
||||
if (in_fov && num_valid && predicted_enemy_pos != vmd_zero_vector) {
|
||||
if (in_fov) {
|
||||
|
||||
// Do salvo thing separately - to prevent messing up things
|
||||
int number_of_firings;
|
||||
@@ -2612,8 +2540,6 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
number_of_firings = num_valid;
|
||||
}
|
||||
|
||||
auto sound_played = gamesnd_id();
|
||||
|
||||
for (int i = 0; i < number_of_firings; ++i)
|
||||
{
|
||||
int valid_index;
|
||||
@@ -2623,13 +2549,6 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
valid_index = i;
|
||||
auto wip = get_turret_weapon_wip(&ss->weapons, valid_weapons[valid_index]);
|
||||
|
||||
bool play_sound = false;
|
||||
|
||||
if (sound_played != wip->launch_snd) {
|
||||
sound_played = wip->launch_snd;
|
||||
play_sound = true;
|
||||
}
|
||||
|
||||
// Forces the firing turret to retain the firingpoints of their weapons:
|
||||
// if the turret has multiple banks, the first bank will only fire from the first firepoint,
|
||||
// the second bank only from the second firepoint, and so on.
|
||||
@@ -2732,6 +2651,7 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
vm_vec_scale_add(&end, &gpos, &gvec, model_get_radius(model_num));
|
||||
|
||||
mc_info hull_check;
|
||||
mc_info_init(&hull_check);
|
||||
hull_check.model_instance_num = shipp->model_instance_num;
|
||||
hull_check.model_num = model_num;
|
||||
hull_check.orient = &objp->orient;
|
||||
@@ -2749,13 +2669,15 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
{
|
||||
// starting animation checks
|
||||
if (ss->turret_animation_position == MA_POS_NOT_SET) {
|
||||
bool started = false;
|
||||
//For legacy animations using subtype for turret number
|
||||
auto animList = Ship_info[shipp->ship_info_index].animations.getAll(model_get_instance(shipp->model_instance_num), animation::ModelAnimationTriggerType::TurretFiring, ss->system_info->subobj_num, true);
|
||||
started |= Ship_info[shipp->ship_info_index].animations.startAll(model_get_instance(shipp->model_instance_num), animation::ModelAnimationTriggerType::TurretFiring, animation::ModelAnimationDirection::FWD, false, false, false, ss->system_info->subobj_num, true);
|
||||
//For modern animations using proper triggered-by-subsys name
|
||||
animList += Ship_info[shipp->ship_info_index].animations.get(model_get_instance(shipp->model_instance_num), animation::ModelAnimationTriggerType::TurretFiring, animation::anim_name_from_subsys(ss->system_info));
|
||||
|
||||
if (animList.start(animation::ModelAnimationDirection::FWD)) {
|
||||
ss->turret_animation_done_time = timestamp(animList.getTime());
|
||||
started |= Ship_info[shipp->ship_info_index].animations.start(model_get_instance(shipp->model_instance_num), animation::ModelAnimationTriggerType::TurretFiring, animation::anim_name_from_subsys(ss->system_info), animation::ModelAnimationDirection::FWD);
|
||||
if (started) {
|
||||
int duration = Ship_info[shipp->ship_info_index].animations.getTimeAll(model_get_instance(shipp->model_instance_num), animation::ModelAnimationTriggerType::TurretFiring, ss->system_info->subobj_num, true);
|
||||
int duration2 = Ship_info[shipp->ship_info_index].animations.getTime(model_get_instance(shipp->model_instance_num), animation::ModelAnimationTriggerType::TurretFiring, animation::anim_name_from_subsys(ss->system_info));
|
||||
ss->turret_animation_done_time = timestamp(duration > duration2 ? duration : duration2);
|
||||
ss->turret_animation_position = MA_POS_SET;
|
||||
}
|
||||
}
|
||||
@@ -2784,7 +2706,7 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
flak_jitter_aim(&shoot_vector, dist_to_enemy, ship_get_subsystem_strength(shipp, SUBSYSTEM_WEAPONS), wip);
|
||||
}
|
||||
|
||||
turret_fire_weapon(valid_weapons[valid_index], ss, parent_objnum, &gpos, &shoot_vector, &predicted_enemy_pos, 100.0f, play_sound);
|
||||
turret_fire_weapon(valid_weapons[valid_index], ss, parent_objnum, &gpos, &shoot_vector, &predicted_enemy_pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2853,7 +2775,7 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
}
|
||||
}
|
||||
|
||||
bool turret_std_fov_test(const ship_subsys *ss, const vec3d *gvec, const vec3d *v2e, float size_mod)
|
||||
bool turret_std_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mod)
|
||||
{
|
||||
model_subsystem *tp = ss->system_info;
|
||||
float dot = vm_vec_dot(v2e, gvec);
|
||||
@@ -2863,7 +2785,7 @@ bool turret_std_fov_test(const ship_subsys *ss, const vec3d *gvec, const vec3d *
|
||||
return false;
|
||||
}
|
||||
|
||||
bool turret_adv_fov_test(const ship_subsys *ss, const vec3d *gvec, const vec3d *v2e, float size_mod)
|
||||
bool turret_adv_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mod)
|
||||
{
|
||||
model_subsystem *tp = ss->system_info;
|
||||
float dot = vm_vec_dot(v2e, gvec);
|
||||
@@ -2889,10 +2811,10 @@ bool turret_adv_fov_test(const ship_subsys *ss, const vec3d *gvec, const vec3d *
|
||||
return false;
|
||||
}
|
||||
|
||||
bool turret_fov_test(const ship_subsys *ss, const vec3d *gvec, const vec3d *v2e, float size_mod)
|
||||
bool turret_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mod)
|
||||
{
|
||||
bool in_fov = false;
|
||||
if (ss->system_info->turret_base_fov > -1.0f)
|
||||
if (ss->system_info->flags[Model::Subsystem_Flags::Turret_restricted_fov])
|
||||
in_fov = turret_adv_fov_test(ss, gvec, v2e, size_mod);
|
||||
else
|
||||
in_fov = turret_std_fov_test(ss, gvec, v2e, size_mod);
|
||||
|
||||
@@ -397,6 +397,8 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
|
||||
|
||||
t1 = timer_get_fixed_seconds();
|
||||
for ( i = 0; i < frame_diff; i++ ) {
|
||||
anim_check_for_palette_change(instance);
|
||||
|
||||
// if we're playing backwards, every frame must be a keyframe and we set the data ptr here
|
||||
if(instance->direction == ANIM_DIRECT_REVERSE){
|
||||
if ( anim_instance_is_streamed(instance) ) {
|
||||
@@ -641,7 +643,7 @@ void anim_read_header(anim *ptr, CFILE *fp)
|
||||
|
||||
if (diff != 0) {
|
||||
if (ptr->height > 16) {
|
||||
nprintf(("ANI","ANI %s with size %dx%d (%.1f%% wasted)\n", ptr->name, ptr->width, ptr->height, waste));
|
||||
mprintf(("ANI %s with size %dx%d (%.1f%% wasted)\n", ptr->name, ptr->width, ptr->height, waste));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -670,7 +672,7 @@ void anim_read_header(anim *ptr, CFILE *fp)
|
||||
* @param file_mapped Whether to use memory-mapped file or not.
|
||||
*
|
||||
* @details Memory-mapped files will page in the animation from disk as it is needed, but performance is not as good.
|
||||
* @return Pointer to anim that is loaded if success, NULL if failure.
|
||||
* @return Pointer to anim that is loaded if sucess, NULL if failure.
|
||||
*/
|
||||
anim *anim_load(const char *real_filename, int cf_dir_type, int file_mapped)
|
||||
{
|
||||
@@ -788,6 +790,9 @@ anim *anim_load(const char *real_filename, int cf_dir_type, int file_mapped)
|
||||
|
||||
cfclose(fp);
|
||||
|
||||
// store screen signature, so we can tell if palette changes
|
||||
ptr->screen_sig = gr_screen.signature;
|
||||
|
||||
anim_set_palette(ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,23 +18,30 @@
|
||||
const int packer_code = PACKER_CODE;
|
||||
const int transparent_code = 254;
|
||||
|
||||
void anim_check_for_palette_change(anim_instance *instance) {
|
||||
if ( instance->parent->screen_sig != gr_screen.signature ) {
|
||||
instance->parent->screen_sig = gr_screen.signature;
|
||||
anim_set_palette(instance->parent);
|
||||
}
|
||||
}
|
||||
|
||||
anim_instance *init_anim_instance(anim *ptr, int bpp)
|
||||
{
|
||||
anim_instance *inst;
|
||||
|
||||
Assertion(ptr, "Bad pointer in init_anim_instance(), please report to the SCP!");
|
||||
if (!ptr) {
|
||||
Int3();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( ptr->flags & ANF_STREAMED ) {
|
||||
Assertion(ptr->file_offset > -1, "Bad file offset of %d in init_anim_instance(), please report to the SCP!", ptr->file_offset);
|
||||
if ( ptr->file_offset < 0 ) {
|
||||
Int3();
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
Assertion(ptr->data, "Bad data in init_anim_instance(), please report to the SCP!");
|
||||
if ( !ptr->data ) {
|
||||
Int3();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -90,6 +97,8 @@ ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap
|
||||
return NULL;
|
||||
}
|
||||
|
||||
anim_check_for_palette_change(inst);
|
||||
|
||||
if ( anim_instance_is_streamed(inst) ) {
|
||||
if ( xlate_pal ){
|
||||
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
|
||||
|
||||
@@ -58,6 +58,7 @@ typedef struct anim {
|
||||
ubyte xparent_g; // green component for the transparent color in source image
|
||||
ubyte xparent_b; // blue component for the transparent color in source image
|
||||
int flags;
|
||||
uint screen_sig;
|
||||
int file_offset; // file offset to start of frame data
|
||||
int cache_file_offset;
|
||||
ubyte *cache;
|
||||
@@ -104,6 +105,7 @@ anim_instance *init_anim_instance(anim *ptr, int bpp);
|
||||
void free_anim_instance(anim_instance *inst);
|
||||
ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap, int bpp);
|
||||
void anim_set_palette(anim *a);
|
||||
void anim_check_for_palette_change(anim_instance *inst);
|
||||
|
||||
|
||||
#endif /* __PACKUNPACK_H__ */
|
||||
+310
-774
File diff suppressed because it is too large.
Load diff
+28
-39
@@ -14,29 +14,34 @@
|
||||
|
||||
#include "globalincs/globals.h" // for NAME_LENGTH
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "io/timer.h"
|
||||
|
||||
|
||||
class object;
|
||||
class polymodel;
|
||||
struct collision_info_struct;
|
||||
class model_draw_list;
|
||||
|
||||
#define MAX_ASTEROIDS 2000 //Increased from 512 to 2000 in 2022
|
||||
#define MAX_ASTEROIDS 512
|
||||
|
||||
#define NUM_ASTEROID_SIZES 3
|
||||
#define NUM_ASTEROID_POFS 3 // Number of POFs per debris size
|
||||
#define NUM_DEBRIS_SIZES 3
|
||||
#define NUM_DEBRIS_POFS 3 // Number of POFs per debris size
|
||||
|
||||
#define ASTEROID_TYPE_DEBRIS -1
|
||||
#define ASTEROID_TYPE_SMALL 0
|
||||
#define ASTEROID_TYPE_MEDIUM 1
|
||||
#define ASTEROID_TYPE_LARGE 2
|
||||
|
||||
// these should always be equal for the benefit of generic asteroids (c.f. asteroid_page_in)
|
||||
#define MAX_ACTIVE_DEBRIS_TYPES NUM_ASTEROID_SIZES
|
||||
#define MAX_ACTIVE_DEBRIS_TYPES NUM_DEBRIS_SIZES
|
||||
|
||||
// Goober5000 - currently same as MAX_SHIP_DETAIL_LEVELS (put here to avoid an #include)
|
||||
#define MAX_ASTEROID_DETAIL_LEVELS 5
|
||||
|
||||
// whether to do retail behavior, just throw at the first big ship in the field
|
||||
// must be explicitly opted out of by the mission
|
||||
extern bool Default_asteroid_throwing_behavior;
|
||||
|
||||
extern SCP_vector<SCP_string> Asteroid_target_ships;
|
||||
|
||||
// Data structure to track the active asteroids
|
||||
typedef struct asteroid_obj {
|
||||
asteroid_obj *next, *prev;
|
||||
@@ -48,22 +53,19 @@ extern asteroid_obj Asteroid_obj_list;
|
||||
// Data structure for determining a type and amount of other asteroids an
|
||||
// asteroid will split to when destroyed.
|
||||
typedef struct asteroid_split_info {
|
||||
int asteroid_type; //index position
|
||||
char name[NAME_LENGTH]; //asteroid name
|
||||
int min; //minimum asteroids to spawn
|
||||
int max; //maximum asteroids to spawn
|
||||
int asteroid_type;
|
||||
int min;
|
||||
int max;
|
||||
} asteroid_split_info;
|
||||
|
||||
class asteroid_info
|
||||
{
|
||||
public:
|
||||
char name[NAME_LENGTH]; // name for the asteroid
|
||||
int type; // type of asteroid, 0 = small, 1 = medium, 2 = large, -1 = debris
|
||||
char pof_files[NUM_ASTEROID_POFS][MAX_FILENAME_LEN]; // POF files to load/associate with ship
|
||||
char pof_files[NUM_DEBRIS_POFS][MAX_FILENAME_LEN]; // POF files to load/associate with ship
|
||||
int num_detail_levels; // number of detail levels for this ship
|
||||
int detail_distance[MAX_ASTEROID_DETAIL_LEVELS]; // distance to change detail levels at
|
||||
float max_speed; // cap on speed for asteroid
|
||||
float rotational_vel_multiplier; // rotational velocity multiplier for asteroid --wookieejedi
|
||||
int damage_type_idx; //Damage type of the asteroid
|
||||
int damage_type_idx_sav; // stored value from table used to reset damage_type_idx
|
||||
float inner_rad; // radius within which maximum area effect damage is applied
|
||||
@@ -72,30 +74,27 @@ public:
|
||||
float blast; // maximum blast impulse from area effect explosion
|
||||
float initial_asteroid_strength; // starting strength of asteroid
|
||||
SCP_vector< asteroid_split_info > split_info;
|
||||
polymodel *modelp[NUM_ASTEROID_POFS];
|
||||
int model_num[NUM_ASTEROID_POFS];
|
||||
polymodel *modelp[NUM_DEBRIS_POFS];
|
||||
int model_num[NUM_DEBRIS_POFS];
|
||||
SCP_vector<int> explosion_bitmap_anims;
|
||||
float fireball_radius_multiplier; // the model radius is multiplied by this to determine the fireball size
|
||||
SCP_string display_name; // only used for hud targeting display and for 'ship' asteroids
|
||||
float spawn_weight; // ship asteroids only, relative proportion to spawn compared to other types in its asteroid field
|
||||
float gravity_const; // multiplier for mission gravity
|
||||
|
||||
asteroid_info( )
|
||||
: type(ASTEROID_TYPE_DEBRIS), num_detail_levels(0), max_speed(0),
|
||||
rotational_vel_multiplier(1), damage_type_idx(0),
|
||||
: num_detail_levels( 0 ), max_speed( 0 ), damage_type_idx( 0 ),
|
||||
damage_type_idx_sav( -1 ), inner_rad( 0 ), outer_rad( 0 ),
|
||||
damage( 0 ), blast( 0 ), initial_asteroid_strength( 0 ),
|
||||
fireball_radius_multiplier( -1 ), spawn_weight( 1 ), gravity_const( 0 )
|
||||
fireball_radius_multiplier( -1 )
|
||||
{
|
||||
name[ 0 ] = 0;
|
||||
display_name = "";
|
||||
memset( detail_distance, 0, sizeof( detail_distance ) );
|
||||
|
||||
for (int i = 0; i < NUM_ASTEROID_POFS; i++)
|
||||
for (int i = 0; i < NUM_DEBRIS_POFS; i++)
|
||||
{
|
||||
modelp[i] = NULL;
|
||||
model_num[i] = -1;
|
||||
pof_files[i][0] = '\0';
|
||||
pof_files[i][0] = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -109,9 +108,9 @@ typedef struct asteroid {
|
||||
int model_instance_num;
|
||||
int asteroid_type; // 0..MAX_DEBRIS_TYPES
|
||||
int asteroid_subtype; // Index in asteroid_info for modelnum and modelp
|
||||
TIMESTAMP check_for_wrap; // timestamp to check for asteroid wrapping around field
|
||||
TIMESTAMP check_for_collide; // timestamp to check for asteroid colliding with escort ships
|
||||
TIMESTAMP final_death_time; // timestamp to swap in new models after explosion starts
|
||||
int check_for_wrap; // timestamp to check for asteroid wrapping around field
|
||||
int check_for_collide; // timestamp to check for asteroid colliding with escort ships
|
||||
int final_death_time; // timestamp to swap in new models after explosion starts
|
||||
int collide_objnum; // set to objnum that asteroid will be impacting soon
|
||||
int collide_objsig; // object signature corresponding to collide_objnum
|
||||
vec3d death_hit_pos; // hit pos that caused death
|
||||
@@ -122,7 +121,7 @@ typedef struct asteroid {
|
||||
// TYPEDEF FOR DEBRIS TYPE
|
||||
typedef enum {
|
||||
DG_ASTEROID,
|
||||
DG_DEBRIS
|
||||
DG_SHIP
|
||||
} debris_genre_t;
|
||||
|
||||
// TYPEDEF FOR FIELD TYPE
|
||||
@@ -135,7 +134,7 @@ typedef struct asteroid_field {
|
||||
vec3d min_bound; // Minimum range of field.
|
||||
vec3d max_bound; // Maximum range of field.
|
||||
float bound_rad;
|
||||
bool has_inner_bound;
|
||||
int has_inner_bound;
|
||||
vec3d inner_min_bound;
|
||||
vec3d inner_max_bound;
|
||||
vec3d vel; // Average asteroid moves at this velocity.
|
||||
@@ -145,9 +144,6 @@ typedef struct asteroid_field {
|
||||
debris_genre_t debris_genre; // type of debris (ship or asteroid) [generic type]
|
||||
int field_debris_type[MAX_ACTIVE_DEBRIS_TYPES]; // one of the debris type defines above
|
||||
int num_used_field_debris_types; // how many of the above are used
|
||||
bool enhanced_visibility_checks; // if true then range checks are overridden for spawning and wrapping asteroids in the field
|
||||
|
||||
SCP_vector<SCP_string> target_names; // default retail behavior is to just throw at the first big ship in the field
|
||||
} asteroid_field;
|
||||
|
||||
extern SCP_vector< asteroid_info > Asteroid_info;
|
||||
@@ -161,28 +157,21 @@ extern vec3d Asteroid_icon_closeup_position; // closeup position for asteroid f
|
||||
extern float Asteroid_icon_closeup_zoom; // zoom position for asteroid field briefing icon rendering
|
||||
|
||||
void asteroid_init();
|
||||
bool asteroid_is_within_view(vec3d *pos, float range, bool range_override = false);
|
||||
void asteroid_level_init();
|
||||
void asteroid_level_close();
|
||||
void asteroid_create_all();
|
||||
void asteroid_create_asteroid_field(int num_asteroids, int field_type, int asteroid_speed, bool brown, bool blue, bool orange, vec3d o_min, vec3d o_max, bool inner_box, vec3d i_min, vec3d i_max, SCP_vector<SCP_string> targets);
|
||||
void asteroid_create_debris_field(int num_asteroids, int asteroid_speed, int debris1, int debris2, int debris3, vec3d o_min, vec3d o_max, bool enhanced);
|
||||
void asteroid_render(object* obj, model_draw_list* scene);
|
||||
void asteroid_render(object * obj, model_draw_list *scene);
|
||||
void asteroid_delete( object *asteroid_objp );
|
||||
void asteroid_process_pre( object *asteroid_objp );
|
||||
void asteroid_process_post( object *asteroid_objp);
|
||||
int asteroid_check_collision( object *asteroid_objp, object * other_obj, vec3d * hitpos, collision_info_struct *asteroid_hit_info=NULL, vec3d* hitnormal=NULL );
|
||||
void asteroid_hit( object *pasteroid_objp, object *other_objp, vec3d *hitpos, float damage, vec3d* force );
|
||||
void asteroid_hit( object *pasteroid_objp, object *other_objp, vec3d *hitpos, float damage );
|
||||
int asteroid_count();
|
||||
int asteroid_collide_objnum(object *asteroid_objp);
|
||||
float asteroid_time_to_impact(object *asteroid_objp);
|
||||
void asteroid_show_brackets();
|
||||
void asteroid_target_closest_danger();
|
||||
void asteroid_add_target(object* objp);
|
||||
int get_asteroid_index(const char* asteroid_name);
|
||||
|
||||
// need to extern for keycontrol debug commands
|
||||
object *asteroid_create(asteroid_field *asfieldp, int asteroid_type, int asteroid_subtype, bool check_visibility = false);
|
||||
|
||||
// need to extern for multiplayer
|
||||
void asteroid_sub_create(object *parent_objp, int asteroid_type, vec3d *relvec);
|
||||
|
||||
@@ -47,9 +47,10 @@ NavMessage NavMsgs[NP_NUM_MESSAGES];
|
||||
int audio_handle;
|
||||
int NavLinkDistance;
|
||||
// time offsets for autonav events
|
||||
TIMESTAMP LockAPConv;
|
||||
TIMESTAMP EndAPCinematic;
|
||||
TIMESTAMP MoveCamera;
|
||||
int LockAPConv;
|
||||
int EndAPCinematic;
|
||||
int MoveCamera;
|
||||
int camMovingTime;
|
||||
//float CameraSpeed;
|
||||
bool CinematicStarted, CameraMoving;
|
||||
vec3d cameraPos, cameraTarget;
|
||||
@@ -150,9 +151,6 @@ bool CanAutopilot(const vec3d *targetPos, bool send_msg)
|
||||
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
|
||||
{
|
||||
object *other_objp = &Objects[so->objnum];
|
||||
if (other_objp->flags[Object::Object_Flags::Should_be_dead])
|
||||
continue;
|
||||
|
||||
// attacks player?
|
||||
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
|
||||
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags[Ship::Info_Flags::Cargo])) // ignore cargo
|
||||
@@ -208,9 +206,8 @@ bool StartAutopilot()
|
||||
{
|
||||
// Check for support ship and dismiss it if it is not doing anything.
|
||||
// If the support ship is doing something then tell the user such.
|
||||
for (auto so: list_range(&Ship_obj_list))
|
||||
for ( object *objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) )
|
||||
{
|
||||
auto objp = &Objects[so->objnum];
|
||||
if ((objp->type == OBJ_SHIP) && !(objp->flags[Object::Object_Flags::Should_be_dead]))
|
||||
{
|
||||
Assertion((objp->instance >= 0) && (objp->instance < MAX_SHIPS),
|
||||
@@ -265,9 +262,9 @@ bool StartAutopilot()
|
||||
}
|
||||
|
||||
if (The_mission.flags[Mission::Mission_Flags::Use_ap_cinematics])
|
||||
LockAPConv = _timestamp(); // lock convergence instantly
|
||||
LockAPConv = timestamp(); // lock convergence instantly
|
||||
else
|
||||
LockAPConv = _timestamp(3 * MILLISECONDS_PER_SECOND); // 3 seconds before we lock convergence
|
||||
LockAPConv = timestamp(3000); // 3 seconds before we lock convergence
|
||||
Player_use_ai = 1;
|
||||
set_time_compression(1);
|
||||
lock_time_compression(true);
|
||||
@@ -405,7 +402,7 @@ bool StartAutopilot()
|
||||
&& Autopilot_flight_leader != &Objects[Ships[i].objnum]) //only if not flight leader's object
|
||||
{
|
||||
ai_info *aip = &Ai_info[Ships[i].ai_index];
|
||||
int wingnum = Ships[i].wingnum, wing_index = get_wing_index(&Objects[Ships[i].objnum], wingnum);
|
||||
int wingnum = aip->wing, wing_index = get_wing_index(&Objects[Ships[i].objnum], wingnum);
|
||||
vec3d goal_point;
|
||||
object *leader_objp = get_wing_leader(wingnum);
|
||||
|
||||
@@ -831,8 +828,9 @@ bool StartAutopilot()
|
||||
//CameraMoving = false;
|
||||
|
||||
|
||||
EndAPCinematic = _timestamp((10 * MILLISECONDS_PER_SECOND * tc_factor) + NPS_TICKRATE); // 10 objective seconds before end of cinematic
|
||||
MoveCamera = _timestamp(fl2i(5.5 * MILLISECONDS_PER_SECOND * tc_factor) + NPS_TICKRATE);
|
||||
EndAPCinematic = timestamp((10000*tc_factor)+NPS_TICKRATE); // 10 objective seconds before end of cinematic
|
||||
MoveCamera = timestamp((5500*tc_factor)+NPS_TICKRATE);
|
||||
camMovingTime = int(4.5*float(tc_factor));
|
||||
set_time_compression((float)tc_factor);
|
||||
}
|
||||
|
||||
@@ -869,7 +867,7 @@ void EndAutoPilot()
|
||||
Assert( CurrentNav >= 0 );
|
||||
|
||||
int goal = 0;
|
||||
const char *goal_name = NULL;
|
||||
char *goal_name = NULL;
|
||||
|
||||
if (Navs[CurrentNav].flags & NP_WAYPOINT)
|
||||
{
|
||||
@@ -925,7 +923,10 @@ void EndAutoPilot()
|
||||
if ( ((aigp->target_name != NULL) && !stricmp(aigp->target_name, goal_name))
|
||||
&& (aigp->ai_mode == goal) )
|
||||
{
|
||||
ai_goal_reset(aigp);
|
||||
aigp->ai_mode = AI_GOAL_NONE;
|
||||
aigp->signature = -1;
|
||||
aigp->priority = -1;
|
||||
aigp->flags.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -946,7 +947,10 @@ void EndAutoPilot()
|
||||
if ( ((aigp->target_name != NULL) && !stricmp(aigp->target_name, goal_name))
|
||||
&& (aigp->ai_mode == goal) )
|
||||
{
|
||||
ai_goal_reset(aigp);
|
||||
aigp->ai_mode = AI_GOAL_NONE;
|
||||
aigp->signature = -1;
|
||||
aigp->priority = -1;
|
||||
aigp->flags.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1011,7 +1015,7 @@ void nav_warp(bool prewarp=false)
|
||||
vm_vec_scale(&velocity, (float)Ai_info[Ships[Autopilot_flight_leader->instance].ai_index].waypoint_speed_cap);
|
||||
|
||||
// Find all ships that are supposed to autopilot with the player and move them
|
||||
// to the cinematic location or the final destination
|
||||
// to the cinimatic location or the final destination
|
||||
for (int i = 0; i < MAX_SHIPS; i++)
|
||||
{
|
||||
if (Ships[i].objnum != -1
|
||||
@@ -1020,12 +1024,11 @@ void nav_warp(bool prewarp=false)
|
||||
{
|
||||
vm_vec_add(&Objects[Ships[i].objnum].pos, &Objects[Ships[i].objnum].pos, &targetPos);
|
||||
Objects[Ships[i].objnum].phys_info.vel = velocity;
|
||||
|
||||
// retime collision pairs
|
||||
if (Objects[Ships[i].objnum].flags[Object::Object_Flags::Collides])
|
||||
obj_collide_obj_cache_stale(&Objects[Ships[i].objnum]);
|
||||
}
|
||||
}
|
||||
|
||||
// retime all collision pairs
|
||||
obj_collide_retime_cached_pairs();
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
@@ -1050,13 +1053,15 @@ void NavSystem_Do()
|
||||
if(cam != NULL)
|
||||
cam->set_rotation_facing(&Player_obj->pos);
|
||||
|
||||
if (timestamp_elapsed(MoveCamera) && !CameraMoving && vm_vec_mag(&cameraTarget) > 0.0f)
|
||||
if (timestamp() >= MoveCamera && !CameraMoving && vm_vec_mag(&cameraTarget) > 0.0f)
|
||||
{
|
||||
//Free_camera->set_position(&cameraTarget, float(camMovingTime), float(camMovingTime)/2.0f);
|
||||
//Free_camera->set_translation_velocity(&cameraTarget);
|
||||
CameraMoving = true;
|
||||
}
|
||||
|
||||
|
||||
if (timestamp_elapsed(EndAPCinematic) || !CanAutopilot())
|
||||
if (timestamp() >= EndAPCinematic || !CanAutopilot())
|
||||
{
|
||||
nav_warp();
|
||||
EndAutoPilot();
|
||||
@@ -1184,10 +1189,6 @@ void send_autopilot_msgID(int msgid)
|
||||
if (msgid < 0 || msgid >= NP_NUM_MESSAGES)
|
||||
return;
|
||||
|
||||
// bail out if message is not set
|
||||
if (NavMsgs[msgid].message[0] == '\0')
|
||||
return;
|
||||
|
||||
send_autopilot_msg(NavMsgs[msgid].message, NavMsgs[msgid].filename);
|
||||
}
|
||||
// ********************************************************************************************
|
||||
@@ -1217,7 +1218,7 @@ void send_autopilot_msg(const char *msg, const char *snd)
|
||||
}
|
||||
|
||||
if (msg[0] != '\0' && strcmp(msg, "none") != 0)
|
||||
message_training_queue("autopilot builtin message", TIMESTAMP::immediate(), 5); // display message for five seconds
|
||||
message_training_queue("autopilot builtin message", timestamp(0), 5); // display message for five seconds
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
@@ -1227,15 +1228,6 @@ void NavSystem_Init()
|
||||
for (int i = 0; i < MAX_NAVPOINTS; i++)
|
||||
Navs[i].clear();
|
||||
|
||||
//Initialize all these as empty strings so we can detect and bail out later -Mjn
|
||||
for (int i = 0; i < NP_NUM_MESSAGES; i++)
|
||||
NavMsgs[i].message[0] = '\0';
|
||||
|
||||
//Set defaults here before parsing
|
||||
NavLinkDistance = 1000;
|
||||
AutopilotMinEnemyDistance = 5000;
|
||||
AutopilotMinAsteroidDistance = 1000;
|
||||
LockWeaponsDuringAutopilot = false;
|
||||
AutoPilotEngaged = false;
|
||||
CurrentNav = -1;
|
||||
audio_handle = -1;
|
||||
@@ -1243,9 +1235,10 @@ void NavSystem_Init()
|
||||
UseCutsceneBars = true;
|
||||
|
||||
// defaults... can be tabled or bound to mission later
|
||||
parse_autopilot_table("autopilot.tbl");
|
||||
|
||||
parse_modular_table("*-aplt.tbm", parse_autopilot_table);
|
||||
if (cf_exists_full("autopilot.tbl", CF_TYPE_TABLES))
|
||||
parse_autopilot_table("autopilot.tbl");
|
||||
else
|
||||
parse_autopilot_table(NULL);
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
@@ -1256,16 +1249,10 @@ void parse_autopilot_table(const char *filename)
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
if (!Parsing_modular_table) {
|
||||
// if table doesn't exist, use the default table
|
||||
if (cf_exists_full(filename, CF_TYPE_TABLES))
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
else
|
||||
read_file_text_from_default(defaults_get_file("autopilot.tbl"));
|
||||
} else {
|
||||
if (filename == NULL)
|
||||
read_file_text_from_default(defaults_get_file("autopilot.tbl"));
|
||||
else
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
}
|
||||
|
||||
reset_parse();
|
||||
|
||||
@@ -1273,17 +1260,23 @@ void parse_autopilot_table(const char *filename)
|
||||
required_string("#Autopilot");
|
||||
|
||||
// autopilot link distance
|
||||
if (optional_string("$Link Distance:"))
|
||||
stuff_int(&NavLinkDistance);
|
||||
required_string("$Link Distance:");
|
||||
stuff_int(&NavLinkDistance);
|
||||
|
||||
if (optional_string("$Interrupt autopilot if enemy within distance:"))
|
||||
stuff_int(&AutopilotMinEnemyDistance);
|
||||
else
|
||||
AutopilotMinEnemyDistance = 5000;
|
||||
|
||||
if (optional_string("$Interrupt autopilot if asteroid within distance:"))
|
||||
stuff_int(&AutopilotMinAsteroidDistance);
|
||||
else
|
||||
AutopilotMinAsteroidDistance = 1000;
|
||||
|
||||
if (optional_string("$Lock Weapons During Autopilot:"))
|
||||
stuff_boolean(&LockWeaponsDuringAutopilot);
|
||||
else
|
||||
LockWeaponsDuringAutopilot = false;
|
||||
|
||||
// optional no cutscene bars
|
||||
if (optional_string("+No_Cutscene_Bars"))
|
||||
@@ -1298,14 +1291,13 @@ void parse_autopilot_table(const char *filename)
|
||||
"$Support Present:", "$Support Working:" };
|
||||
for (int i = 0; i < NP_NUM_MESSAGES; i++)
|
||||
{
|
||||
if (optional_string(msg_tags[i])) {
|
||||
required_string(msg_tags[i]);
|
||||
|
||||
required_string("+Msg:");
|
||||
stuff_string(NavMsgs[i].message, F_MESSAGE, 256);
|
||||
required_string("+Msg:");
|
||||
stuff_string(NavMsgs[i].message, F_MESSAGE, 256);
|
||||
|
||||
required_string("+Snd File:");
|
||||
stuff_string(NavMsgs[i].filename, F_NAME, 256);
|
||||
}
|
||||
required_string("+Snd File:");
|
||||
stuff_string(NavMsgs[i].filename, F_NAME, 256);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -29,17 +29,16 @@
|
||||
class NavPoint
|
||||
{
|
||||
public:
|
||||
char m_NavName[32] = { 0 };
|
||||
int flags = 0;
|
||||
ubyte normal_color[3] = { 0x80, 0x80, 0xFF };
|
||||
ubyte visited_color[3] = { 0xFF, 0xFF, 0x00 };
|
||||
char m_NavName[32];
|
||||
int flags;
|
||||
ubyte normal_color[3];
|
||||
ubyte visited_color[3];
|
||||
|
||||
const void *target_obj = nullptr;
|
||||
int waypoint_num = -1; //only used when flags & NP_WAYPOINT
|
||||
const void *target_obj;
|
||||
int waypoint_num; //only used when flags & NP_WAYPOINT
|
||||
|
||||
const vec3d *GetPosition();
|
||||
|
||||
// these assignments should match the initialization
|
||||
void clear()
|
||||
{
|
||||
m_NavName[0] = 0;
|
||||
@@ -79,7 +78,7 @@ extern bool AutoPilotEngaged;
|
||||
extern int CurrentNav;
|
||||
extern NavPoint Navs[MAX_NAVPOINTS];
|
||||
extern NavMessage NavMsgs[NP_NUM_MESSAGES];
|
||||
extern TIMESTAMP LockAPConv;
|
||||
extern int LockAPConv;
|
||||
extern SCP_map<int,int> autopilot_wings;
|
||||
|
||||
// Cycles through the NavPoint List
|
||||
|
||||
@@ -100,7 +100,7 @@ void bm_lock_apng( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort fla
|
||||
void bm_lock_jpg( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
|
||||
void bm_lock_pcx( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
|
||||
void bm_lock_tga( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
|
||||
void bm_lock_user( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags, bool convert = true );
|
||||
void bm_lock_user( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
|
||||
|
||||
const size_t BM_BLOCK_SIZE = 4096;
|
||||
|
||||
|
||||
+14
-106
@@ -53,7 +53,6 @@ MONITOR(SizeBitmapPage)
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// Definition of public variables (declared as extern in bmpman.h).
|
||||
int ENVMAP = -1;
|
||||
int IRRMAP = -1;
|
||||
|
||||
size_t bm_texture_ram = 0;
|
||||
int Bm_paging = 0;
|
||||
@@ -425,7 +424,6 @@ DCF(bm_used, "Shows BmpMan Slot Usage") {
|
||||
|
||||
SCP_stringstream text;
|
||||
text << "BmpMan Used Slots\n";
|
||||
text << " " << std::dec << std::setw(4) << std::setfill('0') << none << ", NONE\n";
|
||||
text << " " << std::dec << std::setw(4) << std::setfill('0') << pcx << ", PCX\n";
|
||||
text << " " << std::dec << std::setw(4) << std::setfill('0') << user << ", User\n";
|
||||
text << " " << std::dec << std::setw(4) << std::setfill('0') << tga << ", TGA\n";
|
||||
@@ -586,59 +584,6 @@ int bm_create(int bpp, int w, int h, void *data, int flags) {
|
||||
return n;
|
||||
}
|
||||
|
||||
int bm_create_3d(int bpp, int w, int h, int d, void* data) {
|
||||
Assert((bpp == 16) || (bpp == 24) || (bpp == 32));
|
||||
|
||||
Assertion(bm_inited, "bmpman must be initialized before this function can be called!");
|
||||
|
||||
int n = find_block_of(1);
|
||||
|
||||
// Out of bitmap slots
|
||||
if (n == -1)
|
||||
return -1;
|
||||
|
||||
// make sure that we have valid data
|
||||
if (data == nullptr) {
|
||||
UNREACHABLE("No valid data received for 3D Bitmap creation!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto entry = bm_get_entry(n);
|
||||
|
||||
memset(entry, 0, sizeof(bitmap_entry));
|
||||
|
||||
sprintf_safe(entry->filename, "TMP%dx%dx%d+%d", w, h, d, bpp);
|
||||
entry->type = BM_TYPE_3D;
|
||||
entry->comp_type = BM_TYPE_NONE;
|
||||
|
||||
entry->bm.w = (short)w;
|
||||
entry->bm.h = (short)h;
|
||||
entry->bm.d = (short)d;
|
||||
entry->bm.rowsize = (short)w;
|
||||
entry->bm.bpp = (ubyte)bpp;
|
||||
entry->bm.true_bpp = (ubyte)bpp;
|
||||
entry->bm.flags = (ubyte)BMP_TEX_XPARENT;
|
||||
entry->bm.data = 0;
|
||||
entry->bm.palette = nullptr;
|
||||
|
||||
entry->info.user.bpp = (ubyte)bpp;
|
||||
entry->info.user.data = data;
|
||||
entry->info.user.flags = (ubyte)BMP_TEX_XPARENT;
|
||||
|
||||
entry->signature = Bm_next_signature++;
|
||||
|
||||
entry->handle = n;
|
||||
entry->mem_taken = (w * h * d * (bpp >> 3));
|
||||
|
||||
entry->load_count++;
|
||||
|
||||
bm_update_memory_used(n, (int)entry->mem_taken);
|
||||
|
||||
gr_bm_create(bm_get_slot(n));
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void bm_convert_format(bitmap *bmp, ushort flags) {
|
||||
int idx;
|
||||
|
||||
@@ -682,7 +627,7 @@ void bm_free_data(bitmap_slot* bs, bool release)
|
||||
|
||||
// Don't free up memory for user defined bitmaps, since
|
||||
// BmpMan isn't the one in charge of allocating/deallocing them.
|
||||
if (be->type == BM_TYPE_USER || be->type == BM_TYPE_3D) {
|
||||
if (be->type==BM_TYPE_USER) {
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
if ( be->data_size != 0 )
|
||||
bm_texture_ram -= be->data_size;
|
||||
@@ -738,7 +683,7 @@ void bm_free_data_fast(int handle)
|
||||
|
||||
// Don't free up memory for user defined bitmaps, since
|
||||
// BmpMan isn't the one in charge of allocating/deallocing them.
|
||||
if (be->type == BM_TYPE_USER || be->type == BM_TYPE_3D) {
|
||||
if (be->type == BM_TYPE_USER) {
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
if ( be->data_size != 0 )
|
||||
bm_texture_ram -= be->data_size;
|
||||
@@ -946,27 +891,6 @@ int bm_get_info(int handle, int *w, int * h, ushort* flags, int *nframes, int *f
|
||||
}
|
||||
}
|
||||
|
||||
int bm_get_depth(int handle, int* depth) {
|
||||
bitmap* bmp;
|
||||
|
||||
if (!bm_inited) return -1;
|
||||
|
||||
auto entry = bm_get_entry(handle);
|
||||
|
||||
Assertion(entry->handle == handle, "Invalid bitmap handle %d passed to bm_get_info().\nThis might be due to an invalid animation somewhere else.\n", handle); // INVALID BITMAP HANDLE!
|
||||
|
||||
if (entry->type != BM_TYPE_3D) {
|
||||
*depth = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bmp = &(entry->bm);
|
||||
|
||||
*depth = bmp->d;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
int bm_get_num_mipmaps(int num) {
|
||||
auto entry = bm_get_entry(num);
|
||||
|
||||
@@ -1482,10 +1406,6 @@ static int bm_load_image_data(int handle, int bpp, ushort flags, bool nodebug)
|
||||
bm_lock_user(handle, bs, bmp, true_bpp, flags);
|
||||
break;
|
||||
|
||||
case BM_TYPE_3D:
|
||||
bm_lock_user(handle, bs, bmp, true_bpp, flags, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
Warning(LOCATION, "Unsupported type in bm_lock -- %d\n", c_type);
|
||||
return -1;
|
||||
@@ -1596,13 +1516,10 @@ int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *ke
|
||||
// MAX_FILENAME_LEN-10 == 5 character frame designator plus '.' plus 3 letter ext plus NULL terminator
|
||||
// we only check for -5 here since the filename should already have the extension on it, and it must have passed the previous check
|
||||
if (strlen(filename) > MAX_FILENAME_LEN - 5) {
|
||||
// Don't check PNGs yet, because a PNG could be a regular non-animated image
|
||||
if (type != BM_TYPE_PNG) {
|
||||
Warning(LOCATION, "Passed filename, '%s', is too long to support an extension and frames!!\n\nMaximum length for an ANI/EFF/APNG, minus the extension, is %i characters.\n", filename, MAX_FILENAME_LEN - 10);
|
||||
if (img_cfp != nullptr)
|
||||
cfclose(img_cfp);
|
||||
return -1;
|
||||
}
|
||||
Warning(LOCATION, "Passed filename, '%s', is too long to support an extension and frames!!\n\nMaximum length for an ANI/EFF/APNG, minus the extension, is %i characters.\n", filename, MAX_FILENAME_LEN - 10);
|
||||
if (img_cfp != nullptr)
|
||||
cfclose(img_cfp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// it's an effect file, any readable image type with eff being txt
|
||||
@@ -1613,7 +1530,7 @@ int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *ke
|
||||
cfclose(img_cfp);
|
||||
return -1;
|
||||
} else {
|
||||
nprintf(("BmpMan","BMPMAN: Found EFF (%s) with %d frames at %d fps.\n", filename, anim_frames, anim_fps));
|
||||
mprintf(("BMPMAN: Found EFF (%s) with %d frames at %d fps.\n", filename, anim_frames, anim_fps));
|
||||
}
|
||||
if (anim_fps == 0) {
|
||||
Error(LOCATION, "animation (%s) has invalid fps of 0, fix this!", filename);
|
||||
@@ -1682,18 +1599,10 @@ int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *ke
|
||||
throw e;
|
||||
}
|
||||
else {
|
||||
nprintf(("apng","Failed to load apng: %s\n", e.what()));
|
||||
mprintf(("Failed to load apng: %s\n", e.what()));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Now do the same filename length check that was deferred for PNGs above
|
||||
if (strlen(filename) > MAX_FILENAME_LEN - 5) {
|
||||
Warning(LOCATION, "Passed filename, '%s', is too long to support an extension and frames!!\n\nMaximum length for an ANI/EFF/APNG, minus the extension, is %i characters.\n", filename, MAX_FILENAME_LEN - 10);
|
||||
if (img_cfp != nullptr)
|
||||
cfclose(img_cfp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Warning(LOCATION, "Unsupported image type: %i", type);
|
||||
@@ -1925,7 +1834,7 @@ int bm_load_sub_fast(const char *real_filename, int *handle, int dir_type, bool
|
||||
}
|
||||
|
||||
int bm_load_sub_slow(const char *real_filename, const int num_ext, const char **ext_list, CFILE **img_cfp, int dir_type) {
|
||||
auto res = cf_find_file_location_ext(real_filename, num_ext, ext_list, dir_type);
|
||||
auto res = cf_find_file_location_ext(real_filename, num_ext, ext_list, dir_type, false);
|
||||
|
||||
// could not be found, or is invalid for some reason
|
||||
if (!res.found)
|
||||
@@ -2478,7 +2387,7 @@ void bm_lock_tga(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags
|
||||
bm_convert_format(bmp, flags);
|
||||
}
|
||||
|
||||
void bm_lock_user(int /*handle*/, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags, bool convert) {
|
||||
void bm_lock_user(int /*handle*/, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags) {
|
||||
auto be = &bs->entry;
|
||||
|
||||
// Unload any existing data
|
||||
@@ -2518,8 +2427,7 @@ void bm_lock_user(int /*handle*/, bitmap_slot *bs, bitmap *bmp, int bpp, ushort
|
||||
break;
|
||||
}
|
||||
|
||||
if (convert)
|
||||
bm_convert_format(bmp, flags);
|
||||
bm_convert_format(bmp, flags);
|
||||
}
|
||||
|
||||
int bm_make_render_target(int width, int height, int flags) {
|
||||
@@ -2603,7 +2511,7 @@ void *bm_malloc(int n, size_t size) {
|
||||
void bm_page_in_aabitmap(int handle, int nframes) {
|
||||
int i;
|
||||
|
||||
if (handle < 0)
|
||||
if (handle == -1)
|
||||
return;
|
||||
|
||||
Assert(bm_get_entry(handle)->handle == handle);
|
||||
@@ -2714,7 +2622,7 @@ void bm_page_in_stop() {
|
||||
}
|
||||
}
|
||||
|
||||
nprintf(("BmpMan","BMPMAN: %d/%d bitmap slots in use.\n", total_bitmaps, total_slots));
|
||||
mprintf(("Bmpman: %d/%d bitmap slots in use.\n", total_bitmaps, total_slots));
|
||||
#endif
|
||||
|
||||
Bm_paging = 0;
|
||||
@@ -3222,7 +3130,7 @@ int bm_unload_fast(int handle, int clear_render_targets) {
|
||||
return -1; // Already been released
|
||||
}
|
||||
|
||||
if (be->type == BM_TYPE_USER || be->type == BM_TYPE_3D) {
|
||||
if (be->type == BM_TYPE_USER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
+2
-28
@@ -79,9 +79,7 @@ enum BM_TYPE
|
||||
BM_TYPE_CUBEMAP_DDS, //!< generic DDS cubemap (uncompressed cubemap surface)
|
||||
BM_TYPE_CUBEMAP_DXT1, //!< 24-bit cubemap (compressed cubemap surface)
|
||||
BM_TYPE_CUBEMAP_DXT3, //!< 32-bit cubemap (compressed cubemap surface)
|
||||
BM_TYPE_CUBEMAP_DXT5, //!< 32-bit cubemap (compressed cubemap surface)
|
||||
|
||||
BM_TYPE_3D //!< 3D in-memory
|
||||
BM_TYPE_CUBEMAP_DXT5 //!< 32-bit cubemap (compressed cubemap surface)
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -92,7 +90,6 @@ struct bitmap
|
||||
{
|
||||
short w; //!< Width, in number of pixels
|
||||
short h; //!< Height, in number of pixels
|
||||
short d; //!< Depth, in number of pixels
|
||||
short rowsize; //!< What you need to add to go to next row
|
||||
int bpp; //!< Requested bitdepth of each pixel. ( 7, 8, 15, 16, 24, 32)
|
||||
int true_bpp; //!< The image's actual bitdepth
|
||||
@@ -119,7 +116,6 @@ extern const char *bm_ani_ext_list[]; //!< List of extensions for those types
|
||||
extern const int BM_ANI_NUM_TYPES; //!< Calculated number of bitmap animation types
|
||||
|
||||
extern int ENVMAP; //!< References a map that is for environment mapping -Bobboau
|
||||
extern int IRRMAP; //!< References a filtered envmap for diffuse environment lighting - qazwsxal
|
||||
|
||||
/**
|
||||
* @brief Initilizes the bitmap manager
|
||||
@@ -220,19 +216,6 @@ int bm_load_duplicate(const char *filename);
|
||||
*/
|
||||
int bm_create(int bpp, int w, int h, void *data = NULL, int flags = 0);
|
||||
|
||||
/**
|
||||
* Loads a 3D bitmap which exists somewhere in the RAM.
|
||||
*
|
||||
* @param bpp The bitdepth of the bitmap
|
||||
* @param w The width of the bitmap
|
||||
* @param h The height of the bitmap
|
||||
* @param d The depth of the bitmap
|
||||
* @param[in] data The bitmap's data glob
|
||||
*
|
||||
* @note The used RAM cannot be freed until bm_release is called on the created bitmap
|
||||
*/
|
||||
int bm_create_3d(int bpp, int w, int h, int d, void* data = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Unloads a bitmap's data, but not the bitmap info
|
||||
*
|
||||
@@ -389,16 +372,6 @@ int bm_is_valid(int handle);
|
||||
*/
|
||||
int bm_get_info(int handle, int *w = nullptr, int * h = nullptr, ushort* flags = nullptr, int *nframes = nullptr, int *fps = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Gets 3D info on the bitmap indexed by handle.
|
||||
*
|
||||
* @param[out] depth If non-null, gets the depth
|
||||
*
|
||||
* @returns The handle on success
|
||||
* @returns -1 on failure
|
||||
*/
|
||||
int bm_get_depth(int handle, int* depth);
|
||||
|
||||
/**
|
||||
* @brief Gets the filename of the bitmap indexed by handle
|
||||
*
|
||||
@@ -573,6 +546,7 @@ void bm_set_components_argb_32_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, u
|
||||
*/
|
||||
void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
|
||||
extern int ENVMAP; //this holds a reference to a map that is for environment mapping -Bobboau
|
||||
|
||||
/**
|
||||
* @brief Returns the compression type of the bitmap indexed by handle
|
||||
|
||||
+21
-59
@@ -14,8 +14,8 @@
|
||||
#include "ship/ship.h" //compute_slew_matrix
|
||||
|
||||
//*************************IMPORTANT GLOBALS*************************
|
||||
fov_t VIEWER_ZOOM_DEFAULT = 0.75f; // Default viewer zoom, 0.625 as per multi-lateral agreement on 3/24/97
|
||||
fov_t COCKPIT_ZOOM_DEFAULT = 0.75f;
|
||||
float VIEWER_ZOOM_DEFAULT = 0.75f; // Default viewer zoom, 0.625 as per multi-lateral agreement on 3/24/97
|
||||
float COCKPIT_ZOOM_DEFAULT = 0.75f;
|
||||
float Sexp_fov = 0.0f;
|
||||
warp_camera Warp_camera;
|
||||
|
||||
@@ -27,33 +27,6 @@ SCP_vector<camera*> Cameras;
|
||||
camid Current_camera;
|
||||
camid Main_camera;
|
||||
|
||||
asymmetric_fov operator* (const asymmetric_fov& left, const float& right) {
|
||||
return asymmetric_fov{ left.left * right, left.right * right, left.up * right, left.down * right };
|
||||
}
|
||||
asymmetric_fov operator+ (const asymmetric_fov& left, const float& right) {
|
||||
float ar = (left.up - left.down) / (left.right - left.left);
|
||||
return asymmetric_fov{ left.left - right * 0.5f, left.right + right * 0.5f, left.up + right * 0.5f * ar, left.down - right * 0.5f * ar };
|
||||
}
|
||||
asymmetric_fov operator- (const asymmetric_fov& left, const float& right) {
|
||||
float ar = (left.up - left.down) / (left.right - left.left);
|
||||
return asymmetric_fov{ left.left + right * 0.5f, left.right - right * 0.5f, left.up - right * 0.5f * ar, left.down + right * 0.5f * ar };
|
||||
}
|
||||
|
||||
#define APPLY_TO_FOV_T(op, name) \
|
||||
struct apply_##name##_to_fov { \
|
||||
float r; \
|
||||
template<typename T> \
|
||||
fov_t operator()(const T& l) { \
|
||||
return fov_t(l op r); \
|
||||
} \
|
||||
}; \
|
||||
fov_t operator op (const fov_t& zoom, const float& scale) { \
|
||||
return mpark::visit(apply_##name##_to_fov{scale}, zoom); \
|
||||
}
|
||||
APPLY_TO_FOV_T(*, mul)
|
||||
APPLY_TO_FOV_T(+, add)
|
||||
APPLY_TO_FOV_T(-, sub)
|
||||
|
||||
static SCP_string fov_display(float val)
|
||||
{
|
||||
auto degrees = fl_degrees(val);
|
||||
@@ -61,20 +34,15 @@ static SCP_string fov_display(float val)
|
||||
sprintf(out, u8"%.1f\u00B0", degrees);
|
||||
return out;
|
||||
}
|
||||
auto FovOption = options::OptionBuilder<float>("Graphics.FOV",
|
||||
std::pair<const char*, int>{"Field Of View", 1703},
|
||||
std::pair<const char*, int>{"The vertical field of view", 1704})
|
||||
.category("Graphics")
|
||||
.range(0.436332f, 1.5708f)
|
||||
.change_listener([](const float& val, bool) {
|
||||
VIEWER_ZOOM_DEFAULT = val;
|
||||
return true;
|
||||
})
|
||||
.display(fov_display)
|
||||
.default_val(0.75f)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.importance(60)
|
||||
.finish();
|
||||
auto FovOption = options::OptionBuilder<float>("Graphics.FOV", "Field Of View", "The vertical field of view.")
|
||||
.category("Graphics")
|
||||
.range(0.436332f, 1.5708f)
|
||||
.bind_to(&VIEWER_ZOOM_DEFAULT)
|
||||
.display(fov_display)
|
||||
.default_val(0.75f)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.importance(60)
|
||||
.finish();
|
||||
|
||||
//*************************CLASS: camera*************************
|
||||
//This is where the camera class begins! :D
|
||||
@@ -117,7 +85,7 @@ void camera::reset()
|
||||
func_custom_orientation = NULL;
|
||||
|
||||
fov.clear();
|
||||
fov.set(g3_get_hfov(VIEWER_ZOOM_DEFAULT));
|
||||
fov.set(VIEWER_ZOOM_DEFAULT);
|
||||
|
||||
pos_x.clear();
|
||||
pos_y.clear();
|
||||
@@ -136,7 +104,7 @@ void camera::set_name(const char *in_name)
|
||||
strncpy(name, in_name, NAME_LENGTH-1);
|
||||
}
|
||||
|
||||
void camera::set_fov(fov_t in_fov, float in_fov_time, float in_fov_acceleration_time, float in_fov_deceleration_time)
|
||||
void camera::set_fov(float in_fov, float in_fov_time, float in_fov_acceleration_time, float in_fov_deceleration_time)
|
||||
{
|
||||
if(in_fov_time == 0.0f && in_fov_acceleration_time == 0.0f && in_fov_deceleration_time == 0.0f)
|
||||
{
|
||||
@@ -146,23 +114,26 @@ void camera::set_fov(fov_t in_fov, float in_fov_time, float in_fov_acceleration_
|
||||
}
|
||||
|
||||
flags &= ~CAM_STATIONARY_FOV;
|
||||
if(g3_get_hfov(in_fov) <= 0.0f)
|
||||
if(in_fov <= 0.0f)
|
||||
{
|
||||
fov.setVD(in_fov_time, in_fov_acceleration_time, 0.0f);
|
||||
}
|
||||
|
||||
fov.setAVD(g3_get_hfov(in_fov), in_fov_time, in_fov_acceleration_time, in_fov_deceleration_time, 0.0f);
|
||||
fov.setAVD(in_fov, in_fov_time, in_fov_acceleration_time, in_fov_deceleration_time, 0.0f);
|
||||
}
|
||||
|
||||
void camera::set_object_host(object *objp, int n_object_host_submodel)
|
||||
{
|
||||
if(objp == NULL)
|
||||
object_host = object_h();
|
||||
|
||||
object_host = object_h(objp);
|
||||
object_host_submodel = n_object_host_submodel;
|
||||
set_custom_position_function(NULL);
|
||||
set_custom_orientation_function(NULL);
|
||||
if(n_object_host_submodel > 0)
|
||||
{
|
||||
if(objp != nullptr && objp->type == OBJ_SHIP)
|
||||
if(objp->type == OBJ_SHIP)
|
||||
{
|
||||
ship_subsys* ssp = GET_FIRST(&Ships[objp->instance].subsys_list);
|
||||
while ( ssp != END_OF_LIST( &Ships[objp->instance].subsys_list ) )
|
||||
@@ -348,14 +319,11 @@ int camera::get_object_target_submodel()
|
||||
return object_target_submodel;
|
||||
}
|
||||
|
||||
fov_t camera::get_fov()
|
||||
float camera::get_fov()
|
||||
{
|
||||
if(!(flags & CAM_STATIONARY_FOV))
|
||||
{
|
||||
float fov_now;
|
||||
fov.get(&fov_now, nullptr);
|
||||
return fov_now;
|
||||
//TODO enable moving asymmetric fov
|
||||
fov.get(&c_fov, NULL);
|
||||
}
|
||||
|
||||
return c_fov;
|
||||
@@ -863,10 +831,7 @@ void subtitle::do_frame(float frametime)
|
||||
|
||||
auto sizing_mode = do_screen_scaling ? GR_RESIZE_FULL : GR_RESIZE_NONE;
|
||||
if (do_screen_scaling)
|
||||
{
|
||||
gr_set_screen_scale(Show_subtitle_screen_adjusted_res[0], Show_subtitle_screen_adjusted_res[1]);
|
||||
gr_set_clip(0, 0, Show_subtitle_screen_adjusted_res[0], Show_subtitle_screen_adjusted_res[1]);
|
||||
}
|
||||
|
||||
// do the actual drawing ---------------------
|
||||
|
||||
@@ -914,10 +879,7 @@ void subtitle::do_frame(float frametime)
|
||||
// finished the actual drawing ---------------
|
||||
|
||||
if (do_screen_scaling)
|
||||
{
|
||||
gr_reset_screen_scale();
|
||||
gr_reset_clip();
|
||||
}
|
||||
|
||||
// restore old font
|
||||
if (old_fontnum >= 0)
|
||||
|
||||
+5
-18
@@ -10,8 +10,6 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <mpark/variant.hpp>
|
||||
|
||||
#define CAM_STATIONARY_FOV (1<<0)
|
||||
#define CAM_STATIONARY_ORI (1<<1)
|
||||
#define CAM_STATIONARY_POS (1<<2)
|
||||
@@ -20,17 +18,6 @@
|
||||
#define EXTERN_CAM_BBOX_CONSTANT_PADDING 5.0f
|
||||
#define EXTERN_CAM_BBOX_MULTIPLIER_PADDING 1.5f
|
||||
|
||||
struct asymmetric_fov {
|
||||
float left, right, up, down;
|
||||
friend asymmetric_fov operator* (const asymmetric_fov&, const float&);
|
||||
friend asymmetric_fov operator+ (const asymmetric_fov&, const float&);
|
||||
friend asymmetric_fov operator- (const asymmetric_fov&, const float&);
|
||||
};
|
||||
using fov_t = mpark::variant<float, asymmetric_fov>;
|
||||
fov_t operator* (const fov_t&, const float&);
|
||||
fov_t operator+ (const fov_t&, const float&);
|
||||
fov_t operator- (const fov_t&, const float&);
|
||||
|
||||
class camera
|
||||
{
|
||||
protected:
|
||||
@@ -54,7 +41,7 @@ protected:
|
||||
avd_movement ori[9];
|
||||
|
||||
//Cache stuff
|
||||
fov_t c_fov;
|
||||
float c_fov;
|
||||
vec3d c_pos;
|
||||
matrix c_ori;
|
||||
public:
|
||||
@@ -72,7 +59,7 @@ public:
|
||||
void set_custom_position_function(void (*n_func_custom_position)(camera *cam, vec3d *pos));
|
||||
void set_custom_orientation_function(void (*n_func_custom_orientation)(camera *cam, matrix *ori));
|
||||
|
||||
void set_fov(fov_t in_fov, float in_fov_time = 0.0f, float in_fov_acceleration_time = 0.0f, float in_deceleration_time = 0.0f);
|
||||
void set_fov(float in_fov, float in_fov_time = 0.0f, float in_fov_acceleration_time = 0.0f, float in_deceleration_time = 0.0f);
|
||||
|
||||
void set_position(vec3d *in_position = NULL, float in_translation_time = 0.0f, float in_translation_acceleration_time = 0.0f, float in_translation_deceleration_time = 0.0f, float in_end_velocity = 0.0f);
|
||||
|
||||
@@ -87,7 +74,7 @@ public:
|
||||
int get_object_host_submodel();
|
||||
object *get_object_target();
|
||||
int get_object_target_submodel();
|
||||
fov_t get_fov();
|
||||
float get_fov();
|
||||
void get_info(vec3d *position, matrix *orientation, bool apply_camera_orientation = true);
|
||||
|
||||
//Is
|
||||
@@ -168,8 +155,8 @@ public:
|
||||
|
||||
//Some global stuff
|
||||
extern SCP_vector<subtitle> Subtitles;
|
||||
extern fov_t VIEWER_ZOOM_DEFAULT;
|
||||
extern fov_t COCKPIT_ZOOM_DEFAULT;
|
||||
extern float VIEWER_ZOOM_DEFAULT;
|
||||
extern float COCKPIT_ZOOM_DEFAULT;
|
||||
extern float Sexp_fov;
|
||||
|
||||
//Helpful functions
|
||||
|
||||
+60
-83
@@ -59,6 +59,8 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
|
||||
{ CF_TYPE_MODELS, "data" DIR_SEPARATOR_STR "models", ".pof", CF_TYPE_DATA },
|
||||
{ CF_TYPE_TABLES, "data" DIR_SEPARATOR_STR "tables", ".tbl .tbm .lua", CF_TYPE_DATA },
|
||||
{ CF_TYPE_SOUNDS, "data" DIR_SEPARATOR_STR "sounds", ".wav .ogg", CF_TYPE_DATA },
|
||||
{ CF_TYPE_SOUNDS_8B22K, "data" DIR_SEPARATOR_STR "sounds" DIR_SEPARATOR_STR "8b22k", ".wav .ogg", CF_TYPE_SOUNDS },
|
||||
{ CF_TYPE_SOUNDS_16B11K, "data" DIR_SEPARATOR_STR "sounds" DIR_SEPARATOR_STR "16b11k", ".wav .ogg", CF_TYPE_SOUNDS },
|
||||
{ CF_TYPE_VOICE, "data" DIR_SEPARATOR_STR "voice", "", CF_TYPE_DATA },
|
||||
{ CF_TYPE_VOICE_BRIEFINGS, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "briefing", ".wav .ogg", CF_TYPE_VOICE },
|
||||
{ CF_TYPE_VOICE_CMD_BRIEF, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "command_briefings", ".wav .ogg", CF_TYPE_VOICE },
|
||||
@@ -68,7 +70,7 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
|
||||
{ CF_TYPE_VOICE_TRAINING, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "training", ".wav .ogg", CF_TYPE_VOICE },
|
||||
{ CF_TYPE_MUSIC, "data" DIR_SEPARATOR_STR "music", ".wav .ogg", CF_TYPE_DATA },
|
||||
{ CF_TYPE_MOVIES, "data" DIR_SEPARATOR_STR "movies", ".mve .msb .ogg .mp4 .srt .webm .png",CF_TYPE_DATA },
|
||||
{ CF_TYPE_INTERFACE, "data" DIR_SEPARATOR_STR "interface", ".pcx .ani .dds .tga .eff .png .jpg .rml .rcss", CF_TYPE_DATA },
|
||||
{ CF_TYPE_INTERFACE, "data" DIR_SEPARATOR_STR "interface", ".pcx .ani .dds .tga .eff .png .jpg", CF_TYPE_DATA },
|
||||
{ CF_TYPE_FONT, "data" DIR_SEPARATOR_STR "fonts", ".vf .ttf .otf", CF_TYPE_DATA },
|
||||
{ CF_TYPE_EFFECTS, "data" DIR_SEPARATOR_STR "effects", ".ani .eff .pcx .neb .tga .jpg .png .dds .sdr", CF_TYPE_DATA },
|
||||
{ CF_TYPE_HUD, "data" DIR_SEPARATOR_STR "hud", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA },
|
||||
@@ -77,7 +79,6 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
|
||||
{ CF_TYPE_SQUAD_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "squads", ".pcx .png .dds", CF_TYPE_PLAYERS },
|
||||
{ CF_TYPE_SINGLE_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "single", ".pl2 .cs2 .plr .csg .css .json", CF_TYPE_PLAYERS },
|
||||
{ CF_TYPE_MULTI_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "multi", ".plr .json", CF_TYPE_PLAYERS },
|
||||
{ CF_TYPE_PLAYER_BINDS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "presets", ".json", CF_TYPE_PLAYERS },
|
||||
{ CF_TYPE_CACHE, "data" DIR_SEPARATOR_STR "cache", ".clr .tmp .bx", CF_TYPE_DATA }, //clr=cached color
|
||||
{ CF_TYPE_MULTI_CACHE, "data" DIR_SEPARATOR_STR "multidata", ".pcx .png .jpg .dds .fs2 .txt", CF_TYPE_DATA },
|
||||
{ CF_TYPE_MISSIONS, "data" DIR_SEPARATOR_STR "missions", ".fs2 .fc2 .ntl .ssv", CF_TYPE_DATA },
|
||||
@@ -87,7 +88,10 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
|
||||
{ CF_TYPE_INTEL_ANIMS, "data" DIR_SEPARATOR_STR "intelanims", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA },
|
||||
{ CF_TYPE_SCRIPTS, "data" DIR_SEPARATOR_STR "scripts", ".lua .lc .fnl", CF_TYPE_DATA },
|
||||
{ CF_TYPE_FICTION, "data" DIR_SEPARATOR_STR "fiction", ".txt", CF_TYPE_DATA },
|
||||
{ CF_TYPE_FREDDOCS, "data" DIR_SEPARATOR_STR "freddocs", ".html", CF_TYPE_DATA }
|
||||
{ CF_TYPE_FREDDOCS, "data" DIR_SEPARATOR_STR "freddocs", ".html", CF_TYPE_DATA },
|
||||
{ CF_TYPE_INTERFACE_MARKUP, "data" DIR_SEPARATOR_STR "interface" DIR_SEPARATOR_STR "markup", ".rml", CF_TYPE_INTERFACE },
|
||||
{ CF_TYPE_INTERFACE_CSS, "data" DIR_SEPARATOR_STR "interface" DIR_SEPARATOR_STR "css", ".rcss", CF_TYPE_INTERFACE },
|
||||
{ CF_TYPE_PLAYER_BINDS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "presets", ".json", CF_TYPE_PLAYERS },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -325,7 +329,7 @@ static int _cfile_chdir(const char *new_dir, const char *cur_dir __UNUSED)
|
||||
*/
|
||||
int cfile_push_chdir(int type)
|
||||
{
|
||||
SCP_string dir;
|
||||
char dir[CFILE_ROOT_DIRECTORY_LEN];
|
||||
char OriginalDirectory[CFILE_ROOT_DIRECTORY_LEN];
|
||||
|
||||
_getcwd(OriginalDirectory, CFILE_ROOT_DIRECTORY_LEN - 1);
|
||||
@@ -338,9 +342,9 @@ int cfile_push_chdir(int type)
|
||||
|
||||
strcpy_s(Cfile_stack[Cfile_stack_pos++], OriginalDirectory);
|
||||
|
||||
cf_create_default_path_string(dir, type, NULL);
|
||||
cf_create_default_path_string(dir, sizeof(dir) - 1, type, NULL);
|
||||
|
||||
return _cfile_chdir(dir.c_str(), OriginalDirectory);
|
||||
return _cfile_chdir(dir, OriginalDirectory);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -438,7 +442,7 @@ int cfile_flush_dir(int dir_type)
|
||||
// filename = name of filename or filepath to process
|
||||
// ext = extension to add. Must start with the period
|
||||
// Returns: new filename or filepath with extension.
|
||||
const char *cf_add_ext(const char *filename, const char *ext)
|
||||
char *cf_add_ext(const char *filename, const char *ext)
|
||||
{
|
||||
static char path[MAX_PATH_LEN];
|
||||
|
||||
@@ -465,26 +469,26 @@ const char *cf_add_ext(const char *filename, const char *ext)
|
||||
*/
|
||||
int cf_delete(const char *filename, int path_type, uint32_t location_flags)
|
||||
{
|
||||
SCP_string longname;
|
||||
char longname[MAX_PATH_LEN];
|
||||
|
||||
Assert(CF_TYPE_SPECIFIED(path_type));
|
||||
|
||||
cf_create_default_path_string(longname, path_type, filename, location_flags);
|
||||
cf_create_default_path_string(longname, sizeof(longname) - 1, path_type, filename, false, location_flags);
|
||||
|
||||
return (_unlink(longname.c_str()) != -1);
|
||||
return (_unlink(longname) != -1);
|
||||
}
|
||||
|
||||
|
||||
// Same as _access function to read a file's access bits
|
||||
int cf_access(const char *filename, int dir_type, int mode)
|
||||
{
|
||||
SCP_string longname;
|
||||
char longname[MAX_PATH_LEN];
|
||||
|
||||
Assert( CF_TYPE_SPECIFIED(dir_type) );
|
||||
|
||||
cf_create_default_path_string(longname, dir_type, filename);
|
||||
cf_create_default_path_string( longname, sizeof(longname)-1, dir_type, filename );
|
||||
|
||||
return access(longname.c_str(), mode);
|
||||
return access(longname,mode);
|
||||
}
|
||||
|
||||
|
||||
@@ -529,18 +533,18 @@ int cf_exists_full_ext(const char *filename, int dir_type, const int num_ext, co
|
||||
#ifdef _WIN32
|
||||
void cf_attrib(const char *filename, int set, int clear, int dir_type)
|
||||
{
|
||||
SCP_string longname;
|
||||
char longname[MAX_PATH_LEN];
|
||||
|
||||
Assert( CF_TYPE_SPECIFIED(dir_type) );
|
||||
|
||||
cf_create_default_path_string(longname, dir_type, filename);
|
||||
cf_create_default_path_string( longname, sizeof(longname)-1, dir_type, filename );
|
||||
|
||||
FILE *fp = fopen(longname.c_str(), "rb");
|
||||
FILE *fp = fopen(longname, "rb");
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
|
||||
DWORD z = GetFileAttributes(longname.c_str());
|
||||
SetFileAttributes(longname.c_str(), z | (set & ~clear));
|
||||
DWORD z = GetFileAttributes(longname);
|
||||
SetFileAttributes(longname, z | (set & ~clear));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -551,13 +555,13 @@ int cf_rename(const char *old_name, const char *name, int dir_type)
|
||||
Assert( CF_TYPE_SPECIFIED(dir_type) );
|
||||
|
||||
int ret_code;
|
||||
SCP_string old_longname;
|
||||
SCP_string new_longname;
|
||||
char old_longname[_MAX_PATH];
|
||||
char new_longname[_MAX_PATH];
|
||||
|
||||
cf_create_default_path_string(old_longname, dir_type, old_name);
|
||||
cf_create_default_path_string(new_longname, dir_type, name);
|
||||
cf_create_default_path_string( old_longname, sizeof(old_longname)-1, dir_type, old_name );
|
||||
cf_create_default_path_string( new_longname, sizeof(old_longname)-1, dir_type, name );
|
||||
|
||||
ret_code = rename(old_longname.c_str(), new_longname.c_str());
|
||||
ret_code = rename(old_longname, new_longname );
|
||||
if(ret_code != 0){
|
||||
switch(errno){
|
||||
case EACCES :
|
||||
@@ -601,7 +605,7 @@ void cf_create_directory(int dir_type, uint32_t location_flags)
|
||||
{
|
||||
int num_dirs = 0;
|
||||
int dir_tree[CF_MAX_PATH_TYPES];
|
||||
SCP_string longname;
|
||||
char longname[MAX_PATH_LEN];
|
||||
struct stat statbuf;
|
||||
|
||||
Assertion( CF_TYPE_SPECIFIED(dir_type), "Invalid dir_type passed to cf_create_directory." );
|
||||
@@ -619,10 +623,10 @@ void cf_create_directory(int dir_type, uint32_t location_flags)
|
||||
int i;
|
||||
|
||||
for (i=num_dirs-1; i>=0; i-- ) {
|
||||
cf_create_default_path_string(longname, dir_tree[i], nullptr, location_flags);
|
||||
if (stat(longname.c_str(), &statbuf) != 0) {
|
||||
mprintf(( "CFILE: Creating new directory '%s'\n", longname.c_str() ));
|
||||
mkdir_recursive(longname.c_str());
|
||||
cf_create_default_path_string(longname, sizeof(longname) - 1, dir_tree[i], nullptr, false, location_flags);
|
||||
if (stat(longname, &statbuf) != 0) {
|
||||
mprintf(( "CFILE: Creating new directory '%s'\n", longname ));
|
||||
mkdir_recursive(longname);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -644,7 +648,7 @@ void cf_create_directory(int dir_type, uint32_t location_flags)
|
||||
//
|
||||
|
||||
CFILE* _cfopen(const char* source, int line, const char* file_path, const char* mode, int type, int dir_type,
|
||||
bool /* localize */, uint32_t location_flags)
|
||||
bool localize, uint32_t location_flags)
|
||||
{
|
||||
/* Bobboau, what is this doing here? 31 is way too short... - Goober5000
|
||||
if( strlen(file_path) > 31 )
|
||||
@@ -671,23 +675,21 @@ CFILE* _cfopen(const char* source, int line, const char* file_path, const char*
|
||||
// the harddisk. No fancy packfile stuff here!
|
||||
|
||||
if ( strchr(mode,'w') || strchr(mode,'+') || strchr(mode,'a') ) {
|
||||
SCP_string longname;
|
||||
char longname[_MAX_PATH];
|
||||
auto last_separator = strrchr(file_path, DIR_SEPARATOR_CHAR);
|
||||
|
||||
// For write-only files, require a full path or a path type
|
||||
if ( last_separator ) {
|
||||
// Full path given?
|
||||
longname = file_path;
|
||||
strcpy_s(longname, file_path );
|
||||
} else {
|
||||
// Path type given?
|
||||
Assert( dir_type != CF_TYPE_ANY );
|
||||
if (dir_type == CF_TYPE_ANY)
|
||||
return NULL;
|
||||
|
||||
// Create the directory if necessary
|
||||
cf_create_directory(dir_type, location_flags);
|
||||
|
||||
cf_create_default_path_string(longname, dir_type, file_path, location_flags);
|
||||
cf_create_default_path_string(longname, sizeof(longname) - 1, dir_type, file_path, false, location_flags);
|
||||
}
|
||||
Assert( !(type & CFILE_MEMORY_MAPPED) );
|
||||
|
||||
@@ -726,7 +728,7 @@ CFILE* _cfopen(const char* source, int line, const char* file_path, const char*
|
||||
strcpy_s(happy_mode, mode);
|
||||
}
|
||||
|
||||
FILE *fp = fopen(longname.c_str(), happy_mode);
|
||||
FILE *fp = fopen(longname, happy_mode);
|
||||
if (fp) {
|
||||
return cf_open_fill_cfblock(source, line, last_separator ? (last_separator + 1) : file_path, fp, dir_type);
|
||||
}
|
||||
@@ -737,8 +739,10 @@ CFILE* _cfopen(const char* source, int line, const char* file_path, const char*
|
||||
//================================================
|
||||
// Search for file on disk, on cdrom, or in a packfile
|
||||
|
||||
auto find_res = cf_find_file_location(file_path, dir_type, location_flags);
|
||||
char copy_file_path[MAX_PATH_LEN]; // FIX change in memory from cf_find_file_location
|
||||
strcpy_s(copy_file_path, file_path);
|
||||
|
||||
auto find_res = cf_find_file_location( copy_file_path, dir_type, localize, location_flags );
|
||||
if ( find_res.found ) {
|
||||
|
||||
// Fount it, now create a cfile out of it
|
||||
@@ -1235,17 +1239,15 @@ void cfread_string(char *buf, int n, CFILE *file)
|
||||
} while (c != 0 );
|
||||
}
|
||||
|
||||
void cfread_string_len(char *buf, int buffer_size, CFILE *file)
|
||||
void cfread_string_len(char *buf,int n, CFILE *file)
|
||||
{
|
||||
int len;
|
||||
len = cfread_int(file);
|
||||
Assertion( (len <= buffer_size), "String cannot fit in buffer, len: %i, buffer: %i", len, buffer_size);
|
||||
if (len) {
|
||||
Assertion( (len < n), "len: %i, n: %i", len, n );
|
||||
if (len)
|
||||
cfread(buf, len, 1, file);
|
||||
Assertion(len != buffer_size || buf[len - 1] == 0, "Unterminated string does not fit in buffer");
|
||||
}
|
||||
|
||||
buf[MIN(len, buffer_size - 1)] = 0;
|
||||
buf[len] = 0;
|
||||
}
|
||||
|
||||
SCP_string cfread_string_len(CFILE *file)
|
||||
@@ -1844,53 +1846,28 @@ int cfile_get_path_type(const SCP_string& dir)
|
||||
{
|
||||
SCP_string buf = dir;
|
||||
|
||||
// remove leading and trailing slashes
|
||||
if ( !buf.empty() ) {
|
||||
auto start = buf.find_first_not_of("\\/");
|
||||
auto end = buf.find_last_not_of("\\/");
|
||||
|
||||
if (start == SCP_string::npos) {
|
||||
buf = "";
|
||||
} else if ( (start > 0) || (end < buf.length()-1) ) {
|
||||
buf = buf.substr(start, end-start+1);
|
||||
}
|
||||
// Remove trailing slashes; avoid buffer overflow on 1-char strings
|
||||
while (buf.size() > 0 && (buf[buf.size() - 1] == '\\' || buf[buf.size() - 1] == '/')) {
|
||||
buf.resize(buf.size() - 1);
|
||||
}
|
||||
|
||||
if (buf.empty()) {
|
||||
return CF_TYPE_ROOT;
|
||||
// Remove leading slashes
|
||||
while (buf.size() > 0 && (buf[0] == '\\' || buf[0] == '/')) {
|
||||
buf = buf.substr(1);
|
||||
}
|
||||
|
||||
// Use official DIR_SEPARATOR_CHAR
|
||||
extern void normalize_directory_separators(SCP_string &str);
|
||||
normalize_directory_separators(buf);
|
||||
|
||||
// identify path type
|
||||
auto best_match = CF_TYPE_INVALID;
|
||||
|
||||
for (auto& Pathtype : Pathtypes) {
|
||||
if ( !Pathtype.path ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip root, it should have been detected before getting here
|
||||
if (Pathtype.index == CF_TYPE_ROOT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't allow unknown subdirs directly under data
|
||||
if (Pathtype.index == CF_TYPE_DATA) {
|
||||
if (buf == Pathtype.path) {
|
||||
best_match = CF_TYPE_DATA;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// for everything else just find closest match, allowing for unknown subdirectories
|
||||
if ( !strnicmp(buf.c_str(), Pathtype.path, strlen(Pathtype.path)) ) {
|
||||
best_match = Pathtype.index;
|
||||
for (char& c : buf) {
|
||||
if (c == '\\' || c == '/') {
|
||||
c = DIR_SEPARATOR_CHAR;
|
||||
}
|
||||
}
|
||||
|
||||
return best_match;
|
||||
for (auto& Pathtype : Pathtypes) {
|
||||
if (Pathtype.path != nullptr && buf == Pathtype.path) {
|
||||
return Pathtype.index;
|
||||
}
|
||||
}
|
||||
|
||||
return CF_TYPE_INVALID;
|
||||
}
|
||||
+41
-38
@@ -49,38 +49,42 @@ typedef struct {
|
||||
#define CF_TYPE_MODELS 5
|
||||
#define CF_TYPE_TABLES 6
|
||||
#define CF_TYPE_SOUNDS 7
|
||||
#define CF_TYPE_VOICE 8
|
||||
#define CF_TYPE_VOICE_BRIEFINGS 9
|
||||
#define CF_TYPE_VOICE_CMD_BRIEF 10
|
||||
#define CF_TYPE_VOICE_DEBRIEFINGS 11
|
||||
#define CF_TYPE_VOICE_PERSONAS 12
|
||||
#define CF_TYPE_VOICE_SPECIAL 13
|
||||
#define CF_TYPE_VOICE_TRAINING 14
|
||||
#define CF_TYPE_MUSIC 15
|
||||
#define CF_TYPE_MOVIES 16
|
||||
#define CF_TYPE_INTERFACE 17
|
||||
#define CF_TYPE_FONT 18
|
||||
#define CF_TYPE_EFFECTS 19
|
||||
#define CF_TYPE_HUD 20
|
||||
#define CF_TYPE_PLAYERS 21
|
||||
#define CF_TYPE_PLAYER_IMAGES 22
|
||||
#define CF_TYPE_SQUAD_IMAGES 23
|
||||
#define CF_TYPE_SINGLE_PLAYERS 24
|
||||
#define CF_TYPE_MULTI_PLAYERS 25
|
||||
#define CF_TYPE_PLAYER_BINDS 26
|
||||
#define CF_TYPE_CACHE 27
|
||||
#define CF_TYPE_MULTI_CACHE 28
|
||||
#define CF_TYPE_MISSIONS 29
|
||||
#define CF_TYPE_CONFIG 30
|
||||
#define CF_TYPE_DEMOS 31
|
||||
#define CF_TYPE_CBANIMS 32
|
||||
#define CF_TYPE_INTEL_ANIMS 33
|
||||
#define CF_TYPE_SCRIPTS 34
|
||||
#define CF_TYPE_FICTION 35
|
||||
#define CF_TYPE_FREDDOCS 36
|
||||
#define CF_TYPE_SOUNDS_8B22K 8
|
||||
#define CF_TYPE_SOUNDS_16B11K 9
|
||||
#define CF_TYPE_VOICE 10
|
||||
#define CF_TYPE_VOICE_BRIEFINGS 11
|
||||
#define CF_TYPE_VOICE_CMD_BRIEF 12
|
||||
#define CF_TYPE_VOICE_DEBRIEFINGS 13
|
||||
#define CF_TYPE_VOICE_PERSONAS 14
|
||||
#define CF_TYPE_VOICE_SPECIAL 15
|
||||
#define CF_TYPE_VOICE_TRAINING 16
|
||||
#define CF_TYPE_MUSIC 17
|
||||
#define CF_TYPE_MOVIES 18
|
||||
#define CF_TYPE_INTERFACE 19
|
||||
#define CF_TYPE_FONT 20
|
||||
#define CF_TYPE_EFFECTS 21
|
||||
#define CF_TYPE_HUD 22
|
||||
#define CF_TYPE_PLAYERS 23
|
||||
#define CF_TYPE_PLAYER_IMAGES 24
|
||||
#define CF_TYPE_SQUAD_IMAGES 25
|
||||
#define CF_TYPE_SINGLE_PLAYERS 26
|
||||
#define CF_TYPE_MULTI_PLAYERS 27
|
||||
#define CF_TYPE_CACHE 28
|
||||
#define CF_TYPE_MULTI_CACHE 29
|
||||
#define CF_TYPE_MISSIONS 30
|
||||
#define CF_TYPE_CONFIG 31
|
||||
#define CF_TYPE_DEMOS 32
|
||||
#define CF_TYPE_CBANIMS 33
|
||||
#define CF_TYPE_INTEL_ANIMS 34
|
||||
#define CF_TYPE_SCRIPTS 35
|
||||
#define CF_TYPE_FICTION 36
|
||||
#define CF_TYPE_FREDDOCS 37
|
||||
#define CF_TYPE_INTERFACE_MARKUP 38
|
||||
#define CF_TYPE_INTERFACE_CSS 39
|
||||
#define CF_TYPE_PLAYER_BINDS 40
|
||||
|
||||
#define CF_MAX_PATH_TYPES \
|
||||
37 // Can be as high as you'd like //DTP; yeah but beware alot of things uses CF_MAX_PATH_TYPES
|
||||
41 // Can be as high as you'd like //DTP; yeah but beware alot of things uses CF_MAX_PATH_TYPES
|
||||
|
||||
// TRUE if type is specified and valid
|
||||
#define CF_TYPE_SPECIFIED(path_type) (((path_type)>CF_TYPE_INVALID) && ((path_type)<CF_MAX_PATH_TYPES))
|
||||
@@ -171,7 +175,7 @@ int cfile_init(const char *exe_dir, const char *cdrom_dir=NULL);
|
||||
void cfile_close();
|
||||
|
||||
// add an extension to a filename if it doesn't already have it
|
||||
const char *cf_add_ext(const char *filename, const char *ext);
|
||||
char *cf_add_ext(const char *filename, const char *ext);
|
||||
|
||||
// return filename of a CFILE you called cfopen() successfully on.
|
||||
const char *cf_get_filename(const CFILE *cfile);
|
||||
@@ -322,17 +326,15 @@ void cfread_vector(vec3d* vec, CFILE* file, vec3d* deflt = nullptr);
|
||||
// to n characters.
|
||||
void cfread_string(char *buf,int n, CFILE *file);
|
||||
/**
|
||||
* @brief Read a fixed length string that is not null-terminated, with the length stored in file.
|
||||
* @brief Read a fixed length string that is not null-terminated, with the length stored in file
|
||||
*
|
||||
* If it is not null-terminated, the length of the string *must* be less than the size of the buffer (to make room for one)
|
||||
*
|
||||
* @param buf Pre-allocated array to store string
|
||||
* @param buffer_size Size of pre-allocated array
|
||||
* @param n Size of pre-allocated array
|
||||
* @param file File to read from
|
||||
*
|
||||
* @note Appends NULL character to string (buf)
|
||||
*/
|
||||
void cfread_string_len(char *buf,int buffer_size, CFILE *file);
|
||||
void cfread_string_len(char *buf,int n, CFILE *file);
|
||||
|
||||
/**
|
||||
* @brief Read a string from the file where the length is stored in the file
|
||||
@@ -391,7 +393,7 @@ struct CFileLocation {
|
||||
// size - File size
|
||||
// offset - Offset into pack file. 0 if not a packfile.
|
||||
// Returns: If not found returns 0.
|
||||
CFileLocation cf_find_file_location(const char* filespec, int pathtype,
|
||||
CFileLocation cf_find_file_location(const char* filespec, int pathtype, bool localize = false,
|
||||
uint32_t location_flags = CF_LOCATION_ALL);
|
||||
|
||||
struct CFileLocationExt : public CFileLocation {
|
||||
@@ -415,7 +417,8 @@ struct CFileLocationExt : public CFileLocation {
|
||||
// offset - Offset into pack file. 0 if not a packfile.
|
||||
// Returns: If not found returns -1, else returns offset into ext_list.
|
||||
// (NOTE: This function is exponentially slow, so don't use it unless truely needed!!)
|
||||
CFileLocationExt cf_find_file_location_ext(const char* filename, const int ext_num, const char** ext_list, int pathtype);
|
||||
CFileLocationExt cf_find_file_location_ext(const char* filename, const int ext_num, const char** ext_list, int pathtype,
|
||||
bool localize = false);
|
||||
|
||||
// Functions to change directories
|
||||
int cfile_chdir(const char *dir);
|
||||
|
||||
+338
-653
File diff suppressed because it is too large.
Load diff
@@ -42,8 +42,8 @@ bool cf_check_location_flags(uint32_t check_flags, uint32_t desired_flags);
|
||||
// Output: path - Fully qualified pathname.
|
||||
//Returns 0 if result would be too long (invalid result)
|
||||
int cf_create_default_path_string(char* path, uint path_max, int pathtype, const char* filename = nullptr,
|
||||
uint32_t location_flags = CF_LOCATION_ALL);
|
||||
int cf_create_default_path_string(SCP_string& path, int pathtype, const char* filename = nullptr,
|
||||
bool localize = false, uint32_t location_flags = CF_LOCATION_ALL);
|
||||
int cf_create_default_path_string(SCP_string& path, int pathtype, const char* filename = nullptr, bool localize = false,
|
||||
uint32_t location_flags = CF_LOCATION_ALL);
|
||||
|
||||
#endif //_CFILESYSTEM_H
|
||||
@@ -1,186 +0,0 @@
|
||||
#include "cheats_table.h"
|
||||
#include "parse/parselo.h"
|
||||
|
||||
void cheat_table_init() {
|
||||
customCheats.clear();
|
||||
|
||||
if (cf_exists_full("cheats.tbl", CF_TYPE_TABLES)) {
|
||||
parse_cheat_table("cheats.tbl");
|
||||
}
|
||||
parse_modular_table("*-cht.tbm", parse_cheat_table);
|
||||
}
|
||||
|
||||
bool CustomCheat::canUseCheat() {
|
||||
return !requireCheatsEnabled || Cheats_enabled;
|
||||
}
|
||||
|
||||
void CustomCheat::runCheat() {
|
||||
if (!canUseCheat()) return;
|
||||
|
||||
//Only try to send the message if we actually have one to send and are in a mission
|
||||
if (!cheatMsg.empty() && (Game_mode & GM_IN_MISSION))
|
||||
HUD_printf("%s", cheatMsg.c_str());
|
||||
|
||||
scripting::hooks::OnCheat->run(scripting::hook_param_list(scripting::hook_param("Cheat", 's', cheatCode)));
|
||||
CheatUsed = cheatCode;
|
||||
}
|
||||
|
||||
void SpawnShipCheat::runCheat() {
|
||||
CustomCheat::runCheat();
|
||||
|
||||
if (canUseCheat() && (Game_mode & GM_IN_MISSION) && Player_obj != nullptr) {
|
||||
extern void prevent_spawning_collision(object *new_obj);
|
||||
ship_subsys *ptr;
|
||||
char name[NAME_LENGTH];
|
||||
int ship_idx, ship_class;
|
||||
|
||||
// if not found, then don't create it :(
|
||||
ship_class = ship_info_lookup(shipClassName.c_str());
|
||||
if (ship_class < 0)
|
||||
return;
|
||||
|
||||
vec3d pos = Player_obj->pos;
|
||||
matrix orient = Player_obj->orient;
|
||||
pos.xyz.x += frand_range(-700.0f, 700.0f);
|
||||
pos.xyz.y += frand_range(-700.0f, 700.0f);
|
||||
pos.xyz.z += frand_range(-700.0f, 700.0f);
|
||||
|
||||
int objnum = ship_create(&orient, &pos, ship_class);
|
||||
if (objnum < 0)
|
||||
return;
|
||||
|
||||
ship *shipp = &Ships[Objects[objnum].instance];
|
||||
shipp->ship_name[0] = '\0';
|
||||
shipp->display_name.clear();
|
||||
for (size_t j = 0; j < Player_orders.size(); j++)
|
||||
shipp->orders_accepted.insert(j);
|
||||
|
||||
// Goober5000 - stolen from support ship creation
|
||||
// create a name for the ship with a number. look for collisions until one isn't found anymore
|
||||
ship_idx = 1;
|
||||
do {
|
||||
sprintf(name, "%s %d", shipName.c_str(), ship_idx);
|
||||
if ( (ship_name_lookup(name) == -1) && (ship_find_exited_ship_by_name(name) == -1) )
|
||||
{
|
||||
strcpy_s(shipp->ship_name, name);
|
||||
break;
|
||||
}
|
||||
|
||||
ship_idx++;
|
||||
} while(1);
|
||||
|
||||
shipp->flags.set(Ship::Ship_Flags::Escort);
|
||||
shipp->escort_priority = 1000 - ship_idx;
|
||||
|
||||
// now make sure we're not colliding with anyone
|
||||
prevent_spawning_collision(&Objects[objnum]);
|
||||
|
||||
// Goober5000 - beam free
|
||||
for (ptr = GET_FIRST(&shipp->subsys_list); ptr != END_OF_LIST(&shipp->subsys_list); ptr = GET_NEXT(ptr))
|
||||
{
|
||||
// mark all turrets as beam free
|
||||
if (ptr->system_info->type == SUBSYSTEM_TURRET)
|
||||
{
|
||||
ptr->weapons.flags.set(Ship::Weapon_Flags::Beam_Free);
|
||||
ptr->turret_next_fire_stamp = timestamp(Random::next(50, 4000));
|
||||
}
|
||||
}
|
||||
|
||||
// Cyborg17 to prevent a nullptr...
|
||||
ship_set_warp_effects(&Objects[objnum]);
|
||||
// warpin
|
||||
shipfx_warpin_start(&Objects[objnum]);
|
||||
}
|
||||
}
|
||||
|
||||
void parse_cheat_table(const char* filename) {
|
||||
try {
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
optional_string("#CUSTOM CHEATS");
|
||||
|
||||
while (optional_string("$Cheat:")) {
|
||||
SCP_string code, msg, shipClass, shipName;
|
||||
bool requireCheats = false;
|
||||
bool shipSpawn = false;
|
||||
required_string("+Code:");
|
||||
stuff_string(code, F_RAW);
|
||||
|
||||
//We are limited to the buffer size used for the traditional cheats. We can still use short cheats, though.
|
||||
if (code.length() > CHEAT_BUFFER_LEN) {
|
||||
Warning(LOCATION, "Cheat code %s is too long. It will be cut off to maximum length (%i characters).", code.c_str(), CHEAT_BUFFER_LEN);
|
||||
code = code.substr(0, CHEAT_BUFFER_LEN);
|
||||
}
|
||||
|
||||
if (optional_string("+Message:")) {
|
||||
stuff_string(msg, F_MESSAGE);
|
||||
}
|
||||
|
||||
if (optional_string("+RequireCheats:")) {
|
||||
stuff_boolean(&requireCheats);
|
||||
}
|
||||
|
||||
if (optional_string("+SpawnShip:")) {
|
||||
shipSpawn = true;
|
||||
required_string("+Name:");
|
||||
stuff_string(shipName, F_NAME);
|
||||
required_string("+Class:");
|
||||
stuff_string(shipClass, F_NAME);
|
||||
|
||||
int shipClassInfo = ship_info_lookup(shipClass.c_str());
|
||||
if (shipClassInfo < 0) {
|
||||
shipSpawn = false;
|
||||
Warning(LOCATION, "There is no ship class named '%s'. The '%s' cheat won't summon a ship.", shipClass.c_str(), code.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (shipSpawn) {
|
||||
std::unique_ptr<CustomCheat> shipCheat(new SpawnShipCheat(code, msg, requireCheats, shipClass, shipName));
|
||||
|
||||
if(customCheats.count(code) == 1) {
|
||||
Warning(LOCATION, "A cheat for code '%s' already exists. It will be replaced.", code.c_str());
|
||||
customCheats[code] = std::move(shipCheat);
|
||||
} else {
|
||||
customCheats.emplace(code, std::move(shipCheat));
|
||||
}
|
||||
} else {
|
||||
std::unique_ptr<CustomCheat> cheat(new CustomCheat(code, msg, requireCheats));
|
||||
|
||||
if(customCheats.count(code) == 1) {
|
||||
Warning(LOCATION, "A cheat for code '%s' already exists. It will be replaced.", code.c_str());
|
||||
customCheats[code] = std::move(cheat);
|
||||
} else {
|
||||
customCheats.emplace(code, std::move(cheat));
|
||||
}
|
||||
}
|
||||
}
|
||||
required_string("#END");
|
||||
}
|
||||
catch (const parse::ParseException& e) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool checkForCustomCheats(const char* buffer, int buffer_length) {
|
||||
const char* check_buffer = buffer;
|
||||
for (int i = 0; i < buffer_length; i++) {
|
||||
if (*check_buffer == '\0') {
|
||||
check_buffer++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through our map of custom cheats and check if the code is within the buffer.
|
||||
// We don't just check for equality, as the player may have typed other characters before the cheat.
|
||||
for (auto &ccheat : customCheats) {
|
||||
auto found = std::strstr(check_buffer, ccheat.first.c_str());
|
||||
if (found != nullptr) {
|
||||
ccheat.second->runCheat();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
#include "globalincs/globals.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "io/key.h"
|
||||
#include "hud/hudmessage.h"
|
||||
#include "hud/hudsquadmsg.h"
|
||||
#include "scripting/global_hooks.h"
|
||||
#include "scripting/hook_api.h"
|
||||
#include "ship/ship.h"
|
||||
#include "ship/shipfx.h"
|
||||
|
||||
#define CHEAT_BUFFER_LEN 17
|
||||
|
||||
class CustomCheat {
|
||||
public:
|
||||
SCP_string cheatCode;
|
||||
SCP_string cheatMsg;
|
||||
bool requireCheatsEnabled;
|
||||
|
||||
CustomCheat(SCP_string cheat_code, SCP_string cheat_msg, bool require_cheats_enabled) :
|
||||
cheatCode(std::move(cheat_code)),
|
||||
cheatMsg(std::move(cheat_msg)),
|
||||
requireCheatsEnabled(require_cheats_enabled) { }
|
||||
|
||||
virtual ~CustomCheat() = default;
|
||||
|
||||
virtual void runCheat();
|
||||
|
||||
bool canUseCheat();
|
||||
};
|
||||
|
||||
class SpawnShipCheat : public CustomCheat {
|
||||
protected:
|
||||
SCP_string shipClassName;
|
||||
SCP_string shipName;
|
||||
public:
|
||||
|
||||
SpawnShipCheat(SCP_string cheat_code, SCP_string cheat_msg, bool require_cheats_enabled, SCP_string class_name, SCP_string ship_name) : CustomCheat(cheat_code, cheat_msg, require_cheats_enabled),
|
||||
shipClassName(std::move(class_name)),
|
||||
shipName(std::move(ship_name)) { }
|
||||
|
||||
void runCheat() override;
|
||||
};
|
||||
|
||||
static SCP_map<SCP_string, std::unique_ptr<CustomCheat>> customCheats;
|
||||
|
||||
void cheat_table_init();
|
||||
void parse_cheat_table(const char* filename);
|
||||
bool checkForCustomCheats(const char* converted_buffer, int buffer_length);
|
||||
+62
-184
@@ -15,7 +15,6 @@
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "globalincs/version.h"
|
||||
#include "graphics/openxr.h"
|
||||
#include "graphics/shadows.h"
|
||||
#include "hud/hudconfig.h"
|
||||
#include "io/joy.h"
|
||||
@@ -23,7 +22,6 @@
|
||||
#include "network/multi_log.h"
|
||||
#include "options/OptionsManager.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "osapi/dialogs.h"
|
||||
#include "parse/sexp.h"
|
||||
#include "scripting/scripting.h"
|
||||
#include "sound/openal.h"
|
||||
@@ -157,7 +155,6 @@ typedef struct
|
||||
// Please group them by type, ie graphics, gameplay etc, maximum 20 different types
|
||||
Flag exe_params[] =
|
||||
{
|
||||
//flag launcher text FSO on_flags off_flags category reference URL
|
||||
{ "-nospec", "Disable specular", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nospec", },
|
||||
{ "-noglow", "Disable glow maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noglow", },
|
||||
{ "-noenv", "Disable environment maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noenv", },
|
||||
@@ -173,12 +170,9 @@ Flag exe_params[] =
|
||||
{ "-fb_thrusters", "Enable Framebuffer Thrusters", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_thrusters", },
|
||||
{ "-no_deferred", "Disable Deferred Lighting", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_deferred"},
|
||||
{ "-enable_shadows", "Enable Shadows", true, EASY_ALL_ON | EASY_HI_MEM_ON, EASY_DEFAULT | EASY_HI_MEM_OFF, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-enable_shadows"},
|
||||
{ "-deferred_cockpit", "Enable Deferred Lighting for Cockpits", true, EASY_ALL_ON | EASY_HI_MEM_ON, EASY_DEFAULT | EASY_HI_MEM_OFF, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-deferred_cockpit"},
|
||||
|
||||
//flag launcher text FSO on_flags off_flags category reference URL
|
||||
{ "-no_vsync", "Disable vertical sync", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_vsync", },
|
||||
|
||||
//flag launcher text FSO on_flags off_flags category reference URL
|
||||
{ "-fps", "Show frames per second on HUD", false, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fps", },
|
||||
{ "-dualscanlines", "Add another pair of scanning lines", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dualscanlines", },
|
||||
{ "-targetinfo", "Enable info next to target", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-targetinfo", },
|
||||
@@ -186,30 +180,25 @@ Flag exe_params[] =
|
||||
{ "-rearm_timer", "Enable rearm/repair completion timer", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-rearm_timer", },
|
||||
{ "-ballistic_gauge", "Enable analog ballistic ammo gauge", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ballistic_gauge", },
|
||||
|
||||
//flag launcher text FSO on_flags off_flags category reference URL
|
||||
{ "-window", "Run in window", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-window", },
|
||||
{ "-fullscreen_window", "Run in fullscreen window", false, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fullscreen_window", },
|
||||
{ "-capture_mouse", "Capture the mouse within the window", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-capture_mouse", },
|
||||
{ "-stretch_menu", "Stretch interface to fill screen", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stretch_menu", },
|
||||
{ "-noscalevid", "Disable scale-to-window for movies", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noscalevid", },
|
||||
{ "-nomotiondebris", "Disable motion debris", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomotiondebris",},
|
||||
{ "-ship_choice_3d", "Use 3D models for ship selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ship_choice_3d", },
|
||||
{ "-weapon_choice_3d", "Use 3D models for weapon selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-weapon_choice_3d", },
|
||||
{ "-3dwarp", "Enable 3D warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dwarp", },
|
||||
{ "-warp_flash", "Enable flash upon warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-warp_flash", },
|
||||
{ "-no_ap_interrupt", "Disable interrupting autopilot", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ap_interrupt", },
|
||||
{ "-no_screenshake", "Disable screen shaking", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_screenshake", },
|
||||
{ "-vr", "Enable Virtual Reality Mode", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-vr", },
|
||||
{ "-no_unfocused_pause","Don't pause if the window isn't focused", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_unfocused_pause", },
|
||||
|
||||
//flag launcher text FSO on_flags off_flags category reference URL
|
||||
{ "-nosound", "Disable all sound", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nosound", },
|
||||
{ "-nomusic", "Disable music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomusic", },
|
||||
{ "-no_enhanced_sound", "Disable enhanced sound", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_enhanced_sound", },
|
||||
|
||||
//flag launcher text FSO on_flags off_flags category reference URL
|
||||
{ "-portable_mode", "Store config in portable location", false, 0, EASY_DEFAULT, "Launcher", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-portable_mode", },
|
||||
{ "-joy_info", "Outputs SDL joystick info", true, 0, EASY_DEFAULT, "Launcher", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-joy_info",},
|
||||
|
||||
//flag launcher text FSO on_flags off_flags category reference URL
|
||||
{ "-standalone", "Run as standalone server", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-standalone", },
|
||||
{ "-startgame", "Skip mainhall and start hosting", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-startgame", },
|
||||
{ "-closed", "Start hosted server as closed", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-closed", },
|
||||
@@ -218,11 +207,8 @@ Flag exe_params[] =
|
||||
{ "-clientdamage", "", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-clientdamage", },
|
||||
{ "-mpnoreturn", "Disable flight deck option", true, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mpnoreturn", },
|
||||
{ "-gateway_ip", "Set gateway IP address", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-gateway_ip", },
|
||||
{ "-ingame_join", "Disable in-game joining", true, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
|
||||
|
||||
//flag launcher text FSO on_flags off_flags category reference URL
|
||||
{ "-no_set_gamma", "Disable setting of gamma", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_set_gamma", },
|
||||
{ "-no_ingame_options", "Disable using ingame options", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ingame_options", },
|
||||
{ "-nomovies", "Disable video playback", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomovies", },
|
||||
{ "-noparseerrors", "Disable parsing errors", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noparseerrors", },
|
||||
{ "-loadallweps", "Load all weapons, even those not used", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-loadallweps", },
|
||||
@@ -240,16 +226,13 @@ Flag exe_params[] =
|
||||
{ "-prefer_ipv4", "Prefer IPv4 DNS lookups", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-prefer_ipv4", },
|
||||
{ "-prefer_ipv6", "Prefer IPv6 DNS lookups", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-prefer_ipv6", },
|
||||
{ "-log_multi_packet", "Log multi packet types ", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-log_multi_packet",},
|
||||
{ "-no_bsp_align", "Disable pof BSP data alignment", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_bsp_align", },
|
||||
#ifdef WIN32
|
||||
{ "-fix_registry", "Use a different registry path", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fix_registry", },
|
||||
#endif
|
||||
|
||||
//flag launcher text FSO on_flags off_flags category reference URL
|
||||
{ "-ingame_join", "Allow in-game joining", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
|
||||
{ "-voicer", "Enable voice recognition", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-voicer", },
|
||||
|
||||
//flag launcher text FSO on_flags off_flags category reference URL
|
||||
{ "-override_data", "Enable override directory", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-override_data", },
|
||||
{ "-bmpmanusage", "Show how many BMPMAN slots are in use", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-bmpmanusage", },
|
||||
{ "-pos", "Show position of camera", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pos", },
|
||||
{ "-stats", "Show statistics", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stats", },
|
||||
@@ -268,6 +251,7 @@ Flag exe_params[] =
|
||||
{ "-verify_vps", "Spew VP CRCs to vp_crcs.txt", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-verify_vps", },
|
||||
{ "-reparse_mainhall", "Reparse mainhall.tbl when loading halls", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-reparse_mainhall", },
|
||||
{ "-noninteractive", "Disables interactive dialogs", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noninteractive", },
|
||||
{ "-no_unfocused_pause","Don't pause if the window isn't focused", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_unfocused_pause", },
|
||||
{ "-benchmark_mode", "Puts the game into benchmark mode", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-benchmark_mode", },
|
||||
{ "-profile_frame_time","Profile frame time", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_frame_time", },
|
||||
{ "-profile_write_file", "Write profiling information to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_write_file", },
|
||||
@@ -276,9 +260,6 @@ Flag exe_params[] =
|
||||
{ "-gr_debug", "Output graphics debug information", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-gr_debug", },
|
||||
{ "-stdout_log", "Output log file to stdout", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stdout_log", },
|
||||
{ "-slow_frames_ok", "Don't adjust timestamps for slow frames", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-slow_frames_ok", },
|
||||
{ "-imgui_debug", "Show imgui debug/demo window in the lab", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-imgui_debug", },
|
||||
{ "-luadev", "Make lua errors non-fatal", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-luadev", },
|
||||
{"-vulkan", "Use vulkan render backend", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-vulkan", },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -335,15 +316,17 @@ int Cmdline_use_last_pilot = 0;
|
||||
// Graphics related
|
||||
cmdline_parm fov_arg("-fov", "Vertical field-of-view factor", AT_FLOAT); // Cmdline_fov -- comand line FOV -Bobboau
|
||||
cmdline_parm fov_cockpit_arg("-fov_cockpit", "Vertical field-of-view factor for Cockpits", AT_FLOAT);
|
||||
cmdline_parm ambient_power_arg("-ambient", "Multiplies the brightness of all ambient light", AT_FLOAT);
|
||||
cmdline_parm light_power_arg("-light", "Multiplies the brightness of all light", AT_FLOAT);
|
||||
cmdline_parm emissive_power_arg("-emissive", "Multiplies the brightness of all ambient light", AT_FLOAT);
|
||||
cmdline_parm emissive_arg("-emissive_light", "Enable emissive light from ships", AT_NONE); // semi-deprecated but still functional
|
||||
cmdline_parm clip_dist_arg("-clipdist", "Changes the distance from the viewpoint for the near-clipping plane", AT_FLOAT); // Cmdline_clip_dist
|
||||
cmdline_parm spec_static_arg("-spec_static", "Adjusts suns contribution to specular highlights", AT_FLOAT);
|
||||
cmdline_parm spec_point_arg("-spec_point", "Adjusts laser weapons contribution to specular highlights", AT_FLOAT);
|
||||
cmdline_parm spec_tube_arg("-spec_tube", "Adjusts beam weapons contribution to specular highlights", AT_FLOAT);
|
||||
cmdline_parm ambient_factor_arg("-ambient_factor", "Adjusts ambient light applied to all parts of a ship", AT_INT); // Cmdline_ambient_factor
|
||||
cmdline_parm env("-noenv", NULL, AT_NONE); // Cmdline_env
|
||||
cmdline_parm glow_arg("-noglow", NULL, AT_NONE); // Cmdline_glow -- use Bobs glow code
|
||||
cmdline_parm nomotiondebris_arg("-nomotiondebris", NULL, AT_NONE); // Cmdline_nomotiondebris -- Removes those ugly floating rocks -C
|
||||
cmdline_parm noscalevid_arg("-noscalevid", NULL, AT_NONE); // Cmdline_noscalevid -- disable video scaling that fits to window
|
||||
cmdline_parm spec_arg("-nospec", NULL, AT_NONE); // Cmdline_spec --
|
||||
cmdline_parm emissive_arg("-emissive_light", "Enable emissive light from ships", AT_NONE); // Cmdline_no_emissive -- don't use emissive light in OGL
|
||||
cmdline_parm normal_arg("-nonormal", NULL, AT_NONE); // Cmdline_normal -- disable normal mapping
|
||||
cmdline_parm height_arg("-noheight", NULL, AT_NONE); // Cmdline_height -- enable support for parallax mapping
|
||||
cmdline_parm enable_3d_shockwave_arg("-3dshockwave", NULL, AT_NONE);
|
||||
@@ -356,19 +339,16 @@ cmdline_parm deprecated_fxaa_arg("-fxaa", nullptr, AT_NONE);
|
||||
cmdline_parm deprecated_fxaa_preset_arg("-fxaa_preset", "FXAA quality (0-2), requires post-processing and -fxaa", AT_INT);
|
||||
cmdline_parm deprecated_smaa_arg("-smaa", nullptr, AT_NONE);
|
||||
cmdline_parm deprecated_smaa_preset_arg("-smaa_preset", "SMAA quality (0-3), requires post-processing and -smaa", AT_INT);
|
||||
cmdline_parm msaa_enabled_arg("-msaa", nullptr, AT_INT);
|
||||
cmdline_parm fb_explosions_arg("-fb_explosions", NULL, AT_NONE);
|
||||
cmdline_parm fb_thrusters_arg("-fb_thrusters", NULL, AT_NONE);
|
||||
cmdline_parm flightshaftsoff_arg("-nolightshafts", NULL, AT_NONE);
|
||||
cmdline_parm shadow_quality_arg("-shadow_quality", NULL, AT_INT);
|
||||
cmdline_parm enable_shadows_arg("-enable_shadows", NULL, AT_NONE);
|
||||
cmdline_parm no_deferred_lighting_arg("-no_deferred", NULL, AT_NONE); // Cmdline_no_deferred
|
||||
cmdline_parm deferred_lighting_cockpit_arg("-deferred_cockpit", nullptr, AT_NONE);
|
||||
cmdline_parm anisotropy_level_arg("-anisotropic_filter", NULL, AT_INT);
|
||||
|
||||
float Cmdline_ambient_power = 1.0f;
|
||||
float Cmdline_emissive_power = 0.0f;
|
||||
float Cmdline_light_power = 1.0f;
|
||||
float Cmdline_clip_dist = Default_min_draw_distance;
|
||||
int Cmdline_ambient_factor = 128;
|
||||
int Cmdline_env = 1;
|
||||
int Cmdline_mipmap = 0;
|
||||
int Cmdline_glow = 1;
|
||||
@@ -382,9 +362,7 @@ int Cmdline_softparticles = 0;
|
||||
int Cmdline_bloom_intensity = 25;
|
||||
bool Cmdline_force_lightshaft_off = false;
|
||||
int Cmdline_no_deferred_lighting = 0;
|
||||
bool Cmdline_deferred_lighting_cockpit = false;
|
||||
int Cmdline_aniso_level = 0;
|
||||
int Cmdline_msaa_enabled = 0;
|
||||
|
||||
// Game Speed related
|
||||
cmdline_parm no_fpscap("-no_fps_capping", "Don't limit frames-per-second", AT_NONE); // Cmdline_NoFPSCap
|
||||
@@ -395,35 +373,35 @@ int Cmdline_no_vsync = 0;
|
||||
|
||||
// HUD related
|
||||
cmdline_parm ballistic_gauge("-ballistic_gauge", NULL, AT_NONE); // Cmdline_ballistic_gauge
|
||||
cmdline_parm dualscanlines_arg("-dualscanlines", NULL, AT_NONE); // Cmdline_dualscanlines -- Change to phreaks options including new targeting code; semi-deprecated but still functional
|
||||
cmdline_parm dualscanlines_arg("-dualscanlines", NULL, AT_NONE); // Cmdline_dualscanlines -- Change to phreaks options including new targeting code
|
||||
cmdline_parm orb_radar("-orbradar", NULL, AT_NONE); // Cmdline_orb_radar
|
||||
cmdline_parm rearm_timer_arg("-rearm_timer", NULL, AT_NONE); // Cmdline_rearm_timer; semi-deprecated but still functional-Mjn
|
||||
cmdline_parm targetinfo_arg("-targetinfo", NULL, AT_NONE); // Cmdline_targetinfo -- Adds ship name/class to right of target box -C; semi-deprecated but still functional-Mjn
|
||||
cmdline_parm rearm_timer_arg("-rearm_timer", NULL, AT_NONE); // Cmdline_rearm_timer
|
||||
cmdline_parm targetinfo_arg("-targetinfo", NULL, AT_NONE); // Cmdline_targetinfo -- Adds ship name/class to right of target box -C
|
||||
|
||||
int Cmdline_ballistic_gauge = 0; // WMCoolmon's gauge thingy
|
||||
int Cmdline_dualscanlines = 0;
|
||||
int Cmdline_orb_radar = 0;
|
||||
int Cmdline_rearm_timer = 0;
|
||||
int Cmdline_targetinfo = 0;
|
||||
|
||||
// Gameplay related
|
||||
cmdline_parm use_3dwarp("-3dwarp", nullptr, AT_NONE); // Is now Fireball_use_3d_warp
|
||||
cmdline_parm ship_choice_3d_arg("-ship_choice_3d", nullptr, AT_NONE); // Cmdline_ship_choice_3d
|
||||
cmdline_parm weapon_choice_3d_arg("-weapon_choice_3d", nullptr, AT_NONE); // Cmdline_weapon_choice_3d
|
||||
cmdline_parm use_warp_flash("-warp_flash", nullptr, AT_NONE); // Cmdline_warp_flash
|
||||
cmdline_parm allow_autpilot_interrupt("-no_ap_interrupt", nullptr, AT_NONE);
|
||||
cmdline_parm stretch_menu("-stretch_menu", nullptr, AT_NONE); // Cmdline_stretch_menu
|
||||
cmdline_parm capture_mouse("-capture_mouse", nullptr, AT_NONE); // Cmdline_capture_mouse
|
||||
cmdline_parm no_screenshake("-no_screenshake", nullptr, AT_NONE); // Cmdline_no_screenshake
|
||||
cmdline_parm vr("-vr", nullptr, AT_NONE);
|
||||
cmdline_parm deadzone("-deadzone",
|
||||
"Sets the joystick deadzone. Integer value from 0 to 100 as a percentage of the joystick's range (100% would make the stick do nothing). Disables deadzone slider in the in-game Options menu.", AT_INT); //Cmdline_deadzone
|
||||
|
||||
int Cmdline_ship_choice_3d = 0;
|
||||
int Cmdline_weapon_choice_3d = 0;
|
||||
int Cmdline_warp_flash = 0;
|
||||
int Cmdline_autopilot_interruptable = 1;
|
||||
int Cmdline_stretch_menu = 0;
|
||||
bool Cmdline_capture_mouse = false;
|
||||
int Cmdline_no_screenshake = 0;
|
||||
int Cmdline_deadzone = -1;
|
||||
bool Cmdline_enable_vr = false;
|
||||
|
||||
// Audio related
|
||||
cmdline_parm voice_recognition_arg("-voicer", NULL, AT_NONE); // Cmdline_voice_recognition
|
||||
@@ -443,8 +421,8 @@ cmdline_parm mpnoreturn_arg("-mpnoreturn", NULL, AT_NONE); // Cmdline_mpnoreturn
|
||||
cmdline_parm objupd_arg("-cap_object_update", "Multiplayer object update cap (0-3)", AT_INT);
|
||||
cmdline_parm gateway_ip_arg("-gateway_ip", "Set gateway IP address", AT_STRING);
|
||||
|
||||
char *Cmdline_almission = nullptr; //DTP for autoload multi mission.
|
||||
int Cmdline_ingamejoin = 1;
|
||||
char *Cmdline_almission = NULL; //DTP for autoload multi mission.
|
||||
int Cmdline_ingamejoin = 0;
|
||||
int Cmdline_mpnoreturn = 0;
|
||||
int Cmdline_objupd = 3; // client object updates on LAN by default
|
||||
char *Cmdline_gateway_ip = nullptr;
|
||||
@@ -452,16 +430,13 @@ char *Cmdline_gateway_ip = nullptr;
|
||||
// Launcher related options
|
||||
cmdline_parm portable_mode("-portable_mode", NULL, AT_NONE);
|
||||
cmdline_parm joy_info("-joy_info", "Outputs SDL joystick info", AT_NONE);
|
||||
cmdline_parm lang_arg("-language", "Language name as defined in strings.tbl", AT_STRING);
|
||||
|
||||
bool Cmdline_portable_mode = false;
|
||||
SCP_string Cmdline_lang;
|
||||
|
||||
// Troubleshooting
|
||||
cmdline_parm loadallweapons_arg("-loadallweps", NULL, AT_NONE); // Cmdline_load_all_weapons
|
||||
cmdline_parm nomovies_arg("-nomovies", NULL, AT_NONE); // Cmdline_nomovies -- Allows video streaming
|
||||
cmdline_parm no_set_gamma_arg("-no_set_gamma", NULL, AT_NONE); // Cmdline_no_set_gamma
|
||||
cmdline_parm no_ingame_options_arg("-no_ingame_options", NULL, AT_NONE); // Cmdline_no_ingame_options
|
||||
cmdline_parm no_fbo_arg("-disable_fbo", NULL, AT_NONE); // Cmdline_no_fbo
|
||||
cmdline_parm no_pbo_arg("-disable_pbo", NULL, AT_NONE); // Cmdline_no_pbo
|
||||
cmdline_parm mipmap_arg("-mipmap", NULL, AT_NONE); // Cmdline_mipmap
|
||||
@@ -477,7 +452,6 @@ cmdline_parm noshadercache_arg("-noshadercache", NULL, AT_NONE);
|
||||
cmdline_parm prefer_ipv4_arg("-prefer_ipv4", nullptr, AT_NONE);
|
||||
cmdline_parm prefer_ipv6_arg("-prefer_ipv6", nullptr, AT_NONE);
|
||||
cmdline_parm log_multi_packet_arg("-log_multi_packet", nullptr, AT_NONE);
|
||||
cmdline_parm no_bsp_align_arg("-no_bsp_align", nullptr, AT_NONE);
|
||||
#ifdef WIN32
|
||||
cmdline_parm fix_registry("-fix_registry", NULL, AT_NONE);
|
||||
#endif
|
||||
@@ -485,7 +459,6 @@ cmdline_parm fix_registry("-fix_registry", NULL, AT_NONE);
|
||||
int Cmdline_load_all_weapons = 0;
|
||||
int Cmdline_nomovies = 0;
|
||||
int Cmdline_no_set_gamma = 0;
|
||||
bool Cmdline_no_ingame_options = false;
|
||||
int Cmdline_no_fbo = 0;
|
||||
int Cmdline_no_pbo = 0;
|
||||
int Cmdline_ati_color_swap = 0;
|
||||
@@ -500,12 +473,9 @@ bool Cmdline_noshadercache = false;
|
||||
bool Cmdline_prefer_ipv4 = false;
|
||||
bool Cmdline_prefer_ipv6 = false;
|
||||
bool Cmdline_dump_packet_type = false;
|
||||
bool Cmdline_no_bsp_align = false;
|
||||
#ifdef WIN32
|
||||
bool Cmdline_alternate_registry_path = false;
|
||||
#endif
|
||||
uint Cmdline_rng_seed = 0;
|
||||
bool Cmdline_reuse_rng_seed = false;
|
||||
|
||||
// Developer/Testing related
|
||||
cmdline_parm start_mission_arg("-start_mission", "Skip mainhall and run this mission", AT_STRING); // Cmdline_start_mission
|
||||
@@ -520,9 +490,7 @@ cmdline_parm stats_arg("-stats", NULL, AT_NONE); // Cmdline_show_stats
|
||||
cmdline_parm save_render_targets_arg("-save_render_target", NULL, AT_NONE); // Cmdline_save_render_targets
|
||||
cmdline_parm window_arg("-window", NULL, AT_NONE); // Cmdline_window
|
||||
cmdline_parm fullscreen_window_arg("-fullscreen_window", "Fullscreen/borderless window (Windows only)", AT_NONE);
|
||||
cmdline_parm deprecated_res_arg("-res", "Deprecated, resolution, formatted like 1600x900", AT_STRING);
|
||||
cmdline_parm render_res_arg("-render_res", "Resolution, formatted like 1600x900", AT_STRING);
|
||||
cmdline_parm window_res_arg("-window_res", "Window resolution, formatted like 1600x900.", AT_STRING);
|
||||
cmdline_parm res_arg("-res", "Resolution, formatted like 1600x900", AT_STRING);
|
||||
cmdline_parm center_res_arg("-center_res", "Resolution of center monitor, formatted like 1600x900", AT_STRING);
|
||||
cmdline_parm verify_vps_arg("-verify_vps", NULL, AT_NONE); // Cmdline_verify_vps -- spew VP crcs to vp_crcs.txt
|
||||
cmdline_parm parse_cmdline_only(PARSE_COMMAND_LINE_STRING, "Ignore any cmdline_fso.cfg files", AT_NONE);
|
||||
@@ -539,11 +507,7 @@ cmdline_parm debug_window_arg("-debug_window", NULL, AT_NONE); // Cmdline_debug_
|
||||
cmdline_parm graphics_debug_output_arg("-gr_debug", nullptr, AT_NONE); // Cmdline_graphics_debug_output
|
||||
cmdline_parm log_to_stdout_arg("-stdout_log", nullptr, AT_NONE); // Cmdline_log_to_stdout
|
||||
cmdline_parm slow_frames_ok_arg("-slow_frames_ok", nullptr, AT_NONE); // Cmdline_slow_frames_ok
|
||||
cmdline_parm fixed_seed_rand("-seed", nullptr, AT_INT); // Cmdline_rng_seed,Cmdline_reuse_rng_seed;
|
||||
cmdline_parm luadev_arg("-luadev", "Make lua errors non-fatal", AT_NONE); // Cmdline_lua_devmode
|
||||
cmdline_parm override_arg("-override_data", "Enable override directory", AT_NONE); // Cmdline_override_data
|
||||
cmdline_parm imgui_debug_arg("-imgui_debug", nullptr, AT_NONE);
|
||||
cmdline_parm vulkan("-vulkan", nullptr, AT_NONE);
|
||||
|
||||
|
||||
char *Cmdline_start_mission = NULL;
|
||||
int Cmdline_dis_collisions = 0;
|
||||
@@ -560,7 +524,6 @@ int Cmdline_show_stats = 0;
|
||||
int Cmdline_save_render_targets = 0;
|
||||
int Cmdline_window = 0;
|
||||
int Cmdline_fullscreen_window = 0;
|
||||
tl::optional<std::pair<uint16_t, uint16_t>>Cmdline_window_res = tl::nullopt;
|
||||
char *Cmdline_res = 0;
|
||||
char *Cmdline_center_res = 0;
|
||||
int Cmdline_verify_vps = 0;
|
||||
@@ -577,10 +540,6 @@ bool Cmdline_debug_window = false;
|
||||
bool Cmdline_graphics_debug_output = false;
|
||||
bool Cmdline_log_to_stdout = false;
|
||||
bool Cmdline_slow_frames_ok = false;
|
||||
bool Cmdline_lua_devmode = false;
|
||||
bool Cmdline_override_data = false;
|
||||
bool Cmdline_show_imgui_debug = false;
|
||||
bool Cmdline_vulkan = false;
|
||||
|
||||
// Other
|
||||
cmdline_parm get_flags_arg(GET_FLAGS_STRING, "Output the launcher flags file", AT_STRING);
|
||||
@@ -603,12 +562,6 @@ cmdline_parm deprecated_missile_lighting_arg("-missile_lighting", "Deprecated",
|
||||
cmdline_parm deprecated_cache_bitmaps_arg("-cache_bitmaps", "Deprecated", AT_NONE);
|
||||
cmdline_parm deprecated_no_emissive_arg("-no_emissive_light", "Deprecated", AT_NONE);
|
||||
cmdline_parm deprecated_postprocess_arg("-post_process", "Deprecated", AT_NONE);
|
||||
cmdline_parm deprecated_spec_static_arg("-spec_static", "Deprecated", AT_NONE);
|
||||
cmdline_parm deprecated_spec_point_arg("-spec_point", "Deprecated", AT_NONE);
|
||||
cmdline_parm deprecated_spec_tube_arg("-spec_tube", "Deprecated", AT_NONE);
|
||||
cmdline_parm deprecated_ambient_factor_arg("-ambient_factor", "Deprecated", AT_NONE); //
|
||||
cmdline_parm deprecated_ship_choice_3d_arg("-ship_choice_3d", "Deprecated", AT_NONE);
|
||||
cmdline_parm deprecated_weapon_choice_3d_arg("-weapon_choice_3d", "Deprecated", AT_NONE);
|
||||
|
||||
#ifndef NDEBUG
|
||||
// NOTE: this assumes that os_init() has already been called but isn't a fatal error if it hasn't
|
||||
@@ -848,7 +801,7 @@ void os_validate_parms(int argc, char *argv[])
|
||||
// if we got a -help, --help, -h, or -? then show the help text, otherwise show unknown option
|
||||
if (!stricmp(token, "-help") || !stricmp(token, "--help") || !stricmp(token, "-h") || !stricmp(token, "-?")) {
|
||||
printf("FreeSpace 2 Open, version %s\n", FS_VERSION_FULL);
|
||||
printf("Website: https://scp.indiegames.us\n");
|
||||
printf("Website: http://scp.indiegames.us\n");
|
||||
printf("Github (bug reporting): https://github.com/scp-fs2open/fs2open.github.com/issues\n\n");
|
||||
printf("Usage: fs2_open [options]\n");
|
||||
|
||||
@@ -1659,7 +1612,7 @@ bool SetCmdlineParams()
|
||||
|
||||
// be sure that this string fits in our limits
|
||||
if ( strlen(Cmdline_game_password) >= MAX_PASSWD_LEN ) {
|
||||
ReleaseWarning(LOCATION, "Multi game password is longer than max of %d characters and will be trimmed to fit!", MAX_PASSWD_LEN-1);
|
||||
ReleaseWarning(LOCATION, "Multi game password is longer than max of %d charaters and will be trimmed to fit!", MAX_PASSWD_LEN-1);
|
||||
Cmdline_game_password[MAX_PASSWD_LEN-1] = '\0';
|
||||
}
|
||||
}
|
||||
@@ -1723,48 +1676,31 @@ bool SetCmdlineParams()
|
||||
// d3d windowed
|
||||
if(window_arg.found()) {
|
||||
// We need to set both values since we don't know if we are going to use the new config system
|
||||
//options::OptionsManager::instance()->setOverride("Graphics.WindowMode", "0");
|
||||
options::OptionsManager::instance()->setOverride("Graphics.WindowMode", "0");
|
||||
Cmdline_window = 1;
|
||||
}
|
||||
|
||||
if ( fullscreen_window_arg.found( ) )
|
||||
{
|
||||
//options::OptionsManager::instance()->setOverride("Graphics.WindowMode", "1");
|
||||
options::OptionsManager::instance()->setOverride("Graphics.WindowMode", "1");
|
||||
Cmdline_fullscreen_window = 1;
|
||||
Cmdline_window = 0; /* Make sure no-one sets both */
|
||||
}
|
||||
|
||||
if(render_res_arg.found() || deprecated_res_arg.found()){
|
||||
if (render_res_arg.found()) {
|
||||
Cmdline_res = render_res_arg.str();
|
||||
}
|
||||
else {
|
||||
Cmdline_res = deprecated_res_arg.str();
|
||||
mprintf(("Deprecated -res argument. Use -render_res instead...\n"));
|
||||
}
|
||||
if(res_arg.found()){
|
||||
Cmdline_res = res_arg.str();
|
||||
|
||||
/*int width = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
if (sscanf(Cmdline_res, "%dx%d", &width, &height) == 2) {
|
||||
if ( sscanf(Cmdline_res, "%dx%d", &width, &height) == 2 ) {
|
||||
SCP_string override;
|
||||
sprintf(override, "{\"width\":%d,\"height\":%d}", width, height);
|
||||
options::OptionsManager::instance()->setOverride("Graphics.Resolution", override);
|
||||
} else {
|
||||
Warning(LOCATION, "Failed to parse -res parameter \"%s\". Must be in format \"<width>x<height>\".\n", Cmdline_res);
|
||||
}*/
|
||||
}
|
||||
if(window_res_arg.found()){
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
if ( sscanf(window_res_arg.str(), "%dx%d", &width, &height) == 2 ) {
|
||||
Cmdline_window_res.emplace(static_cast<uint16_t>(width), static_cast<uint16_t>(height));
|
||||
} else {
|
||||
Warning(LOCATION, "Failed to parse -window_res parameter \"%s\". Must be in format \"<width>x<height>\".\n", window_res_arg.str());
|
||||
mprintf(("Failed to parse -res parameter \"%s\". Must be in format \"<width>x<height>\".\n", Cmdline_res));
|
||||
}
|
||||
}
|
||||
|
||||
if(center_res_arg.found()){
|
||||
Cmdline_center_res = center_res_arg.str();
|
||||
}
|
||||
@@ -1780,7 +1716,7 @@ bool SetCmdlineParams()
|
||||
|
||||
if(targetinfo_arg.found())
|
||||
{
|
||||
Extra_target_info = true;
|
||||
Cmdline_targetinfo = 1;
|
||||
}
|
||||
|
||||
if(nomovies_arg.found() ) {
|
||||
@@ -1873,12 +1809,8 @@ bool SetCmdlineParams()
|
||||
}
|
||||
}
|
||||
|
||||
if (vr.found()) {
|
||||
Cmdline_enable_vr = true;
|
||||
if (fov_arg.found() || fov_cockpit_arg.found()) {
|
||||
Warning(LOCATION, "FoV Command line settings found. VR-Mode will override these with the HMD's native FoV...");
|
||||
}
|
||||
openxr_prepare();
|
||||
if( clip_dist_arg.found() ) {
|
||||
Min_draw_distance = Cmdline_clip_dist = clip_dist_arg.get_float();
|
||||
}
|
||||
|
||||
if (orb_radar.found())
|
||||
@@ -1891,7 +1823,7 @@ bool SetCmdlineParams()
|
||||
}
|
||||
|
||||
if ( use_warp_flash.found() ) {
|
||||
Fireball_warp_flash = true;
|
||||
Cmdline_warp_flash = 1;
|
||||
}
|
||||
|
||||
if ( allow_autpilot_interrupt.found() ) {
|
||||
@@ -1910,24 +1842,21 @@ bool SetCmdlineParams()
|
||||
Cmdline_stretch_menu = 1;
|
||||
}
|
||||
|
||||
if ( capture_mouse.found() ) {
|
||||
Cmdline_capture_mouse = true;
|
||||
}
|
||||
// new lighting lines
|
||||
if ( ambient_power_arg.found() )
|
||||
Cmdline_ambient_power = ambient_power_arg.get_float();
|
||||
|
||||
if (emissive_power_arg.found() && emissive_power_arg.has_param()) {
|
||||
Cmdline_emissive_power = emissive_power_arg.get_float();
|
||||
} else if (emissive_arg.found() || emissive_power_arg.found()) {
|
||||
// for legacy support no argument param defaults to the old emissive value
|
||||
Cmdline_emissive_power = 0.30f;
|
||||
// specular comand lines
|
||||
if ( spec_point_arg.found() ) {
|
||||
static_point_factor = spec_point_arg.get_float();
|
||||
}
|
||||
|
||||
if (light_power_arg.found())
|
||||
Cmdline_light_power = light_power_arg.get_float();
|
||||
if ( spec_static_arg.found() ) {
|
||||
static_light_factor = spec_static_arg.get_float();
|
||||
}
|
||||
|
||||
if (spec_arg.found()) {
|
||||
if ( spec_tube_arg.found() ) {
|
||||
static_tube_factor = spec_tube_arg.get_float();
|
||||
}
|
||||
|
||||
if ( spec_arg.found() )
|
||||
{
|
||||
Cmdline_spec = 0;
|
||||
}
|
||||
|
||||
@@ -1936,10 +1865,6 @@ bool SetCmdlineParams()
|
||||
Cmdline_no_set_gamma = 1;
|
||||
}
|
||||
|
||||
if (no_ingame_options_arg.found()) {
|
||||
Cmdline_no_ingame_options = true;
|
||||
}
|
||||
|
||||
if(no_vsync_arg.found() )
|
||||
{
|
||||
Gr_enable_vsync = false;
|
||||
@@ -1983,31 +1908,25 @@ bool SetCmdlineParams()
|
||||
}
|
||||
}
|
||||
|
||||
if (msaa_enabled_arg.found()) {
|
||||
Cmdline_msaa_enabled = msaa_enabled_arg.get_int();
|
||||
switch (Cmdline_msaa_enabled) {
|
||||
case 0:
|
||||
case 4:
|
||||
case 8:
|
||||
case 16:
|
||||
break;
|
||||
default:
|
||||
Warning(LOCATION, "Requested illegal MSAA sample count %d. Allowed are: 0, 4, 8, 16. Setting to 0.", Cmdline_msaa_enabled);
|
||||
Cmdline_msaa_enabled = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( glow_arg.found() )
|
||||
Cmdline_glow = 0;
|
||||
|
||||
if ( ship_choice_3d_arg.found() )
|
||||
Cmdline_ship_choice_3d = 1;
|
||||
|
||||
if ( weapon_choice_3d_arg.found() )
|
||||
Cmdline_weapon_choice_3d = 1;
|
||||
|
||||
if (ingamejoin_arg.found() )
|
||||
Cmdline_ingamejoin = 0;
|
||||
Cmdline_ingamejoin = 1;
|
||||
|
||||
if ( start_mission_arg.found() ) {
|
||||
Cmdline_start_mission = start_mission_arg.str();
|
||||
}
|
||||
|
||||
if ( ambient_factor_arg.found() )
|
||||
Cmdline_ambient_factor = ambient_factor_arg.get_int();
|
||||
|
||||
if ( output_scripting_arg.found() )
|
||||
Output_scripting_meta = true;
|
||||
|
||||
@@ -2065,15 +1984,6 @@ bool SetCmdlineParams()
|
||||
{
|
||||
Cmdline_portable_mode = true;
|
||||
}
|
||||
|
||||
if (lang_arg.found())
|
||||
{
|
||||
Cmdline_lang = lang_arg.str();
|
||||
}
|
||||
|
||||
if (no_bsp_align_arg.found()) {
|
||||
Cmdline_no_bsp_align = true;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
if (fix_registry.found()) {
|
||||
@@ -2099,6 +2009,10 @@ bool SetCmdlineParams()
|
||||
Cmdline_no_fbo = 1;
|
||||
}
|
||||
|
||||
if ( emissive_arg.found() ) {
|
||||
Cmdline_emissive = 1;
|
||||
}
|
||||
|
||||
if ( rearm_timer_arg.found() )
|
||||
Cmdline_rearm_timer = 1;
|
||||
|
||||
@@ -2158,17 +2072,11 @@ bool SetCmdlineParams()
|
||||
|
||||
if( enable_shadows_arg.found() )
|
||||
{
|
||||
// if only using `enable_shadows` then default quality level can be overriden in mod_settings.tbl --wookieejedi
|
||||
Shadow_quality_uses_mod_option = true;
|
||||
|
||||
Shadow_quality = ShadowQuality::Medium;
|
||||
}
|
||||
|
||||
if( shadow_quality_arg.found() )
|
||||
{
|
||||
// set that we are not using default shadow quality level --wookieejedi
|
||||
Shadow_quality_uses_mod_option = false;
|
||||
|
||||
switch (shadow_quality_arg.get_int()) {
|
||||
case 0:
|
||||
Shadow_quality = ShadowQuality::Disabled;
|
||||
@@ -2197,11 +2105,6 @@ bool SetCmdlineParams()
|
||||
Cmdline_no_deferred_lighting = 1;
|
||||
}
|
||||
|
||||
if( deferred_lighting_cockpit_arg.found() )
|
||||
{
|
||||
Cmdline_deferred_lighting_cockpit = true;
|
||||
}
|
||||
|
||||
if (anisotropy_level_arg.found())
|
||||
{
|
||||
Cmdline_aniso_level = anisotropy_level_arg.get_int();
|
||||
@@ -2257,27 +2160,12 @@ bool SetCmdlineParams()
|
||||
if (slow_frames_ok_arg.found()) {
|
||||
Cmdline_slow_frames_ok = true;
|
||||
}
|
||||
if ( luadev_arg.found()) {
|
||||
Cmdline_lua_devmode = true;
|
||||
}
|
||||
|
||||
if ( override_arg.found()) {
|
||||
Cmdline_override_data = true;
|
||||
}
|
||||
|
||||
if (imgui_debug_arg.found()) {
|
||||
Cmdline_show_imgui_debug = true;
|
||||
}
|
||||
|
||||
if (show_video_info.found())
|
||||
{
|
||||
Cmdline_show_video_info = true;
|
||||
}
|
||||
|
||||
if (vulkan.found()) {
|
||||
Cmdline_vulkan = true;
|
||||
}
|
||||
|
||||
//Deprecated flags - CommanderDJ
|
||||
if (deprecated_no_emissive_arg.found()) {
|
||||
Cmdline_emissive = 0;
|
||||
@@ -2342,16 +2230,6 @@ bool SetCmdlineParams()
|
||||
Cmdline_dump_packet_type = true;
|
||||
}
|
||||
|
||||
if (fixed_seed_rand.found()) {
|
||||
Cmdline_rng_seed = abs(fixed_seed_rand.get_int());
|
||||
if (Cmdline_rng_seed>0) {
|
||||
Cmdline_reuse_rng_seed = true;
|
||||
}
|
||||
else {
|
||||
Warning(LOCATION,"-seed must be an integer greater than 0. Invalid input seed will be disregarded.");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+8
-16
@@ -6,13 +6,12 @@
|
||||
* source.
|
||||
*
|
||||
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FS_CMDLINE_HEADER_FILE
|
||||
#define FS_CMDLINE_HEADER_FILE
|
||||
|
||||
#include <tl/optional.hpp>
|
||||
|
||||
int parse_cmdline(int argc, char *argv[]);
|
||||
|
||||
@@ -47,16 +46,17 @@ extern int Cmdline_use_last_pilot;
|
||||
extern int Cmdline_window;
|
||||
extern int Cmdline_fullscreen_window;
|
||||
extern char *Cmdline_res;
|
||||
extern tl::optional<std::pair<uint16_t, uint16_t>>Cmdline_window_res;
|
||||
extern char *Cmdline_center_res;
|
||||
|
||||
|
||||
// FSO OPTIONS -------------------------------------------------
|
||||
|
||||
// Graphics related
|
||||
extern float Cmdline_ambient_power;
|
||||
extern float Cmdline_emissive_power;
|
||||
extern float Cmdline_light_power;
|
||||
extern float Cmdline_clip_dist;
|
||||
extern float static_light_factor;
|
||||
extern float static_point_factor;
|
||||
extern float static_tube_factor;
|
||||
extern int Cmdline_ambient_factor;
|
||||
extern int Cmdline_env;
|
||||
extern int Cmdline_glow;
|
||||
extern int Cmdline_noscalevid; // disables fit-to-window for movies - taylor
|
||||
@@ -68,10 +68,8 @@ extern int Cmdline_softparticles;
|
||||
extern int Cmdline_bloom_intensity;
|
||||
extern bool Cmdline_force_lightshaft_off;
|
||||
extern int Cmdline_no_deferred_lighting;
|
||||
extern bool Cmdline_deferred_lighting_cockpit;
|
||||
extern int Cmdline_emissive;
|
||||
extern int Cmdline_aniso_level;
|
||||
extern int Cmdline_msaa_enabled;
|
||||
|
||||
// Game Speed related
|
||||
extern int Cmdline_NoFPSCap;
|
||||
@@ -82,16 +80,16 @@ extern int Cmdline_ballistic_gauge;
|
||||
extern int Cmdline_dualscanlines;
|
||||
extern int Cmdline_orb_radar;
|
||||
extern int Cmdline_rearm_timer;
|
||||
extern int Cmdline_targetinfo;
|
||||
|
||||
// Gameplay related
|
||||
extern int Cmdline_ship_choice_3d;
|
||||
extern int Cmdline_weapon_choice_3d;
|
||||
extern int Cmdline_warp_flash;
|
||||
extern int Cmdline_autopilot_interruptable;
|
||||
extern int Cmdline_stretch_menu;
|
||||
extern bool Cmdline_capture_mouse;
|
||||
extern int Cmdline_no_screenshake;
|
||||
extern int Cmdline_deadzone;
|
||||
extern bool Cmdline_enable_vr;
|
||||
|
||||
// Audio related
|
||||
extern int Cmdline_voice_recognition;
|
||||
@@ -108,13 +106,11 @@ extern char *Cmdline_gateway_ip;
|
||||
|
||||
// Launcher related options
|
||||
extern bool Cmdline_portable_mode;
|
||||
extern SCP_string Cmdline_lang;
|
||||
|
||||
// Troubleshooting
|
||||
extern int Cmdline_load_all_weapons;
|
||||
extern int Cmdline_nomovies; // WMC Toggles movie playing support
|
||||
extern int Cmdline_no_set_gamma;
|
||||
extern bool Cmdline_no_ingame_options;
|
||||
extern int Cmdline_no_fbo;
|
||||
extern int Cmdline_no_pbo;
|
||||
extern int Cmdline_mipmap;
|
||||
@@ -159,10 +155,6 @@ extern bool Cmdline_debug_window;
|
||||
extern bool Cmdline_graphics_debug_output;
|
||||
extern bool Cmdline_log_to_stdout;
|
||||
extern bool Cmdline_slow_frames_ok;
|
||||
extern bool Cmdline_lua_devmode;
|
||||
extern bool Cmdline_override_data;
|
||||
extern bool Cmdline_show_imgui_debug;
|
||||
extern bool Cmdline_vulkan;
|
||||
|
||||
enum class WeaponSpewType { NONE = 0, STANDARD, ALL };
|
||||
extern WeaponSpewType Cmdline_spew_weapon_stats;
|
||||
|
||||
@@ -51,14 +51,6 @@ void cmeasure_set_ship_launch_vel(object *objp, object *parent_objp, int arand)
|
||||
|
||||
objp->phys_info.max_vel.xyz.z = -25.0f;
|
||||
vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, objp->phys_info.max_vel.xyz.z );
|
||||
|
||||
// if this cmeasure has a single segment trail, let the trail know since we just changed the velocity
|
||||
// yeah this is hacky but that's what this function gets for CHANGING the velocity on objects with a ""CONSTANT VELOCITY""
|
||||
weapon* wp = &Weapons[objp->instance];
|
||||
if (wp->trail_ptr && wp->trail_ptr->single_segment) {
|
||||
wp->trail_ptr->vel[0] = objp->phys_info.vel;
|
||||
wp->trail_ptr->vel[1] = objp->phys_info.vel;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -23,7 +23,6 @@
|
||||
#define CCF_HAT 0x04 //!< btn is a hat
|
||||
#define CCF_BALL 0x02 //!< btn is a ball
|
||||
#define CCF_BUTTON 0x01 //!< btn is actually a button
|
||||
#define CCF_NONE 0x00 //!< No flags. Alias is "NONE"
|
||||
|
||||
/*!
|
||||
* These are used to index a corresponding axis value from an array.
|
||||
@@ -295,8 +294,6 @@ enum IoActionId : int {
|
||||
JOY_ABS_THROTTLE_AXIS = 127,
|
||||
JOY_REL_THROTTLE_AXIS = 128,
|
||||
|
||||
TOGGLE_HUD_SHADOWS,
|
||||
|
||||
/*!
|
||||
* This must always be below the last defined item
|
||||
*/
|
||||
@@ -433,26 +430,6 @@ private:
|
||||
short btn = -1; //!< The button, key combo, or axis that's bound.
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct cc_line
|
||||
* @brief Defines an interactable line to display control names and their bindings
|
||||
*/
|
||||
struct cc_line {
|
||||
const char* label;
|
||||
int cc_index; // index into Control_config of item
|
||||
int y; // Y coordinate of line
|
||||
int kx, kw, jx, jw; // x start and width of keyboard and joystick bound text
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct conflict
|
||||
* @brief Defines an conflict between bindings
|
||||
*/
|
||||
struct conflict {
|
||||
int first = -1; // index of other control in conflict with this one
|
||||
int second = -1; // index of other control in conflict with this one
|
||||
};
|
||||
|
||||
/*!
|
||||
* A pair of bindings.
|
||||
* @note Please don't set the bindings directly, use ::take() instead.
|
||||
@@ -588,9 +565,7 @@ public:
|
||||
CC_type type; //!< manner control should be checked in
|
||||
|
||||
// Items used during gameplay
|
||||
TIMESTAMP digital_used; //!< has control been used yet in mission? If so, this is the timestamp.
|
||||
// Note this is not a UI timestamp because this is purely for mission timing purposes.
|
||||
int analog_value; // For axes, this denotes the last frame's value
|
||||
int used; //!< has control been used yet in mission? If so, this is the timestamp. For axes, this denotes the last frame's value
|
||||
bool disabled = true; //!< whether this action should be available at all
|
||||
bool locked = false; //!< whether this action will be triggered by the respectively bound key
|
||||
bool scriptEnabledByDefault = false; //!< whether this binding will execute it's registered hooks if triggered. Resets each mission
|
||||
@@ -661,15 +636,6 @@ private:
|
||||
SCP_vector<CCI>& ControlConfig;
|
||||
};
|
||||
|
||||
enum class selItem : int {
|
||||
selItem_REND, // Must be first to allow cycling
|
||||
|
||||
None,
|
||||
Primary,
|
||||
Secondary,
|
||||
|
||||
selItem_END // Must be last to allow cycling
|
||||
};
|
||||
|
||||
extern int Failed_key_index;
|
||||
|
||||
@@ -678,9 +644,6 @@ extern int Joy_sensitivity;
|
||||
|
||||
extern int Control_config_overlay_id;
|
||||
|
||||
extern SCP_vector<cc_line> Cc_lines; //!< Stores the keyboard details for the UI
|
||||
extern SCP_vector<conflict> Conflicts; //!< Stores conflict data for the keybinds
|
||||
|
||||
extern SCP_vector<CCI> Control_config; //!< Stores the keyboard configuration
|
||||
extern SCP_vector<CC_preset> Control_config_presets; // tabled control presets; pointers to config_item arrays
|
||||
extern const char **Joy_button_text; // String table of button labels. XSTR'd on init.
|
||||
@@ -721,7 +684,7 @@ void control_config_common_close();
|
||||
/*!
|
||||
* @brief init config menu
|
||||
*/
|
||||
void control_config_init(bool API_Access = false);
|
||||
void control_config_init();
|
||||
|
||||
/*!
|
||||
* @brief do a frame of the config menu
|
||||
@@ -731,73 +694,12 @@ void control_config_do_frame(float frametime);
|
||||
/*!
|
||||
* @brief close config menu
|
||||
*/
|
||||
void control_config_close(bool API_Access = false);
|
||||
|
||||
/*!
|
||||
* @brief setup for binding a control
|
||||
*/
|
||||
void control_config_do_bind(bool API_Access = false);
|
||||
|
||||
/*!
|
||||
* @brief setup for searching a control
|
||||
*/
|
||||
void control_config_do_search(bool API_Access = false);
|
||||
|
||||
/**
|
||||
* @brief Unbinds the selected control
|
||||
*/
|
||||
bool control_config_remove_binding(int ctrl, selItem item, bool API_Access = false);
|
||||
|
||||
/**
|
||||
* @brief Clears all conflicting control bindings, except the selected control
|
||||
*/
|
||||
bool control_config_clear_other(int ctrl, bool API_Access = false);
|
||||
|
||||
/**
|
||||
* @brief Unbinds ALL controls
|
||||
* TODO: unbind axes and reset inversion
|
||||
*/
|
||||
bool control_config_clear_all(bool API_Access = false);
|
||||
|
||||
/**
|
||||
* @brief Reverts all bindings to their preset. If already default, cycle to the next presets.
|
||||
*/
|
||||
bool control_config_do_reset(bool cycle = true, bool API_Access = false);
|
||||
|
||||
/**
|
||||
* @brief Toggles a modifier on or off for a control binding
|
||||
*/
|
||||
bool control_config_toggle_modifier(int bit, int ctrl, bool API_Access = false);
|
||||
|
||||
/**
|
||||
* @brief Toggles inversion for the selected axis control
|
||||
*/
|
||||
bool control_config_toggle_invert(int ctrl, selItem item, bool API_Access = false);
|
||||
|
||||
/*!
|
||||
* @brief Performs a single undo opration, reverting the most recent change to bindings, if any
|
||||
*/
|
||||
void control_config_do_undo(bool API_Access = false);
|
||||
|
||||
/*!
|
||||
*@brief Runs every frame to check for input and binds the input if appropriate
|
||||
*/
|
||||
int control_config_bind_key_on_frame(int ctrl, selItem item, bool API_Access = false);
|
||||
|
||||
/*!
|
||||
*@brief Runs every frame to check for input. Returns the index of the item the key is bound to or -1 if nothing.
|
||||
*/
|
||||
int control_config_search_key_on_frame(bool API_Access = false);
|
||||
|
||||
/*!
|
||||
* Does a cursory conflict check, then accepts changes to the bindings, if any, and request the menu to close.
|
||||
*/
|
||||
bool control_config_accept(bool API_Access = false);
|
||||
void control_config_close();
|
||||
|
||||
/*!
|
||||
* @brief Cancel configuration of controls, revert any changes, return to previous menu/game state
|
||||
*/
|
||||
void control_config_cancel_exit(bool API_Access = false);
|
||||
void control_config_cancel_exit();
|
||||
|
||||
/*!
|
||||
* @brief Copies all bindings within preset into Control_config
|
||||
@@ -828,30 +730,6 @@ bool control_config_use_preset_by_name(const SCP_string &name);
|
||||
|
||||
SCP_vector<CC_preset>::iterator control_config_get_current_preset(bool invert_agnostic = false);
|
||||
|
||||
/*!
|
||||
* @brief Deletes the preset
|
||||
*
|
||||
* @returns TRUE if successful
|
||||
* @returns FALSE if the preset is default or currently selected
|
||||
*/
|
||||
bool control_config_delete_preset(CC_preset preset);
|
||||
|
||||
/*!
|
||||
* @brief Clones a preset
|
||||
*
|
||||
* @returns TRUE if successful
|
||||
* @returns FALSE if the preset already exists with that name
|
||||
*/
|
||||
bool control_config_clone_preset(CC_preset preset, SCP_string name);
|
||||
|
||||
/*!
|
||||
* @brief Saves a preset with the current controls
|
||||
*
|
||||
* @returns TRUE if successful
|
||||
* @returns FALSE if the preset already exists with that name
|
||||
*/
|
||||
bool control_config_create_new_preset(SCP_string name);
|
||||
|
||||
/*!
|
||||
* Returns the IoActionId (index within Control_config[]) of a control bound to the given key
|
||||
*
|
||||
|
||||
@@ -45,29 +45,27 @@ int Failed_key_index;
|
||||
// Joystick configuration
|
||||
int Joy_dead_zone_size = 10;
|
||||
|
||||
auto DeadZoneOption = options::OptionBuilder<int>("Input.JoystickDeadZone",
|
||||
std::pair<const char*, int>{"Deadzone", 1377},
|
||||
std::pair<const char*, int>{"The deadzone used for all joysticks", 1744})
|
||||
.category("Input")
|
||||
.range(0, 45)
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(10)
|
||||
.bind_to(&Joy_dead_zone_size)
|
||||
.importance(1)
|
||||
.finish();
|
||||
auto DeadZoneOption =
|
||||
options::OptionBuilder<int>("Input.JoystickDeadZone", "Deadzone", "The deadzone of the selected joystick.")
|
||||
.category("Input")
|
||||
.range(0, 45)
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(10)
|
||||
.bind_to(&Joy_dead_zone_size)
|
||||
.importance(1)
|
||||
.finish();
|
||||
|
||||
int Joy_sensitivity = 9;
|
||||
|
||||
auto SensitivityOption = options::OptionBuilder<int>("Input.JoystickSensitivity",
|
||||
std::pair<const char*, int>{"Sensitivity", 1745},
|
||||
std::pair<const char*, int>{"The sensitivity used for all joysticks", 1746})
|
||||
.category("Input")
|
||||
.range(0, 9)
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(9)
|
||||
.bind_to(&Joy_sensitivity)
|
||||
.importance(2)
|
||||
.finish();
|
||||
auto SensitivityOption =
|
||||
options::OptionBuilder<int>("Input.JoystickSensitivity", "Sensitivity", "The sentitivity of the selected joystick.")
|
||||
.category("Input")
|
||||
.range(0, 9)
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(9)
|
||||
.bind_to(&Joy_sensitivity)
|
||||
.importance(2)
|
||||
.finish();
|
||||
|
||||
//! arrays which hold the key mappings. The array index represents a key-independent action.
|
||||
//! please use SPACES for aligning the fields of this array
|
||||
@@ -160,8 +158,8 @@ void control_config_common_init_bindings() {
|
||||
// flight controls (flight modes)
|
||||
(BANK_WHEN_PRESSED, -1, -1, SHIP_TAB, 1, "Bank When Pressed", CC_TYPE_CONTINUOUS)
|
||||
(AFTERBURNER, KEY_TAB, 5, SHIP_TAB, 1, "Afterburner", CC_TYPE_CONTINUOUS)
|
||||
(GLIDE_WHEN_PRESSED, -1, -1, SHIP_TAB, 1774, "Glide When Pressed", CC_TYPE_CONTINUOUS)
|
||||
(TOGGLE_GLIDING, KEY_ALTED | KEY_G, -1, SHIP_TAB, 1775, "Toggle Gliding", CC_TYPE_TRIGGER)
|
||||
(GLIDE_WHEN_PRESSED, -1, -1, SHIP_TAB, 0, "Glide When Pressed", CC_TYPE_CONTINUOUS)
|
||||
(TOGGLE_GLIDING, KEY_ALTED | KEY_G, -1, SHIP_TAB, 0, "Toggle Gliding", CC_TYPE_TRIGGER)
|
||||
|
||||
// flight controls (axes)
|
||||
(JOY_HEADING_AXIS, JOY_X_AXIS, MOUSE_X_AXIS, SHIP_TAB, 1016, "Turn (Yaw) Axis", CC_TYPE_AXIS_REL)
|
||||
@@ -175,7 +173,7 @@ void control_config_common_init_bindings() {
|
||||
(FIRE_SECONDARY, KEY_SPACEBAR, 1, WEAPON_TAB, 1, "Fire Secondary Weapon", CC_TYPE_CONTINUOUS)
|
||||
(CYCLE_NEXT_PRIMARY, KEY_PERIOD, -1, WEAPON_TAB, 1, "Cycle Primary Weapon Forward", CC_TYPE_TRIGGER)
|
||||
(CYCLE_PREV_PRIMARY, KEY_COMMA, -1, WEAPON_TAB, 1, "Cycle Primary Weapon Backward", CC_TYPE_TRIGGER)
|
||||
(CYCLE_PRIMARY_WEAPON_SEQUENCE, KEY_O, -1, WEAPON_TAB, 1776, "Cycle Primary Weapon Firing Rate", CC_TYPE_TRIGGER)
|
||||
(CYCLE_PRIMARY_WEAPON_SEQUENCE, KEY_O, -1, WEAPON_TAB, 0, "Cycle Primary Weapon Firing Rate", CC_TYPE_TRIGGER)
|
||||
(CYCLE_SECONDARY, KEY_DIVIDE, -1, WEAPON_TAB, 1, "Cycle Secondary Weapon Forward", CC_TYPE_TRIGGER)
|
||||
(CYCLE_NUM_MISSLES, KEY_SHIFTED | KEY_DIVIDE, -1, WEAPON_TAB, 1, "Cycle Secondary Weapon Firing Rate", CC_TYPE_TRIGGER)
|
||||
(LAUNCH_COUNTERMEASURE, KEY_X, 3, WEAPON_TAB, 1, "Launch Countermeasure", CC_TYPE_TRIGGER)
|
||||
@@ -211,8 +209,8 @@ void control_config_common_init_bindings() {
|
||||
(PADLOCK_DOWN, -1, 32, COMPUTER_TAB, 1, "View Rear", CC_TYPE_CONTINUOUS)
|
||||
(PADLOCK_LEFT, -1, 34, COMPUTER_TAB, 1, "View Left", CC_TYPE_CONTINUOUS)
|
||||
(PADLOCK_RIGHT, -1, 35, COMPUTER_TAB, 1, "View Right", CC_TYPE_CONTINUOUS)
|
||||
(VIEW_TOPDOWN, -1, -1, COMPUTER_TAB, 1777, "Top-Down View", CC_TYPE_TRIGGER)
|
||||
(VIEW_TRACK_TARGET, -1, -1, COMPUTER_TAB, 1778, "Target Padlock View", CC_TYPE_TRIGGER)
|
||||
(VIEW_TOPDOWN, -1, -1, COMPUTER_TAB, 0, "Top-Down View", CC_TYPE_TRIGGER)
|
||||
(VIEW_TRACK_TARGET, -1, -1, COMPUTER_TAB, 0, "Target Padlock View", CC_TYPE_TRIGGER)
|
||||
|
||||
(RADAR_RANGE_CYCLE, KEY_RAPOSTRO, -1, COMPUTER_TAB, 1, "Cycle Radar Range", CC_TYPE_TRIGGER)
|
||||
(SQUADMSG_MENU, KEY_C, -1, COMPUTER_TAB, 1, "Communications Menu", CC_TYPE_TRIGGER)
|
||||
@@ -237,8 +235,8 @@ void control_config_common_init_bindings() {
|
||||
|
||||
// Navigation and Autopilot
|
||||
(SHOW_NAVMAP, -1, -1, NO_TAB, 1, "Show Nav Map", CC_TYPE_TRIGGER, true)
|
||||
(AUTO_PILOT_TOGGLE, KEY_ALTED | KEY_A, -1, COMPUTER_TAB, 1779, "Toggle Auto Pilot", CC_TYPE_TRIGGER)
|
||||
(NAV_CYCLE, KEY_ALTED | KEY_N, -1, COMPUTER_TAB, 1780, "Cycle Nav Points", CC_TYPE_TRIGGER)
|
||||
(AUTO_PILOT_TOGGLE, KEY_ALTED | KEY_A, -1, COMPUTER_TAB, 0, "Toggle Auto Pilot", CC_TYPE_TRIGGER)
|
||||
(NAV_CYCLE, KEY_ALTED | KEY_N, -1, COMPUTER_TAB, 0, "Cycle Nav Points", CC_TYPE_TRIGGER)
|
||||
|
||||
// Escort
|
||||
(ADD_REMOVE_ESCORT, KEY_ALTED | KEY_E, -1, COMPUTER_TAB, 1, "Add or Remove Escort", CC_TYPE_TRIGGER)
|
||||
@@ -260,15 +258,14 @@ void control_config_common_init_bindings() {
|
||||
// HUD
|
||||
(TOGGLE_HUD, KEY_SHIFTED | KEY_O, -1, COMPUTER_TAB, 1, "Toggle HUD", CC_TYPE_TRIGGER)
|
||||
(TOGGLE_HUD_CONTRAST, KEY_L, -1, COMPUTER_TAB, 1, "Toggle High HUD Contrast", CC_TYPE_TRIGGER)
|
||||
(TOGGLE_HUD_SHADOWS, KEY_ALTED | KEY_L, -1, COMPUTER_TAB, 1781, "Toggle HUD Drop Shadows", CC_TYPE_TRIGGER)
|
||||
(HUD_TARGETBOX_TOGGLE_WIREFRAME, KEY_ALTED | KEY_SHIFTED | KEY_Q, -1, COMPUTER_TAB, 1, "Toggle HUD Wireframe Target View", CC_TYPE_TRIGGER)
|
||||
|
||||
// Custom Controls
|
||||
(CUSTOM_CONTROL_1, KEY_ALTED | KEY_SHIFTED | KEY_1, -1, COMPUTER_TAB, 1784, "Custom Control 1", CC_TYPE_TRIGGER, true)
|
||||
(CUSTOM_CONTROL_2, KEY_ALTED | KEY_SHIFTED | KEY_2, -1, COMPUTER_TAB, 1785, "Custom Control 2", CC_TYPE_TRIGGER, true)
|
||||
(CUSTOM_CONTROL_3, KEY_ALTED | KEY_SHIFTED | KEY_3, -1, COMPUTER_TAB, 1786, "Custom Control 3", CC_TYPE_TRIGGER, true)
|
||||
(CUSTOM_CONTROL_4, KEY_ALTED | KEY_SHIFTED | KEY_4, -1, COMPUTER_TAB, 1787, "Custom Control 4", CC_TYPE_TRIGGER, true)
|
||||
(CUSTOM_CONTROL_5, KEY_ALTED | KEY_SHIFTED | KEY_5, -1, COMPUTER_TAB, 1788, "Custom Control 5", CC_TYPE_TRIGGER, true)
|
||||
(CUSTOM_CONTROL_1, KEY_ALTED | KEY_SHIFTED | KEY_1, -1, COMPUTER_TAB, 0, "Custom Control 1", CC_TYPE_TRIGGER, true)
|
||||
(CUSTOM_CONTROL_2, KEY_ALTED | KEY_SHIFTED | KEY_2, -1, COMPUTER_TAB, 0, "Custom Control 2", CC_TYPE_TRIGGER, true)
|
||||
(CUSTOM_CONTROL_3, KEY_ALTED | KEY_SHIFTED | KEY_3, -1, COMPUTER_TAB, 0, "Custom Control 3", CC_TYPE_TRIGGER, true)
|
||||
(CUSTOM_CONTROL_4, KEY_ALTED | KEY_SHIFTED | KEY_4, -1, COMPUTER_TAB, 0, "Custom Control 4", CC_TYPE_TRIGGER, true)
|
||||
(CUSTOM_CONTROL_5, KEY_ALTED | KEY_SHIFTED | KEY_5, -1, COMPUTER_TAB, 0, "Custom Control 5", CC_TYPE_TRIGGER, true)
|
||||
.end(); // Builder
|
||||
|
||||
// init default preset
|
||||
@@ -412,7 +409,6 @@ SCP_unordered_map<SCP_string, IoActionId> old_text = {
|
||||
{"Increase Time Compression", TIME_SPEED_UP},
|
||||
{"Decrease Time Compression", TIME_SLOW_DOWN},
|
||||
{"Toggle High HUD Contrast", TOGGLE_HUD_CONTRAST},
|
||||
{"Toggle HUD Drop Shadows", TOGGLE_HUD_SHADOWS},
|
||||
{"(Multiplayer) Toggle Network Info", MULTI_TOGGLE_NETINFO},
|
||||
{"(Multiplayer) Self Destruct", MULTI_SELF_DESTRUCT},
|
||||
|
||||
@@ -451,7 +447,7 @@ const char* Joy_button_text_french_u[] = {
|
||||
"Bouton 13", "Bouton 14", "Bouton 15", "Bouton 16", "Bouton 17", "Bouton 18",
|
||||
"Bouton 19", "Bouton 20", "Bouton 21", "Bouton 22", "Bouton 23", "Bouton 24",
|
||||
"Bouton 25", "Bouton 26", "Bouton 27", "Bouton 28", "Bouton 29", "Bouton 30",
|
||||
"Bouton 31", "Bouton 32", ("Chapeau Arri\xc3\xa8""re"), "Chapeau Avant", "Chapeau Gauche", "Chapeau Droite"
|
||||
"Bouton 31", "Bouton 32", "Chapeau Arri\xc3\xa8""re", "Chapeau Avant", "Chapeau Gauche", "Chapeau Droite"
|
||||
};
|
||||
|
||||
const char* Joy_button_text_polish_u[] = {
|
||||
@@ -460,7 +456,7 @@ const char* Joy_button_text_polish_u[] = {
|
||||
"Przyc.13", "Przyc.14", "Przyc.15", "Przyc.16", "Przyc.17", "Przyc.18",
|
||||
"Przyc.19", "Przyc.20", "Przyc.21", "Przyc.22", "Przyc.23", "Przyc.24",
|
||||
"Przyc.25", "Przyc.26", "Przyc.27", "Przyc.28", "Przyc.29", "Przyc.30",
|
||||
"Przyc.31", "Przyc.32", "Hat Ty\xc5\x82", ("Hat Prz\xc3\xb3""d"), "Hat Lewo", "Hat Prawo"
|
||||
"Przyc.31", "Przyc.32", "Hat Ty\xc5\x82", "Hat Prz\xc3\xb3""d", "Hat Lewo", "Hat Prawo"
|
||||
};
|
||||
|
||||
const char* Joy_button_text_english_u[] = {
|
||||
@@ -645,9 +641,7 @@ const char *translate_key(char *key)
|
||||
|
||||
if (!first.empty() && !second.empty()) {
|
||||
strcpy_s(text, first.textify().c_str());
|
||||
strcat_s(text, " ");
|
||||
strcat_s(text, XSTR("or", 1672));
|
||||
strcat_s(text, " ");
|
||||
strcat_s(text, " or ");
|
||||
strcat_s(text, second.textify().c_str());
|
||||
|
||||
} else if (!first.empty()) {
|
||||
@@ -657,7 +651,7 @@ const char *translate_key(char *key)
|
||||
strcpy_s(text, second.textify().c_str());
|
||||
|
||||
} else {
|
||||
strcpy_s(text, XSTR("None", 1673));
|
||||
strcpy_s(text, "None");
|
||||
}
|
||||
|
||||
return text;
|
||||
@@ -668,7 +662,7 @@ const char *textify_scancode(int code)
|
||||
static char text[BTN_MSG_LEN];
|
||||
|
||||
if (code < 0)
|
||||
return XSTR("None", 1673);
|
||||
return "None";
|
||||
|
||||
int keycode = code & KEY_MASK;
|
||||
|
||||
@@ -742,8 +736,7 @@ void control_config_common_init()
|
||||
}
|
||||
|
||||
for (int i = 0; i < Action::NUM_VALUES; i++) {
|
||||
Control_config[i + JOY_AXIS_BEGIN].analog_value = JOY_AXIS_CENTER;
|
||||
Control_config[i + JOY_AXIS_BEGIN].digital_used = TIMESTAMP::invalid();
|
||||
Control_config[i + JOY_AXIS_BEGIN].used = JOY_AXIS_CENTER;
|
||||
}
|
||||
|
||||
// TODO It's not memory efficient to keep the presets loaded into memory all the time, but we do need to know which
|
||||
@@ -801,8 +794,6 @@ void control_config_common_init()
|
||||
Mouse_button_text[6] = vm_strdup(XSTR("Wheel Down", 1656));
|
||||
Mouse_button_text[7] = vm_strdup(XSTR("Wheel Left", 1657));
|
||||
Mouse_button_text[8] = vm_strdup(XSTR("Wheel Right", 1658));
|
||||
|
||||
Script_system.OnStateDestroy.add([](lua_State*) -> void { Lua_hooks.clear(); });
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1131,7 +1122,6 @@ void LoadEnumsIntoActionMap() {
|
||||
ADD_ENUM_TO_ACTION_MAP(TIME_SLOW_DOWN)
|
||||
|
||||
ADD_ENUM_TO_ACTION_MAP(TOGGLE_HUD_CONTRAST)
|
||||
ADD_ENUM_TO_ACTION_MAP(TOGGLE_HUD_SHADOWS)
|
||||
|
||||
ADD_ENUM_TO_ACTION_MAP(MULTI_TOGGLE_NETINFO)
|
||||
|
||||
@@ -1406,8 +1396,7 @@ void control_enable_hook(IoActionId id, bool enable) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Stuffs the CCF flags into the given char. Needs item_id for validation.
|
||||
* @details Unknown, unrecognized, or excessive flags are silently ignored on Release builds. Debug builds complain.
|
||||
* Stuffs the CCF flags into the given char. Needs item_id for validation
|
||||
*/
|
||||
void stuff_CCF(char& flags, size_t item_id) {
|
||||
Assert(item_id < Control_config.size());
|
||||
@@ -1421,9 +1410,7 @@ void stuff_CCF(char& flags, size_t item_id) {
|
||||
SCP_string flag_str;
|
||||
size_t pos = 0;
|
||||
size_t len = 0;
|
||||
|
||||
// Lambda to add flags.
|
||||
// Debug version Eats the substring as it is found.
|
||||
|
||||
auto ADD_FLAG = [&](char id) {
|
||||
flag_str = ValToCCF(id);
|
||||
pos = szTempBuffer.find(flag_str);
|
||||
@@ -1434,8 +1421,6 @@ void stuff_CCF(char& flags, size_t item_id) {
|
||||
}
|
||||
};
|
||||
#else
|
||||
// Lambda to add flags.
|
||||
// Release version doesn't modify szTempBuffer as it searches for substrings.
|
||||
auto ADD_FLAG = [&](char id) {
|
||||
if (szTempBuffer.find(ValToCCF(id)) != SCP_string::npos)
|
||||
flags |= id;
|
||||
@@ -1449,38 +1434,13 @@ void stuff_CCF(char& flags, size_t item_id) {
|
||||
ADD_FLAG(CCF_HAT);
|
||||
ADD_FLAG(CCF_BALL);
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Eat the "CCF_NONE" and "NONE" substrings
|
||||
auto EAT_FLAG = [&](SCP_string str) {
|
||||
pos = szTempBuffer.find(str);
|
||||
len = str.length();
|
||||
if (pos != SCP_string::npos) {
|
||||
if (flags != 0) {
|
||||
// Complain about bad habits
|
||||
error_display(0,
|
||||
"Flag 'NONE' passed to config item %i along with other flags, ignoring: \n'%s'",
|
||||
static_cast<int>(item_id),
|
||||
szTempBuffer.c_str()
|
||||
);
|
||||
}
|
||||
szTempBuffer.erase(pos, len);
|
||||
}
|
||||
};
|
||||
|
||||
EAT_FLAG("CCF_NONE");
|
||||
EAT_FLAG("NONE");
|
||||
|
||||
// Complain about any unknown flag strings
|
||||
replace_all(szTempBuffer, ",", " ");
|
||||
drop_white_space(szTempBuffer);
|
||||
|
||||
if (!szTempBuffer.empty()) {
|
||||
error_display(0,
|
||||
"Unknown (or excessive) flags passed to config item %i, ignoring: \n'%s'",
|
||||
static_cast<int>(item_id),
|
||||
szTempBuffer.c_str()
|
||||
);
|
||||
error_display(0, "Unknown flags passed to config item %i, ignoring: \n'%s'", static_cast<int>(item_id), szTempBuffer.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2312,7 +2272,7 @@ SCP_string ValToCCF(char id) {
|
||||
}
|
||||
|
||||
if (str.empty()) {
|
||||
// If unsupported flags, or (id == CCF_NONE), list as "None"
|
||||
// If unsupported flags, or no flags at all, list as "None"
|
||||
str = "NONE";
|
||||
}
|
||||
|
||||
@@ -2796,8 +2756,7 @@ CCI& CCI::operator=(const CCI& A) {
|
||||
indexXSTR = A.indexXSTR;
|
||||
text = A.text;
|
||||
type = A.type;
|
||||
analog_value = A.analog_value;
|
||||
digital_used = A.digital_used;
|
||||
used = A.used;
|
||||
disabled = A.disabled;
|
||||
locked = A.locked;
|
||||
scriptEnabledByDefault = A.scriptEnabledByDefault;
|
||||
|
||||
@@ -35,7 +35,7 @@ Section lookupSectionValue(const char* name) {
|
||||
return Section::Invalid;
|
||||
}
|
||||
|
||||
void load_preset_files(SCP_string clone) {
|
||||
void load_preset_files() {
|
||||
SCP_vector<SCP_string> filelist;
|
||||
cf_get_file_list(filelist, CF_TYPE_PLAYER_BINDS, NOX("*.json"), CF_SORT_NAME, nullptr,
|
||||
CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
|
||||
@@ -128,8 +128,7 @@ void load_preset_files(SCP_string clone) {
|
||||
// Done with the file
|
||||
auto it = preset_find_duplicate(preset);
|
||||
|
||||
// If we just cloned the file, then allow the duplicate. Just this once.
|
||||
if ((clone == preset.name) || (it == Control_config_presets.end())) {
|
||||
if (it == Control_config_presets.end()) {
|
||||
Control_config_presets.push_back(preset);
|
||||
|
||||
} else if ((it->name != preset.name) || (it->type != Preset_t::pst)) {
|
||||
@@ -148,31 +147,6 @@ bool preset_file_exists(SCP_string name) {
|
||||
return cf_exists(name.c_str(), CF_TYPE_PLAYER_BINDS) != 0;
|
||||
}
|
||||
|
||||
bool delete_preset_file(CC_preset preset) {
|
||||
|
||||
// can't remove the default preset!
|
||||
if (preset.name == "default") {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto it = control_config_get_current_preset();
|
||||
|
||||
// can't remove the currently loaded preset either!
|
||||
if (preset.name == it->name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SCP_string filename = preset.name + ".json";
|
||||
|
||||
cf_delete(filename.c_str(), CF_TYPE_PLAYER_BINDS, CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
|
||||
|
||||
// Reload the presets from file.
|
||||
Control_config_presets.resize(1);
|
||||
load_preset_files();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool save_preset_file(CC_preset preset, bool overwrite) {
|
||||
// Must have a name
|
||||
if (preset.name.empty()) {
|
||||
|
||||
@@ -209,24 +209,12 @@ private:
|
||||
*/
|
||||
bool save_preset_file(CC_preset preset, bool overwrite);
|
||||
|
||||
/**
|
||||
* @brief Deletes the given preset to file.
|
||||
* @param[in] preset The preset to delete
|
||||
*
|
||||
* @returns True if successful, or
|
||||
* @returns False Preset is default, or
|
||||
* @returns False Preset file is the currently selected preset
|
||||
*/
|
||||
bool delete_preset_file(CC_preset preset);
|
||||
|
||||
/**
|
||||
* @brief Loads in all preset .json files from 'players/presets'
|
||||
* @details If a preset file is unique, it is loaded into the game and available for use by the player. However, if
|
||||
* a preset is a duplicate of another preset, it is ignored, and the player is warned of it
|
||||
*
|
||||
* @param[in] clone Used to check if we just cloned a particular preset and allows just that clone in without warning
|
||||
*/
|
||||
void load_preset_files(SCP_string clone = "");
|
||||
void load_preset_files();
|
||||
|
||||
/**
|
||||
* @brief Checks if the given preset is a duplicate within Control_config_presets vector
|
||||
|
||||
@@ -52,7 +52,6 @@ struct MovieProperties {
|
||||
FrameSize size;
|
||||
|
||||
float fps = -1.0f;
|
||||
float duration = 0.0f;
|
||||
|
||||
FramePixelFormat pixelFormat = FramePixelFormat::Invalid;
|
||||
};
|
||||
@@ -109,7 +108,7 @@ class Decoder {
|
||||
* @note A implementation should initialize the datastructures required for decoding here.
|
||||
*
|
||||
* @param fileName The name of the file that should be opened
|
||||
* @return @c true if the initialization was successful, @c false otherwise
|
||||
* @return @c true if the initialization was successfull, @c false otherwise
|
||||
*/
|
||||
virtual bool initialize(const SCP_string& fileName, const PlaybackProperties& properties) = 0;
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ void VideoPresenter::uploadVideoFrame(const VideoFramePtr& frame) {
|
||||
}
|
||||
}
|
||||
|
||||
void VideoPresenter::displayFrame(float x1, float y1, float x2, float y2, float alpha) {
|
||||
void VideoPresenter::displayFrame(float x1, float y1, float x2, float y2) {
|
||||
GR_DEBUG_SCOPE("Draw video frame");
|
||||
|
||||
movie_vertex vertex_data[4];
|
||||
@@ -127,26 +127,10 @@ void VideoPresenter::displayFrame(float x1, float y1, float x2, float y2, float
|
||||
layout.add_vertex_component(vertex_format_data::POSITION2, sizeof(vertex_data[0]), offsetof(movie_vertex, pos));
|
||||
layout.add_vertex_component(vertex_format_data::TEX_COORD2, sizeof(vertex_data[0]), offsetof(movie_vertex, uv));
|
||||
|
||||
switch (_properties.pixelFormat) {
|
||||
case FramePixelFormat::YUV420:
|
||||
material_set_movie(&_movie_material,
|
||||
_planeTextureHandles[0],
|
||||
_planeTextureHandles[1],
|
||||
_planeTextureHandles[2],
|
||||
alpha);
|
||||
if (_properties.pixelFormat == FramePixelFormat::YUV420) {
|
||||
gr_render_movie(&_movie_material, PRIM_TYPE_TRISTRIP, &layout, 4, gr_immediate_buffer_handle, offset);
|
||||
break;
|
||||
case FramePixelFormat::BGR:
|
||||
material_set_unlit(&_rgb_material, _planeTextureHandles[0], alpha, false, false);
|
||||
} else {
|
||||
gr_render_primitives(&_rgb_material, PRIM_TYPE_TRISTRIP, &layout, 0, 4, gr_immediate_buffer_handle, offset);
|
||||
break;
|
||||
case FramePixelFormat::BGRA:
|
||||
material_set_unlit(&_rgb_material, _planeTextureHandles[0], alpha, true, false);
|
||||
gr_render_primitives(&_rgb_material, PRIM_TYPE_TRISTRIP, &layout, 0, 4, gr_immediate_buffer_handle, offset);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE("Unhandled enum value!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class VideoPresenter {
|
||||
|
||||
void uploadVideoFrame(const VideoFramePtr& frame);
|
||||
|
||||
void displayFrame(float x1, float y1, float x2, float y2, float alpha = 1.0f);
|
||||
void displayFrame(float x1, float y1, float x2, float y2);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+24
-102
@@ -48,101 +48,38 @@ void cutscene_close()
|
||||
}
|
||||
}
|
||||
|
||||
static cutscene_info *get_cutscene_pointer(char *cutscene_filename)
|
||||
{
|
||||
for (int i = 0; i < (int)Cutscenes.size(); i++) {
|
||||
if (!stricmp(cutscene_filename, Cutscenes[i].filename)) {
|
||||
return &Cutscenes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Didn't find anything.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void cutscene_info_init(cutscene_info *csni)
|
||||
{
|
||||
csni->filename[0] = '\0';
|
||||
csni->name[0] = '\0';
|
||||
csni->description = NULL;
|
||||
csni->flags = {};
|
||||
}
|
||||
|
||||
// initialization stuff for cutscenes
|
||||
void parse_cutscene_table(const char* filename)
|
||||
void cutscene_init()
|
||||
{
|
||||
|
||||
atexit(cutscene_close);
|
||||
char buf[MULTITEXT_LENGTH];
|
||||
cutscene_info csnt;
|
||||
cutscene_info_init(&csnt);
|
||||
|
||||
cutscene_info *csnp;
|
||||
bool create_if_not_found = true;
|
||||
cutscene_info cutinfo;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
|
||||
read_file_text("cutscenes.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// parse in all the cutscenes
|
||||
Cutscenes.clear();
|
||||
skip_to_string("#Cutscenes");
|
||||
ignore_white_space();
|
||||
|
||||
bool isFirstCutscene = true;
|
||||
|
||||
while (required_string_either("#End", "$Filename:"))
|
||||
{
|
||||
bool csn_new = false;
|
||||
|
||||
required_string("$Filename:");
|
||||
stuff_string(csnt.filename, F_PATHNAME, MAX_FILENAME_LEN);
|
||||
stuff_string(cutinfo.filename, F_PATHNAME, MAX_FILENAME_LEN);
|
||||
|
||||
if (optional_string("+nocreate")) {
|
||||
if (!Parsing_modular_table) {
|
||||
Warning(LOCATION, "+nocreate flag used for cutscene in non-modular table\n");
|
||||
}
|
||||
create_if_not_found = false;
|
||||
}
|
||||
required_string("$Name:");
|
||||
stuff_string(cutinfo.name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// Does this cutscene exist already?
|
||||
// If so, load this new info into it
|
||||
csnp = get_cutscene_pointer(csnt.filename);
|
||||
if (csnp != NULL) {
|
||||
if (!Parsing_modular_table) {
|
||||
error_display(1,
|
||||
"Error: Cutscene %s already exists. All cutscene names must be unique.",
|
||||
csnt.filename);
|
||||
}
|
||||
} else {
|
||||
// Don't create cutscene if it has +nocreate and is in a modular table.
|
||||
if (!create_if_not_found && Parsing_modular_table) {
|
||||
if (!skip_to_start_of_string_either("$Filename:", "#End")) {
|
||||
error_display(1, "Missing [#End] or [$Filename] after cutscene %s", csnt.filename);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Cutscenes.push_back(csnt);
|
||||
csn_new = true;
|
||||
csnp = &Cutscenes[Cutscenes.size() -1];
|
||||
}
|
||||
|
||||
//If $Name is not found use the $Filename instead because this field needs data
|
||||
//but only do this if if we're parsing the tbl and not a tbm
|
||||
if (optional_string("$Name:")) {
|
||||
stuff_string(csnp->name, F_NAME, NAME_LENGTH);
|
||||
mprintf(("Adding cutscene %s\n", csnp->name));
|
||||
} else if (strlen(csnp->name) == 0) {
|
||||
strcpy_s(csnp->name, csnt.filename);
|
||||
mprintf(("Missing $Name: in cutscene.tbl. Using filename %s instead.\n", csnt.filename));
|
||||
}
|
||||
|
||||
//If $Description is not found we can leave it blank
|
||||
if (optional_string("$Description:")) {
|
||||
stuff_string(buf, F_MULTITEXT, sizeof(buf));
|
||||
drop_white_space(buf);
|
||||
compact_multitext_string(buf);
|
||||
csnp->description = vm_strdup(buf);
|
||||
}
|
||||
required_string("$Description:");
|
||||
stuff_string(buf, F_MULTITEXT, sizeof(buf));
|
||||
drop_white_space(buf);
|
||||
compact_multitext_string(buf);
|
||||
cutinfo.description = vm_strdup(buf);
|
||||
|
||||
if (optional_string("$cd:"))
|
||||
{
|
||||
@@ -151,14 +88,13 @@ void parse_cutscene_table(const char* filename)
|
||||
stuff_int(&junk);
|
||||
}
|
||||
|
||||
if (csn_new) {
|
||||
csnp->flags.reset();
|
||||
}
|
||||
cutinfo.flags.reset();
|
||||
|
||||
if (Cutscenes.empty())
|
||||
if (isFirstCutscene)
|
||||
{
|
||||
isFirstCutscene = false;
|
||||
// The original code assumes the first movie is the intro, so make it viewable
|
||||
csnp->flags.set(Cutscene::Cutscene_Flags::Viewable);
|
||||
cutinfo.flags.set(Cutscene::Cutscene_Flags::Viewable);
|
||||
}
|
||||
|
||||
if (optional_string("$Always Viewable:"))
|
||||
@@ -166,19 +102,17 @@ void parse_cutscene_table(const char* filename)
|
||||
bool flag;
|
||||
stuff_boolean(&flag);
|
||||
if (flag)
|
||||
csnp->flags.set(Cutscene::Cutscene_Flags::Always_viewable);
|
||||
cutinfo.flags.set(Cutscene::Cutscene_Flags::Always_viewable);
|
||||
}
|
||||
if (optional_string("$Never Viewable:"))
|
||||
{
|
||||
bool flag;
|
||||
stuff_boolean(&flag);
|
||||
if (flag)
|
||||
csnp->flags.set(Cutscene::Cutscene_Flags::Never_viewable);
|
||||
}
|
||||
if (optional_string("$Custom data:")) {
|
||||
parse_string_map(csnp->custom_data, "$end_custom_data", "+Val:");
|
||||
cutinfo.flags.set(Cutscene::Cutscene_Flags::Never_viewable);
|
||||
}
|
||||
|
||||
Cutscenes.push_back(cutinfo);
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
@@ -190,20 +124,6 @@ void parse_cutscene_table(const char* filename)
|
||||
}
|
||||
}
|
||||
|
||||
void cutscene_init()
|
||||
{
|
||||
|
||||
atexit(cutscene_close);
|
||||
|
||||
Cutscenes.clear();
|
||||
|
||||
// first parse the default table
|
||||
parse_cutscene_table("cutscenes.tbl");
|
||||
|
||||
// parse any modular tables
|
||||
parse_modular_table("*-csn.tbm", parse_cutscene_table);
|
||||
}
|
||||
|
||||
// marks a cutscene as viewable
|
||||
void cutscene_mark_viewable(const char* filename)
|
||||
{
|
||||
@@ -222,6 +142,7 @@ void cutscene_mark_viewable(const char* filename)
|
||||
|
||||
// change to lower case
|
||||
strlwr(file);
|
||||
int i = 0;
|
||||
for (SCP_vector<cutscene_info>::iterator cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut)
|
||||
{
|
||||
// change the cutscene file name to lower case
|
||||
@@ -234,6 +155,7 @@ void cutscene_mark_viewable(const char* filename)
|
||||
cut->flags.set(Cutscene::Cutscene_Flags::Viewable);
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
Warning(LOCATION, "Could not find cutscene '%s' in listing; cannot mark it viewable...", filename);
|
||||
|
||||
@@ -32,7 +32,6 @@ typedef struct cutscene_info
|
||||
char name[NAME_LENGTH];
|
||||
char* description;
|
||||
flagset<Cutscene::Cutscene_Flags> flags;
|
||||
SCP_map<SCP_string, SCP_string> custom_data;
|
||||
} cutscene_info;
|
||||
|
||||
extern SCP_vector<cutscene_info> Cutscenes;
|
||||
|
||||
@@ -503,7 +503,6 @@ MovieProperties FFMPEGDecoder::getProperties() const
|
||||
props.size.height = static_cast<size_t>(m_status->videoCodecPars.height);
|
||||
|
||||
props.fps = static_cast<float>(getFrameRate(m_status->videoStream, m_status->videoCodecCtx));
|
||||
props.duration = static_cast<float>(m_status->videoStream->duration * av_q2d(m_status->videoStream->time_base));
|
||||
|
||||
props.pixelFormat = getPixelFormat(getConversionFormat(m_status->videoCodecPars.pixel_format));
|
||||
|
||||
|
||||
@@ -174,15 +174,10 @@ void determine_display_positions(Player* player, PlaybackState* state) {
|
||||
void initialize_player_state(Player* player, PlaybackState* state) {
|
||||
determine_display_positions(player, state);
|
||||
|
||||
if (!Movie_subtitle_font.empty()) {
|
||||
state->subtitle_font = font::FontManager::getFontIndex(Movie_subtitle_font);
|
||||
state->subtitle_font = font::FontManager::getFontIndex(Movie_subtitle_font);
|
||||
|
||||
if (state->subtitle_font < 0) {
|
||||
Warning(LOCATION, "Failed to load subtitle font '%s'! Subtitles will be disabled.", Movie_subtitle_font.c_str());
|
||||
}
|
||||
}
|
||||
else if (font::FontManager::numberOfFonts() > 0) {
|
||||
state->subtitle_font = 0; // if not explicitly specified, default to the first available font
|
||||
if (state->subtitle_font < 0) {
|
||||
Warning(LOCATION, "Failed to load subtitle font '%s'! Subtitles will be disabled.", Movie_subtitle_font.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -355,8 +355,7 @@ void Player::stopPlayback() {
|
||||
audioPlaybackClose(&m_state);
|
||||
videoPlaybackClose(&m_state);
|
||||
|
||||
if(m_decoderThread->joinable())
|
||||
m_decoderThread->join();
|
||||
m_decoderThread->join();
|
||||
}
|
||||
|
||||
void Player::decoderThread() {
|
||||
@@ -386,13 +385,13 @@ const PlayerState& Player::getInternalState() const {
|
||||
const MovieProperties& Player::getMovieProperties() const {
|
||||
return m_state.props;
|
||||
}
|
||||
void Player::draw(float x1, float y1, float x2, float y2, float alpha) {
|
||||
void Player::draw(float x1, float y1, float x2, float y2) {
|
||||
if (!m_state.currentFrame) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_state.videoPresenter) {
|
||||
m_state.videoPresenter->displayFrame(x1, y1, x2, y2, alpha);
|
||||
m_state.videoPresenter->displayFrame(x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
SCP_string Player::getCurrentSubtitle() {
|
||||
|
||||
@@ -110,7 +110,7 @@ class Player {
|
||||
* @param x2 The X coordinate of the bottom right corner
|
||||
* @param y2 The Y coordinate of the bottom right corner
|
||||
*/
|
||||
void draw(float x1, float y1, float x2, float y2, float alpha = 1.0f);
|
||||
void draw(float x1, float y1, float x2, float y2);
|
||||
|
||||
/**
|
||||
* @brief Gets the subtitle text that should be displayed now
|
||||
|
||||
+160
-251
@@ -25,10 +25,8 @@
|
||||
#include "radar/radar.h"
|
||||
#include "radar/radarsetup.h"
|
||||
#include "render/3d.h"
|
||||
#include "scripting/global_hooks.h"
|
||||
#include "scripting/hook_api.h"
|
||||
#include "scripting/scripting.h"
|
||||
#include "scripting/api/objs/vecmath.h"
|
||||
#include "ship/ship.h"
|
||||
#include "ship/shipfx.h"
|
||||
#include "species_defs/species_defs.h"
|
||||
@@ -36,8 +34,8 @@
|
||||
#include "utils/Random.h"
|
||||
#include "weapon/weapon.h"
|
||||
|
||||
constexpr int MIN_RADIUS_FOR_PERSISTENT_DEBRIS = 50; // ship radius at which debris from it becomes persistant
|
||||
constexpr int DEBRIS_SOUND_DELAY = 2000; // time to start debris sound after created
|
||||
#define MIN_RADIUS_FOR_PERSISTANT_DEBRIS 50 // ship radius at which debris from it becomes persistant
|
||||
#define DEBRIS_SOUND_DELAY 2000 // time to start debris sound after created
|
||||
|
||||
int Num_hull_pieces; // number of hull pieces in existence
|
||||
// we now maintain a kind of "virtual" Hull_debris_list,
|
||||
@@ -56,11 +54,18 @@ int Debris_num_submodels = 0;
|
||||
|
||||
#define DEBRIS_INDEX(dp) (int)(dp-Debris.data())
|
||||
|
||||
const auto OnDebrisCreatedHook = scripting::Hook::Factory(
|
||||
"On Debris Created",
|
||||
"Invoked when a piece of debris is created.",
|
||||
{
|
||||
{"Debris", "debris", "The newly created debris object"},
|
||||
{"Source", "object", "The object (probably a ship) from which this debris piece was spawned."},
|
||||
});
|
||||
|
||||
/**
|
||||
* Start the sequence of a piece of debris writhing in unholy agony!!!
|
||||
*/
|
||||
static void debris_start_death_roll(object *debris_obj, debris *debris_p, vec3d *hitpos = nullptr)
|
||||
static void debris_start_death_roll(object *debris_obj, debris *debris_p)
|
||||
{
|
||||
if (debris_p->is_hull) {
|
||||
// tell everyone else to blow up the piece of debris
|
||||
@@ -82,15 +87,6 @@ static void debris_start_death_roll(object *debris_obj, debris *debris_p, vec3d
|
||||
}
|
||||
}
|
||||
|
||||
if (scripting::hooks::OnDebrisDeath->isActive()) {
|
||||
scripting::hooks::OnDebrisDeath->run(scripting::hook_param_list(
|
||||
scripting::hook_param("Debris", 'o', debris_obj),
|
||||
scripting::hook_param("Hitpos",
|
||||
'o',
|
||||
scripting::api::l_Vector.Set(hitpos ? *hitpos : vmd_zero_vector),
|
||||
hitpos != nullptr)));
|
||||
}
|
||||
|
||||
debris_obj->flags.set(Object::Object_Flags::Should_be_dead);
|
||||
}
|
||||
|
||||
@@ -189,9 +185,7 @@ void debris_delete( object * obj )
|
||||
|
||||
db = &Debris[num];
|
||||
|
||||
if (db->model_instance_num >= 0) {
|
||||
model_delete_instance(db->model_instance_num);
|
||||
}
|
||||
model_delete_instance(db->model_instance_num);
|
||||
|
||||
if ( db->is_hull ) {
|
||||
debris_remove_from_hull_list(db);
|
||||
@@ -224,7 +218,7 @@ void debris_process_post(object * obj, float frame_time)
|
||||
|
||||
if ( timestamp_elapsed(db->sound_delay) ) {
|
||||
obj_snd_assign(objnum, db->ambient_sound, &vmd_zero_vector);
|
||||
db->sound_delay = TIMESTAMP::invalid();
|
||||
db->sound_delay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,17 +238,17 @@ void debris_process_post(object * obj, float frame_time)
|
||||
|
||||
if ( !timestamp_elapsed(db->fire_timeout) && timestamp_elapsed(db->next_fireball)) {
|
||||
|
||||
db->next_fireball = _timestamp_rand(db->arc_frequency,db->arc_frequency*2 );
|
||||
db->next_fireball = timestamp_rand(db->arc_frequency,db->arc_frequency*2 );
|
||||
db->arc_frequency += 100;
|
||||
|
||||
if (db->is_hull) {
|
||||
|
||||
int n, n_arcs = Random::next(1, 3); // Create 1-3 sparks
|
||||
|
||||
vec3d v1 = submodel_get_random_point(db->model_num, db->submodel_num);
|
||||
vec3d v2 = submodel_get_random_point(db->model_num, db->submodel_num);
|
||||
vec3d v3 = submodel_get_random_point(db->model_num, db->submodel_num);
|
||||
vec3d v4 = submodel_get_random_point(db->model_num, db->submodel_num);
|
||||
vec3d v1, v2, v3, v4;
|
||||
|
||||
submodel_get_two_random_points_better(db->model_num, db->submodel_num, &v1, &v2);
|
||||
submodel_get_two_random_points_better(db->model_num, db->submodel_num, &v3, &v4);
|
||||
|
||||
n = 0;
|
||||
|
||||
@@ -262,9 +256,9 @@ void debris_process_post(object * obj, float frame_time)
|
||||
|
||||
// Create the spark effects
|
||||
for (int i=0; i<MAX_DEBRIS_ARCS; ++i) {
|
||||
if ( !db->arc_timestamp[i].isValid() ) {
|
||||
if ( !timestamp_valid( db->arc_timestamp[i] ) ) {
|
||||
|
||||
db->arc_timestamp[i] = _timestamp(lifetime); // live up to a second
|
||||
db->arc_timestamp[i] = timestamp(lifetime); // live up to a second
|
||||
|
||||
switch( n ) {
|
||||
case 0:
|
||||
@@ -319,15 +313,19 @@ void debris_process_post(object * obj, float frame_time)
|
||||
}
|
||||
|
||||
for (int i=0; i<MAX_DEBRIS_ARCS; ++i) {
|
||||
if ( db->arc_timestamp[i].isValid() ) {
|
||||
if ( timestamp_valid( db->arc_timestamp[i] ) ) {
|
||||
if ( timestamp_elapsed( db->arc_timestamp[i] ) ) {
|
||||
// Kill off the spark
|
||||
db->arc_timestamp[i] = TIMESTAMP::invalid();
|
||||
db->arc_timestamp[i] = timestamp(-1);
|
||||
} else {
|
||||
// Maybe move a vertex.... 20% of the time maybe?
|
||||
int mr = Random::next();
|
||||
if ( mr < Random::MAX_VALUE/5 ) {
|
||||
db->arc_pts[i][mr % 2] = submodel_get_random_point(db->model_num, db->submodel_num);
|
||||
vec3d v1, v2;
|
||||
|
||||
submodel_get_two_random_points_better(db->model_num, db->submodel_num, &v1, &v2);
|
||||
|
||||
db->arc_pts[i][mr % 2] = v1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -359,7 +357,7 @@ int debris_find_oldest()
|
||||
}
|
||||
|
||||
#define DEBRIS_ROTVEL_SCALE 5.0f
|
||||
void calc_debris_physics_properties( physics_info *pi, vec3d *min, vec3d *max, float density );
|
||||
void calc_debris_physics_properties( physics_info *pi, vec3d *min, vec3d *max );
|
||||
|
||||
MONITOR(NumSmallDebris)
|
||||
MONITOR(NumHullDebris)
|
||||
@@ -370,45 +368,30 @@ MONITOR(NumHullDebris)
|
||||
* @param source_obj Source object
|
||||
* @param model_num Model number
|
||||
* @param submodel_num Sub-model number
|
||||
* @param pos Position in global coordinates
|
||||
* @param exp_center Explosion center in global coordinates
|
||||
* @param hull_flag Whether this debris is a chunk of a ship's hull (as opposed to shrapnel)
|
||||
* @param pos Position in vector space
|
||||
* @param exp_center Explosion center in vector space
|
||||
* @param hull_flag Hull flag settings
|
||||
* @param exp_force Explosion force, used to assign velocity to pieces. 1.0f assigns velocity like before. 2.0f assigns twice as much to non-inherited part of velocity
|
||||
* @param source_subsys The subsystem this debris came from, if any
|
||||
*/
|
||||
object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d *pos, vec3d *exp_center, bool hull_flag, float exp_force, ship_subsys* source_subsys)
|
||||
object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d *pos, vec3d *exp_center, int hull_flag, float exp_force)
|
||||
{
|
||||
int parent_objnum;
|
||||
object *obj;
|
||||
ship *shipp;
|
||||
bool vaporize;
|
||||
int objnum, parent_objnum;
|
||||
object *obj;
|
||||
ship *shipp;
|
||||
debris *db;
|
||||
polymodel *pm;
|
||||
int vaporize;
|
||||
physics_info *pi = NULL;
|
||||
ship_info *sip = NULL;
|
||||
|
||||
parent_objnum = OBJ_INDEX(source_obj);
|
||||
|
||||
Assert( (source_obj->type == OBJ_SHIP ) || (source_obj->type == OBJ_GHOST));
|
||||
Assert( source_obj->instance >= 0 && source_obj->instance < MAX_SHIPS );
|
||||
shipp = &Ships[source_obj->instance];
|
||||
|
||||
sip = &Ship_info[shipp->ship_info_index];
|
||||
vaporize = (shipp->flags[Ship::Ship_Flags::Vaporize]);
|
||||
|
||||
obj = debris_create_only(parent_objnum, shipp->ship_info_index, shipp->alt_type_index, shipp->team, -1.0f, -1, model_num, submodel_num, pos, nullptr, hull_flag, vaporize, shipp->debris_damage_type_idx);
|
||||
if (obj != nullptr)
|
||||
{
|
||||
debris_create_set_velocity(&Debris[obj->instance], shipp, exp_center, exp_force, source_subsys);
|
||||
debris_create_fire_hook(obj, source_obj);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
object *debris_create_only(int parent_objnum, int parent_ship_class, int alt_type_index, int team, float hull_strength, int spark_timeout, int model_num, int submodel_num, vec3d *pos, matrix *orient, bool hull_flag, bool vaporize, int damage_type_idx)
|
||||
{
|
||||
int objnum;
|
||||
object *obj;
|
||||
debris *db;
|
||||
ship_info *sip;
|
||||
matrix orient_buf;
|
||||
|
||||
// try to maintain our soft limit
|
||||
if (hull_flag && (Num_hull_pieces >= SOFT_LIMIT_DEBRIS_PIECES)) {
|
||||
// cause oldest hull debris chunk to blow up
|
||||
@@ -431,73 +414,10 @@ object *debris_create_only(int parent_objnum, int parent_ship_class, int alt_typ
|
||||
|
||||
db = &Debris[n];
|
||||
|
||||
|
||||
// validate or deduce some parameters
|
||||
|
||||
if ( pos == nullptr ) {
|
||||
if (parent_objnum >= 0) {
|
||||
pos = &Objects[parent_objnum].pos;
|
||||
} else {
|
||||
pos = &vmd_zero_vector;
|
||||
}
|
||||
}
|
||||
|
||||
if ( orient == nullptr ) {
|
||||
if (parent_objnum >= 0 && hull_flag) {
|
||||
orient = &Objects[parent_objnum].orient;
|
||||
} else {
|
||||
// non-hull debris has no relation to its parent orientation
|
||||
vec3d rand;
|
||||
vm_vec_rand_vec(&rand);
|
||||
vm_vector_2_matrix(&orient_buf, &rand);
|
||||
orient = &orient_buf;
|
||||
}
|
||||
}
|
||||
|
||||
sip = (parent_ship_class < 0) ? nullptr : &Ship_info[parent_ship_class];
|
||||
if (hull_flag && !sip)
|
||||
{
|
||||
Warning(LOCATION, "Cannot create hull debris without a ship class!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (hull_strength < 0.0f)
|
||||
{
|
||||
if (parent_objnum >= 0 && Objects[parent_objnum].type == OBJ_SHIP)
|
||||
hull_strength = Ships[Objects[parent_objnum].instance].ship_max_hull_strength / 8.0f;
|
||||
else
|
||||
hull_strength = 10.0f;
|
||||
}
|
||||
|
||||
if (hull_flag && (model_num < 0 || submodel_num < 0))
|
||||
{
|
||||
Warning(LOCATION, "Model and submodel numbers must be specified for hull debris!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (team < 0 && hull_flag)
|
||||
{
|
||||
if (parent_objnum >= 0 && Objects[parent_objnum].type == OBJ_SHIP)
|
||||
team = Ships[Objects[parent_objnum].instance].team;
|
||||
else if (Player_ship)
|
||||
team = Player_ship->team;
|
||||
else
|
||||
team = 0;
|
||||
}
|
||||
|
||||
if (damage_type_idx < 0)
|
||||
{
|
||||
if (parent_objnum >= 0 && Objects[parent_objnum].type == OBJ_SHIP)
|
||||
damage_type_idx = Ships[Objects[parent_objnum].instance].debris_damage_type_idx;
|
||||
}
|
||||
|
||||
// done validation
|
||||
|
||||
|
||||
if (!hull_flag) {
|
||||
if (model_num >= 0) {
|
||||
db->model_num = model_num;
|
||||
db->submodel_num = (sip == nullptr || sip->generic_debris_num_submodels <= 0) ? 0 : Random::next(sip->generic_debris_num_submodels);
|
||||
db->submodel_num = Random::next(sip->generic_debris_num_submodels);
|
||||
}
|
||||
else if (vaporize) {
|
||||
db->model_num = Debris_vaporize_model;
|
||||
@@ -527,18 +447,25 @@ object *debris_create_only(int parent_objnum, int parent_ship_class, int alt_typ
|
||||
}
|
||||
}
|
||||
|
||||
// Create Debris piece n!
|
||||
if ( hull_flag ) {
|
||||
if (Random::next() < (Random::MAX_VALUE/6)) // Make some pieces blow up shortly after explosion.
|
||||
db->lifeleft = 2.0f * (frand()) + 0.5f;
|
||||
else {
|
||||
db->flags.set(Debris_Flags::DoNotExpire);
|
||||
db->lifeleft = -1.0f; // large hull pieces stay around forever
|
||||
if(hull_flag && sip->debris_min_lifetime >= 0.0f && sip->debris_max_lifetime >= 0.0f)
|
||||
{
|
||||
db->lifeleft = (( sip->debris_max_lifetime - sip->debris_min_lifetime ) * frand()) + sip->debris_min_lifetime;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create Debris piece n!
|
||||
if ( hull_flag ) {
|
||||
if (Random::next() < (Random::MAX_VALUE/6)) // Make some pieces blow up shortly after explosion.
|
||||
db->lifeleft = 2.0f * (frand()) + 0.5f;
|
||||
else {
|
||||
db->flags.set(Debris_Flags::DoNotExpire);
|
||||
db->lifeleft = -1.0f; // large hull pieces stay around forever
|
||||
}
|
||||
} else {
|
||||
// small non-hull pieces should stick around longer the larger they are
|
||||
// sqrtf should make sure its never too crazy long
|
||||
db->lifeleft = (frand() * 2.0f + 0.1f) * sqrtf(radius);
|
||||
}
|
||||
} else {
|
||||
// small non-hull pieces should stick around longer the larger they are
|
||||
// sqrtf should make sure its never too crazy long
|
||||
db->lifeleft = (frand() * 2.0f + 0.1f) * sqrtf(radius);
|
||||
}
|
||||
|
||||
//WMC - Oh noes, we may need to change lifeleft
|
||||
@@ -567,18 +494,18 @@ object *debris_create_only(int parent_objnum, int parent_ship_class, int alt_typ
|
||||
db->flags.set(Debris_Flags::Used);
|
||||
db->is_hull = hull_flag;
|
||||
db->source_objnum = parent_objnum;
|
||||
db->damage_type_idx = damage_type_idx;
|
||||
db->ship_info_index = parent_ship_class;
|
||||
db->team = team;
|
||||
db->ambient_sound = (sip == nullptr) ? gamesnd_id(-1) : sip->debris_ambient_sound;
|
||||
db->fire_timeout = TIMESTAMP::never(); // if not changed, timestamp_elapsed() will return false
|
||||
db->damage_type_idx = shipp->debris_damage_type_idx;
|
||||
db->ship_info_index = shipp->ship_info_index;
|
||||
db->team = shipp->team;
|
||||
db->ambient_sound = sip->debris_ambient_sound;
|
||||
db->fire_timeout = 0; // if not changed, timestamp_elapsed() will return false
|
||||
db->time_started = Missiontime;
|
||||
db->species = (sip == nullptr) ? -1 : sip->species;
|
||||
db->parent_alt_name = alt_type_index;
|
||||
db->species = Ship_info[shipp->ship_info_index].species;
|
||||
db->parent_alt_name = shipp->alt_type_index;
|
||||
db->damage_mult = 1.0f;
|
||||
|
||||
for (int i=0; i<MAX_DEBRIS_ARCS; ++i) { // NOLINT
|
||||
db->arc_timestamp[i] = TIMESTAMP::invalid();
|
||||
db->arc_timestamp[i] = timestamp(-1);
|
||||
}
|
||||
|
||||
if ( db->is_hull ) {
|
||||
@@ -592,23 +519,36 @@ object *debris_create_only(int parent_objnum, int parent_ship_class, int alt_typ
|
||||
db->arc_frequency = 0;
|
||||
}
|
||||
|
||||
db->next_fireball = _timestamp_rand(500,2000); //start one 1/2 - 2 secs later
|
||||
db->next_fireball = timestamp_rand(500,2000); //start one 1/2 - 2 secs later
|
||||
|
||||
flagset<Object::Object_Flags> default_flags;
|
||||
default_flags.set(Object::Object_Flags::Renders);
|
||||
default_flags.set(Object::Object_Flags::Physics);
|
||||
default_flags.set(Object::Object_Flags::Collides, hull_flag != 0);
|
||||
if ( pos == nullptr )
|
||||
pos = &source_obj->pos;
|
||||
|
||||
objnum = obj_create(OBJ_DEBRIS, parent_objnum, n, orient, pos, radius, default_flags, false);
|
||||
flagset<Object::Object_Flags> default_flags;
|
||||
default_flags.set(Object::Object_Flags::Renders);
|
||||
default_flags.set(Object::Object_Flags::Physics);
|
||||
default_flags.set(Object::Object_Flags::Collides, hull_flag != 0);
|
||||
|
||||
matrix orient = source_obj->orient;
|
||||
if (!db->is_hull) {
|
||||
// non-hull debris has no relation to its parent orientation
|
||||
vec3d rand;
|
||||
vm_vec_rand_vec(&rand);
|
||||
vm_vector_2_matrix(&orient, &rand);
|
||||
}
|
||||
|
||||
objnum = obj_create(OBJ_DEBRIS, parent_objnum, n, &orient, pos, radius, default_flags, false);
|
||||
if ( objnum == -1 ) {
|
||||
mprintf(("Couldn't create debris object -- out of object slots\n"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
db->objnum = objnum;
|
||||
|
||||
obj = &Objects[objnum];
|
||||
pi = &obj->phys_info;
|
||||
|
||||
db->model_instance_num = hull_flag ? model_create_instance(objnum, db->model_num) : -1;
|
||||
db->model_instance_num = model_create_instance(objnum, db->model_num);
|
||||
|
||||
// assign the network signature. The signature will be 0 for non-hull pieces, but since that
|
||||
// is our invalid signature, it should be okay.
|
||||
@@ -618,7 +558,10 @@ object *debris_create_only(int parent_objnum, int parent_ship_class, int alt_typ
|
||||
obj->net_signature = multi_get_next_network_signature( MULTI_SIG_DEBRIS );
|
||||
}
|
||||
|
||||
obj->hull_strength = hull_strength;
|
||||
if (source_obj->type == OBJ_SHIP) {
|
||||
obj->hull_strength = Ships[source_obj->instance].ship_max_hull_strength/8.0f;
|
||||
} else
|
||||
obj->hull_strength = 10.0f;
|
||||
|
||||
if (hull_flag) {
|
||||
if(sip->debris_min_hitpoints >= 0.0f && sip->debris_max_hitpoints >= 0.0f)
|
||||
@@ -636,59 +579,40 @@ object *debris_create_only(int parent_objnum, int parent_ship_class, int alt_typ
|
||||
obj->hull_strength = sip->debris_max_hitpoints;
|
||||
}
|
||||
db->damage_mult = sip->debris_damage_mult;
|
||||
|
||||
db->sound_delay = _timestamp(DEBRIS_SOUND_DELAY);
|
||||
|
||||
// limit the amount of time that fireballs appear
|
||||
// let fireball length be linked to radius of ship. Range is .33 radius => 3.33 radius seconds.
|
||||
if (spark_timeout >= 0) {
|
||||
db->fire_timeout = _timestamp(spark_timeout);
|
||||
} else if (parent_objnum >= 0) {
|
||||
float t = 1000*Objects[parent_objnum].radius/3 + Random::next(fl2i(1000*3*Objects[parent_objnum].radius));
|
||||
db->fire_timeout = _timestamp(fl2i(t)); // fireballs last from 5 - 30 seconds
|
||||
} else {
|
||||
db->fire_timeout = TIMESTAMP::immediate();
|
||||
}
|
||||
|
||||
if (parent_objnum >= 0 && Objects[parent_objnum].radius >= MIN_RADIUS_FOR_PERSISTENT_DEBRIS) {
|
||||
db->flags.set(Debris_Flags::DoNotExpire);
|
||||
} else {
|
||||
debris_add_to_hull_list(db);
|
||||
}
|
||||
}
|
||||
|
||||
if (hull_flag) {
|
||||
MONITOR_INC(NumHullDebris,1);
|
||||
} else {
|
||||
MONITOR_INC(NumSmallDebris,1);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
void debris_create_set_velocity(debris *db, ship *source_shipp, vec3d *exp_center, float exp_force, ship_subsys* source_subsys)
|
||||
{
|
||||
auto obj = &Objects[db->objnum];
|
||||
auto source_obj = (source_shipp == nullptr) ? nullptr : &Objects[source_shipp->objnum];
|
||||
physics_info *pi = &obj->phys_info;
|
||||
vec3d rotvel, radial_vel, to_center;
|
||||
|
||||
if ( exp_center )
|
||||
vm_vec_sub( &to_center, &obj->pos, exp_center );
|
||||
vm_vec_sub( &to_center,pos, exp_center );
|
||||
else
|
||||
vm_vec_zero(&to_center);
|
||||
|
||||
float scale;
|
||||
if ( db->is_hull ) {
|
||||
|
||||
if ( hull_flag ) {
|
||||
float t;
|
||||
scale = exp_force * i2fl(Random::next(10, 29)); // for radial_vel away from location of blast center
|
||||
db->sound_delay = timestamp(DEBRIS_SOUND_DELAY);
|
||||
|
||||
// set up physics mass and I_inv for hull debris pieces
|
||||
auto pm = model_get(db->model_num);
|
||||
pm = model_get(model_num);
|
||||
vec3d *min, *max;
|
||||
min = &pm->submodel[db->submodel_num].min;
|
||||
max = &pm->submodel[db->submodel_num].max;
|
||||
float density = source_subsys != nullptr ? source_subsys->system_info->density : Ship_info[source_shipp->ship_info_index].debris_density;
|
||||
calc_debris_physics_properties( &obj->phys_info, min, max, density);
|
||||
min = &pm->submodel[submodel_num].min;
|
||||
max = &pm->submodel[submodel_num].max;
|
||||
calc_debris_physics_properties( &obj->phys_info, min, max );
|
||||
|
||||
// limit the amount of time that fireballs appear
|
||||
// let fireball length be linked to radius of ship. Range is .33 radius => 3.33 radius seconds.
|
||||
t = 1000*Objects[db->source_objnum].radius/3 + Random::next(fl2i(1000*3*Objects[db->source_objnum].radius));
|
||||
db->fire_timeout = timestamp(fl2i(t)); // fireballs last from 5 - 30 seconds
|
||||
|
||||
if ( Objects[db->source_objnum].radius < MIN_RADIUS_FOR_PERSISTANT_DEBRIS ) {
|
||||
debris_add_to_hull_list(db);
|
||||
} else {
|
||||
db->flags.set(Debris_Flags::DoNotExpire);
|
||||
nprintf(("Alan","A forever chunk of debris was created from ship with radius %f\n",Objects[db->source_objnum].radius));
|
||||
}
|
||||
}
|
||||
else {
|
||||
scale = exp_force * i2fl(Random::next(10, 29)); // for radial_vel away from blast center (non-hull)
|
||||
@@ -703,21 +627,15 @@ void debris_create_set_velocity(debris *db, ship *source_shipp, vec3d *exp_cente
|
||||
vm_vec_copy_scale(&radial_vel, &to_center, scale );
|
||||
}
|
||||
|
||||
if (source_obj)
|
||||
{
|
||||
// DA: here we need to vel_from_rot = w x to_center, where w is world is unrotated to world coords and offset is the
|
||||
// displacement fromt the center of the parent object to the center of the debris piece
|
||||
vec3d world_rotvel, vel_from_rotvel;
|
||||
vm_vec_unrotate ( &world_rotvel, &source_obj->phys_info.rotvel, &source_obj->orient );
|
||||
vm_vec_cross ( &vel_from_rotvel, &world_rotvel, &to_center );
|
||||
vm_vec_scale ( &vel_from_rotvel, DEBRIS_ROTVEL_SCALE);
|
||||
// DA: here we need to vel_from_rot = w x to_center, where w is world is unrotated to world coords and offset is the
|
||||
// displacement fromt the center of the parent object to the center of the debris piece
|
||||
vec3d world_rotvel, vel_from_rotvel;
|
||||
vm_vec_unrotate ( &world_rotvel, &source_obj->phys_info.rotvel, &source_obj->orient );
|
||||
vm_vec_cross ( &vel_from_rotvel, &world_rotvel, &to_center );
|
||||
vm_vec_scale ( &vel_from_rotvel, DEBRIS_ROTVEL_SCALE);
|
||||
|
||||
vm_vec_add (&obj->phys_info.vel, &radial_vel, &source_obj->phys_info.vel);
|
||||
vm_vec_add2(&obj->phys_info.vel, &vel_from_rotvel);
|
||||
}
|
||||
|
||||
|
||||
float radius = submodel_get_radius(db->model_num, db->submodel_num);
|
||||
vm_vec_add (&obj->phys_info.vel, &radial_vel, &source_obj->phys_info.vel);
|
||||
vm_vec_add2(&obj->phys_info.vel, &vel_from_rotvel);
|
||||
|
||||
// make sure rotational velocity does not get too high
|
||||
if (radius < 1.0) {
|
||||
@@ -729,49 +647,47 @@ void debris_create_set_velocity(debris *db, ship *source_shipp, vec3d *exp_cente
|
||||
vm_vec_rand_vec_quick(&rotvel);
|
||||
vm_vec_scale(&rotvel, scale);
|
||||
|
||||
pi->flags |= PF_DEAD_DAMP;
|
||||
pi->rotvel = rotvel;
|
||||
pi->flags |= (PF_DEAD_DAMP | PF_BALLISTIC);
|
||||
check_rotvel_limit( &obj->phys_info );
|
||||
|
||||
// check that debris is not created with too high a velocity
|
||||
if (db->is_hull)
|
||||
if (hull_flag)
|
||||
{
|
||||
shipfx_debris_limit_speed(db, source_shipp);
|
||||
shipfx_debris_limit_speed(db, shipp);
|
||||
}
|
||||
|
||||
// blow out his reverse thrusters. Or drag, same thing.
|
||||
pi->rotdamp = 10000.0f;
|
||||
if (source_shipp != nullptr) {
|
||||
pi->gravity_const = Ship_info[source_shipp->ship_info_index].debris_gravity_const;
|
||||
} else {
|
||||
pi->gravity_const = 1.0f;
|
||||
}
|
||||
|
||||
pi->side_slip_time_const = 10000.0f;
|
||||
pi->flags |= (PF_REDUCED_DAMP | PF_DEAD_DAMP); // set damping equal for all axis and not changable
|
||||
|
||||
vm_vec_zero(&pi->max_vel); // make so he can't turn on his own VOLITION anymore.
|
||||
vm_vec_zero(&pi->max_rotvel); // make so he can't change speed on his own VOLITION anymore.
|
||||
|
||||
// ensure vel is valid
|
||||
Assert( !vm_is_vec_nan(&obj->phys_info.vel) );
|
||||
}
|
||||
|
||||
void debris_create_fire_hook(object *obj, object *source_obj)
|
||||
{
|
||||
if (scripting::hooks::OnDebrisCreated->isActive()) {
|
||||
scripting::hooks::ShipSourceConditions conditions;
|
||||
conditions.source_shipp = (source_obj != nullptr && source_obj->type == OBJ_SHIP) ? &Ships[source_obj->instance] : nullptr;
|
||||
scripting::hooks::OnDebrisCreated->run(std::move(conditions),
|
||||
scripting::hook_param_list(
|
||||
scripting::hook_param("Debris", 'o', obj),
|
||||
scripting::hook_param("Source", 'o', source_obj)));
|
||||
if (OnDebrisCreatedHook->isActive()) {
|
||||
OnDebrisCreatedHook->run(scripting::hook_param_list(
|
||||
scripting::hook_param("Debris", 'o', obj),
|
||||
scripting::hook_param("Source", 'o', source_obj)));
|
||||
}
|
||||
|
||||
if (db->is_hull) {
|
||||
MONITOR_INC(NumHullDebris,1);
|
||||
} else {
|
||||
MONITOR_INC(NumSmallDebris,1);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alas, poor debris_obj got whacked. Fortunately, we know who did it, where and how hard, so we
|
||||
* can do something about it.
|
||||
*/
|
||||
void debris_hit(object *debris_obj, object * /*other_obj*/, vec3d *hitpos, float damage, vec3d* force)
|
||||
void debris_hit(object *debris_obj, object * /*other_obj*/, vec3d *hitpos, float damage)
|
||||
{
|
||||
debris *debris_p = &Debris[debris_obj->instance];
|
||||
|
||||
@@ -811,15 +727,10 @@ void debris_hit(object *debris_obj, object * /*other_obj*/, vec3d *hitpos, float
|
||||
damage = 0.0f;
|
||||
}
|
||||
|
||||
if (hitpos && force && The_mission.ai_profile->flags[AI::Profile_Flags::Whackable_debris]) {
|
||||
vec3d rel_hit_pos = *hitpos - debris_obj->pos;
|
||||
physics_calculate_and_apply_whack(force, &rel_hit_pos, &debris_obj->phys_info, &debris_obj->orient, &debris_obj->phys_info.I_body_inv);
|
||||
}
|
||||
|
||||
debris_obj->hull_strength -= damage;
|
||||
|
||||
if (debris_obj->hull_strength < 0.0f) {
|
||||
debris_start_death_roll(debris_obj, debris_p, hitpos);
|
||||
debris_start_death_roll(debris_obj, debris_p );
|
||||
} else {
|
||||
// otherwise, give all the other players an update on the debris
|
||||
if(MULTIPLAYER_MASTER){
|
||||
@@ -836,6 +747,7 @@ void debris_hit(object *debris_obj, object * /*other_obj*/, vec3d *hitpos, float
|
||||
int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, collision_info_struct *debris_hit_info, vec3d* hitNormal)
|
||||
{
|
||||
mc_info mc;
|
||||
mc_info_init(&mc);
|
||||
|
||||
Assert( pdebris->type == OBJ_DEBRIS );
|
||||
|
||||
@@ -875,7 +787,7 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
|
||||
weapon *wp = &Weapons[other_obj->instance];
|
||||
wp->collisionInfo = new mc_info; // The weapon will free this memory later
|
||||
*wp->collisionInfo = mc;
|
||||
memcpy(wp->collisionInfo, &mc, sizeof(mc_info));
|
||||
|
||||
return mc.num_hits;
|
||||
}
|
||||
@@ -926,9 +838,10 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
mc.flags = (MC_CHECK_MODEL | MC_CHECK_SPHERELINE);
|
||||
|
||||
// copy important data
|
||||
int orig_flags = mc.flags; // make a copy of start end positions of sphere in big ship RF
|
||||
vec3d orig_p0 = *mc.p0;
|
||||
vec3d orig_p1 = *mc.p1;
|
||||
int copy_flags = mc.flags; // make a copy of start end positions of sphere in big ship RF
|
||||
vec3d copy_p0, copy_p1;
|
||||
copy_p0 = *mc.p0;
|
||||
copy_p1 = *mc.p1;
|
||||
|
||||
// first test against the sphere - if this fails then don't do any submodel tests
|
||||
mc.flags = MC_ONLY_SPHERE | MC_CHECK_SPHERELINE;
|
||||
@@ -954,7 +867,7 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
}
|
||||
|
||||
// Only check single submodel now, since children of moving submodels are handled as moving as well
|
||||
mc.flags = orig_flags | MC_SUBMODEL;
|
||||
mc.flags = copy_flags | MC_SUBMODEL;
|
||||
|
||||
if (Ship_info[Ships[pship_obj->instance].ship_info_index].collision_lod > -1) {
|
||||
mc.lod = Ship_info[Ships[pship_obj->instance].ship_info_index].collision_lod;
|
||||
@@ -1004,9 +917,9 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
}
|
||||
|
||||
// Now complete base model collision checks that do not take into account rotating submodels.
|
||||
mc.flags = orig_flags;
|
||||
mc.p0 = &orig_p0;
|
||||
mc.p1 = &orig_p1;
|
||||
mc.flags = copy_flags;
|
||||
*mc.p0 = copy_p0;
|
||||
*mc.p1 = copy_p1;
|
||||
mc.orient = &heavy_obj->orient;
|
||||
|
||||
// usual ship_ship collision test
|
||||
@@ -1116,7 +1029,7 @@ int debris_get_team(object *objp)
|
||||
/**
|
||||
* Fills in debris physics properties when created, specifically mass and moment of inertia
|
||||
*/
|
||||
void calc_debris_physics_properties( physics_info *pi, vec3d *mins, vec3d *maxs, float density )
|
||||
void calc_debris_physics_properties( physics_info *pi, vec3d *mins, vec3d *maxs )
|
||||
{
|
||||
float dx, dy, dz, mass;
|
||||
dx = maxs->xyz.x - mins->xyz.x;
|
||||
@@ -1125,7 +1038,7 @@ void calc_debris_physics_properties( physics_info *pi, vec3d *mins, vec3d *maxs,
|
||||
|
||||
// John, with new bspgen, just set pi->mass = mass
|
||||
mass = 0.12f * dx * dy * dz;
|
||||
pi->mass = (float) pow(mass, 0.6666667f) * 4.65f * density;
|
||||
pi->mass = (float) pow(mass, 0.6666667f) * 4.65f;
|
||||
|
||||
pi->I_body_inv.vec.rvec.xyz.x = 12.0f / (pi->mass * (dy*dy + dz*dz));
|
||||
pi->I_body_inv.vec.rvec.xyz.y = 0.0f;
|
||||
@@ -1158,8 +1071,11 @@ void debris_render(object * obj, model_draw_list *scene)
|
||||
|
||||
texture_info *tbase = nullptr;
|
||||
|
||||
auto pm = model_get(db->model_num);
|
||||
auto pmi = model_get_instance(db->model_instance_num);
|
||||
auto pm = model_get(pmi->model_num);
|
||||
|
||||
model_clear_instance( db->model_num );
|
||||
model_instance_clear_arcs(pm, pmi);
|
||||
|
||||
// Swap in a different texture depending on the species
|
||||
if (db->species >= 0)
|
||||
@@ -1172,18 +1088,11 @@ void debris_render(object * obj, model_draw_list *scene)
|
||||
}
|
||||
}
|
||||
|
||||
polymodel_instance *pmi = nullptr;
|
||||
if (db->model_instance_num >= 0)
|
||||
{
|
||||
pmi = model_get_instance(db->model_instance_num);
|
||||
model_instance_clear_arcs(pm, pmi);
|
||||
|
||||
// Only render electrical arcs if within 500m of the eye (for a 10m piece)
|
||||
if ( vm_vec_dist_quick( &obj->pos, &Eye_position ) < obj->radius*50.0f ) {
|
||||
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
|
||||
if ( db->arc_timestamp[i].isValid() ) {
|
||||
model_instance_add_arc( pm, pmi, db->submodel_num, &db->arc_pts[i][0], &db->arc_pts[i][1], MARC_TYPE_DAMAGED );
|
||||
}
|
||||
// Only render electrical arcs if within 500m of the eye (for a 10m piece)
|
||||
if ( vm_vec_dist_quick( &obj->pos, &Eye_position ) < obj->radius*50.0f ) {
|
||||
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
|
||||
if ( timestamp_valid( db->arc_timestamp[i] ) ) {
|
||||
model_instance_add_arc( pm, pmi, db->submodel_num, &db->arc_pts[i][0], &db->arc_pts[i][1], MARC_TYPE_DAMAGED );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-19
@@ -43,15 +43,15 @@ typedef struct debris {
|
||||
int model_num; // What model this uses
|
||||
int model_instance_num; // What model instance this uses - needed for arcs
|
||||
int submodel_num; // What submodel this uses
|
||||
TIMESTAMP next_fireball; // When to start a fireball
|
||||
bool is_hull; // indicates whether this is a collideable, destructable piece of debris from the model, or just a generic debris fragment
|
||||
int next_fireball; // When to start a fireball
|
||||
int is_hull; // indicates whether this is a collideable, destructable piece of debris from the model, or just a generic debris fragment
|
||||
int species; // What species this is from. -1 if don't care.
|
||||
TIMESTAMP fire_timeout; // timestamp that holds time for fireballs to stop appearing
|
||||
TIMESTAMP sound_delay; // timestamp to signal when sound should start
|
||||
int fire_timeout; // timestamp that holds time for fireballs to stop appearing
|
||||
int sound_delay; // timestamp to signal when sound should start
|
||||
fix time_started; // time when debris was created
|
||||
|
||||
vec3d arc_pts[MAX_DEBRIS_ARCS][2]; // The endpoints of each arc
|
||||
TIMESTAMP arc_timestamp[MAX_DEBRIS_ARCS]; // When this times out, the spark goes away. Invalid is not used
|
||||
int arc_timestamp[MAX_DEBRIS_ARCS]; // When this times out, the spark goes away. -1 is not used
|
||||
int arc_frequency; // Starts at 1000, gets bigger
|
||||
|
||||
int parent_alt_name;
|
||||
@@ -69,21 +69,9 @@ void debris_init();
|
||||
void debris_render(object * obj, model_draw_list *scene);
|
||||
void debris_delete( object * obj );
|
||||
void debris_process_post( object * obj, float frame_time);
|
||||
|
||||
// Create debris, set velocity, and fire scripting hook
|
||||
object *debris_create( object *source_obj, int model_num, int submodel_num, vec3d *pos, vec3d *exp_center, bool hull_flag, float exp_force, ship_subsys* source_subsys = nullptr );
|
||||
|
||||
// Create debris but don't do anything else
|
||||
object *debris_create_only(int parent_objnum, int parent_ship_class, int alt_type_index, int team, float hull_strength, int spark_timeout, int model_num, int submodel_num, vec3d *pos, matrix *orient, bool hull_flag, bool vaporize, int damage_type_idx);
|
||||
|
||||
// Set velocity after debris creation
|
||||
void debris_create_set_velocity(debris *db, ship *source_shipp, vec3d *exp_center, float exp_force, ship_subsys* source_subsys = nullptr);
|
||||
|
||||
// Fire scripting hook after debris creation
|
||||
void debris_create_fire_hook(object *obj, object *source_obj);
|
||||
|
||||
object *debris_create( object * source_obj, int model_num, int submodel_num, vec3d *pos, vec3d *exp_center, int hull_flag, float exp_force );
|
||||
int debris_check_collision( object * obj, object * other_obj, vec3d * hitpos, collision_info_struct *debris_hit_info=NULL, vec3d* hitnormal = NULL );
|
||||
void debris_hit( object * debris_obj, object * other_obj, vec3d * hitpos, float damage, vec3d* force );
|
||||
void debris_hit( object * debris_obj, object * other_obj, vec3d * hitpos, float damage );
|
||||
int debris_get_team(object *objp);
|
||||
|
||||
void debris_add_to_hull_list(debris *db);
|
||||
|
||||
+25
-37
@@ -161,7 +161,6 @@ SCP_vector<DecalDefinition> DecalDefinitions;
|
||||
|
||||
// Variable to indicate if the system is able to work correctly on the current system
|
||||
bool Decal_system_active = true;
|
||||
bool Decal_option_active = true;
|
||||
|
||||
void parse_decals_table(const char* filename) {
|
||||
try {
|
||||
@@ -187,7 +186,7 @@ void parse_decals_table(const char* filename) {
|
||||
}
|
||||
|
||||
if (!gr_is_capable(CAPABILITY_DEFERRED_LIGHTING)) {
|
||||
// We need deferred lighting
|
||||
// we need deferred lighting
|
||||
Decal_system_active = false;
|
||||
mprintf(("Note: Decal system has been disabled due to lack of deferred lighting.\n"));
|
||||
}
|
||||
@@ -197,7 +196,7 @@ void parse_decals_table(const char* filename) {
|
||||
mprintf(("Note: Decal system has been disabled due to lack of normal mapping.\n"));
|
||||
}
|
||||
if (!gr_is_capable(CAPABILITY_SEPARATE_BLEND_FUNCTIONS)) {
|
||||
// We need separate blending functions for different color buffers
|
||||
// WWe need separate blending functions for different color buffers
|
||||
Decal_system_active = false;
|
||||
mprintf(("Note: Decal system has been disabled due to lack of separate color buffer blend functions.\n"));
|
||||
}
|
||||
@@ -328,18 +327,20 @@ void parseDecalReference(creation_info& dest_info, bool is_new_entry) {
|
||||
SCP_string name;
|
||||
stuff_string(name, F_NAME);
|
||||
|
||||
// decals are not initialized in FRED, so no decal definitions are known
|
||||
if (!Fred_running) {
|
||||
auto decalRef = findDecalDefinition(name);
|
||||
auto decalRef = findDecalDefinition(name);
|
||||
|
||||
if (decalRef < 0) {
|
||||
error_display(0, "Decal definition '%s' is unknown!", name.c_str());
|
||||
}
|
||||
dest_info.definition_handle = decalRef;
|
||||
if (decalRef < 0) {
|
||||
error_display(0, "Decal definition '%s' is unknown!", name.c_str());
|
||||
}
|
||||
dest_info.definition_handle = decalRef;
|
||||
|
||||
if (required_string_if_new("+Radius:", is_new_entry)) {
|
||||
dest_info.radius = util::parseUniformRange(0.0001f);
|
||||
stuff_float(&dest_info.radius);
|
||||
|
||||
if (dest_info.radius <= 0.0f) {
|
||||
error_display(0, "Invalid radius of %f! Must be a positive number.", dest_info.radius);
|
||||
dest_info.radius = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (required_string_if_new("+Lifetime:", is_new_entry)) {
|
||||
@@ -350,14 +351,10 @@ void parseDecalReference(creation_info& dest_info, bool is_new_entry) {
|
||||
dest_info.lifetime = util::parseUniformRange(0.0001f);
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("+Use Random Rotation:")) {
|
||||
stuff_boolean(&dest_info.random_rotation);
|
||||
}
|
||||
}
|
||||
|
||||
void loadBitmaps(const creation_info& info) {
|
||||
if (!Decal_system_active || !Decal_option_active) {
|
||||
if (!Decal_system_active) {
|
||||
return;
|
||||
}
|
||||
// Silently ignore invalid definition handle since weapons use the default values if the decal option is not present
|
||||
@@ -374,7 +371,7 @@ void loadBitmaps(const creation_info& info) {
|
||||
}
|
||||
|
||||
void pageInDecal(const creation_info& info) {
|
||||
if (!Decal_system_active || !Decal_option_active) {
|
||||
if (!Decal_system_active) {
|
||||
return;
|
||||
}
|
||||
// Silently ignore invalid definition handle since weapons use the default values if the decal option is not present
|
||||
@@ -416,12 +413,9 @@ matrix4 getDecalTransform(Decal& decal) {
|
||||
// this will lead to a situation where we would look at the decal texture "from behind" causing the texture to
|
||||
// appear flipped. We fix that here for the graphics transform by inverting the Z scaling.
|
||||
|
||||
// ALSO for some reason the uvec needs to be flipped as well, otherwise the decals render upside-down. Without
|
||||
// being sure of the root cause, this at least makes it appear correct for modders.
|
||||
|
||||
// Apply scaling
|
||||
vm_vec_scale(&worldOrient.vec.rvec, decal.scale.xyz.x);
|
||||
vm_vec_scale(&worldOrient.vec.uvec, -decal.scale.xyz.y);
|
||||
vm_vec_scale(&worldOrient.vec.uvec, decal.scale.xyz.y);
|
||||
vm_vec_scale(&worldOrient.vec.fvec, -decal.scale.xyz.z);
|
||||
|
||||
matrix4 mat4;
|
||||
@@ -431,12 +425,12 @@ matrix4 getDecalTransform(Decal& decal) {
|
||||
}
|
||||
|
||||
void renderAll() {
|
||||
if (!Decal_system_active || !Decal_option_active) {
|
||||
if (!Decal_system_active) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear out any invalid decals
|
||||
for (auto iter = active_decals.begin(); iter != active_decals.end();) {
|
||||
for (auto iter = active_decals.begin(); iter != active_decals.end(); ++iter) {
|
||||
if (!iter->isValid()) {
|
||||
// if we're sitting on the very last element, popping-back will invalidate the iterator!
|
||||
if (iter + 1 == active_decals.end()) {
|
||||
@@ -448,10 +442,6 @@ void renderAll() {
|
||||
active_decals.pop_back();
|
||||
continue;
|
||||
}
|
||||
|
||||
// next decal, only increment the iterator if we found a valid value so nothing gets skipped
|
||||
// otherwise we may skip a decal which can then get through to the draw_list loop while being invalid
|
||||
++iter;
|
||||
}
|
||||
|
||||
if (active_decals.empty()) {
|
||||
@@ -462,15 +452,14 @@ void renderAll() {
|
||||
|
||||
graphics::decal_draw_list draw_list(active_decals.size());
|
||||
for (auto& decal : active_decals) {
|
||||
|
||||
Assertion(decal.definition_handle >= 0 && decal.definition_handle < (int)DecalDefinitions.size(),
|
||||
"Invalid decal handle detected!");
|
||||
auto& decalDef = DecalDefinitions[decal.definition_handle];
|
||||
|
||||
int diffuse_bm = -1;
|
||||
int glow_bm = -1;
|
||||
int normal_bm = -1;
|
||||
|
||||
Assertion(decal.definition_handle >= 0 && decal.definition_handle < (int) DecalDefinitions.size(),
|
||||
"Invalid decal handle detected!");
|
||||
auto& decalDef = DecalDefinitions[decal.definition_handle];
|
||||
|
||||
auto decal_time = mission_time - decal.creation_time;
|
||||
auto progress = decal_time / decal.lifetime;
|
||||
|
||||
@@ -502,7 +491,7 @@ void renderAll() {
|
||||
}
|
||||
|
||||
void addDecal(creation_info& info, object* host, int submodel, const vec3d& local_pos, const matrix& local_orient) {
|
||||
if (!Decal_system_active || !Decal_option_active) {
|
||||
if (!Decal_system_active) {
|
||||
return;
|
||||
}
|
||||
// Silently ignore invalid definition handle since weapons use the default values if the decal option is not present
|
||||
@@ -530,10 +519,9 @@ void addDecal(creation_info& info, object* host, int submodel, const vec3d& loca
|
||||
newDecal.position = local_pos;
|
||||
newDecal.orientation = local_orient;
|
||||
if (info.width < 0.0f || info.height < 0.0f) {
|
||||
float radius = info.radius.next();
|
||||
newDecal.scale.xyz.x = radius;
|
||||
newDecal.scale.xyz.y = radius;
|
||||
newDecal.scale.xyz.z = radius;
|
||||
newDecal.scale.xyz.x = info.radius;
|
||||
newDecal.scale.xyz.y = info.radius;
|
||||
newDecal.scale.xyz.z = info.radius;
|
||||
} else {
|
||||
newDecal.scale.xyz.x = info.width;
|
||||
newDecal.scale.xyz.y = info.height;
|
||||
|
||||
@@ -52,7 +52,6 @@ class DecalDefinition {
|
||||
|
||||
extern SCP_vector<DecalDefinition> DecalDefinitions;
|
||||
extern bool Decal_system_active;
|
||||
extern bool Decal_option_active;
|
||||
|
||||
|
||||
/**
|
||||
@@ -65,11 +64,10 @@ typedef int DecalReference;
|
||||
*/
|
||||
struct creation_info {
|
||||
DecalReference definition_handle = -1;
|
||||
util::UniformFloatRange radius = ::util::UniformFloatRange(-1.0f);
|
||||
float radius = -1.0f;
|
||||
float width = -1.0f;
|
||||
float height = -1.0f;
|
||||
util::UniformFloatRange lifetime = ::util::UniformFloatRange(-1.0f);
|
||||
bool random_rotation = false;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -72,10 +72,7 @@ $Player Damage Factor: 0.25, 0.5, 0.65, 0.85, 1
|
||||
|
||||
;; factor applied to subsystem damage suffered by the player
|
||||
;; (in addition to Player Damage Factor)
|
||||
$Player Subsys Damage Factor: 0.2, 0.4, 0.6, 0.8, 1
|
||||
|
||||
;; factor applied to damage inflicted by the player
|
||||
$Player Damage Inflicted Factor: 1, 1, 1, 1, 1
|
||||
$Player Subsys Damage Factor: 0.2, 0.4, 0.6, 0.8, 1
|
||||
|
||||
;; measure of time (in F1_0 units) after which the AI will recalculate
|
||||
;; the position of its target
|
||||
|
||||
Loaded 100 of 1483 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user