mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-08 07:28:22 -10:00
Compare commits
276
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db5a90c955 | ||
|
|
95f26ef625 | ||
|
|
bc7654392a | ||
|
|
760b035a3a | ||
|
|
ce2fd88c24 | ||
|
|
3d6c02ffe2 | ||
|
|
2aae150981 | ||
|
|
620afa0c1e | ||
|
|
7fdcd4abc7 | ||
|
|
18394f7074 | ||
|
|
8bde63a9ae | ||
|
|
f021e9df8a | ||
|
|
4a1d794a64 | ||
|
|
fecb9b16af | ||
|
|
7e637d5d5a | ||
|
|
ff5bc2f6a0 | ||
|
|
c08a669c2e | ||
|
|
03f6f09c93 | ||
|
|
74c2a204c7 | ||
|
|
a9ad87ea08 | ||
|
|
0a86623e9e | ||
|
|
2f957668e3 | ||
|
|
38d9a975ce | ||
|
|
f26643c43d | ||
|
|
c2cb07ded3 | ||
|
|
7a04f76a46 | ||
|
|
006d2a49b1 | ||
|
|
a281f35f1a | ||
|
|
88f7e41d8c | ||
|
|
f2998a2c69 | ||
|
|
1b0a3ea6f9 | ||
|
|
5e274a008c | ||
|
|
38be5c248c | ||
|
|
0450ef0d1a | ||
|
|
e6a2a2a7f9 | ||
|
|
bbb6a6f199 | ||
|
|
1c0b58e11b | ||
|
|
0bf0735cd9 | ||
|
|
cc3791b594 | ||
|
|
799906a921 | ||
|
|
043e3fab79 | ||
|
|
2e34c29215 | ||
|
|
96228d6e98 | ||
|
|
dc4daafd61 | ||
|
|
4b37796628 | ||
|
|
45a434a60a | ||
|
|
488ec8d5a8 | ||
|
|
b1460eb3fa | ||
|
|
671fe21a75 | ||
|
|
d6606ad642 | ||
|
|
d9b2b428a0 | ||
|
|
e87fcfaf28 | ||
|
|
65d1b7f99a | ||
|
|
712337a2da | ||
|
|
b9169cc425 | ||
|
|
b7a0124a9b | ||
|
|
27925607b8 | ||
|
|
38d8f17990 | ||
|
|
5143855863 | ||
|
|
648a1d009d | ||
|
|
df531fc595 | ||
|
|
5802f718f6 | ||
|
|
7d62d741b9 | ||
|
|
45258aabb4 | ||
|
|
db34b4d53c | ||
|
|
7c2077baf2 | ||
|
|
eef7623e9f | ||
|
|
529ac05034 | ||
|
|
6ac8559630 | ||
|
|
2626e7862b | ||
|
|
b3cd35258c | ||
|
|
0fb12b89eb | ||
|
|
c082babd9c | ||
|
|
d5f3be091c | ||
|
|
790227a2bf | ||
|
|
803f08f969 | ||
|
|
f2c40a2669 | ||
|
|
63756c00af | ||
|
|
2147571dff | ||
|
|
bb9c76103b | ||
|
|
857e61f638 | ||
|
|
58053a02b2 | ||
|
|
e8ea8733d0 | ||
|
|
184bbb52bb | ||
|
|
b00410ab01 | ||
|
|
525d8e34d0 | ||
|
|
4cdf10b399 | ||
|
|
c652d5a84c | ||
|
|
1a356834b4 | ||
|
|
3f48f7c4ad | ||
|
|
3e8a9d9738 | ||
|
|
592eefb60f | ||
|
|
373218d7d9 | ||
|
|
1bdd6c3c4c | ||
|
|
1313434e11 | ||
|
|
bf996313dc | ||
|
|
2eb5a3ecde | ||
|
|
1aee2401e5 | ||
|
|
f8203e9da3 | ||
|
|
b24bcbcc62 | ||
|
|
0b8c1b6853 | ||
|
|
6ae6c550a7 | ||
|
|
9c521d04d8 | ||
|
|
c6c9945e50 | ||
|
|
8dfeca4ac3 | ||
|
|
bb4898cb04 | ||
|
|
6e38656658 | ||
|
|
e72dd4c2ca | ||
|
|
be8725c6c6 | ||
|
|
15c921223b | ||
|
|
ec241fcab3 | ||
|
|
0e00ab670c | ||
|
|
1f9a2ca4ce | ||
|
|
0d697672dc | ||
|
|
1fe62ea8d1 | ||
|
|
687694c732 | ||
|
|
9093af9b95 | ||
|
|
3b0dca6cd9 | ||
|
|
817b7dc975 | ||
|
|
d4d7c8dbd2 | ||
|
|
bb89553b0a | ||
|
|
e4acd15a1e | ||
|
|
d16f46fb1c | ||
|
|
77ad3ba0aa | ||
|
|
da31995331 | ||
|
|
25d326567e | ||
|
|
03696d07ca | ||
|
|
0528538a6f | ||
|
|
3a48613a2d | ||
|
|
a7b795e965 | ||
|
|
99875810c6 | ||
|
|
13420121dd | ||
|
|
26c5152d4a | ||
|
|
5066e498a3 | ||
|
|
4bf806c485 | ||
|
|
2403f13483 | ||
|
|
8e98cddd6e | ||
|
|
30cabc4174 | ||
|
|
8a3b36d921 | ||
|
|
b74824f793 | ||
|
|
6a26ca5061 | ||
|
|
9b78fad1c5 | ||
|
|
d34570ae90 | ||
|
|
a0f4c4d2b3 | ||
|
|
63990c54a9 | ||
|
|
6593565165 | ||
|
|
af93922ba5 | ||
|
|
daeb1a7940 | ||
|
|
f56cbc59f1 | ||
|
|
79418a073d | ||
|
|
ce2e165510 | ||
|
|
e9ee311709 | ||
|
|
7576d4f2fe | ||
|
|
866b06ca35 | ||
|
|
f4d7b45e4d | ||
|
|
d23e4b8e87 | ||
|
|
f3d15f8ddc | ||
|
|
c9fe191d31 | ||
|
|
bad255fffb | ||
|
|
be260ef74c | ||
|
|
0ac3d52261 | ||
|
|
f7df03c654 | ||
|
|
a7e1a27e36 | ||
|
|
d83de47ef2 | ||
|
|
59435abfb2 | ||
|
|
ab319a631c | ||
|
|
7c2950480e | ||
|
|
a80bc26bfc | ||
|
|
ead3c62d23 | ||
|
|
5cd502fb79 | ||
|
|
905d777e18 | ||
|
|
66deb83980 | ||
|
|
de3e382180 | ||
|
|
0190fda7ee | ||
|
|
9651dc1598 | ||
|
|
743cf779bf | ||
|
|
bf13ce54a8 | ||
|
|
fcd3264fad | ||
|
|
e33419c48d | ||
|
|
a73df5bcb4 | ||
|
|
4e707fc8e9 | ||
|
|
2e7057ed8d | ||
|
|
ba9285e09a | ||
|
|
138eddfbd2 | ||
|
|
66be185d0c | ||
|
|
0c355efaa2 | ||
|
|
89a6e2aa7d | ||
|
|
84033d901c | ||
|
|
4b49123070 | ||
|
|
213bcbc80b | ||
|
|
0da34f0bc8 | ||
|
|
8fcf385e7e | ||
|
|
4f4722ccad | ||
|
|
7d94561ea5 | ||
|
|
248cec7cf9 | ||
|
|
e987d1cd7b | ||
|
|
f1aa29551b | ||
|
|
76734fb5ed | ||
|
|
fb0a62c400 | ||
|
|
1403301b65 | ||
|
|
1d1eb5ec4d | ||
|
|
7283412880 | ||
|
|
1d2ca8eb5a | ||
|
|
130ddb41f1 | ||
|
|
9462241c0b | ||
|
|
14bba9aea1 | ||
|
|
c7b43b0e0e | ||
|
|
1355c484fe | ||
|
|
1866c6adb5 | ||
|
|
a11517984e | ||
|
|
f207d2d12c | ||
|
|
4970252e9f | ||
|
|
d789e9b33a | ||
|
|
292f7d3b03 | ||
|
|
3bfc37172a | ||
|
|
2bb1c10557 | ||
|
|
40fac5dd5f | ||
|
|
2a33e374c2 | ||
|
|
d48d00d946 | ||
|
|
562875130c | ||
|
|
4401101fea | ||
|
|
509f887f6c | ||
|
|
266079997a | ||
|
|
f4a3903478 | ||
|
|
f4202df450 | ||
|
|
e619c0c3d3 | ||
|
|
ff0b79b6be | ||
|
|
701d20c112 | ||
|
|
9a45c9fd05 | ||
|
|
146102e82c | ||
|
|
be2c18d608 | ||
|
|
c9644cdcae | ||
|
|
d088e895f8 | ||
|
|
f1a9b2639b | ||
|
|
a1690dcb90 | ||
|
|
2c4088efdd | ||
|
|
da3725a3ac | ||
|
|
81b7460e57 | ||
|
|
c9a1127764 | ||
|
|
6eb9ae2aec | ||
|
|
d3d9ee3092 | ||
|
|
f66fc92859 | ||
|
|
94cbc350a4 | ||
|
|
550e9ec5b2 | ||
|
|
de3463958d | ||
|
|
03d7845124 | ||
|
|
661dceb0d8 | ||
|
|
202686dab6 | ||
|
|
b8da1106eb | ||
|
|
43f7921121 | ||
|
|
f4669db41c | ||
|
|
b3df3364e4 | ||
|
|
b6a76b788d | ||
|
|
e21b07662e | ||
|
|
9b4b0b552b | ||
|
|
bdab7a0c55 | ||
|
|
e269cdab6e | ||
|
|
edc76bcb40 | ||
|
|
cbde5a8e85 | ||
|
|
7fcfc35820 | ||
|
|
f852421d76 | ||
|
|
2321311725 | ||
|
|
38cd1bff86 | ||
|
|
71ee9501f9 | ||
|
|
221670589e | ||
|
|
9a47a664f7 | ||
|
|
7b7b19b71b | ||
|
|
666b9a5751 | ||
|
|
733e1adcba | ||
|
|
8421d8d8e6 | ||
|
|
63ed4c8254 | ||
|
|
3124c55642 | ||
|
|
485eb16fe3 | ||
|
|
a493f07333 | ||
|
|
e543c1aea2 | ||
|
|
0d1d6fdf44 |
No files matched your search
@@ -15,7 +15,7 @@ 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-1ff82e8
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: gcc-5
|
||||
COMPILER: gcc-9
|
||||
ENABLE_QTFRED: OFF
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
@@ -269,6 +269,18 @@ jobs:
|
||||
ARCH: ${{ matrix.arch }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Sign builds
|
||||
working-directory: ./build/bin
|
||||
run: |
|
||||
# make sure OpenAL framework is signed
|
||||
find . -name OpenAL -type f | while read xx; do codesign --force -s - $xx; done
|
||||
find . -name OpenAL.framework -type d | while read xx; do codesign --force -s - $xx; done
|
||||
# make sure dylibs are signed
|
||||
find . -name \*.dylib -type f | while read xx; do codesign --force -s - $xx; done
|
||||
# sign binaries
|
||||
find . -perm +111 -type f | grep MacOS | while read xx; do codesign --force -s - $xx; done
|
||||
# sign apps
|
||||
find . -name \*.app -maxdepth 1 | while read xx; do codesign --force -s - $xx; done
|
||||
- name: Package build result
|
||||
working-directory: ./build/bin
|
||||
# Use GNU tar here (part of runner image) to avoid weird corruption bug with bsdtar
|
||||
|
||||
@@ -44,7 +44,7 @@ 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-1ff82e8
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
# checks-out your repository under $GITHUB_WORKSPACE, so your workflow can access it.
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: gcc-5
|
||||
COMPILER: gcc-9
|
||||
ENABLE_QTFRED: OFF
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
@@ -339,6 +339,18 @@ jobs:
|
||||
ARCH: ${{ matrix.arch }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Sign builds
|
||||
working-directory: ./build/bin
|
||||
run: |
|
||||
# make sure OpenAL framework is signed
|
||||
find . -name OpenAL -type f | while read xx; do codesign --force -s - $xx; done
|
||||
find . -name OpenAL.framework -type d | while read xx; do codesign --force -s - $xx; done
|
||||
# make sure dylibs are signed
|
||||
find . -name \*.dylib -type f | while read xx; do codesign --force -s - $xx; done
|
||||
# sign binaries
|
||||
find . -perm +111 -type f | grep MacOS | while read xx; do codesign --force -s - $xx; done
|
||||
# sign apps
|
||||
find . -name \*.app -maxdepth 1 | while read xx; do codesign --force -s - $xx; done
|
||||
- name: Package build result
|
||||
working-directory: ./build/bin
|
||||
# Use GNU tar here (part of runner image) to avoid weird corruption bug with bsdtar
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
name: Publish Standalone docker image
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'nightly_*'
|
||||
- 'release_*'
|
||||
|
||||
jobs:
|
||||
build_images:
|
||||
if: github.repository == 'scp-fs2open/fs2open.github.com'
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
include:
|
||||
- configuration: FastDebug
|
||||
tag_suffix: -debug
|
||||
- configuration: Release
|
||||
tag_suffix: ""
|
||||
fail-fast: false
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Docker meta
|
||||
id: docker_meta
|
||||
uses: crazy-max/ghaction-docker-meta@v1
|
||||
with:
|
||||
images: ghcr.io/scp-fs2open/standalone_server
|
||||
tag-latest: false
|
||||
|
||||
- name: Login to GitHub Docker Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.CR_PAT }}
|
||||
- name: Build and push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/standalone/Dockerfile
|
||||
push: true
|
||||
tags: ${{ steps.docker_meta.outputs.tags }}${{ matrix.tag_suffix }}
|
||||
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||
build-args: |
|
||||
build_type=${{ matrix.configuration }}
|
||||
@@ -15,7 +15,7 @@ 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-1ff82e8
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: gcc-5
|
||||
COMPILER: gcc-9
|
||||
ENABLE_QTFRED: OFF
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
@@ -282,6 +282,18 @@ jobs:
|
||||
ARCH: ${{ matrix.arch }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Sign builds
|
||||
working-directory: ./build/bin
|
||||
run: |
|
||||
# make sure OpenAL framework is signed
|
||||
find . -name OpenAL -type f | while read xx; do codesign --force -s - $xx; done
|
||||
find . -name OpenAL.framework -type d | while read xx; do codesign --force -s - $xx; done
|
||||
# make sure dylibs are signed
|
||||
find . -name \*.dylib -type f | while read xx; do codesign --force -s - $xx; done
|
||||
# sign binaries
|
||||
find . -perm +111 -type f | grep MacOS | while read xx; do codesign --force -s - $xx; done
|
||||
# sign apps
|
||||
find . -name \*.app -maxdepth 1 | while read xx; do codesign --force -s - $xx; done
|
||||
- name: Package build result
|
||||
working-directory: ./build/bin
|
||||
# Use GNU tar here (part of runner image) to avoid weird corruption bug with bsdtar
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
compiler: [gcc-5, gcc-13, clang-16]
|
||||
compiler: [gcc-9, gcc-13, clang-16]
|
||||
cmake_options: [""]
|
||||
include:
|
||||
# Also include configurations that check if the code compiles without the graphics backends
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
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-1ff82e8
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
compiler: [gcc-5, gcc-13, clang-16]
|
||||
compiler: [gcc-9, gcc-13, clang-16]
|
||||
cmake_options: [""]
|
||||
include:
|
||||
# Also include configurations that check if the code compiles without the graphics backends
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
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-1ff82e8
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
|
||||
@@ -2,14 +2,17 @@ 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
|
||||
# keep this from running on everyone's fork
|
||||
# if: github.ref == 'refs/heads/master'
|
||||
|
||||
#This mode is for testing
|
||||
#on: [push, pull_request]
|
||||
|
||||
# In production, push on a specific schedule
|
||||
on:
|
||||
schedule:
|
||||
- cron: "1 0 * * 5" # Run once per a week on Friday morning (midnight UTC, 4 AM EST), to avoid Coverity's submission limits
|
||||
|
||||
- cron: "57 18 * * *" # Run once per a week on Friday morning (4 AM EST), to avoid Coverity's submission limits
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.12
|
||||
coverity_email: [email protected]
|
||||
@@ -18,26 +21,17 @@ env:
|
||||
jobs:
|
||||
build:
|
||||
name: Build FSO With Coverity Wrapper
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-1ff82e8
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- { name: "GCC on ubuntu", os: ubuntu-latest, build_type: "Release" }
|
||||
steps:
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
sudo apt-get install ninja-build
|
||||
sudo apt install cmake libsdl2-dev g++
|
||||
sudo apt-get install libopenal-dev
|
||||
sudo apt-get install -y libudev-dev
|
||||
sudo apt-get install doxygen
|
||||
sudo apt install graphviz
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive # `true` to checkout submodules, `recursive` to recursively checkout submodules
|
||||
submodules: true # `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
|
||||
@@ -51,17 +45,10 @@ jobs:
|
||||
echo "$(pwd)/cov-scan/bin" >> $GITHUB_PATH
|
||||
echo "NPROC=$(getconf _NPROCESSORS_ONLN)" >> $GITHUB_ENV
|
||||
|
||||
- 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 for FSO
|
||||
env:
|
||||
CONFIGURATION: Release
|
||||
compiler: gcc-5
|
||||
CONFIGURATION: FastDebug
|
||||
COMPILER: gcc-9
|
||||
ENABLE_QTFRED: OFF
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ "$COMPILER" = "gcc-5" ]; then
|
||||
export CC=gcc-5
|
||||
export CXX=g++-5
|
||||
if [ "$COMPILER" = "gcc-9" ]; then
|
||||
export CC=gcc-9
|
||||
export CXX=g++-9
|
||||
fi
|
||||
if [ "$COMPILER" = "gcc-13" ]; then
|
||||
export CC=gcc-13
|
||||
|
||||
@@ -7,15 +7,15 @@ PLACEHOLDER
|
||||
[b]Deprecations:[/b]
|
||||
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.
|
||||
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. Any features listed under Deprecations 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=99015.0]23.2.1 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.
|
||||
[b]All platforms: [/b] For every day use, we recommend [url=https://knossosnet.github.io/Knossos-Release-Page/]Knossos.NET[/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=https://www.hard-light.net/forums/index.php?topic=89162]wxLauncher 0.12.x Test Build[/url] (legacy project for a unified launcher)
|
||||
[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
|
||||
@@ -41,7 +41,7 @@ Linux: [url=https://www.hard-light.net/forums/index.php/topic,53206.0.html]YAL[
|
||||
|
||||
[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]
|
||||
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!
|
||||
Don't want to deal with that? Use [url=https://knossosnet.github.io/Knossos-Release-Page/]Knossos.NET[/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]
|
||||
|
||||
+2
-2
@@ -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 24)
|
||||
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
|
||||
|
||||
@@ -47,7 +47,7 @@ ProgramInstance::ProgramInstance(const actions::Program* program) : _program(pro
|
||||
|
||||
ProgramState ProgramInstance::step()
|
||||
{
|
||||
if (!_locals.host.IsValid()) {
|
||||
if (!_locals.host.isValid()) {
|
||||
return ProgramState::Done;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -597,8 +597,8 @@ extern void set_predicted_enemy_pos(vec3d *predicted_enemy_pos, object *pobjp, v
|
||||
extern int is_instructor(object *objp);
|
||||
extern int find_enemy(int objnum, float range, int max_attackers, int ship_info_index = -1);
|
||||
|
||||
float ai_get_weapon_speed(ship_weapon *swp);
|
||||
void set_predicted_enemy_pos_turret(vec3d *predicted_enemy_pos, vec3d *gun_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, float weapon_speed, float time_enemy_in_range);
|
||||
float ai_get_weapon_speed(const ship_weapon *swp);
|
||||
void set_predicted_enemy_pos_turret(vec3d *predicted_enemy_pos, const vec3d *gun_pos, const object *pobjp, const vec3d *enemy_pos, const vec3d *enemy_vel, float weapon_speed, float time_enemy_in_range);
|
||||
|
||||
// function to change rearm status for ai ships (called from sexpression code)
|
||||
extern void ai_set_rearm_status( int team, int new_status );
|
||||
|
||||
@@ -157,7 +157,9 @@ namespace AI {
|
||||
Whackable_debris,
|
||||
Whackable_asteroids,
|
||||
Dynamic_goals_afterburn_hard,
|
||||
Player_orders_afterburn_hard,
|
||||
Hudsquadmsg_tactical_disarm_disable,
|
||||
Align_to_target_when_guarding_still,
|
||||
|
||||
NUM_VALUES
|
||||
};
|
||||
|
||||
@@ -625,8 +625,12 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
set_flag(profile, "$dynamic goals afterburn hard:", AI::Profile_Flags::Dynamic_goals_afterburn_hard);
|
||||
|
||||
set_flag(profile, "$player orders afterburn hard:", AI::Profile_Flags::Player_orders_afterburn_hard);
|
||||
|
||||
set_flag(profile, "$hud squad messages use tactical disarm/disable:", AI::Profile_Flags::Hudsquadmsg_tactical_disarm_disable);
|
||||
|
||||
set_flag(profile, "$align to target when guarding stationary ship:", AI::Profile_Flags::Align_to_target_when_guarding_still);
|
||||
|
||||
// if we've been through once already and are at the same place, force a move
|
||||
if (saved_Mp && (saved_Mp == Mp))
|
||||
{
|
||||
|
||||
+6
-6
@@ -76,7 +76,7 @@ extern void big_ship_collide_recover_start(object *objp, object *big_objp, vec3d
|
||||
// If truly_random flag set (haha), then generate a pretty random number. Otherwise, generate a static rand which
|
||||
// tends to not change from frame to frame.
|
||||
// Try four times and choose nearest point to increase chance of getting a good point.
|
||||
void ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal, ship_subsys *ss)
|
||||
void ai_bpap(const object *objp, const vec3d *attacker_objp_pos, const vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal, const ship_subsys *ss)
|
||||
{
|
||||
float nearest_dist;
|
||||
vec3d result_point, best_point;
|
||||
@@ -193,7 +193,7 @@ done_1:
|
||||
//
|
||||
// Note: Default value for fov is 1.0f 1.0f means don't use fov parameter.
|
||||
// If fov != 1.0f, try up to four times to find a point that's in the field of view.
|
||||
void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
|
||||
void ai_big_pick_attack_point_turret(const object *objp, ship_subsys *ssp, const vec3d *gpos, const vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
|
||||
{
|
||||
if (!timestamp_elapsed(ssp->turret_pick_big_attack_point_timestamp)) {
|
||||
vec3d result_point;
|
||||
@@ -213,7 +213,7 @@ void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos
|
||||
// Note: Default value for fov is 1.0f 1.0f means don't use fov parameter.
|
||||
// If fov != 1.0f, try up to four times to find a point that's in the field of view.
|
||||
// Note, attacker_objp can be a ship or a weapon.
|
||||
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov)
|
||||
void ai_big_pick_attack_point(const object *objp, const object *attacker_objp, vec3d *attack_point, float fov)
|
||||
{
|
||||
Assert(objp->instance > -1);
|
||||
Assert(objp->type == OBJ_SHIP);
|
||||
@@ -411,7 +411,7 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
}
|
||||
}
|
||||
|
||||
if ( ship_subsystem_in_sight(En_objp, aip->targeted_subsys, &geye, &gsubpos, 1) ) {
|
||||
if ( ship_subsystem_in_sight(En_objp, aip->targeted_subsys, &geye, &gsubpos, true) ) {
|
||||
subsys_in_sight = 1;
|
||||
}
|
||||
}
|
||||
@@ -541,7 +541,7 @@ bool ai_new_maybe_reposition_attack_subsys() {
|
||||
get_subsystem_pos(&gsubpos, target_objp, aip->targeted_subsys);
|
||||
|
||||
// you're in sight! shoot it!
|
||||
if (ship_subsystem_in_sight(En_objp, aip->targeted_subsys, &geye, &gsubpos, 0))
|
||||
if (ship_subsystem_in_sight(En_objp, aip->targeted_subsys, &geye, &gsubpos, false))
|
||||
return false;
|
||||
|
||||
// not in sight, gotta get there
|
||||
@@ -1034,7 +1034,7 @@ void ai_big_chase()
|
||||
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 ballistic_aiming = !IS_VEC_NULL(&The_mission.gravity) && wip && wip->gravity_const != 0.0f;
|
||||
bool valid_ballistic_trajectory = true;
|
||||
|
||||
if (!ballistic_aiming) {
|
||||
|
||||
+2
-2
@@ -24,8 +24,8 @@ void ai_big_subsys_path_cleanup(ai_info *aip);
|
||||
void ai_big_strafe();
|
||||
int ai_big_maybe_enter_strafe_mode(const object *objp, int weapon_objnum);
|
||||
void ai_big_strafe_maybe_attack_turret(const object *ship_objp, const object *weapon_objp);
|
||||
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov=1.0f);
|
||||
void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float weapon_travel_dist, float fov=1.0f);
|
||||
void ai_big_pick_attack_point(const object *objp, const object *attacker_objp, vec3d *attack_point, float fov=1.0f);
|
||||
void ai_big_pick_attack_point_turret(const object *objp, ship_subsys *ssp, const vec3d *gpos, const vec3d *gvec, vec3d *attack_point, float weapon_travel_dist, float fov=1.0f);
|
||||
|
||||
// default distance for following subsystem path points --wookieejedi
|
||||
// the value is 5 because that was the original value specified in ai_big_maybe_follow_subsys_path()
|
||||
|
||||
+41
-36
@@ -1021,7 +1021,7 @@ void ai_level_init()
|
||||
/**
|
||||
* Check if object is a stealth ship
|
||||
*/
|
||||
bool is_object_stealth_ship(object* objp)
|
||||
bool is_object_stealth_ship(const object *objp)
|
||||
{
|
||||
if (objp->type == OBJ_SHIP) {
|
||||
if (Ships[objp->instance].flags[Ship::Ship_Flags::Stealth]) {
|
||||
@@ -1109,7 +1109,7 @@ float get_skill_stealth_dot_scaler()
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
int ai_is_stealth_visible(object *viewer_objp, object *stealth_objp)
|
||||
int ai_is_stealth_visible(const object *viewer_objp, const object *stealth_objp)
|
||||
{
|
||||
ship *shipp;
|
||||
vec3d vec_to_stealth;
|
||||
@@ -1905,7 +1905,7 @@ int Player_attacking_enabled = 1;
|
||||
/**
|
||||
* Determine whether an object is targetable within a nebula
|
||||
*/
|
||||
int object_is_targetable(object *target, ship *viewer)
|
||||
bool object_is_targetable(const object *target, const ship *viewer)
|
||||
{
|
||||
// if target is ship, check if visible by team
|
||||
if (target->type == OBJ_SHIP)
|
||||
@@ -2413,7 +2413,7 @@ int find_nearby_threat(int objnum, int enemy_team_mask, float range, int *count)
|
||||
/**
|
||||
* Number of live turrets with target_objnum
|
||||
*/
|
||||
int num_turrets_attacking(object *turret_parent, int target_objnum)
|
||||
int num_turrets_attacking(const object *turret_parent, int target_objnum)
|
||||
{
|
||||
ship_subsys *ss;
|
||||
ship *shipp;
|
||||
@@ -3515,6 +3515,7 @@ void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags, int
|
||||
aip->wp_index = start_index;
|
||||
aip->wp_flags = wp_flags;
|
||||
aip->mode = AIM_WAYPOINTS;
|
||||
aip->submode_parm0 = start_index; // keep track of the start index because we need it for Fix_ai_path_order_bug
|
||||
|
||||
Assert(aip->active_goal != AI_ACTIVE_GOAL_DYNAMIC);
|
||||
}
|
||||
@@ -3636,7 +3637,7 @@ int Debug_k = 0;
|
||||
*
|
||||
* Return this value. Return value of 0.0f means no collision is possible.
|
||||
*/
|
||||
float compute_collision_time(vec3d *targpos, vec3d *targvel, vec3d *attackpos, float weapon_speed)
|
||||
float compute_collision_time(const vec3d *targpos, const vec3d *targvel, const vec3d *attackpos, float weapon_speed)
|
||||
{
|
||||
vec3d vec_to_target;
|
||||
float pos_dot_vel;
|
||||
@@ -6305,7 +6306,7 @@ int ai_fire_primary_weapon(object *objp)
|
||||
// threshold => max distance from pos to be considered "near"
|
||||
//
|
||||
// exit: number of ships within threshold units of pos
|
||||
int num_nearby_fighters(int enemy_team_mask, vec3d *pos, float threshold)
|
||||
int num_nearby_fighters(int enemy_team_mask, const vec3d *pos, float threshold)
|
||||
{
|
||||
ship_obj *so;
|
||||
object *ship_objp;
|
||||
@@ -6476,7 +6477,7 @@ bool ai_select_secondary_weapon(object *objp, ship_weapon *swp, flagset<Weapon::
|
||||
/**
|
||||
* @return number of objects homing on object *target_objp
|
||||
*/
|
||||
int compute_num_homing_objects(object *target_objp)
|
||||
int compute_num_homing_objects(const object *target_objp)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
@@ -6558,7 +6559,7 @@ float compute_incoming_payload(object *target_objp)
|
||||
// OR: secondary los flag is set but no line of sight is availabe
|
||||
// Note: If player is attacking a ship, that ship is allowed to fire at player. Otherwise, we get in a situation in which
|
||||
// player is attacking a large ship, but that large ship is not defending itself with missiles.
|
||||
int check_ok_to_fire(int objnum, int target_objnum, weapon_info *wip, int secondary_bank, ship_subsys* turret)
|
||||
bool check_ok_to_fire(int objnum, int target_objnum, const weapon_info *wip, int secondary_bank, const vec3d *firing_pos_global)
|
||||
{
|
||||
int num_homers = 0;
|
||||
|
||||
@@ -6574,8 +6575,8 @@ int check_ok_to_fire(int objnum, int target_objnum, weapon_info *wip, int second
|
||||
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Require_exact_los] || wip->wi_flags[Weapon::Info_Flags::Require_exact_los]) {
|
||||
//Check if th AI has Line of Sight and is allowed to fire
|
||||
if (!check_los(objnum, target_objnum, 10.0f, -1, secondary_bank, turret)) {
|
||||
return 0;
|
||||
if (!check_los(objnum, target_objnum, 10.0f, -1, secondary_bank, firing_pos_global)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6589,14 +6590,14 @@ int check_ok_to_fire(int objnum, int target_objnum, weapon_info *wip, int second
|
||||
// At Easy, 2/7...at Expert, 5/7
|
||||
int t = ((Missiontime /(65536*10)) ^ target_objnum ^ 0x01) % (NUM_SKILL_LEVELS+2);
|
||||
if (t > Ai_info[Ships[tobjp->instance].ai_index].ai_chance_to_use_missiles_on_plr) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
int swarmers = 0;
|
||||
if (wip->wi_flags[Weapon::Info_Flags::Swarm])
|
||||
swarmers = 2; // Note, always want to be able to fire swarmers if no currently incident homers.
|
||||
if (The_mission.ai_profile->max_allowed_player_homers[Game_skill_level] < num_homers + swarmers) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
} else if (num_homers > 3) {
|
||||
float incoming_payload;
|
||||
@@ -6604,22 +6605,22 @@ int check_ok_to_fire(int objnum, int target_objnum, weapon_info *wip, int second
|
||||
incoming_payload = compute_incoming_payload(&Objects[target_objnum]);
|
||||
|
||||
if (incoming_payload > tobjp->hull_strength) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Returns true if *aip has a line of sight to its current target.
|
||||
// threshold defines the minimum radius for an object to be considered relevant for LoS
|
||||
bool check_los(int objnum, int target_objnum, float threshold, int primary_bank, int secondary_bank, ship_subsys* turret) {
|
||||
bool check_los(int objnum, int target_objnum, float threshold, int primary_bank, int secondary_bank, const vec3d *firing_pos_global) {
|
||||
|
||||
//Do both checks over an XOR-Check for more detailed messages
|
||||
int sources = (primary_bank != -1 ? 1 : 0) + (secondary_bank != -1 ? 1 : 0) + (turret != nullptr ? 1 : 0);
|
||||
int sources = (primary_bank != -1 ? 1 : 0) + (secondary_bank != -1 ? 1 : 0) + (firing_pos_global != nullptr ? 1 : 0);
|
||||
Assertion(sources >= 1, "Cannot check line of sight from a model with neither a primar bank, nor secondary bank nor a turret set as a source.");
|
||||
Assertion(sources <= 1, "Cannot check line of sight from a model with more than one source set.");
|
||||
|
||||
@@ -6627,10 +6628,8 @@ bool check_los(int objnum, int target_objnum, float threshold, int primary_bank,
|
||||
|
||||
object* firing_ship = &Objects[objnum];
|
||||
|
||||
if (turret != nullptr) {
|
||||
vec3d turret_fvec;
|
||||
//It doesn't like not having an fvec output vector, so give it a dummy vector
|
||||
ship_get_global_turret_gun_info(firing_ship, turret, &start, &turret_fvec, 1, nullptr);
|
||||
if (firing_pos_global != nullptr) {
|
||||
start = *firing_pos_global;
|
||||
} else {
|
||||
bool is_primary = secondary_bank == -1;
|
||||
ship *shipp = &Ships[firing_ship->instance];
|
||||
@@ -6942,7 +6941,7 @@ float ai_get_weapon_dist(ship_weapon *swp)
|
||||
return MIN((Weapon_info[weapon_num].max_speed * Weapon_info[weapon_num].lifetime), Weapon_info[weapon_num].weapon_range);
|
||||
}
|
||||
|
||||
float ai_get_weapon_speed(ship_weapon *swp)
|
||||
float ai_get_weapon_speed(const ship_weapon *swp)
|
||||
{
|
||||
int bank_num, weapon_num;
|
||||
|
||||
@@ -6986,7 +6985,7 @@ weapon_info* ai_get_weapon(ship_weapon *swp)
|
||||
// Also, stuff globals G_predicted_pos, G_collision_time and G_fire_pos.
|
||||
// *pobjp object firing the weapon
|
||||
// *eobjp object being fired upon
|
||||
void set_predicted_enemy_pos_turret(vec3d *predicted_enemy_pos, vec3d *gun_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, float weapon_speed, float time_enemy_in_range)
|
||||
void set_predicted_enemy_pos_turret(vec3d *predicted_enemy_pos, const vec3d *gun_pos, const object *pobjp, const vec3d *enemy_pos, const vec3d *enemy_vel, float weapon_speed, float time_enemy_in_range)
|
||||
{
|
||||
ship *shipp = &Ships[pobjp->instance];
|
||||
float range_time;
|
||||
@@ -10243,7 +10242,7 @@ void guard_object_was_hit(object *guard_objp, object *hitter_objp)
|
||||
}
|
||||
|
||||
// don't attack if you can't see him
|
||||
if ( awacs_get_level(hitter_objp, &Ships[aip->shipnum], 1) < 1 ) {
|
||||
if ( awacs_get_level(hitter_objp, &Ships[aip->shipnum], true) < 1.0f ) {
|
||||
// if he's a stealth and visible, but not targetable, ok to attack.
|
||||
if ( is_object_stealth_ship(hitter_objp) ) {
|
||||
if ( ai_is_stealth_visible(guard_objp, hitter_objp) != STEALTH_IN_FRUSTUM ) {
|
||||
@@ -10893,14 +10892,14 @@ void ai_guard()
|
||||
// Goal point is in front.
|
||||
// If close to goal point, don't change direction, just change speed.
|
||||
if (dist_to_goal_point > Pl_objp->radius + 10.0f) {
|
||||
turn_towards_point(Pl_objp, &goal_point, NULL, 0.0f);
|
||||
turn_towards_point(Pl_objp, &goal_point, nullptr, 0.0f);
|
||||
}
|
||||
|
||||
set_accel_for_target_speed(Pl_objp, guard_objp->phys_info.speed + (dist_to_goal_point-40.0f)/20.0f);
|
||||
}
|
||||
} else {
|
||||
if (dot_to_goal_point > 0.8f) {
|
||||
turn_towards_point(Pl_objp, &goal_point, NULL, 0.0f);
|
||||
turn_towards_point(Pl_objp, &goal_point, nullptr, 0.0f);
|
||||
set_accel_for_target_speed(Pl_objp, guard_objp->phys_info.speed + dist_to_goal_point*0.1f);
|
||||
} else {
|
||||
set_accel_for_target_speed(Pl_objp, guard_objp->phys_info.speed - dist_to_goal_point*0.1f - 1.0f);
|
||||
@@ -10909,10 +10908,14 @@ void ai_guard()
|
||||
// consider guard object STILL
|
||||
} else if (guard_objp->radius < 50.0f) {
|
||||
if (dist_to_goal_point > 15.0f) {
|
||||
turn_towards_point(Pl_objp, &goal_point, NULL, 0.0f);
|
||||
turn_towards_point(Pl_objp, &goal_point, nullptr, 0.0f);
|
||||
set_accel_for_target_speed(Pl_objp, (dist_to_goal_point-10.0f)/2.0f);
|
||||
} else if (Pl_objp->phys_info.speed < 1.0f) {
|
||||
turn_away_from_point(Pl_objp, &guard_objp->pos, 0.0f);
|
||||
if (aip->ai_profile_flags[AI::Profile_Flags::Align_to_target_when_guarding_still]) {
|
||||
turn_towards_point(Pl_objp, &guard_objp->pos, nullptr, 0.0f, &guard_objp->orient);
|
||||
} else {
|
||||
turn_away_from_point(Pl_objp, &guard_objp->pos, 0.0f);
|
||||
}
|
||||
}
|
||||
// It's a big ship
|
||||
} else if (dist_to_guardobj > MAX_GUARD_DIST + Pl_objp->radius + guard_objp->radius) {
|
||||
@@ -12612,7 +12615,12 @@ int ai_formation()
|
||||
if (aip->mode == AIM_WAYPOINTS) {
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_ai_path_order_bug]){
|
||||
// skip if wing leader has no waypoint order or a different waypoint list
|
||||
if ((laip->mode != AIM_WAYPOINTS) || !(aip->wp_list == laip->wp_list)){
|
||||
// ...or if it's a different start index or direction
|
||||
if ( (laip->mode != AIM_WAYPOINTS)
|
||||
|| (laip->wp_list != aip->wp_list)
|
||||
|| (laip->submode_parm0 != aip->submode_parm0)
|
||||
|| ((laip->wp_flags & WPF_BACKTRACK) != (aip->wp_flags & WPF_BACKTRACK))
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -13900,10 +13908,7 @@ int ai_acquire_depart_path(object *pl_objp, int parent_objnum, int allowed_path_
|
||||
*/
|
||||
void ai_bay_depart()
|
||||
{
|
||||
ai_info *aip;
|
||||
int anchor_shipnum;
|
||||
|
||||
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
|
||||
auto aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
|
||||
|
||||
// if no path to follow, leave this mode
|
||||
if ( aip->path_start < 0 ) {
|
||||
@@ -13912,8 +13917,8 @@ void ai_bay_depart()
|
||||
}
|
||||
|
||||
// check if parent ship valid; if not, abort depart
|
||||
anchor_shipnum = ship_name_lookup(Parse_names[Ships[Pl_objp->instance].departure_anchor]);
|
||||
if (anchor_shipnum < 0 || !ship_useful_for_departure(anchor_shipnum, Ships[Pl_objp->instance].departure_path_mask))
|
||||
auto anchor_ship_entry = ship_registry_get(Parse_names[Ships[Pl_objp->instance].departure_anchor]);
|
||||
if (!anchor_ship_entry || !ship_useful_for_departure(anchor_ship_entry->shipnum, Ships[Pl_objp->instance].departure_path_mask))
|
||||
{
|
||||
mprintf(("Aborting bay departure!\n"));
|
||||
aip->mode = AIM_NONE;
|
||||
@@ -13924,7 +13929,7 @@ void ai_bay_depart()
|
||||
|
||||
ai_manage_bay_doors(Pl_objp, aip, false);
|
||||
|
||||
if ( Ships[anchor_shipnum].bay_doors_status != MA_POS_READY )
|
||||
if ( anchor_ship_entry->shipp()->bay_doors_status != MA_POS_READY )
|
||||
return;
|
||||
|
||||
// follow the path to the final point
|
||||
@@ -15812,7 +15817,7 @@ void maybe_set_dynamic_chase(ai_info *aip, int hitter_objnum)
|
||||
}
|
||||
|
||||
// only set as target if can be targeted.
|
||||
if (awacs_get_level(&Objects[hitter_objnum], &Ships[aip->shipnum], 1) < 1) {
|
||||
if (awacs_get_level(&Objects[hitter_objnum], &Ships[aip->shipnum], true) < 1.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -751,6 +751,9 @@ void ai_add_goal_sub_player(int type, int mode, int submode, const char *target_
|
||||
if ( target_name != NULL )
|
||||
aigp->target_name = ai_get_goal_target_name( target_name, &aigp->target_name_index );
|
||||
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Player_orders_afterburn_hard])
|
||||
aigp->flags.set(AI::Goal_Flags::Afterburn_hard);
|
||||
|
||||
|
||||
// special case certain orders from player so that ships continue to do the right thing
|
||||
|
||||
|
||||
@@ -14,24 +14,24 @@
|
||||
#include "weapon/weapon.h"
|
||||
|
||||
//Returns true if the specified object is a stealth ship, false if not
|
||||
bool is_object_stealth_ship(object* objp);
|
||||
bool is_object_stealth_ship(const object* objp);
|
||||
|
||||
//Number of live turrets on the object attacking
|
||||
int num_turrets_attacking(object *turret_parent, int target_objnum);
|
||||
int num_turrets_attacking(const object *turret_parent, int target_objnum);
|
||||
|
||||
//Determine whether an object is targetable within a nebula (checks for stealth)
|
||||
int object_is_targetable(object *target, ship *viewer);
|
||||
bool object_is_targetable(const object *target, const ship *viewer);
|
||||
|
||||
//Returns the number of enemy fighters within threshold of pos.
|
||||
int num_nearby_fighters(int enemy_team_mask, vec3d *pos, float threshold);
|
||||
int num_nearby_fighters(int enemy_team_mask, const vec3d *pos, float threshold);
|
||||
|
||||
//Returns true if OK for *aip to fire its current weapon at its current target.
|
||||
int check_ok_to_fire(int objnum, int target_objnum, weapon_info *wip, int secondary_bank, ship_subsys* turret);
|
||||
bool check_ok_to_fire(int objnum, int target_objnum, const weapon_info *wip, int secondary_bank, const vec3d *firing_pos_global);
|
||||
|
||||
//Returns true if *aip has a line of sight to its current target.
|
||||
bool check_los(int objnum, int target_objnum, float threshold, int primary_bank, int secondary_bank, ship_subsys* turret);
|
||||
bool check_los(int objnum, int target_objnum, float threshold, int primary_bank, int secondary_bank, const vec3d *firing_pos_global);
|
||||
|
||||
//Does all the stuff needed to aim and fire a turret.
|
||||
void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss);
|
||||
void ai_turret_execute_behavior(const ship *shipp, ship_subsys *ss);
|
||||
|
||||
#endif
|
||||
+1
-1
@@ -389,7 +389,7 @@ ai_achievability ai_lua_is_achievable(const ai_goal* aigp, int objnum){
|
||||
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()) {
|
||||
if (!enumData.isValid()) {
|
||||
Error(LOCATION, "LuaAI SEXP achievability hook returned an invalid avilability enum.");
|
||||
return ai_achievability::ACHIEVABLE;
|
||||
}
|
||||
|
||||
+146
-195
@@ -118,7 +118,7 @@ void turret_instance_find_world_orient(matrix* out_mat, int model_instance_num,
|
||||
* @param tpos Turret initial position
|
||||
* @param dist Distance from turret to center point of object
|
||||
*
|
||||
* @return 1 if objp is in fov of the specified turret. Otherwise return 0.
|
||||
* @return true if objp is in fov of the specified turret. Otherwise return false.
|
||||
*/
|
||||
bool object_in_turret_fov(const object *objp, const ship_subsys *ss, const vec3d *tvec, const vec3d *tpos, float dist)
|
||||
{
|
||||
@@ -175,9 +175,9 @@ bool object_in_turret_fov(const object *objp, const ship_subsys *ss, const vec3d
|
||||
* @param bomb_objp Bomb specified
|
||||
* @param ship_objp Ship specified
|
||||
*
|
||||
* @return 1 if bomb_objp is headed towards ship_objp
|
||||
* @return true if bomb_objp is headed towards ship_objp
|
||||
*/
|
||||
int bomb_headed_towards_ship(object *bomb_objp, object *ship_objp)
|
||||
bool bomb_headed_towards_ship(const object *bomb_objp, const object *ship_objp)
|
||||
{
|
||||
float dot;
|
||||
vec3d bomb_to_ship_vector;
|
||||
@@ -185,11 +185,7 @@ int bomb_headed_towards_ship(object *bomb_objp, object *ship_objp)
|
||||
vm_vec_normalized_dir(&bomb_to_ship_vector, &ship_objp->pos, &bomb_objp->pos);
|
||||
dot = vm_vec_dot(&bomb_objp->orient.vec.fvec, &bomb_to_ship_vector);
|
||||
|
||||
if ( dot > 0 ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ( dot > 0 );
|
||||
}
|
||||
|
||||
// Set active weapon for turret
|
||||
@@ -201,7 +197,7 @@ int bomb_headed_towards_ship(object *bomb_objp, object *ship_objp)
|
||||
* @note All non-negative return values are expressed in what I like to call "widx"s.
|
||||
* @return -1 if unable to find a weapon for the target at all.
|
||||
*/
|
||||
int turret_select_best_weapon(ship_subsys *turret, object * /*target*/)
|
||||
int turret_select_best_weapon(const ship_subsys *turret, const object * /*target*/)
|
||||
{
|
||||
//TODO: Fill this out with extraodinary gun-picking algorithms
|
||||
if(turret->weapons.num_primary_banks > 0)
|
||||
@@ -335,7 +331,7 @@ bool turret_weapon_has_subtype(const ship_weapon *swp, int subtype)
|
||||
*
|
||||
* @return a pointer to the Weapon_info for weapon_num
|
||||
*/
|
||||
weapon_info *get_turret_weapon_wip(ship_weapon *swp, int weapon_num)
|
||||
const weapon_info *get_turret_weapon_wip(const ship_weapon *swp, int weapon_num)
|
||||
{
|
||||
Assert(weapon_num < MAX_SHIP_WEAPONS);
|
||||
Assert(weapon_num >= 0);
|
||||
@@ -352,7 +348,7 @@ weapon_info *get_turret_weapon_wip(ship_weapon *swp, int weapon_num)
|
||||
return &Weapon_info[wi_index];
|
||||
}
|
||||
|
||||
int get_turret_weapon_next_fire_stamp(ship_weapon *swp, int weapon_num)
|
||||
int get_turret_weapon_next_fire_stamp(const ship_weapon *swp, int weapon_num)
|
||||
{
|
||||
Assert(weapon_num < MAX_SHIP_WEAPONS);
|
||||
Assert(weapon_num >= 0);
|
||||
@@ -379,7 +375,7 @@ void set_turret_weapon_next_fire_stamp(ship_weapon *swp, int weapon_num, int del
|
||||
*
|
||||
* @todo This function is kinda slow
|
||||
*/
|
||||
float longest_turret_weapon_range(ship_weapon *swp)
|
||||
float longest_turret_weapon_range(const ship_weapon *swp)
|
||||
{
|
||||
float longest_range_so_far = 0.0f;
|
||||
float weapon_range;
|
||||
@@ -770,10 +766,10 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
* @param laser_flag
|
||||
* @param missile_flag
|
||||
*/
|
||||
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)
|
||||
int get_nearest_turret_objnum(int turret_parent_objnum, const ship_subsys *turret_subsys, int enemy_team_mask, const vec3d *tpos, const 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)
|
||||
{
|
||||
eval_enemy_obj_struct eeo;
|
||||
ship_weapon *swp = &turret_subsys->weapons;
|
||||
auto swp = &turret_subsys->weapons;
|
||||
|
||||
// list of stuff to go thru
|
||||
ship_obj *so;
|
||||
@@ -1067,7 +1063,7 @@ DCF_BOOL(use_parent_target, Use_parent_target)
|
||||
* @param tvec Forward vector of turret (world coords)
|
||||
* @param current_enemy Objnum of current turret target
|
||||
*/
|
||||
int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy)
|
||||
int find_turret_enemy(const ship_subsys *turret_subsys, int objnum, const vec3d *tpos, const vec3d *tvec, int current_enemy)
|
||||
{
|
||||
int enemy_team_mask, enemy_objnum;
|
||||
ship_info *sip;
|
||||
@@ -1188,8 +1184,6 @@ void ship_get_global_turret_info(const object *objp, const model_subsystem *tp,
|
||||
model_instance_local_to_global_dir(gvec, &tp->turret_norm, model_instance_num, tp->subobj_num, &objp->orient, true);
|
||||
}
|
||||
|
||||
void turret_ai_update_aim(ai_info *aip, object *En_Objp, ship_subsys *ss);
|
||||
|
||||
/**
|
||||
* Given an object and a turret on that object, return the actual firing point of the gun and its normal.
|
||||
*
|
||||
@@ -1200,86 +1194,44 @@ void turret_ai_update_aim(ai_info *aip, object *En_Objp, ship_subsys *ss);
|
||||
* @param objp Pointer to object
|
||||
* @param ssp Pointer to turret subsystem
|
||||
* @param gpos Absolute position of gun firing point
|
||||
* @param avg_origin Use virtual gun pos corresponding to the average of the firing points
|
||||
* @param gvec Vector from *gpos to *targetp
|
||||
* @param use_angles Use current angles
|
||||
* @param targetp Pointer to target object
|
||||
* @param targetp Absolute position of target object
|
||||
*/
|
||||
void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, int use_angles, vec3d *targetp)
|
||||
void ship_get_global_turret_gun_info(const object *objp, const ship_subsys *ssp, vec3d *gpos, bool avg_origin, vec3d *gvec, bool use_angles, const vec3d *targetp)
|
||||
{
|
||||
vec3d * gun_pos;
|
||||
vec3d *gun_pos;
|
||||
model_subsystem *tp = ssp->system_info;
|
||||
polymodel_instance *pmi = model_get_instance(Ships[objp->instance].model_instance_num);
|
||||
polymodel *pm = model_get(pmi->model_num);
|
||||
|
||||
gun_pos = &tp->turret_firing_point[ssp->turret_next_fire_pos % tp->turret_num_firing_points];
|
||||
vec3d avg_gun_pos;
|
||||
if (avg_origin) {
|
||||
vm_vec_avg_n(&avg_gun_pos, tp->turret_num_firing_points, tp->turret_firing_point);
|
||||
gun_pos = &avg_gun_pos;
|
||||
} else {
|
||||
gun_pos = &tp->turret_firing_point[ssp->turret_next_fire_pos % tp->turret_num_firing_points];
|
||||
}
|
||||
|
||||
model_instance_local_to_global_point(gpos, gun_pos, pm, pmi, tp->turret_gun_sobj, &objp->orient, &objp->pos);
|
||||
|
||||
// we might not need to calculate this
|
||||
if (!gvec)
|
||||
return;
|
||||
|
||||
if (use_angles) {
|
||||
model_instance_local_to_global_dir(gvec, &tp->turret_norm, pm, pmi, tp->turret_gun_sobj, &objp->orient);
|
||||
} else if (tp->flags[Model::Subsystem_Flags::Share_fire_direction]) {
|
||||
vec3d avg, tmp_pos, tmp_target, enemy_point, turret_norm;
|
||||
vm_vec_avg_n(&avg, tp->turret_num_firing_points, tp->turret_firing_point);
|
||||
|
||||
model_instance_local_to_global_point(&tmp_pos, &avg, pm, pmi, tp->turret_gun_sobj, &objp->orient, &objp->pos);
|
||||
|
||||
if (targetp == nullptr) {
|
||||
ship* shipp = &Ships[Objects[ssp->parent_objnum].instance];
|
||||
Assertion(ssp->turret_enemy_objnum >= 0, "The turret enemy object number %d for %s on ship name %s is invalid.", ssp->turret_enemy_objnum, ssp->sub_name, shipp->ship_name);
|
||||
object *lep = &Objects[ssp->turret_enemy_objnum];
|
||||
|
||||
int best_weapon_tidx = turret_select_best_weapon(ssp, lep);
|
||||
|
||||
//This turret doesn't have any good weapons
|
||||
if (best_weapon_tidx < 0)
|
||||
return;
|
||||
|
||||
weapon_info *wip = get_turret_weapon_wip(&ssp->weapons, best_weapon_tidx);
|
||||
|
||||
float weapon_system_strength = ship_get_subsystem_strength(shipp, SUBSYSTEM_WEAPONS);
|
||||
|
||||
turret_ai_update_aim(&Ai_info[shipp->ai_index], &Objects[ssp->turret_enemy_objnum], ssp);
|
||||
|
||||
if ((ssp->targeted_subsys != nullptr) && !(ssp->flags[Ship::Subsystem_Flags::No_SS_targeting])) {
|
||||
vm_vec_unrotate(&enemy_point, &ssp->targeted_subsys->system_info->pnt, &Objects[ssp->turret_enemy_objnum].orient);
|
||||
vm_vec_add2(&enemy_point, &ssp->last_aim_enemy_pos);
|
||||
} else {
|
||||
if ((lep->type == OBJ_SHIP) && (Ship_info[Ships[lep->instance].ship_info_index].is_big_or_huge())) {
|
||||
// the turret norm here is from the perspective of the base submodel, not the gun submodel
|
||||
model_instance_local_to_global_dir(&turret_norm, &tp->turret_norm, pm, pmi, pm->submodel[tp->subobj_num].parent, &objp->orient);
|
||||
ai_big_pick_attack_point_turret(lep, ssp, &tmp_pos, &turret_norm, &enemy_point, MIN(wip->max_speed * wip->lifetime, wip->weapon_range), tp->turret_fov);
|
||||
}
|
||||
else {
|
||||
enemy_point = ssp->last_aim_enemy_pos;
|
||||
}
|
||||
}
|
||||
|
||||
vec3d target_moving_direction = ssp->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_moving_direction, &objp->phys_info.vel, wip->vel_inherit_amount);
|
||||
}
|
||||
|
||||
set_predicted_enemy_pos_turret(&tmp_target, &tmp_pos, objp, &enemy_point, &target_moving_direction, wip->max_speed, ssp->turret_time_enemy_in_range * (weapon_system_strength + 1.0f) / 2.0f);
|
||||
} else {
|
||||
tmp_target = *targetp;
|
||||
}
|
||||
|
||||
vm_vec_normalized_dir(gvec, &tmp_target, &tmp_pos);
|
||||
} else {
|
||||
//vector gun_pos2;
|
||||
//vm_vec_add(&gun_pos2, gpos, gun_pos);
|
||||
Assertion(targetp != nullptr, "The targetp parameter must not be null here!");
|
||||
vm_vec_normalized_dir(gvec, targetp, gpos);
|
||||
}
|
||||
|
||||
// per firingpoint based changes go here for turrets
|
||||
}
|
||||
|
||||
/**
|
||||
* Update turret aiming data based on max turret aim update delay
|
||||
*/
|
||||
void turret_ai_update_aim(ai_info *aip, object *En_Objp, ship_subsys *ss)
|
||||
void turret_ai_update_aim(const ai_info *aip, const object *En_Objp, ship_subsys *ss)
|
||||
{
|
||||
if (Missiontime >= ss->next_aim_pos_time)
|
||||
{
|
||||
@@ -1294,26 +1246,15 @@ void turret_ai_update_aim(ai_info *aip, object *En_Objp, ship_subsys *ss)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rotate a turret towards an enemy.
|
||||
*
|
||||
* Some obscure model thing only John Slagel knows about.
|
||||
* Sets predicted enemy position.
|
||||
* Sets predicted enemy position. Previously done at the beginning of aifft_rotate_turret.
|
||||
* If the turret (*ss) has a subsystem targeted, the subsystem is used as the predicted point.
|
||||
*
|
||||
* @return TRUE if caller should use angles in subsequent rotations.
|
||||
*/
|
||||
int aifft_rotate_turret(object *objp, ship *shipp, ship_subsys *ss, object *lep, vec3d *predicted_enemy_pos, vec3d *gvec)
|
||||
void aifft_update_predicted_enemy_pos(const object *objp, const ship *shipp, ship_subsys *ss, const vec3d *global_gun_pos, const vec3d *global_gun_vec, const object *lep, vec3d *predicted_enemy_pos)
|
||||
{
|
||||
int ret_val __UNUSED = 0; // to be used in future, see comment @ end of function
|
||||
auto pmi = model_get_instance(shipp->model_instance_num);
|
||||
auto pm = model_get(pmi->model_num);
|
||||
|
||||
if (ss->turret_enemy_objnum != -1) {
|
||||
model_subsystem *tp = ss->system_info;
|
||||
vec3d gun_pos, gun_vec, target_vel;
|
||||
//float weapon_speed;
|
||||
vec3d target_vel;
|
||||
float weapon_system_strength;
|
||||
//HACK HACK HACK -WMC
|
||||
//This should use the best weapon variable
|
||||
@@ -1322,15 +1263,13 @@ int aifft_rotate_turret(object *objp, ship *shipp, ship_subsys *ss, object *lep,
|
||||
|
||||
//This turret doesn't have any good weapons
|
||||
if (best_weapon_tidx < 0)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
weapon_info *wip = get_turret_weapon_wip(&ss->weapons, best_weapon_tidx);
|
||||
auto wip = get_turret_weapon_wip(&ss->weapons, best_weapon_tidx);
|
||||
|
||||
// weapon_system_strength scales time enemy in range in 0..1. So, the lower this is, the worse the aiming will be.
|
||||
weapon_system_strength = ship_get_subsystem_strength(shipp, SUBSYSTEM_WEAPONS);
|
||||
|
||||
ship_get_global_turret_info(objp, tp, &gun_pos, &gun_vec);
|
||||
|
||||
//Update "known" position and velocity of target. Only matters if max_aim_update_delay is set.
|
||||
turret_ai_update_aim(&Ai_info[shipp->ai_index], &Objects[ss->turret_enemy_objnum], ss);
|
||||
|
||||
@@ -1344,7 +1283,7 @@ int aifft_rotate_turret(object *objp, ship *shipp, ship_subsys *ss, object *lep,
|
||||
}
|
||||
} else {
|
||||
if ((lep->type == OBJ_SHIP) && (Ship_info[Ships[lep->instance].ship_info_index].is_big_or_huge())) {
|
||||
ai_big_pick_attack_point_turret(lep, ss, &gun_pos, &gun_vec, &enemy_point, tp->turret_fov, MIN(wip->max_speed * wip->lifetime, wip->weapon_range));
|
||||
ai_big_pick_attack_point_turret(lep, ss, global_gun_pos, global_gun_vec, &enemy_point, tp->turret_fov, MIN(wip->max_speed * wip->lifetime, wip->weapon_range));
|
||||
} else {
|
||||
enemy_point = ss->last_aim_enemy_pos;
|
||||
}
|
||||
@@ -1357,25 +1296,13 @@ int aifft_rotate_turret(object *objp, ship *shipp, ship_subsys *ss, object *lep,
|
||||
vm_vec_scale_sub2(&target_vel, &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);
|
||||
set_predicted_enemy_pos_turret(predicted_enemy_pos, global_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;
|
||||
if (physics_lead_ballistic_trajectory(global_gun_pos, &enemy_point, &target_vel, wip->max_speed, &gravity_vec, &shoot_vec)) {
|
||||
*predicted_enemy_pos = *global_gun_pos + shoot_vec * 1000.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1387,36 +1314,54 @@ int aifft_rotate_turret(object *objp, ship *shipp, ship_subsys *ss, object *lep,
|
||||
// Add to predicted_enemy_pos value in .45 to 1.5x radius of enemy ship, so will often miss, but not by a huge amount.
|
||||
vm_vec_scale_add2(predicted_enemy_pos, &rand_vec, (1.0f - weapon_system_strength)*1.5f * lep->radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate a turret towards an enemy.
|
||||
*
|
||||
* Some obscure model thing only John Slagel knows about.
|
||||
*
|
||||
* @return TRUE if caller should use angles in subsequent rotations.
|
||||
*/
|
||||
bool aifft_rotate_turret(const object *objp, const ship *shipp, ship_subsys *ss, const vec3d *global_gun_pos, const vec3d *global_gun_vec, const vec3d *predicted_enemy_pos)
|
||||
{
|
||||
bool ret_val __UNUSED = false; // to be used in future, see comment @ end of function
|
||||
auto pmi = model_get_instance(shipp->model_instance_num);
|
||||
auto pm = model_get(pmi->model_num);
|
||||
|
||||
if (ss->turret_enemy_objnum != -1) {
|
||||
model_subsystem *tp = ss->system_info;
|
||||
|
||||
//Get the normalized dir between the turret and the predicted enemy position.
|
||||
//If the dot product is smaller than or equal to the turret's FOV, try and point the gun at it.
|
||||
vec3d v2e;
|
||||
vm_vec_normalized_dir(&v2e, predicted_enemy_pos, &gun_pos);
|
||||
vm_vec_normalized_dir(&v2e, predicted_enemy_pos, global_gun_pos);
|
||||
|
||||
bool in_fov;
|
||||
|
||||
in_fov = turret_fov_test(ss, gvec, &v2e);
|
||||
in_fov = turret_fov_test(ss, global_gun_vec, &v2e);
|
||||
|
||||
if (in_fov) {
|
||||
ret_val = model_rotate_gun(objp, pm, pmi, ss, predicted_enemy_pos);
|
||||
} else if ((tp->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);
|
||||
ret_val = model_rotate_gun(objp, pm, pmi, ss, nullptr);
|
||||
}
|
||||
} 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);
|
||||
ret_val = model_rotate_gun(objp, pm, pmi, ss, nullptr);
|
||||
}
|
||||
|
||||
// by default "ret_val" should be set to 1 for multi-part turrets, and 0 for single-part turrets
|
||||
// but we need to keep retail behavior by default, which means always returning 0 unless a special
|
||||
// by default "ret_val" should be set to true for multi-part turrets, and false for single-part turrets
|
||||
// but we need to keep retail behavior by default, which means always returning false unless a special
|
||||
// flag is used. the "ret_val" stuff is here is needed/wanted at a later date however.
|
||||
//return ret_val;
|
||||
|
||||
// return 0 by default (to preserve retail behavior) but allow for a per-subsystem option
|
||||
// return false by default (to preserve retail behavior) but allow for a per-subsystem option
|
||||
// for using the turret normals for firing
|
||||
if (ss->system_info->flags[Model::Subsystem_Flags::Fire_on_normal])
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1424,7 +1369,7 @@ int aifft_rotate_turret(object *objp, ship *shipp, ship_subsys *ss, object *lep,
|
||||
*
|
||||
* @return Dot product of vector from point abs_gunposp to *enemy_subsysp, if hittable
|
||||
*/
|
||||
float aifft_compute_turret_dot(object *objp, object *enemy_objp, vec3d *abs_gunposp, ship_subsys *turret_subsysp, ship_subsys *enemy_subsysp)
|
||||
float aifft_compute_turret_dot(const object *objp, const object *enemy_objp, const vec3d *abs_gunposp, const ship_subsys *turret_subsysp, const ship_subsys *enemy_subsysp)
|
||||
{
|
||||
float dot_out;
|
||||
vec3d subobj_pos, vector_out;
|
||||
@@ -1432,7 +1377,7 @@ float aifft_compute_turret_dot(object *objp, object *enemy_objp, vec3d *abs_gunp
|
||||
vm_vec_unrotate(&subobj_pos, &enemy_subsysp->system_info->pnt, &enemy_objp->orient);
|
||||
vm_vec_add2(&subobj_pos, &enemy_objp->pos);
|
||||
|
||||
if (ship_subsystem_in_sight(enemy_objp, enemy_subsysp, abs_gunposp, &subobj_pos, 1, &dot_out, &vector_out)) {
|
||||
if (ship_subsystem_in_sight(enemy_objp, enemy_subsysp, abs_gunposp, &subobj_pos, true, &dot_out, &vector_out)) {
|
||||
vec3d turret_norm;
|
||||
|
||||
model_instance_local_to_global_dir(&turret_norm, &turret_subsysp->system_info->turret_norm, Ships[objp->instance].model_instance_num, turret_subsysp->system_info->subobj_num, &objp->orient, true);
|
||||
@@ -1486,7 +1431,7 @@ DCF(mf, "Adjusts the maximum number of tries an AI may do when trying to pick a
|
||||
*
|
||||
* @return Dot product from turret to subsystem in *dot_out
|
||||
*/
|
||||
ship_subsys *aifft_find_turret_subsys(object *objp, ship_subsys *ssp, object *enemy_objp, float *dot_out)
|
||||
ship_subsys *aifft_find_turret_subsys(const object *objp, const ship_subsys *ssp, const vec3d *global_gun_pos, const object *enemy_objp, float *dot_out)
|
||||
{
|
||||
ship *eshipp, *shipp;
|
||||
ship_info *esip;
|
||||
@@ -1503,10 +1448,6 @@ ship_subsys *aifft_find_turret_subsys(object *objp, ship_subsys *ssp, object *en
|
||||
float best_dot = 0.0f;
|
||||
*dot_out = best_dot;
|
||||
|
||||
// Compute absolute gun position.
|
||||
vec3d abs_gun_pos;
|
||||
ship_get_global_turret_info(objp, ssp->system_info, &abs_gun_pos, nullptr);
|
||||
|
||||
// Only pick a turret to attack on large ships.
|
||||
if (!esip->is_big_or_huge())
|
||||
return best_subsysp;
|
||||
@@ -1572,7 +1513,7 @@ ship_subsys *aifft_find_turret_subsys(object *objp, ship_subsys *ssp, object *en
|
||||
}
|
||||
|
||||
for(idx=offset; idx<aifft_list_size; idx+=stride){
|
||||
dot = aifft_compute_turret_dot(objp, enemy_objp, &abs_gun_pos, ssp, aifft_list[idx]);
|
||||
dot = aifft_compute_turret_dot(objp, enemy_objp, global_gun_pos, ssp, aifft_list[idx]);
|
||||
|
||||
if ((dot - dot_fov_modifier)* aifft_rank[idx] > best_dot) {
|
||||
best_dot = (dot - dot_fov_modifier)*aifft_rank[idx];
|
||||
@@ -1587,34 +1528,17 @@ ship_subsys *aifft_find_turret_subsys(object *objp, ship_subsys *ssp, object *en
|
||||
}
|
||||
|
||||
/**
|
||||
* @return !0 if the specified target should scan for a new target, otherwise return 0
|
||||
* @return true if the specified target should scan for a new target, otherwise return false
|
||||
*/
|
||||
int turret_should_pick_new_target(ship_subsys *turret)
|
||||
bool turret_should_pick_new_target(ship_subsys *turret)
|
||||
{
|
||||
// int target_type;
|
||||
|
||||
if ( timestamp_elapsed(turret->turret_next_enemy_check_stamp) ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
if ( turret->turret_enemy_objnum == -1 ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
target_type = Objects[turret->turret_enemy_objnum].type;
|
||||
if ( (target_type != OBJ_SHIP) && (target_type != OBJ_ASTEROID) ) {
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
return 0;
|
||||
|
||||
return timestamp_elapsed(turret->turret_next_enemy_check_stamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the next fire timestamp for a turret, based on weapon type and ai class
|
||||
*/
|
||||
void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip)
|
||||
void turret_set_next_fire_timestamp(int weapon_num, const weapon_info *wip, ship_subsys *turret, const ai_info *aip)
|
||||
{
|
||||
Assert(weapon_num < MAX_SHIP_WEAPONS);
|
||||
float wait = 1000.0f;
|
||||
@@ -1727,13 +1651,13 @@ void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsy
|
||||
/**
|
||||
* Decide if a turret should launch an aspect seeking missile
|
||||
*/
|
||||
int turret_should_fire_aspect(ship_subsys *turret, weapon_info *wip, bool in_sight)
|
||||
bool turret_should_fire_aspect(const ship_subsys *turret, const weapon_info *wip, bool in_sight)
|
||||
{
|
||||
if ( in_sight && (turret->turret_time_enemy_in_range >= MIN(wip->min_lock_time,AICODE_TURRET_MAX_TIME_IN_RANGE)) ) {
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1755,9 +1679,9 @@ 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, const vec3d *orig_firing_pos, const vec3d *orig_firing_vec, const vec3d *predicted_pos = nullptr, float flak_range_override = 100.0f, bool play_sound = true)
|
||||
{
|
||||
matrix turret_orient;
|
||||
matrix firing_orient;
|
||||
int weapon_objnum;
|
||||
ai_info *parent_aip;
|
||||
ship *parent_ship;
|
||||
@@ -1819,16 +1743,21 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (check_ok_to_fire(parent_objnum, turret->turret_enemy_objnum, wip, -1, turret)) {
|
||||
if (check_ok_to_fire(parent_objnum, turret->turret_enemy_objnum, wip, -1, orig_firing_pos)) {
|
||||
auto turret_enemy_objp = (turret->turret_enemy_objnum >= 0) ? &Objects[turret->turret_enemy_objnum] : nullptr;
|
||||
|
||||
ship_weapon* swp = &turret->weapons;
|
||||
turret->turret_last_fire_direction = *firing_vec;
|
||||
turret->turret_last_fire_direction = *orig_firing_vec;
|
||||
|
||||
if (turret->turret_inaccuracy > 0.0f)
|
||||
vm_vec_random_cone(firing_vec, firing_vec, turret->turret_inaccuracy);
|
||||
const vec3d *firing_vec = orig_firing_vec;
|
||||
vec3d firing_vec_buf;
|
||||
|
||||
vm_vector_2_matrix(&turret_orient, firing_vec, nullptr, nullptr);
|
||||
if (turret->turret_inaccuracy > 0.0f) {
|
||||
vm_vec_random_cone(&firing_vec_buf, firing_vec, turret->turret_inaccuracy);
|
||||
firing_vec = &firing_vec_buf;
|
||||
}
|
||||
|
||||
vm_vector_2_matrix(&firing_orient, firing_vec, nullptr, nullptr);
|
||||
|
||||
// grab and set some burst data before turret_set_next_fire_timestamp wipes it
|
||||
int old_burst_seed = swp->burst_seed[weapon_num];
|
||||
@@ -2007,11 +1936,15 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vec3d firing_pos_buf;
|
||||
const vec3d *firing_pos = &firing_pos_buf;
|
||||
|
||||
// zookeeper - Firepoints should cycle normally between shots,
|
||||
// so we need to get the position info separately for each shot
|
||||
ship_get_global_turret_gun_info(&Objects[parent_objnum], turret, turret_pos, firing_vec, 1, nullptr);
|
||||
ship_get_global_turret_gun_info(&Objects[parent_objnum], turret, &firing_pos_buf, false, nullptr, true, nullptr);
|
||||
|
||||
weapon_objnum = weapon_create( turret_pos, &turret_orient, turret_weapon_class, parent_objnum, -1, 1, 0,0.0f, turret);
|
||||
weapon_objnum = weapon_create(firing_pos, &firing_orient, turret_weapon_class, parent_objnum, -1, 1, 0, 0.0f, turret);
|
||||
weapon_set_tracking_info(weapon_objnum, parent_objnum, turret->turret_enemy_objnum, 1, turret->targeted_subsys);
|
||||
|
||||
//nprintf(("AI", "Turret_time_enemy_in_range = %7.3f\n", ss->turret_time_enemy_in_range));
|
||||
@@ -2043,7 +1976,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
if(predicted_pos != NULL)
|
||||
{
|
||||
// pick a firing range so that it detonates properly
|
||||
flak_pick_range(objp, turret_pos, predicted_pos, ship_get_subsystem_strength(parent_ship, SUBSYSTEM_WEAPONS));
|
||||
flak_pick_range(objp, firing_pos, predicted_pos, ship_get_subsystem_strength(parent_ship, SUBSYSTEM_WEAPONS));
|
||||
|
||||
// determine what that range was
|
||||
flak_range = flak_get_range(objp);
|
||||
@@ -2056,7 +1989,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
|
||||
// do mflash if the weapon has it
|
||||
if (wip->muzzle_flash >= 0) {
|
||||
mflash_create(turret_pos, firing_vec, &Objects[parent_ship->objnum].phys_info, wip->muzzle_flash);
|
||||
mflash_create(firing_pos, firing_vec, &Objects[parent_ship->objnum].phys_info, wip->muzzle_flash);
|
||||
}
|
||||
|
||||
// in multiplayer (and the master), then send a turret fired packet.
|
||||
@@ -2075,7 +2008,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
if ( play_sound && 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 );
|
||||
snd_play_3d( gamesnd_get_game_sound(wip->launch_snd), firing_pos, &View_position );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2107,7 +2040,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
|
||||
{
|
||||
int weapon_objnum;
|
||||
matrix turret_orient;
|
||||
matrix firing_orient;
|
||||
vec3d turret_pos, turret_fvec;
|
||||
|
||||
// parent not alive, quick out.
|
||||
@@ -2120,7 +2053,7 @@ void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
|
||||
tsi->turret->turret_next_fire_pos = tsi->weapon_num;
|
||||
|
||||
// change firing point
|
||||
ship_get_global_turret_gun_info(&Objects[tsi->parent_objnum], tsi->turret, &turret_pos, &turret_fvec, 1, NULL);
|
||||
ship_get_global_turret_gun_info(&Objects[tsi->parent_objnum], tsi->turret, &turret_pos, false, &turret_fvec, true, nullptr);
|
||||
tsi->turret->turret_next_fire_pos++;
|
||||
|
||||
//check if this really is a swarm. If not, how the hell did it get here?
|
||||
@@ -2135,11 +2068,11 @@ void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
|
||||
turret_fvec = tsi->turret->turret_last_fire_direction;
|
||||
}
|
||||
|
||||
// make turret_orient from turret_fvec -- turret->turret_last_fire_direction
|
||||
vm_vector_2_matrix(&turret_orient, &turret_fvec, NULL, NULL);
|
||||
// make firing_orient from turret_fvec -- turret->turret_last_fire_direction
|
||||
vm_vector_2_matrix(&firing_orient, &turret_fvec, NULL, NULL);
|
||||
|
||||
// create weapon and homing info
|
||||
weapon_objnum = weapon_create(&turret_pos, &turret_orient, tsi->weapon_class, tsi->parent_objnum, -1, 1, 0, 0.0f, tsi->turret);
|
||||
weapon_objnum = weapon_create(&turret_pos, &firing_orient, tsi->weapon_class, tsi->parent_objnum, -1, 1, 0, 0.0f, tsi->turret);
|
||||
weapon_set_tracking_info(weapon_objnum, tsi->parent_objnum, tsi->target_objnum, 1, tsi->target_subsys);
|
||||
|
||||
// do other cool stuff if weapon is created.
|
||||
@@ -2198,7 +2131,7 @@ int Num_turrets_fired = 0;
|
||||
* all turret movement and resetting when idle
|
||||
*/
|
||||
extern int Nebula_sec_range;
|
||||
void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
void ai_turret_execute_behavior(const ship *shipp, ship_subsys *ss)
|
||||
{
|
||||
float weapon_firing_range;
|
||||
float weapon_min_range; // *Weapon minimum firing range -Et1
|
||||
@@ -2282,12 +2215,21 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
objp = &Objects[shipp->objnum];
|
||||
Assert(objp->type == OBJ_SHIP);
|
||||
|
||||
// Use the turret info for all guns, not one gun in particular.
|
||||
vec3d gvec, gpos;
|
||||
ship_get_global_turret_info(objp, tp, &gpos, &gvec);
|
||||
vec3d global_gun_pos, global_gun_vec;
|
||||
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.
|
||||
ship_get_global_turret_gun_info(objp, ss, &global_gun_pos, false, &global_gun_vec, true, nullptr);
|
||||
} else {
|
||||
// Use the turret info for all guns, not one gun in particular.
|
||||
ship_get_global_turret_info(objp, tp, &global_gun_pos, &global_gun_vec);
|
||||
}
|
||||
|
||||
// Update predicted enemy position. This used to be done in aifft_rotate_turret
|
||||
aifft_update_predicted_enemy_pos(objp, shipp, ss, &global_gun_pos, &global_gun_vec, lep, &predicted_enemy_pos);
|
||||
|
||||
// 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);
|
||||
bool use_angles = aifft_rotate_turret(objp, shipp, ss, &global_gun_pos, &global_gun_vec, &predicted_enemy_pos);
|
||||
|
||||
// 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.
|
||||
@@ -2311,18 +2253,20 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
float dist_to_enemy = 0.0f;
|
||||
if (lep) {
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Turrets_ignore_target_radius])
|
||||
dist_to_enemy = MAX(0, vm_vec_normalized_dir(&v2e, &predicted_enemy_pos, &gpos));
|
||||
dist_to_enemy = MAX(0, vm_vec_normalized_dir(&v2e, &predicted_enemy_pos, &global_gun_pos));
|
||||
else
|
||||
dist_to_enemy = MAX(0, vm_vec_normalized_dir(&v2e, &predicted_enemy_pos, &gpos) - lep->radius);
|
||||
dist_to_enemy = MAX(0, vm_vec_normalized_dir(&v2e, &predicted_enemy_pos, &global_gun_pos) - lep->radius);
|
||||
}
|
||||
|
||||
// count the number of enemies, in case we have a spawning weapon
|
||||
int num_ships_nearby = num_nearby_fighters(iff_get_attackee_mask(obj_team(objp)), &gpos, 1500.0f);
|
||||
int num_ships_nearby = num_nearby_fighters(iff_get_attackee_mask(obj_team(objp)), &global_gun_pos, 1500.0f);
|
||||
|
||||
// some flags considering there may be different weapon types on this turret
|
||||
bool we_did_non_spawning_logic = false;
|
||||
bool tentative_return = false;
|
||||
|
||||
float turret_barrel_length = -1.0f;
|
||||
|
||||
//WMC - go through all valid weapons. Fire spawns if there are any.
|
||||
int valid_weapons[MAX_SHIP_WEAPONS];
|
||||
int num_valid = 0;
|
||||
@@ -2354,7 +2298,7 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
if ( (wip->wi_flags[Weapon::Info_Flags::Spawn]) && !(wip->wi_flags[Weapon::Info_Flags::Smart_spawn]) )
|
||||
{
|
||||
if (( num_ships_nearby >= 3 ) || ((num_ships_nearby >= 2) && (frand() < 0.1f))) {
|
||||
turret_fire_weapon(i, ss, parent_objnum, &gpos, &ss->turret_last_fire_direction);
|
||||
turret_fire_weapon(i, ss, parent_objnum, &global_gun_pos, &ss->turret_last_fire_direction);
|
||||
} else {
|
||||
// Regardless of firing rate, don't check whether should fire for awhile.
|
||||
if (tp->flags[Model::Subsystem_Flags::Use_multiple_guns])
|
||||
@@ -2402,10 +2346,16 @@ 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;
|
||||
if (turret_barrel_length < 0.0f) {
|
||||
if (tp->turret_gun_sobj >= 0) {
|
||||
auto pm = model_get(tp->model_num);
|
||||
auto submodel = &pm->submodel[tp->turret_gun_sobj];
|
||||
turret_barrel_length = 2 * submodel->rad;
|
||||
} else {
|
||||
turret_barrel_length = 0.0f;
|
||||
}
|
||||
}
|
||||
if (dist_to_enemy < turret_barrel_length) continue;
|
||||
}
|
||||
|
||||
// Don't try to fire beyond weapon_limit_range (or within min range)
|
||||
@@ -2523,7 +2473,7 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
// Maybe pick a new enemy, unless targeting has been taken over by scripting
|
||||
if ( turret_should_pick_new_target(ss) && !ss->scripting_target_override && !(ss->flags[Ship::Subsystem_Flags::Forced_target])) {
|
||||
Num_find_turret_enemy++;
|
||||
int objnum = find_turret_enemy(ss, parent_objnum, &gpos, &gvec, ss->turret_enemy_objnum);
|
||||
int objnum = find_turret_enemy(ss, parent_objnum, &global_gun_pos, &global_gun_vec, ss->turret_enemy_objnum);
|
||||
|
||||
if (objnum >= 0) {
|
||||
if (ss->turret_enemy_objnum == -1) {
|
||||
@@ -2545,7 +2495,7 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
float dot = 1.0f;
|
||||
lep = &Objects[ss->turret_enemy_objnum];
|
||||
if (( lep->type == OBJ_SHIP ) && !(ss->flags[Ship::Subsystem_Flags::No_SS_targeting])) {
|
||||
ss->targeted_subsys = aifft_find_turret_subsys(objp, ss, lep, &dot);
|
||||
ss->targeted_subsys = aifft_find_turret_subsys(objp, ss, &global_gun_pos, lep, &dot);
|
||||
}
|
||||
// recheck in 2-3 seconds
|
||||
ss->turret_next_enemy_check_stamp = timestamp((int)((MAX(dot, 0.5f) * The_mission.ai_profile->turret_target_recheck_time) + (The_mission.ai_profile->turret_target_recheck_time / 2.0f)));
|
||||
@@ -2586,14 +2536,15 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
return;
|
||||
}
|
||||
|
||||
if ( lep == nullptr ){
|
||||
return;
|
||||
}
|
||||
//This can't happen. See above code
|
||||
//if ( lep == nullptr ){
|
||||
// return;
|
||||
//}
|
||||
|
||||
//This can't happen. See above code
|
||||
//Assert(ss->turret_enemy_objnum != -1);
|
||||
|
||||
bool in_fov = turret_fov_test(ss, &gvec, &v2e);
|
||||
bool in_fov = turret_fov_test(ss, &global_gun_vec, &v2e);
|
||||
bool something_was_ok_to_fire = false;
|
||||
|
||||
// the only reason predicted_enemy_pos might be zero, while everything else is valid is if
|
||||
@@ -2648,13 +2599,13 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
|
||||
// We're ready to fire... now get down to specifics, like where is the
|
||||
// actual gun point and normal, not just the one for whole turret.
|
||||
ship_get_global_turret_gun_info(objp, ss, &gpos, &gvec, use_angles, &predicted_enemy_pos);
|
||||
ship_get_global_turret_gun_info(objp, ss, &global_gun_pos, false, &global_gun_vec, use_angles, &predicted_enemy_pos);
|
||||
|
||||
// Fire in the direction the turret is facing, not right at the target regardless of turret dir.
|
||||
// [Yet this retail comment precedes the calculation of vector-to-enemy...]
|
||||
vm_vec_sub(&v2e, &predicted_enemy_pos, &gpos);
|
||||
vm_vec_sub(&v2e, &predicted_enemy_pos, &global_gun_pos);
|
||||
dist_to_enemy = vm_vec_normalize(&v2e);
|
||||
float dot = vm_vec_dot(&v2e, &gvec);
|
||||
float dot = vm_vec_dot(&v2e, &global_gun_vec);
|
||||
|
||||
// (flak jitter moved to after we obtain shoot_vector below)
|
||||
|
||||
@@ -2719,7 +2670,7 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
// Check if turret should fire and enemy's engines are
|
||||
// in line of sight
|
||||
if (turret_should_fire_aspect(ss, wip, in_sight) &&
|
||||
ship_get_closest_subsys_in_sight(&Ships[lep->signature], SUBSYSTEM_ENGINE, &gpos))
|
||||
ship_get_closest_subsys_in_sight(&Ships[lep->signature], SUBSYSTEM_ENGINE, &global_gun_pos))
|
||||
{
|
||||
ok_to_fire = true;
|
||||
}
|
||||
@@ -2729,14 +2680,14 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
if ( ok_to_fire && (tp->flags[Model::Subsystem_Flags::Turret_hull_check]) ) {
|
||||
int model_num = Ship_info[shipp->ship_info_index].model_num;
|
||||
vec3d end;
|
||||
vm_vec_scale_add(&end, &gpos, &gvec, model_get_radius(model_num));
|
||||
vm_vec_scale_add(&end, &global_gun_pos, &global_gun_vec, model_get_radius(model_num));
|
||||
|
||||
mc_info hull_check;
|
||||
hull_check.model_instance_num = shipp->model_instance_num;
|
||||
hull_check.model_num = model_num;
|
||||
hull_check.orient = &objp->orient;
|
||||
hull_check.pos = &objp->pos;
|
||||
hull_check.p0 = &gpos;
|
||||
hull_check.p0 = &global_gun_pos;
|
||||
hull_check.p1 = &end;
|
||||
hull_check.flags = MC_CHECK_MODEL | MC_CHECK_RAY;
|
||||
|
||||
@@ -2776,7 +2727,7 @@ void ai_turret_execute_behavior(ship *shipp, ship_subsys *ss)
|
||||
// (Despite the retail comment above, retail actually fired toward the enemy; v2e = vector-to-enemy)
|
||||
vec3d shoot_vector = v2e;
|
||||
if (tp->flags[Model::Subsystem_Flags::Fire_on_normal])
|
||||
shoot_vector = gvec;
|
||||
shoot_vector = global_gun_vec;
|
||||
|
||||
// if the weapon is a flak gun, add some jitter to its aim so it fires in a "cone"
|
||||
// to make a cool visual effect and make them less lethal
|
||||
@@ -2784,7 +2735,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, &global_gun_pos, &shoot_vector, &predicted_enemy_pos, 100.0f, play_sound);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1049,6 +1049,7 @@ bool asteroid_is_within_view(vec3d *pos, float range, bool range_override)
|
||||
*/
|
||||
static void maybe_throw_asteroid()
|
||||
{
|
||||
Assertion(Asteroid_field.num_used_field_debris_types > 0, "maybe_throw_asteroid() called while num_used_field_debris_types was 0; this should never happen, get a coder!");
|
||||
|
||||
for (asteroid_target& target : Asteroid_targets) {
|
||||
if (!timestamp_elapsed(target.throw_stamp))
|
||||
@@ -2584,6 +2585,11 @@ void asteroid_frame()
|
||||
return;
|
||||
}
|
||||
|
||||
// If no asteroid types are defined for the field, abort.
|
||||
if (Asteroid_field.num_used_field_debris_types <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If there are no explicit targets, fall back to default retail targeting behavior
|
||||
if (Asteroid_field.target_names.empty()) {
|
||||
int objnum = set_asteroid_throw_objnum();
|
||||
|
||||
+57
-17
@@ -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;
|
||||
fov_t VIEWER_ZOOM_DEFAULT = DEFAULT_FOV;
|
||||
fov_t COCKPIT_ZOOM_DEFAULT = DEFAULT_FOV;
|
||||
float Sexp_fov = 0.0f;
|
||||
warp_camera Warp_camera;
|
||||
|
||||
@@ -54,6 +54,9 @@ APPLY_TO_FOV_T(*, mul)
|
||||
APPLY_TO_FOV_T(+, add)
|
||||
APPLY_TO_FOV_T(-, sub)
|
||||
|
||||
// Used to set the default value for in-game options
|
||||
static constexpr float fov_default = DEFAULT_FOV;
|
||||
|
||||
static SCP_string fov_display(float val)
|
||||
{
|
||||
auto degrees = fl_degrees(val);
|
||||
@@ -64,18 +67,55 @@ static SCP_string fov_display(float val)
|
||||
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")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.range(0.436332f, 1.5708f)
|
||||
.change_listener([](const float& val, bool) {
|
||||
VIEWER_ZOOM_DEFAULT = val;
|
||||
return true;
|
||||
})
|
||||
.display(fov_display)
|
||||
.default_val(0.75f)
|
||||
.default_val(fov_default)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.importance(60)
|
||||
.finish();
|
||||
|
||||
bool Use_cockpit_fov = false;
|
||||
|
||||
auto CockpitFOVToggleOption = options::OptionBuilder<bool>("Graphics.CockpitFOVToggle",
|
||||
std::pair<const char*, int>{"Cockpit FOV Toggle", 1838},
|
||||
std::pair<const char*, int>{"Whether or not to use a different FOV for cockpit rendering from normal rendering", 1839})
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.default_val(false)
|
||||
.change_listener([](bool val, bool) {
|
||||
if (!val) {
|
||||
COCKPIT_ZOOM_DEFAULT = VIEWER_ZOOM_DEFAULT;
|
||||
}
|
||||
return true; // This option will always persist so we never return false
|
||||
})
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.bind_to(&Use_cockpit_fov)
|
||||
.importance(61)
|
||||
.finish();
|
||||
|
||||
auto CockpitFovOption = options::OptionBuilder<float>("Graphics.CockpitFOV",
|
||||
std::pair<const char*, int>{"Cockpit Field Of View", 1840},
|
||||
std::pair<const char*, int>{"The vertical field of view for cockpit rendering. Only works if cockpits are active and cockpit FOV toggle is turned on.", 1841})
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.range(0.436332f, 1.5708f)
|
||||
.change_listener([](const float& val, bool) {
|
||||
if (Use_cockpit_fov){
|
||||
COCKPIT_ZOOM_DEFAULT = val;
|
||||
} else {
|
||||
COCKPIT_ZOOM_DEFAULT = VIEWER_ZOOM_DEFAULT;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.display(fov_display)
|
||||
.default_val(fov_default)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.importance(62)
|
||||
.finish();
|
||||
|
||||
//*************************CLASS: camera*************************
|
||||
//This is where the camera class begins! :D
|
||||
camera::camera(const char *in_name, int in_signature)
|
||||
@@ -301,7 +341,7 @@ void camera::set_rotation_facing(vec3d *in_target, float in_rotation_time, float
|
||||
|
||||
// if we have a host, we need the difference between the camera's current orient and the orient we want
|
||||
// if not, we will later set the absolute orientation, rather than the orientation relative to the host
|
||||
if (object_host.IsValid())
|
||||
if (object_host.isValid())
|
||||
{
|
||||
vm_transpose(orient);
|
||||
temp_matrix = temp_matrix * *orient;
|
||||
@@ -324,7 +364,7 @@ void camera::do_frame(float /*in_frametime*/)
|
||||
|
||||
object *camera::get_object_host()
|
||||
{
|
||||
if(object_host.IsValid())
|
||||
if(object_host.isValid())
|
||||
return object_host.objp;
|
||||
else
|
||||
return NULL;
|
||||
@@ -337,7 +377,7 @@ int camera::get_object_host_submodel()
|
||||
|
||||
object *camera::get_object_target()
|
||||
{
|
||||
if(object_target.IsValid())
|
||||
if(object_target.isValid())
|
||||
return object_target.objp;
|
||||
else
|
||||
return NULL;
|
||||
@@ -373,7 +413,7 @@ void camera::get_info(vec3d *position, matrix *orientation, bool apply_camera_or
|
||||
bool use_host_orient = false;
|
||||
|
||||
//POSITION
|
||||
if(!(flags & CAM_STATIONARY_POS) || object_host.IsValid())
|
||||
if(!(flags & CAM_STATIONARY_POS) || object_host.isValid())
|
||||
{
|
||||
c_pos = vmd_zero_vector;
|
||||
|
||||
@@ -382,7 +422,7 @@ void camera::get_info(vec3d *position, matrix *orientation, bool apply_camera_or
|
||||
pos_y.get(&pt.xyz.y, NULL);
|
||||
pos_z.get(&pt.xyz.z, NULL);
|
||||
|
||||
if(object_host.IsValid())
|
||||
if(object_host.isValid())
|
||||
{
|
||||
object *objp = object_host.objp;
|
||||
int model_num = object_get_model(objp);
|
||||
@@ -444,9 +484,9 @@ void camera::get_info(vec3d *position, matrix *orientation, bool apply_camera_or
|
||||
if(orientation != NULL)
|
||||
{
|
||||
bool target_set = false;
|
||||
if(!(flags & CAM_STATIONARY_ORI) || object_target.IsValid() || object_host.IsValid())
|
||||
if(!(flags & CAM_STATIONARY_ORI) || object_target.isValid() || object_host.isValid())
|
||||
{
|
||||
if(object_target.IsValid())
|
||||
if(object_target.isValid())
|
||||
{
|
||||
object *target_objp = object_target.objp;
|
||||
int model_num = object_get_model(target_objp);
|
||||
@@ -481,7 +521,7 @@ void camera::get_info(vec3d *position, matrix *orientation, bool apply_camera_or
|
||||
vm_vector_2_matrix(&c_ori, &targetvec, NULL, NULL);
|
||||
target_set = true;
|
||||
}
|
||||
else if(object_host.IsValid())
|
||||
else if(object_host.isValid())
|
||||
{
|
||||
if(eyep)
|
||||
{
|
||||
@@ -754,7 +794,7 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, const char* in_text, const char*
|
||||
//Get text size
|
||||
for(int i = 0; i < num_text_lines; i++)
|
||||
{
|
||||
gr_get_string_size(&w, &h, text_line_ptrs[i], text_line_lens[i]);
|
||||
gr_get_string_size(&w, &h, text_line_ptrs[i], static_cast<size_t>(text_line_lens[i]));
|
||||
|
||||
if(w > tw)
|
||||
tw = w;
|
||||
@@ -1011,7 +1051,7 @@ int camid::getSignature()
|
||||
return sig;
|
||||
}
|
||||
|
||||
bool camid::isValid()
|
||||
bool camid::isValid() const
|
||||
{
|
||||
if(idx >= Cameras.size())
|
||||
return false;
|
||||
@@ -1203,7 +1243,7 @@ vec3d normal_cache;
|
||||
void get_turret_cam_pos(camera *cam, vec3d *pos)
|
||||
{
|
||||
object_h obj(cam->get_object_host());
|
||||
if(!obj.IsValid())
|
||||
if(!obj.isValid())
|
||||
return;
|
||||
ship* shipp = &Ships[cam->get_object_host()->instance];
|
||||
ship_subsys* ssp = GET_FIRST(&shipp->subsys_list);
|
||||
@@ -1211,7 +1251,7 @@ void get_turret_cam_pos(camera *cam, vec3d *pos)
|
||||
{
|
||||
if(ssp->system_info->subobj_num == cam->get_object_host_submodel())
|
||||
{
|
||||
ship_get_global_turret_gun_info(cam->get_object_host(), ssp, pos, &normal_cache, 1, NULL);
|
||||
ship_get_global_turret_gun_info(cam->get_object_host(), ssp, pos, true, &normal_cache, true, nullptr);
|
||||
vec3d offset = vmd_zero_vector;
|
||||
offset.xyz.x = 0.0001f;
|
||||
vm_vec_add2(pos, &offset); // prevent beam turrets from crashing with a nullvec
|
||||
@@ -1224,7 +1264,7 @@ void get_turret_cam_pos(camera *cam, vec3d *pos)
|
||||
void get_turret_cam_orient(camera *cam, matrix *ori)
|
||||
{
|
||||
object_h obj(cam->get_object_host());
|
||||
if(!obj.IsValid())
|
||||
if(!obj.isValid())
|
||||
return;
|
||||
vm_vector_2_matrix(ori, &normal_cache, vm_vec_same(&normal_cache, &cam->get_object_host()->orient.vec.uvec)?NULL:&cam->get_object_host()->orient.vec.uvec, NULL);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#define EXTERN_CAM_BBOX_CONSTANT_PADDING 5.0f
|
||||
#define EXTERN_CAM_BBOX_MULTIPLIER_PADDING 1.5f
|
||||
|
||||
#define DEFAULT_FOV 0.75f;
|
||||
|
||||
struct asymmetric_fov {
|
||||
float left, right, up, down;
|
||||
friend asymmetric_fov operator* (const asymmetric_fov&, const float&);
|
||||
|
||||
+17
-17
@@ -91,12 +91,10 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
#define CFILE_STACK_MAX 8
|
||||
|
||||
int cfile_inited = 0;
|
||||
static int Cfile_stack_pos = 0;
|
||||
|
||||
static char Cfile_stack[CFILE_STACK_MAX][CFILE_ROOT_DIRECTORY_LEN];
|
||||
static SCP_vector<SCP_string> Cfile_stack;
|
||||
|
||||
std::array<CFILE, MAX_CFILE_BLOCKS> Cfile_block_list;
|
||||
|
||||
@@ -330,17 +328,16 @@ int cfile_push_chdir(int type)
|
||||
|
||||
_getcwd(OriginalDirectory, CFILE_ROOT_DIRECTORY_LEN - 1);
|
||||
|
||||
Assert(Cfile_stack_pos < CFILE_STACK_MAX);
|
||||
|
||||
if (Cfile_stack_pos >= CFILE_STACK_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy_s(Cfile_stack[Cfile_stack_pos++], OriginalDirectory);
|
||||
|
||||
cf_create_default_path_string(dir, type, NULL);
|
||||
|
||||
return _cfile_chdir(dir.c_str(), OriginalDirectory);
|
||||
int rc = _cfile_chdir(dir.c_str(), OriginalDirectory);
|
||||
|
||||
// if success then push the original directory on to the stack
|
||||
if (rc == 0) {
|
||||
Cfile_stack.push_back(OriginalDirectory);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -363,13 +360,16 @@ int cfile_chdir(const char *dir)
|
||||
|
||||
int cfile_pop_dir()
|
||||
{
|
||||
Assert(Cfile_stack_pos);
|
||||
|
||||
if ( !Cfile_stack_pos )
|
||||
if (Cfile_stack.empty())
|
||||
return -1;
|
||||
|
||||
Cfile_stack_pos--;
|
||||
return cfile_chdir(Cfile_stack[Cfile_stack_pos]);
|
||||
int rc = cfile_chdir(Cfile_stack.back().c_str());
|
||||
|
||||
Assertion(rc == 0, "Failed to chdir() to previous directory (%s)!", Cfile_stack.back().c_str());
|
||||
|
||||
Cfile_stack.pop_back();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// flush (delete all files in) the passed directory (by type), return the # of files deleted
|
||||
|
||||
+103
-62
@@ -40,6 +40,7 @@
|
||||
#ifdef SCP_UNIX
|
||||
#include "osapi/osapi.h"
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
@@ -1208,93 +1209,133 @@ bool cmdline_parm::has_param() {
|
||||
}
|
||||
|
||||
#ifdef SCP_UNIX
|
||||
// Return a vector with all filesystem names of "parent/dir" relative to parent.
|
||||
// dir must not contain a slash.
|
||||
static SCP_vector<SCP_string> unix_get_single_dir_names(const SCP_string& parent, const SCP_string& dir)
|
||||
extern void normalize_directory_separators(SCP_string &str);
|
||||
|
||||
static SCP_string get_real_mod_path(const char *mod)
|
||||
{
|
||||
SCP_vector<SCP_string> ret;
|
||||
DIR *dirp;
|
||||
SCP_string fullpath;
|
||||
SCP_string mod_path = mod;
|
||||
|
||||
DIR *dp;
|
||||
if ((dp = opendir(parent.c_str())) == NULL) {
|
||||
Warning(LOCATION, "Can't open directory '%s' when searching mod paths. Ignoring. errno=%d", parent.c_str(), errno);
|
||||
return ret;
|
||||
normalize_directory_separators(mod_path);
|
||||
|
||||
fullpath = SCP_string(".") + DIR_SEPARATOR_STR;
|
||||
fullpath += mod_path;
|
||||
|
||||
// check if path already exists
|
||||
dirp = opendir(fullpath.c_str());
|
||||
|
||||
if (dirp) {
|
||||
// found it, return unchanged
|
||||
closedir(dirp);
|
||||
|
||||
return mod_path;
|
||||
}
|
||||
|
||||
dirent *dirp;
|
||||
while ((dirp = readdir(dp)) != NULL) {
|
||||
if (!stricmp(dirp->d_name, dir.c_str())) {
|
||||
ret.push_back(dirp->d_name);
|
||||
// not found, check for a difference in case
|
||||
SCP_string new_mod_path;
|
||||
SCP_string part;
|
||||
struct dirent *dir;
|
||||
SCP_string::size_type separator;
|
||||
SCP_string::size_type offset = 0;
|
||||
|
||||
fullpath = SCP_string(".") + DIR_SEPARATOR_STR;
|
||||
|
||||
do {
|
||||
separator = mod_path.find(DIR_SEPARATOR_CHAR, offset);
|
||||
|
||||
if (separator != SCP_string::npos) {
|
||||
part = mod_path.substr(offset, separator-offset);
|
||||
offset += separator-offset + 1;
|
||||
} else {
|
||||
part = mod_path.substr(offset);
|
||||
offset += part.length();
|
||||
}
|
||||
}
|
||||
(void)closedir(dp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
dirp = opendir(fullpath.c_str());
|
||||
|
||||
// Return a vector with all filesystem names of "parent/dir" relative to parent.
|
||||
// Recurses to deal with slashes in dir.
|
||||
static SCP_vector<SCP_string> unix_get_dir_names(const SCP_string& parent, const SCP_string& dir)
|
||||
{
|
||||
size_t slash = dir.find_first_of("/\\");
|
||||
|
||||
// no subdirectories, no need to recurse
|
||||
if (slash == std::string::npos) {
|
||||
return unix_get_single_dir_names(parent, dir);
|
||||
}
|
||||
|
||||
// get the names of the first component of dir
|
||||
SCP_vector<SCP_string> this_dir_names = unix_get_single_dir_names(parent, dir.substr(0, slash));
|
||||
|
||||
SCP_string rest = dir.substr(slash + 1);
|
||||
|
||||
SCP_vector<SCP_string> ret;
|
||||
|
||||
// search for the rest of dir in each of these
|
||||
SCP_vector<SCP_string>::iterator ii, end = this_dir_names.end();
|
||||
for (ii = this_dir_names.begin(); ii != end; ++ii) {
|
||||
SCP_string this_dir_path = parent + "/" + *ii;
|
||||
SCP_vector<SCP_string> mod_path = unix_get_dir_names(this_dir_path, rest);
|
||||
|
||||
// add all found paths relative to parent
|
||||
SCP_vector<SCP_string>::iterator ii2, end2 = mod_path.end();
|
||||
for (ii2 = mod_path.begin(); ii2 != end2; ++ii2) {
|
||||
ret.push_back(*ii + "/" + *ii2);
|
||||
if ( !dirp ) {
|
||||
break;
|
||||
}
|
||||
|
||||
while ((dir = readdir(dirp)) != nullptr) {
|
||||
if (stricmp(dir->d_name, part.c_str())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SCP_string fn = fullpath + dir->d_name;
|
||||
|
||||
// make sure it accessible and a directory
|
||||
struct stat buf;
|
||||
|
||||
if (stat(fn.c_str(), &buf) == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !S_ISDIR(buf.st_mode) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !new_mod_path.empty() ) {
|
||||
new_mod_path += DIR_SEPARATOR_STR;
|
||||
}
|
||||
|
||||
new_mod_path += dir->d_name;
|
||||
|
||||
fullpath += dir->d_name;
|
||||
fullpath += DIR_SEPARATOR_STR;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (dirp) {
|
||||
closedir(dirp);
|
||||
}
|
||||
} while (offset < mod_path.length());
|
||||
|
||||
// Append anything left from mod_path onto the new path. This will catch trailing separators
|
||||
// as well as mod folders which don't exist so that the mod string remains unchanged except
|
||||
// for the directory name case.
|
||||
if (new_mod_path.length() != mod_path.length()) {
|
||||
new_mod_path += mod_path.substr(new_mod_path.length());
|
||||
}
|
||||
|
||||
return ret;
|
||||
return new_mod_path;
|
||||
}
|
||||
|
||||
// For case sensitive filesystems (e.g. Linux/BSD) perform case-insensitive dir matches.
|
||||
//
|
||||
// NOTE: Aside from change in case no alterations should be made to the modlist. Missing
|
||||
// mod folders should be left in place and no errors or warnings should be generated.
|
||||
// There should be no difference between Windows and non-Windows modlist handling.
|
||||
static void handle_unix_modlist(char **modlist, size_t *len)
|
||||
{
|
||||
// search filesystem for given paths
|
||||
SCP_vector<SCP_string> mod_paths;
|
||||
for (char *cur_mod = strtok(*modlist, ","); cur_mod != NULL; cur_mod = strtok(NULL, ","))
|
||||
{
|
||||
SCP_vector<SCP_string> this_mod_paths = unix_get_dir_names(".", cur_mod);
|
||||
// Ignore non-existing mods for unit tests
|
||||
if (!running_unittests && this_mod_paths.empty()) {
|
||||
ReleaseWarning(LOCATION, "Can't find mod '%s'. Ignoring.", cur_mod);
|
||||
}
|
||||
mod_paths.insert(mod_paths.end(), this_mod_paths.begin(), this_mod_paths.end());
|
||||
|
||||
for (char *cur_mod = strtok(*modlist, ","); cur_mod != NULL; cur_mod = strtok(NULL, ",")) {
|
||||
SCP_string path = get_real_mod_path(cur_mod);
|
||||
mod_paths.push_back(path);
|
||||
}
|
||||
|
||||
// create new char[] to replace modlist
|
||||
size_t total_len = 0;
|
||||
SCP_vector<SCP_string>::iterator ii, end = mod_paths.end();
|
||||
for (ii = mod_paths.begin(); ii != end; ++ii) {
|
||||
total_len += ii->length() + 1;
|
||||
|
||||
for (auto &path : mod_paths) {
|
||||
total_len += path.length() + 1;
|
||||
}
|
||||
|
||||
char *new_modlist = new char[total_len + 1];
|
||||
memset(new_modlist, 0, total_len + 1);
|
||||
end = mod_paths.end();
|
||||
for (ii = mod_paths.begin(); ii != end; ++ii) {
|
||||
strcat_s(new_modlist, total_len + 1, ii->c_str());
|
||||
strcat_s(new_modlist, total_len + 1, ","); // replace later with NUL
|
||||
|
||||
for (auto &path : mod_paths) {
|
||||
strcat_s(new_modlist, total_len + 1, path.c_str());
|
||||
strcat_s(new_modlist, total_len + 1, ",");
|
||||
}
|
||||
|
||||
// remove trailing comma
|
||||
new_modlist[total_len-1] = '\0';
|
||||
|
||||
// make the rest of the modlist manipulation unaware that anything happened here
|
||||
delete [] *modlist;
|
||||
*modlist = new_modlist;
|
||||
@@ -1799,7 +1840,7 @@ bool SetCmdlineParams()
|
||||
if(mod_arg.found() ) {
|
||||
Cmdline_mod = mod_arg.str();
|
||||
|
||||
// strip off blank space it it's there
|
||||
// strip off blank space if it's there
|
||||
if ( Cmdline_mod[strlen(Cmdline_mod)-1] == ' ' ) {
|
||||
Cmdline_mod[strlen(Cmdline_mod)-1] = '\0';
|
||||
}
|
||||
@@ -1859,7 +1900,7 @@ bool SetCmdlineParams()
|
||||
if (val > 0.1) {
|
||||
VIEWER_ZOOM_DEFAULT = val;
|
||||
} else {
|
||||
VIEWER_ZOOM_DEFAULT = 0.75f;
|
||||
VIEWER_ZOOM_DEFAULT = DEFAULT_FOV;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -923,8 +923,8 @@ bool control_config_do_reset(bool cycle, bool API_Access)
|
||||
|
||||
// first, determine how many bindings need to be changed
|
||||
for (size_t e = 0; e < Control_config.size(); ++e) {
|
||||
auto item = Control_config[e];
|
||||
auto default_item = default_bindings[e];
|
||||
const auto& item = Control_config[e];
|
||||
const auto& default_item = default_bindings[e];
|
||||
|
||||
if (item.disabled) {
|
||||
// skip
|
||||
|
||||
@@ -947,7 +947,7 @@ int check_control(int id, int key = -1);
|
||||
void control_get_axes_readings(int *axis_v, float frame_time);
|
||||
|
||||
/**
|
||||
* @brief Markes the given control (by IoActionId) as used
|
||||
* @brief Marks the given control (by IoActionId) as used
|
||||
*
|
||||
* @details Updates the ::used timestamp, triggers a script hook, and marks ::continous_ongoing as true
|
||||
*/
|
||||
|
||||
@@ -48,12 +48,13 @@ 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")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.range(0, 45)
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(10)
|
||||
.bind_to(&Joy_dead_zone_size)
|
||||
.importance(1)
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
int Joy_sensitivity = 9;
|
||||
@@ -61,12 +62,13 @@ 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")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.range(0, 9)
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(9)
|
||||
.bind_to(&Joy_sensitivity)
|
||||
.importance(2)
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
//! arrays which hold the key mappings. The array index represents a key-independent action.
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
extern int Cmdline_nomovies;
|
||||
|
||||
bool Movie_active = false;
|
||||
|
||||
|
||||
const char* Cutscene_bitmap_name[GR_NUM_RESOLUTIONS] = {
|
||||
"ViewFootage",
|
||||
@@ -60,6 +62,18 @@ static cutscene_info *get_cutscene_pointer(char *cutscene_filename)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int get_cutscene_index_by_name(const char* name)
|
||||
{
|
||||
for (int i = 0; i < static_cast<int>(Cutscenes.size()); i++) {
|
||||
if (!stricmp(name, Cutscenes[i].name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// Didn't find anything.
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void cutscene_info_init(cutscene_info *csni)
|
||||
{
|
||||
csni->filename[0] = '\0';
|
||||
|
||||
@@ -37,6 +37,8 @@ typedef struct cutscene_info
|
||||
|
||||
extern SCP_vector<cutscene_info> Cutscenes;
|
||||
|
||||
extern bool Movie_active;
|
||||
|
||||
// initializa table data
|
||||
void cutscene_init();
|
||||
|
||||
@@ -48,4 +50,6 @@ void cutscenes_screen_do_frame();
|
||||
|
||||
void cutscene_mark_viewable(const char* filename);
|
||||
|
||||
int get_cutscene_index_by_name(const char* name);
|
||||
|
||||
#endif
|
||||
@@ -278,6 +278,7 @@ bool play(const char* name) {
|
||||
// clear the screen and hide the mouse cursor
|
||||
io::mouse::CursorManager::get()->pushStatus();
|
||||
io::mouse::CursorManager::get()->showCursor(false);
|
||||
Movie_active = true;
|
||||
gr_reset_clip();
|
||||
gr_set_color(255, 255, 255);
|
||||
gr_set_clear_color(0, 0, 0);
|
||||
@@ -304,6 +305,8 @@ bool play(const char* name) {
|
||||
mprintf(("MOVIE ERROR: Found invalid movie! (%s)\n", name));
|
||||
}
|
||||
|
||||
Movie_active = false;
|
||||
|
||||
// show the mouse cursor again
|
||||
io::mouse::CursorManager::get()->popStatus();
|
||||
|
||||
|
||||
@@ -501,11 +501,11 @@ object *debris_create_only(int parent_objnum, int parent_ship_class, int alt_typ
|
||||
}
|
||||
else if (vaporize) {
|
||||
db->model_num = Debris_vaporize_model;
|
||||
db->submodel_num = Random::next(Debris_num_submodels);
|
||||
db->submodel_num = (Debris_num_submodels <= 0 ? 0 : Random::next(Debris_num_submodels));
|
||||
}
|
||||
else {
|
||||
db->model_num = Debris_model;
|
||||
db->submodel_num = Random::next(Debris_num_submodels);
|
||||
db->submodel_num = (Debris_num_submodels <= 0 ? 0 : Random::next(Debris_num_submodels));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -644,7 +644,7 @@ object *debris_create_only(int parent_objnum, int parent_ship_class, int alt_typ
|
||||
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));
|
||||
float t = 1000*Objects[parent_objnum].radius/3 + (fl2i(1000*3*Objects[parent_objnum].radius) == 0 ? 0 : 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();
|
||||
|
||||
@@ -220,8 +220,8 @@ struct Decal {
|
||||
vm_vec_make(&scale, 1.f, 1.f, 1.f);
|
||||
}
|
||||
|
||||
bool isValid() {
|
||||
if (!object.IsValid()) {
|
||||
bool isValid() const {
|
||||
if (!object.isValid()) {
|
||||
return false;
|
||||
}
|
||||
if (object.objp->flags[Object::Object_Flags::Should_be_dead]) {
|
||||
|
||||
@@ -118,10 +118,13 @@ uniform sampler2DArray sMiscmap;
|
||||
uniform sampler2DArray shadow_map;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
#ifndef FLAG_SHADOW_MAP
|
||||
out vec4 fragOut1;
|
||||
out vec4 fragOut2;
|
||||
out vec4 fragOut3;
|
||||
out vec4 fragOut4;
|
||||
#endif
|
||||
|
||||
vec3 FresnelLazarovEnv(vec3 specColor, vec3 view, vec3 normal, float gloss)
|
||||
{
|
||||
@@ -185,10 +188,9 @@ void main()
|
||||
#ifdef FLAG_SHADOW_MAP
|
||||
// need depth and depth squared for variance shadow maps
|
||||
fragOut0 = vec4(vertIn.position.z, vertIn.position.z * vertIn.position.z * VARIANCE_SHADOW_SCALE_INV, 0.0, 1.0);
|
||||
if (true) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
#else
|
||||
vec3 eyeDir = vec3(normalize(-vertIn.position).xyz);
|
||||
vec2 texCoord = vertIn.texCoord.xy;
|
||||
|
||||
@@ -461,4 +463,5 @@ void main()
|
||||
fragOut3 = vec4(specColor.rgb, fresnelFactor);
|
||||
fragOut4 = emissiveColor;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -5,7 +5,6 @@ out vec4 fragOut2;
|
||||
out vec4 fragOut3;
|
||||
out vec4 fragOut4;
|
||||
out vec4 fragOut5;
|
||||
out float gl_FragDepth;
|
||||
|
||||
uniform sampler2DMS texColor;
|
||||
uniform sampler2DMS texPos;
|
||||
|
||||
@@ -51,7 +51,7 @@ bool Fireball_use_3d_warp = false;
|
||||
static auto WarpOption __UNUSED = options::OptionBuilder<bool>("Graphics.3dWarp",
|
||||
std::pair<const char*, int>{"3D Warp", 1770},
|
||||
std::pair<const char*, int>{"Use a 3D model for warp effects", 1771})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.default_val(true)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.bind_to(&Fireball_use_3d_warp)
|
||||
@@ -1052,7 +1052,7 @@ float fireball_wormhole_intensity(fireball *fb)
|
||||
rad = (float)pow((fb->total_time - t) / fb->warp_close_duration, 0.4f);
|
||||
}
|
||||
return rad;
|
||||
}
|
||||
}
|
||||
|
||||
extern void warpin_queue_render(model_draw_list *scene, object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, bool warp_3d, int warp_glow_bitmap, int warp_ball_bitmap, int warp_model_id);
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ bool Fireball_warp_flash = false;
|
||||
static auto WarpFlashOption __UNUSED = options::OptionBuilder<bool>("Graphics.WarpFlash",
|
||||
std::pair<const char*, int>{"Warp Flash", 1768},
|
||||
std::pair<const char*, int>{"Show flash upon warp open or close", 1769})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.default_val(true)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.bind_to_once(&Fireball_warp_flash)
|
||||
|
||||
@@ -499,7 +499,7 @@ void help_overlay_blit(int overlay_id, int resolution_index)
|
||||
font::set_font(help_overlaylist[overlay_id].fontlist.at(resolution_index));
|
||||
for (idx = 0; idx < textcount; idx++) {
|
||||
gr_set_color_fast(&Color_black);
|
||||
gr_get_string_size(&width, &height, help_overlaylist[overlay_id].textlist.at(0).at(idx).string, (int)strlen(help_overlaylist[overlay_id].textlist.at(0).at(idx).string));
|
||||
gr_get_string_size(&width, &height, help_overlaylist[overlay_id].textlist.at(0).at(idx).string, strlen(help_overlaylist[overlay_id].textlist.at(0).at(idx).string));
|
||||
gr_rect(help_overlaylist[overlay_id].textlist.at(resolution_index).at(idx).x_coord-2*HELP_PADDING, help_overlaylist[overlay_id].textlist.at(resolution_index).at(idx).y_coord-3*HELP_PADDING, width+4*HELP_PADDING, height+4*HELP_PADDING, GR_RESIZE_MENU);
|
||||
gr_set_color_fast(&Color_bright_white);
|
||||
gr_printf_menu(help_overlaylist[overlay_id].textlist.at(resolution_index).at(idx).x_coord, help_overlaylist[overlay_id].textlist.at(resolution_index).at(idx).y_coord,
|
||||
|
||||
@@ -114,7 +114,8 @@ const char *GS_event_text[] =
|
||||
"GS_EVENT_PXO_HELP",
|
||||
"GS_EVENT_FICTION_VIEWER", // 65
|
||||
"GS_EVENT_SCRIPTING",
|
||||
"GS_EVENT_SCRIPTING_MISSION"
|
||||
"GS_EVENT_SCRIPTING_MISSION",
|
||||
"GS_EVENT_INGAME_OPTIONS"
|
||||
};
|
||||
//XSTR:ON
|
||||
|
||||
@@ -178,7 +179,8 @@ const char *GS_state_text[] =
|
||||
"GS_STATE_START_GAME",
|
||||
"GS_STATE_FICTION_VIEWER",
|
||||
"GS_STATE_SCRIPTING",
|
||||
"GS_STATE_SCRIPTING_MISSION"
|
||||
"GS_STATE_SCRIPTING_MISSION",
|
||||
"GS_STATE_INGAME_OPTIONS"
|
||||
};
|
||||
//XSTR:ON
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@ enum GS_EVENT {
|
||||
GS_EVENT_FICTION_VIEWER,
|
||||
GS_EVENT_SCRIPTING,
|
||||
GS_EVENT_SCRIPTING_MISSION,
|
||||
GS_EVENT_INGAME_OPTIONS,
|
||||
|
||||
GS_NUM_EVENTS // Last one++
|
||||
};
|
||||
@@ -161,6 +162,7 @@ enum GS_STATE {
|
||||
GS_STATE_FICTION_VIEWER,
|
||||
GS_STATE_SCRIPTING,
|
||||
GS_STATE_SCRIPTING_MISSION,
|
||||
GS_STATE_INGAME_OPTIONS,
|
||||
|
||||
GS_NUM_STATES // Last one++
|
||||
};
|
||||
|
||||
@@ -48,11 +48,12 @@ static bool music_volume_change_listener(float new_val, bool /*initial*/)
|
||||
static auto MusicVolumeOption __UNUSED = options::OptionBuilder<float>("Audio.Music",
|
||||
std::pair<const char*, int>{"Music", 1371},
|
||||
std::pair<const char*, int>{"Volume used for playing music", 1760})
|
||||
.category("Audio")
|
||||
.category(std::make_pair("Audio", 1826))
|
||||
.default_val(Default_music_volume)
|
||||
.range(0.0f, 1.0f)
|
||||
.change_listener(music_volume_change_listener)
|
||||
.importance(1)
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
typedef struct tagSNDPATTERN {
|
||||
|
||||
@@ -319,7 +319,7 @@ enum class InterfaceSounds {
|
||||
MIN_INTERFACE_SOUNDS =70 //!< MIN_INTERFACE_SOUNDS
|
||||
};
|
||||
|
||||
// These two id types are defined as sublcasses so that type safe implicit conversions are possible from the predefined
|
||||
// These two id types are defined as subclasses so that type safe implicit conversions are possible from the predefined
|
||||
// sound enum values
|
||||
|
||||
struct gamesnd_id_tag{};
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
#define MAX_POLYGON_MODELS 300
|
||||
|
||||
// object.h
|
||||
//If this value exceeds 2^16-1, this will break collision pair caching as is. Proceed with caution.
|
||||
#define MAX_OBJECTS 5000 //Increased from 3500 to 5000 in 2022
|
||||
|
||||
// from weapon.h (and beam.h)
|
||||
|
||||
@@ -442,7 +442,7 @@ public:
|
||||
class camera *getCamera();
|
||||
size_t getIndex();
|
||||
int getSignature();
|
||||
bool isValid();
|
||||
bool isValid() const;
|
||||
};
|
||||
|
||||
#include "globalincs/vmallocator.h"
|
||||
@@ -453,7 +453,7 @@ public:
|
||||
// - is not "none"
|
||||
// - is not "<none>"
|
||||
inline bool VALID_FNAME(const char* x) {
|
||||
return strlen((x)) && stricmp((x), "none") != 0 && stricmp((x), "<none>") != 0;
|
||||
return (x[0] != '\0') && stricmp(x, "none") != 0 && stricmp(x, "<none>") != 0;
|
||||
}
|
||||
/**
|
||||
* @brief Checks if the specified string may be a valid file name
|
||||
|
||||
@@ -248,45 +248,48 @@ const auto ModelDetailOption __UNUSED = options::OptionBuilder<int>("Graphics.De
|
||||
std::pair<const char*, int>{"Model Detail", 1739},
|
||||
std::pair<const char*, int>{"Detail level of models", 1740})
|
||||
.importance(8)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.change_listener([](int val, bool) {
|
||||
Detail.detail_distance = val;
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
const auto TexturesOption __UNUSED = options::OptionBuilder<int>("Graphics.Texture",
|
||||
std::pair<const char*, int>{"3D Hardware Textures", 1362},
|
||||
std::pair<const char*, int>{"Level of detail of textures", 1720})
|
||||
.importance(6)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.change_listener([](int val, bool) {
|
||||
Detail.hardware_textures = val;
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
const auto ParticlesOption __UNUSED = options::OptionBuilder<int>("Graphics.Particles",
|
||||
std::pair<const char*, int>{"Particles", 1363},
|
||||
std::pair<const char*, int>{"Level of detail for particles", 1717})
|
||||
.importance(5)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.change_listener([](int val, bool) {
|
||||
Detail.num_particles = val;
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
const auto SmallDebrisOption __UNUSED = options::OptionBuilder<int>("Graphics.SmallDebris",
|
||||
std::pair<const char*, int>{"Impact Effects", 1364},
|
||||
std::pair<const char*, int>{"Level of detail of impact effects", 1743})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.importance(4)
|
||||
@@ -294,32 +297,35 @@ const auto SmallDebrisOption __UNUSED = options::OptionBuilder<int>("Graphics.Sm
|
||||
Detail.num_small_debris = val;
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
const auto ShieldEffectsOption __UNUSED = options::OptionBuilder<int>("Graphics.ShieldEffects",
|
||||
std::pair<const char*, int>{"Shield Hit Effects", 1718},
|
||||
std::pair<const char*, int>{"Level of detail of shield impacts", 1719})
|
||||
.importance(3)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.change_listener([](int val, bool) {
|
||||
Detail.shield_effects = val;
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
const auto StarsOption __UNUSED = options::OptionBuilder<int>("Graphics.Stars",
|
||||
std::pair<const char*, int>{"Stars", 1366},
|
||||
std::pair<const char*, int>{"Number of stars in the mission", 1698})
|
||||
.importance(2)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.change_listener([](int val, bool) {
|
||||
Detail.num_stars = val;
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
// Call this with:
|
||||
|
||||
@@ -21,17 +21,17 @@ template <typename T>
|
||||
using SCP_vector = std::vector<T, std::allocator<T>>;
|
||||
|
||||
template <typename T>
|
||||
bool SCP_vector_contains(SCP_vector<T>& vector, T item) {
|
||||
bool SCP_vector_contains(const SCP_vector<T>& vector, const T& item) {
|
||||
return std::find(vector.begin(), vector.end(), item) != vector.end();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool SCP_vector_inbounds(SCP_vector<T>& vector, int idx) {
|
||||
inline bool SCP_vector_inbounds(const SCP_vector<T>& vector, int idx) {
|
||||
return ((idx >= 0) && (idx < static_cast<int>(vector.size())));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool SCP_vector_inbounds(SCP_vector<T>& vector, size_t idx) {
|
||||
inline bool SCP_vector_inbounds(const SCP_vector<T>& vector, size_t idx) {
|
||||
return idx < vector.size();
|
||||
}
|
||||
|
||||
|
||||
+42
-26
@@ -116,11 +116,12 @@ static bool gamma_change_listener(float new_val, bool initial)
|
||||
static auto GammaOption __UNUSED = options::OptionBuilder<float>("Graphics.Gamma",
|
||||
std::pair<const char*, int>{"Brightness", 1375},
|
||||
std::pair<const char*, int>{"The brightness value used for the game window", 1738})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.default_val(1.0f)
|
||||
.enumerator(gamma_value_enumerator)
|
||||
.display(gamma_display)
|
||||
.change_listener(gamma_change_listener)
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
|
||||
@@ -134,7 +135,7 @@ const auto LightingOption __UNUSED = options::OptionBuilder<int>("Graphics.Light
|
||||
std::pair<const char*, int>{"Lighting", 1367},
|
||||
std::pair<const char*, int>{"Level of detail of the lighting", 1715})
|
||||
.importance(1)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.change_listener([](int val, bool initial) {
|
||||
@@ -144,6 +145,7 @@ const auto LightingOption __UNUSED = options::OptionBuilder<int>("Graphics.Light
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
os::ViewportState Gr_configured_window_state = os::ViewportState::Windowed;
|
||||
@@ -169,7 +171,7 @@ static bool mode_change_func(os::ViewportState state, bool initial)
|
||||
static auto WindowModeOption __UNUSED = options::OptionBuilder<os::ViewportState>("Graphics.WindowMode",
|
||||
std::pair<const char*, int>{"Window Mode", 1772},
|
||||
std::pair<const char*, int>{"Controls how the game window is created", 1773})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.values({{os::ViewportState::Fullscreen, {"Fullscreen", 1679}},
|
||||
{os::ViewportState::Borderless, {"Borderless", 1675}},
|
||||
@@ -260,7 +262,7 @@ static bool videodisplay_change(int display, bool initial)
|
||||
static auto VideoDisplayOption = options::OptionBuilder<int>("Graphics.Display",
|
||||
std::pair<const char*, int>{"Primary display", 1741},
|
||||
std::pair<const char*, int>{"The display used for rendering", 1742})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.deserializer(videodisplay_deserializer)
|
||||
.serializer(videodisplay_serializer)
|
||||
@@ -370,7 +372,7 @@ static bool resolution_change(const ResolutionInfo& /*info*/, bool initial)
|
||||
static auto ResolutionOption = options::OptionBuilder<ResolutionInfo>("Graphics.Resolution",
|
||||
std::pair<const char*, int>{"Resolution", 1748},
|
||||
std::pair<const char*, int>{"The rendering resolution", 1749})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.deserializer(resolution_deserializer)
|
||||
.serializer(resolution_serializer)
|
||||
@@ -386,7 +388,7 @@ bool Gr_enable_soft_particles = false;
|
||||
static auto SoftParticlesOption __UNUSED = options::OptionBuilder<bool>("Graphics.SoftParticles",
|
||||
std::pair<const char*, int>{"Soft Particles", 1761},
|
||||
std::pair<const char*, int>{"Enable or disable soft particle rendering", 1762})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.default_val(true)
|
||||
.bind_to_once(&Gr_enable_soft_particles)
|
||||
@@ -398,13 +400,13 @@ flagset<FramebufferEffects> Gr_framebuffer_effects;
|
||||
static auto FramebufferEffectsOption __UNUSED = options::OptionBuilder<flagset<FramebufferEffects>>("Graphics.FramebufferEffects",
|
||||
std::pair<const char*, int>{"Framebuffer effects", 1732},
|
||||
std::pair<const char*, int>{"Controls which framebuffer effects will be applied to the scene", 1733})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.values({{{}, {"None", 211}},
|
||||
{{FramebufferEffects::Shockwaves}, {"Shockwaves", 1688}},
|
||||
{{FramebufferEffects::Thrusters}, {"Thrusters", 1689}},
|
||||
{{FramebufferEffects::Shockwaves, FramebufferEffects::Thrusters}, {"All", 1690}}})
|
||||
.default_val({FramebufferEffects::Shockwaves, FramebufferEffects::Thrusters})
|
||||
.default_val({})
|
||||
.bind_to_once(&Gr_framebuffer_effects)
|
||||
.importance(77)
|
||||
.finish();
|
||||
@@ -415,7 +417,7 @@ AntiAliasMode Gr_aa_mode_last_frame = AntiAliasMode::None;
|
||||
static auto AAOption __UNUSED = options::OptionBuilder<AntiAliasMode>("Graphics.AAMode",
|
||||
std::pair<const char*, int>{"Anti Aliasing", 1752},
|
||||
std::pair<const char*, int>{"Controls the anti aliasing mode of the engine.", 1753})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.values({{AntiAliasMode::None, {"None", 211}},
|
||||
{AntiAliasMode::FXAA_Low, {"FXAA Low", 1681}},
|
||||
@@ -434,7 +436,7 @@ extern int Cmdline_msaa_enabled;
|
||||
static auto MSAAOption __UNUSED = options::OptionBuilder<int>("Graphics.MSAASamples",
|
||||
std::pair<const char*, int>{"Multisample Anti Aliasing", 1758},
|
||||
std::pair<const char*, int>{"Controls whether multisample anti asliasing is enabled, and with how many samples", 1759})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.values({{0, {"Off", 1693}},
|
||||
{4, {"4 Samples", 1694}},
|
||||
@@ -458,9 +460,9 @@ bool Gr_post_processing_enabled = true;
|
||||
static auto PostProcessOption __UNUSED = options::OptionBuilder<bool>("Graphics.PostProcessing",
|
||||
std::pair<const char*, int>{"Post processing", 1726},
|
||||
std::pair<const char*, int>{"Controls whether post processing is enabled in the engine.", 1727})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.default_val(false)
|
||||
.default_val(true)
|
||||
.bind_to_once(&Gr_post_processing_enabled)
|
||||
.importance(69)
|
||||
.finish();
|
||||
@@ -470,7 +472,7 @@ bool Gr_enable_vsync = true;
|
||||
static auto VSyncOption __UNUSED = options::OptionBuilder<bool>("Graphics.VSync",
|
||||
std::pair<const char*, int>{"Vertical Sync", 1766},
|
||||
std::pair<const char*, int>{"Controls how the engine does vertical synchronization", 1767})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.default_val(true)
|
||||
.bind_to_once(&Gr_enable_vsync)
|
||||
@@ -1754,17 +1756,6 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode,
|
||||
return true;
|
||||
}
|
||||
|
||||
void gr_force_windowed()
|
||||
{
|
||||
if ( !Gr_inited ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( Os_debugger_running ) {
|
||||
os_sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
int gr_activated = 0;
|
||||
void gr_activate(int active)
|
||||
{
|
||||
@@ -1779,7 +1770,7 @@ void gr_activate(int active)
|
||||
}
|
||||
|
||||
if (active) {
|
||||
if (Cmdline_fullscreen_window || Cmdline_window) {
|
||||
if (gr_is_viewport_window()) {
|
||||
os::getMainViewport()->restore();
|
||||
} else {
|
||||
os::getMainViewport()->setState(os::ViewportState::Fullscreen);
|
||||
@@ -1789,7 +1780,7 @@ void gr_activate(int active)
|
||||
}
|
||||
|
||||
if (active) {
|
||||
if (!Cmdline_fullscreen_window && !Cmdline_window) {
|
||||
if (!gr_is_viewport_window()) {
|
||||
gr_set_gamma(Gr_gamma);
|
||||
}
|
||||
}
|
||||
@@ -2968,3 +2959,28 @@ void gr_get_post_process_effect_names(SCP_vector<SCP_string>& names)
|
||||
names.push_back(eff.name);
|
||||
}
|
||||
}
|
||||
|
||||
bool gr_is_viewport_window()
|
||||
{
|
||||
if (Fred_running) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Using_in_game_options) {
|
||||
switch (Gr_configured_window_state)
|
||||
{
|
||||
case os::ViewportState::Windowed:
|
||||
case os::ViewportState::Borderless:
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (Cmdline_window || Cmdline_fullscreen_window) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
+3
-1
@@ -1002,7 +1002,7 @@ extern void gr_printf_menu_zoomed( int x, int y, const char * format, SCP_FORMAT
|
||||
extern void gr_printf_no_resize( int x, int y, const char * format, SCP_FORMAT_STRING ... ) SCP_FORMAT_STRING_ARGS(3, 4);
|
||||
|
||||
// Returns the size of the string in pixels in w and h
|
||||
extern void gr_get_string_size( int *w, int *h, const char * text, int len = 9999 );
|
||||
extern void gr_get_string_size( int *w, int *h, const char * text, size_t len = std::string::npos );
|
||||
|
||||
// Returns the height of the current font
|
||||
extern int gr_get_font_height();
|
||||
@@ -1428,6 +1428,8 @@ void gr_set_gamma(float gamma);
|
||||
|
||||
void gr_get_post_process_effect_names(SCP_vector<SCP_string> &names);
|
||||
|
||||
bool gr_is_viewport_window();
|
||||
|
||||
// Include this last to make the 2D rendering function available everywhere
|
||||
#include "graphics/render.h"
|
||||
|
||||
|
||||
@@ -339,8 +339,8 @@ void gr_set_ambient_light(int red, int green, int blue) {
|
||||
gr_light_ambient[3] = 1.0f;
|
||||
}
|
||||
void gr_get_ambient_light(vec3d* light_vector) {
|
||||
auto abv = ltp::current()->ambient_light_brightness;
|
||||
auto over = ltp::current()->overall_brightness;
|
||||
const auto& abv = ltp::current()->ambient_light_brightness;
|
||||
const auto& over = ltp::current()->overall_brightness;
|
||||
light_vector->xyz.x = over.handle(abv.handle(gr_light_ambient[0]));
|
||||
light_vector->xyz.y = over.handle(abv.handle(gr_light_ambient[1]));
|
||||
light_vector->xyz.z = over.handle(abv.handle(gr_light_ambient[2]));
|
||||
|
||||
@@ -85,7 +85,7 @@ void gr_start_instance_matrix(const vec3d *offset, const matrix *rotation)
|
||||
|
||||
gr_model_matrix_stack.push(offset, rotation);
|
||||
|
||||
auto model_matrix = gr_model_matrix_stack.get_transform();
|
||||
const auto& model_matrix = gr_model_matrix_stack.get_transform();
|
||||
vm_matrix4_x_matrix4(&gr_model_view_matrix, &gr_view_matrix, &model_matrix);
|
||||
|
||||
modelview_matrix_depth++;
|
||||
@@ -109,7 +109,7 @@ void gr_end_instance_matrix()
|
||||
|
||||
gr_model_matrix_stack.pop();
|
||||
|
||||
auto model_matrix = gr_model_matrix_stack.get_transform();
|
||||
const auto& model_matrix = gr_model_matrix_stack.get_transform();
|
||||
vm_matrix4_x_matrix4(&gr_model_view_matrix, &gr_view_matrix, &model_matrix);
|
||||
|
||||
modelview_matrix_depth--;
|
||||
@@ -280,7 +280,7 @@ void gr_end_2d_matrix()
|
||||
|
||||
gr_view_matrix = gr_last_view_matrix;
|
||||
|
||||
auto model_matrix = gr_model_matrix_stack.get_transform();
|
||||
const auto& model_matrix = gr_model_matrix_stack.get_transform();
|
||||
vm_matrix4_x_matrix4(&gr_model_view_matrix, &gr_view_matrix, &model_matrix);
|
||||
|
||||
htl_2d_matrix_set = false;
|
||||
@@ -302,7 +302,7 @@ void gr_push_scale_matrix(const vec3d *scale_factor)
|
||||
|
||||
gr_model_matrix_stack.push(NULL, NULL, scale_factor);
|
||||
|
||||
auto model_matrix = gr_model_matrix_stack.get_transform();
|
||||
const auto& model_matrix = gr_model_matrix_stack.get_transform();
|
||||
vm_matrix4_x_matrix4(&gr_model_view_matrix, &gr_view_matrix, &model_matrix);
|
||||
|
||||
matrix_uniform_up_to_date = false;
|
||||
@@ -315,7 +315,7 @@ void gr_pop_scale_matrix()
|
||||
|
||||
gr_model_matrix_stack.pop();
|
||||
|
||||
auto model_matrix = gr_model_matrix_stack.get_transform();
|
||||
const auto& model_matrix = gr_model_matrix_stack.get_transform();
|
||||
vm_matrix4_x_matrix4(&gr_model_view_matrix, &gr_view_matrix, &model_matrix);
|
||||
|
||||
modelview_matrix_depth--;
|
||||
|
||||
@@ -346,7 +346,7 @@ void gr_opengl_deferred_lighting_finish()
|
||||
auto light_data = prepare_light_uniforms(l, light_uniform_aligner);
|
||||
|
||||
if (l.type == Light_Type::Cone) {
|
||||
light_data->dualCone = l.dual_cone ? 1.0f : 0.0f;
|
||||
light_data->dualCone = (l.flags & LF_DUAL_CONE) ? 1.0f : 0.0f;
|
||||
light_data->coneAngle = l.cone_angle;
|
||||
light_data->coneInnerAngle = l.cone_inner_angle;
|
||||
light_data->coneDir = l.vec2;
|
||||
|
||||
@@ -124,10 +124,10 @@ bool gr_opengl_openxr_create_session() {
|
||||
};
|
||||
|
||||
XrSessionCreateInfo sessionCreateInfo {
|
||||
sessionCreateInfo.type = XR_TYPE_SESSION_CREATE_INFO,
|
||||
sessionCreateInfo.next = &graphicsBinding,
|
||||
sessionCreateInfo.createFlags = 0,
|
||||
sessionCreateInfo.systemId = xr_system
|
||||
XR_TYPE_SESSION_CREATE_INFO,
|
||||
&graphicsBinding,
|
||||
0,
|
||||
xr_system
|
||||
};
|
||||
|
||||
XrResult sessionInit = xrCreateSession(xr_instance, &sessionCreateInfo, &xr_session);
|
||||
@@ -249,9 +249,9 @@ bool gr_opengl_openxr_flip() {
|
||||
xrAcquireSwapchainImage(swapchain, &acquireImageInfo, &activeIndex);
|
||||
|
||||
XrSwapchainImageWaitInfo waitImageInfo{
|
||||
waitImageInfo.type = XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO,
|
||||
XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO,
|
||||
nullptr,
|
||||
waitImageInfo.timeout = std::numeric_limits<int64_t>::max()
|
||||
std::numeric_limits<int64_t>::max()
|
||||
};
|
||||
xrWaitSwapchainImage(swapchain, &waitImageInfo);
|
||||
|
||||
|
||||
@@ -431,7 +431,6 @@ extern GLuint Cockpit_depth_texture;
|
||||
extern GLuint Scene_position_texture;
|
||||
extern GLuint Scene_normal_texture;
|
||||
extern GLuint Scene_specular_texture;
|
||||
extern bool stars_sun_has_glare(int index);
|
||||
extern float Sun_spot;
|
||||
void opengl_post_lightshafts()
|
||||
{
|
||||
@@ -452,7 +451,7 @@ void opengl_post_lightshafts()
|
||||
light_get_global_dir(&light_dir, idx);
|
||||
vm_vec_rotate(&local_light_dir, &light_dir, &Eye_matrix);
|
||||
|
||||
if ( !stars_sun_has_glare(idx) ) {
|
||||
if ( !light_has_glare(idx) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -851,8 +850,8 @@ void opengl_post_shader_header(SCP_stringstream& sflags, shader_type shader_t, i
|
||||
}
|
||||
} else if (shader_t == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS) {
|
||||
char temp[64];
|
||||
const auto ls_params = graphics::Post_processing_manager->getLightshaftParams();
|
||||
sprintf(temp, "#define SAMPLE_NUM %d\n", ls_params.samplenum);
|
||||
const auto& ls_params = graphics::Post_processing_manager->getLightshaftParams();
|
||||
snprintf(temp, 64, "#define SAMPLE_NUM %d\n", ls_params.samplenum);
|
||||
sflags << temp;
|
||||
} else if (shader_t == SDR_TYPE_POST_PROCESS_FXAA) {
|
||||
set_fxaa_defines(sflags);
|
||||
|
||||
@@ -55,7 +55,7 @@ static auto TextureFilteringOption __UNUSED = options::OptionBuilder<int>("Graph
|
||||
std::pair<const char*, int>{"Texture Filtering", 1763},
|
||||
std::pair<const char*, int>{"Texture filtering option", 1764})
|
||||
.importance(1)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(TextureFilteringValues)
|
||||
.default_val(0)
|
||||
.bind_to_once(&GL_mipmap_filter)
|
||||
@@ -107,7 +107,7 @@ static auto AnisotropyOption = options::OptionBuilder<float>("Graphics.Anisotrop
|
||||
std::pair<const char*, int>{"Anistropic filtering", 1736},
|
||||
std::pair<const char*, int>{"Controls the amount of anistropic filtering of the textures", 1737})
|
||||
.enumerator(anisotropic_value_enumerator)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.display(anisotropic_display)
|
||||
.default_func(anisotropic_default)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
|
||||
@@ -43,7 +43,7 @@ bool Post_processing_enable_lightshafts = true;
|
||||
static auto LightshaftsOption __UNUSED = options::OptionBuilder<bool>("Graphics.Lightshafts",
|
||||
std::pair<const char*, int>{"Lightshafts", 1724},
|
||||
std::pair<const char*, int>{"Enables or disables lightshafts (requires post-processing)", 1725})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.default_val(true)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.bind_to(&Post_processing_enable_lightshafts)
|
||||
@@ -55,12 +55,13 @@ int Post_processing_bloom_intensity = 25; // using default value of Cmdline_bloo
|
||||
static auto BloomIntensityOption __UNUSED = options::OptionBuilder<int>("Graphics.BloomIntensity",
|
||||
std::pair<const char*, int>{"Bloom intensity", 1701},
|
||||
std::pair<const char*, int>{"Sets the bloom intensity (requires post-processing)", 1702})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.range(0, 200)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.default_val(25)
|
||||
.bind_to(&Post_processing_bloom_intensity)
|
||||
.importance(55)
|
||||
.flags({options::OptionFlags::RangeTypeInteger})
|
||||
.finish();
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -779,7 +779,7 @@ void endDrawing(graphics::paths::PathRenderer* path) {
|
||||
}
|
||||
}
|
||||
|
||||
void gr_string(float sx, float sy, const char* s, int resize_mode, int in_length) {
|
||||
void gr_string(float sx, float sy, const char* s, int resize_mode, size_t in_length) {
|
||||
if (gr_screen.mode == GR_STUB) {
|
||||
return;
|
||||
}
|
||||
@@ -797,10 +797,10 @@ void gr_string(float sx, float sy, const char* s, int resize_mode, int in_length
|
||||
}
|
||||
|
||||
size_t length;
|
||||
if (in_length < 0) {
|
||||
if (in_length == std::string::npos) {
|
||||
length = strlen(s);
|
||||
} else {
|
||||
length = (size_t) in_length;
|
||||
length = in_length;
|
||||
}
|
||||
|
||||
FSFont* currentFont = FontManager::getCurrentFont();
|
||||
|
||||
@@ -60,7 +60,7 @@ void gr_bitmap_ex(int x, int y, int w, int h, int sx, int sy, int resize_mode =
|
||||
* @param resize_mode The mode for translating the screen positions
|
||||
* @param length The number of bytes in the string to render. -1 will render the whole string.
|
||||
*/
|
||||
void gr_string(float x, float y, const char* string, int resize_mode = GR_RESIZE_FULL, int length = -1);
|
||||
void gr_string(float x, float y, const char* string, int resize_mode = GR_RESIZE_FULL, size_t length = std::string::npos);
|
||||
/**
|
||||
* @brief Renders the specified string to the screen using the current font and color
|
||||
* @param x The x-coordinate
|
||||
@@ -69,7 +69,7 @@ void gr_string(float x, float y, const char* string, int resize_mode = GR_RESIZE
|
||||
* @param resize_mode The mode for translating the screen positions
|
||||
* @param length The number of bytes in the string to render. -1 will render the whole string.
|
||||
*/
|
||||
inline void gr_string(int x, int y, const char* string, int resize_mode = GR_RESIZE_FULL, int length = -1)
|
||||
inline void gr_string(int x, int y, const char* string, int resize_mode = GR_RESIZE_FULL, size_t length = std::string::npos)
|
||||
{
|
||||
gr_string(i2fl(x), i2fl(y), string, resize_mode, length);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ auto ShadowQualityOption = options::OptionBuilder<ShadowQuality>("Graphics.Shado
|
||||
{ShadowQuality::Ultra, {"Ultra", 1721}}})
|
||||
.change_listener([](ShadowQuality val, bool initial) {if (initial) {Shadow_quality = val;}return initial;})
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.default_val(ShadowQuality::Disabled)
|
||||
.importance(80)
|
||||
.finish();
|
||||
|
||||
@@ -669,7 +669,7 @@ int gr_get_dynamic_font_lines(int number_default_lines) {
|
||||
return fl2i((number_default_lines * 10) / (gr_get_font_height() + 1));
|
||||
}
|
||||
|
||||
void gr_get_string_size(int *w1, int *h1, const char *text, int len)
|
||||
void gr_get_string_size(int *w1, int *h1, const char *text, size_t len)
|
||||
{
|
||||
if (!FontManager::isReady())
|
||||
{
|
||||
@@ -685,7 +685,7 @@ void gr_get_string_size(int *w1, int *h1, const char *text, int len)
|
||||
float w = 0.0f;
|
||||
float h = 0.0f;
|
||||
|
||||
FontManager::getCurrentFont()->getStringSize(text, static_cast<size_t>(len), -1, &w, &h);
|
||||
FontManager::getCurrentFont()->getStringSize(text, len, -1, &w, &h);
|
||||
|
||||
if (w1)
|
||||
{
|
||||
|
||||
+52
-46
@@ -81,7 +81,7 @@ int HUD_color_blue = 0;
|
||||
int HUD_color_alpha = HUD_COLOR_ALPHA_DEFAULT; // 1 -> HUD_COLOR_ALPHA_USER_MAX
|
||||
|
||||
int HUD_draw = 1;
|
||||
int HUD_contrast = 0; // high or lo contrast (for nebula, etc)
|
||||
bool HUD_high_contrast = false; // high or low contrast (for nebula, etc)
|
||||
bool HUD_shadows = false;
|
||||
|
||||
// Goober5000
|
||||
@@ -363,7 +363,7 @@ void HudGauge::initPosition(int x, int y)
|
||||
position[1] = y;
|
||||
}
|
||||
|
||||
void HudGauge::getPosition(int *x, int *y)
|
||||
void HudGauge::getPosition(int *x, int *y) const
|
||||
{
|
||||
*x = position[0];
|
||||
*y = position[1];
|
||||
@@ -390,7 +390,7 @@ void HudGauge::initFont(int input_font_num)
|
||||
}
|
||||
}
|
||||
|
||||
int HudGauge::getFont()
|
||||
int HudGauge::getFont() const
|
||||
{
|
||||
return font_num;
|
||||
}
|
||||
@@ -404,7 +404,7 @@ void HudGauge::initOriginAndOffset(float originX, float originY, int offsetX, in
|
||||
tabled_offset[1] = offsetY;
|
||||
}
|
||||
|
||||
void HudGauge::getOriginAndOffset(float *originX, float *originY, int *offsetX, int *offsetY)
|
||||
void HudGauge::getOriginAndOffset(float *originX, float *originY, int *offsetX, int *offsetY) const
|
||||
{
|
||||
*originX = tabled_origin[0];
|
||||
*originY = tabled_origin[1];
|
||||
@@ -420,19 +420,24 @@ void HudGauge::initCoords(bool use_coords, int coordsX, int coordsY)
|
||||
tabled_coords[1] = coordsY;
|
||||
}
|
||||
|
||||
void HudGauge::getCoords(bool *use_coords, int *coordsX, int *coordsY)
|
||||
void HudGauge::getCoords(bool *use_coords, int *coordsX, int *coordsY) const
|
||||
{
|
||||
*use_coords = tabled_use_coords;
|
||||
*coordsX = tabled_coords[0];
|
||||
*coordsY = tabled_coords[1];
|
||||
}
|
||||
|
||||
const char* HudGauge::getCustomGaugeName()
|
||||
void HudGauge::initHiRes(const char* fname)
|
||||
{
|
||||
hi_res = (strncmp(fname, "2_", 2) == 0);
|
||||
}
|
||||
|
||||
const char* HudGauge::getCustomGaugeName() const
|
||||
{
|
||||
return custom_name;
|
||||
}
|
||||
|
||||
const char* HudGauge::getCustomGaugeText()
|
||||
const char* HudGauge::getCustomGaugeText() const
|
||||
{
|
||||
return custom_text.c_str();
|
||||
}
|
||||
@@ -483,17 +488,17 @@ void HudGauge::setGaugeColor(int bright_index)
|
||||
if(bright_index != HUD_C_NONE){
|
||||
switch(bright_index){
|
||||
case HUD_C_DIM:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
gr_init_alphacolor(&gauge_color, gauge_color.red, gauge_color.green, gauge_color.blue, alpha);
|
||||
break;
|
||||
|
||||
case HUD_C_NORMAL:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
gr_init_alphacolor(&gauge_color, gauge_color.red, gauge_color.green, gauge_color.blue, alpha);
|
||||
break;
|
||||
|
||||
case HUD_C_BRIGHT:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
gr_init_alphacolor(&gauge_color, gauge_color.red, gauge_color.green, gauge_color.blue, alpha);
|
||||
break;
|
||||
|
||||
@@ -523,15 +528,15 @@ void HudGauge::setGaugeColor(int bright_index)
|
||||
} else {
|
||||
switch(maybeFlashSexp()) {
|
||||
case 0:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
gr_init_alphacolor(&gauge_color, gauge_color.red, gauge_color.green, gauge_color.blue, alpha);
|
||||
break;
|
||||
case 1:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
gr_init_alphacolor(&gauge_color, gauge_color.red, gauge_color.green, gauge_color.blue, alpha);
|
||||
break;
|
||||
default:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
gr_init_alphacolor(&gauge_color, gauge_color.red, gauge_color.green, gauge_color.blue, alpha);
|
||||
}
|
||||
}
|
||||
@@ -539,33 +544,37 @@ void HudGauge::setGaugeColor(int bright_index)
|
||||
gr_set_color_fast(&gauge_color);
|
||||
}
|
||||
|
||||
bool HudGauge::isCustom()
|
||||
bool HudGauge::isCustom() const
|
||||
{
|
||||
return custom_gauge;
|
||||
}
|
||||
|
||||
int HudGauge::getBaseWidth()
|
||||
bool HudGauge::isHiRes() const
|
||||
{
|
||||
return hi_res;
|
||||
}
|
||||
|
||||
int HudGauge::getBaseWidth() const
|
||||
{
|
||||
return base_w;
|
||||
}
|
||||
|
||||
int HudGauge::getBaseHeight()
|
||||
int HudGauge::getBaseHeight() const
|
||||
{
|
||||
return base_h;
|
||||
}
|
||||
|
||||
float HudGauge::getAspectQuotient()
|
||||
float HudGauge::getAspectQuotient() const
|
||||
{
|
||||
return aspect_quotient;
|
||||
}
|
||||
|
||||
int HudGauge::getConfigType()
|
||||
int HudGauge::getConfigType() const
|
||||
{
|
||||
//return gauge_type;
|
||||
return gauge_config;
|
||||
}
|
||||
|
||||
int HudGauge::getObjectType()
|
||||
int HudGauge::getObjectType() const
|
||||
{
|
||||
return gauge_object;
|
||||
}
|
||||
@@ -588,7 +597,7 @@ void HudGauge::updateColor(int r, int g, int b, int a)
|
||||
gr_init_alphacolor(&gauge_color, r, g, b, a);
|
||||
}
|
||||
|
||||
const color& HudGauge::getColor()
|
||||
const color& HudGauge::getColor() const
|
||||
{
|
||||
return gauge_color;
|
||||
}
|
||||
@@ -613,12 +622,12 @@ void HudGauge::initCockpit_view_choice(int cockpit_view_choice)
|
||||
render_for_cockpit_toggle = cockpit_view_choice;
|
||||
}
|
||||
|
||||
bool HudGauge::isOffbyDefault()
|
||||
bool HudGauge::isOffbyDefault() const
|
||||
{
|
||||
return off_by_default;
|
||||
}
|
||||
|
||||
bool HudGauge::isActive()
|
||||
bool HudGauge::isActive() const
|
||||
{
|
||||
return active && !sexp_override;
|
||||
}
|
||||
@@ -643,7 +652,7 @@ void HudGauge::startPopUp(int time)
|
||||
popup_timer = timestamp(time);
|
||||
}
|
||||
|
||||
int HudGauge::popUpActive()
|
||||
int HudGauge::popUpActive() const
|
||||
{
|
||||
//Assert(gauge_index >=0 && gauge_index < NUM_HUD_GAUGES);
|
||||
if ( !pop_up ) {
|
||||
@@ -673,7 +682,7 @@ void HudGauge::startFlashSexp()
|
||||
flash_status = false;
|
||||
}
|
||||
|
||||
bool HudGauge::flashExpiredSexp()
|
||||
bool HudGauge::flashExpiredSexp() const
|
||||
{
|
||||
if(timestamp_elapsed(flash_duration)) {
|
||||
return true;
|
||||
@@ -1147,7 +1156,7 @@ void HudGauge::initialize()
|
||||
sexp_lock_color = false;
|
||||
}
|
||||
|
||||
bool HudGauge::canRender()
|
||||
bool HudGauge::canRender() const
|
||||
{
|
||||
if (sexp_override) {
|
||||
return false;
|
||||
@@ -1293,12 +1302,12 @@ void HUD_init()
|
||||
last_percent_throttle = 0.0f;
|
||||
|
||||
// default to high contrast in the nebula
|
||||
HUD_contrast = 0;
|
||||
HUD_high_contrast = false;
|
||||
HUD_draw = 1;
|
||||
HUD_disable_except_messages = 0;
|
||||
|
||||
if(The_mission.flags[Mission::Mission_Flags::Fullneb]){
|
||||
HUD_contrast = 1;
|
||||
HUD_high_contrast = true;
|
||||
}
|
||||
|
||||
// reset to infinite
|
||||
@@ -1697,7 +1706,7 @@ void hud_render_preprocess(float frametime)
|
||||
|
||||
if ( hud_disabled() ) {
|
||||
// if the hud is disabled, we still need to make sure that the indicators are properly handled
|
||||
hud_do_lock_indicators(flFrametime);
|
||||
hud_do_lock_indicators(frametime);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1823,15 +1832,15 @@ void hud_maybe_display_supernova()
|
||||
/**
|
||||
* @brief Undertakes main HUD render.
|
||||
*/
|
||||
void hud_render_all()
|
||||
void hud_render_all(float frametime)
|
||||
{
|
||||
int i;
|
||||
|
||||
hud_render_gauges();
|
||||
hud_render_gauges(-1, frametime);
|
||||
|
||||
// start rendering cockpit dependent gauges if possible
|
||||
for ( i = 0; i < (int)Player_displays.size(); ++i ) {
|
||||
hud_render_gauges(i);
|
||||
hud_render_gauges(i, frametime);
|
||||
}
|
||||
|
||||
hud_clear_msg_buffer();
|
||||
@@ -1840,7 +1849,7 @@ void hud_render_all()
|
||||
font::set_font(font::FONT1);
|
||||
}
|
||||
|
||||
void hud_render_gauges(int cockpit_display_num)
|
||||
void hud_render_gauges(int cockpit_display_num, float frametime)
|
||||
{
|
||||
size_t j, num_gauges;
|
||||
ship_info* sip = &Ship_info[Player_ship->ship_info_index];
|
||||
@@ -1866,9 +1875,6 @@ void hud_render_gauges(int cockpit_display_num)
|
||||
}
|
||||
}
|
||||
|
||||
//Since we render things twice in VR mode, frametime needs to be halved for HUD, as the HUD uses the frametime to advance ANI's and crucially, the missile lock...
|
||||
float frametime = openxr_enabled() ? flFrametime * 0.5f : flFrametime;
|
||||
|
||||
// Check if this ship has its own HUD gauges.
|
||||
if ( sip->hud_enabled ) {
|
||||
num_gauges = sip->hud_gauges.size();
|
||||
@@ -3313,17 +3319,17 @@ void hud_set_gauge_color(int gauge_index, int bright_index)
|
||||
if(bright_index != HUD_C_NONE){
|
||||
switch(bright_index){
|
||||
case HUD_C_DIM:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
gr_init_alphacolor(use_color, use_color->red, use_color->green, use_color->blue, alpha);
|
||||
break;
|
||||
|
||||
case HUD_C_NORMAL:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
gr_init_alphacolor(use_color, use_color->red, use_color->green, use_color->blue, alpha);
|
||||
break;
|
||||
|
||||
case HUD_C_BRIGHT:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
gr_init_alphacolor(use_color, use_color->red, use_color->green, use_color->blue, alpha);
|
||||
break;
|
||||
|
||||
@@ -3353,15 +3359,15 @@ void hud_set_gauge_color(int gauge_index, int bright_index)
|
||||
} else {
|
||||
switch(flash_status) {
|
||||
case 0:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
gr_init_alphacolor(use_color, use_color->red, use_color->green, use_color->blue, alpha);
|
||||
break;
|
||||
case 1:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
gr_init_alphacolor(use_color, use_color->red, use_color->green, use_color->blue, alpha);
|
||||
break;
|
||||
default:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
gr_init_alphacolor(use_color, use_color->red, use_color->green, use_color->blue, alpha);
|
||||
break;
|
||||
}
|
||||
@@ -3864,12 +3870,12 @@ void hud_save_restore_camera_data(int save)
|
||||
|
||||
void hud_toggle_contrast()
|
||||
{
|
||||
HUD_contrast = !HUD_contrast;
|
||||
HUD_high_contrast = !HUD_high_contrast;
|
||||
}
|
||||
|
||||
void hud_set_contrast(int high)
|
||||
void hud_set_contrast(bool high)
|
||||
{
|
||||
HUD_contrast = high;
|
||||
HUD_high_contrast = high;
|
||||
}
|
||||
|
||||
void hud_toggle_shadows()
|
||||
@@ -3988,7 +3994,7 @@ HudGauge(HUD_OBJECT_MULTI_MSG, HUD_MESSAGE_LINES, false, true, 0, 255, 255, 255)
|
||||
{
|
||||
}
|
||||
|
||||
bool HudGaugeMultiMsg::canRender()
|
||||
bool HudGaugeMultiMsg::canRender() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
+26
-23
@@ -69,7 +69,7 @@ enum class HudAlignment
|
||||
};
|
||||
|
||||
extern int HUD_draw;
|
||||
extern int HUD_contrast;
|
||||
extern bool HUD_high_contrast;
|
||||
extern bool HUD_shadows;
|
||||
|
||||
#define HUD_NUM_COLOR_LEVELS 16
|
||||
@@ -119,8 +119,8 @@ void hud_close();
|
||||
void hud_level_close();
|
||||
void hud_update_frame(float frametime); // updates hud systems not dependant on rendering
|
||||
void hud_render_preprocess(float frametime); // renders 3d dependant gauges
|
||||
void hud_render_all();
|
||||
void hud_render_gauges(int cockpit_display_num = -1);
|
||||
void hud_render_all(float frametime);
|
||||
void hud_render_gauges(int cockpit_display_num, float frametime);
|
||||
void hud_stop_looped_engine_sounds();
|
||||
|
||||
// set the offset values for this render frame
|
||||
@@ -203,7 +203,7 @@ int hud_disabled_except_messages();
|
||||
|
||||
// contrast stuff
|
||||
void hud_toggle_contrast();
|
||||
void hud_set_contrast(int high);
|
||||
void hud_set_contrast(bool high);
|
||||
void hud_toggle_shadows();
|
||||
|
||||
class HudGauge
|
||||
@@ -223,6 +223,7 @@ protected:
|
||||
bool tabled_use_coords;
|
||||
int tabled_coords[2];
|
||||
float aspect_quotient;
|
||||
bool hi_res;
|
||||
|
||||
bool lock_color;
|
||||
bool sexp_lock_color;
|
||||
@@ -271,28 +272,30 @@ public:
|
||||
void initFont(int input_font_num);
|
||||
void initOriginAndOffset(float originX, float originY, int offsetX, int offsetY);
|
||||
void initCoords(bool use_coords, int coordsX, int coordsY);
|
||||
void initHiRes(const char* fname);
|
||||
|
||||
virtual void initSlew(bool slew);
|
||||
void initCockpitTarget(const char* display_name, int _target_x, int _target_y, int _target_w, int _target_h, int _canvas_w, int _canvas_h);
|
||||
void initRenderStatus(bool render);
|
||||
|
||||
bool isCustom();
|
||||
int getBaseWidth();
|
||||
int getBaseHeight();
|
||||
float getAspectQuotient();
|
||||
bool isCustom() const;
|
||||
bool isHiRes() const;
|
||||
int getBaseWidth() const;
|
||||
int getBaseHeight() const;
|
||||
float getAspectQuotient() const;
|
||||
|
||||
int getConfigType();
|
||||
int getObjectType();
|
||||
void getPosition(int *x, int *y);
|
||||
bool isOffbyDefault();
|
||||
bool isActive();
|
||||
int getConfigType() const;
|
||||
int getObjectType() const;
|
||||
void getPosition(int *x, int *y) const;
|
||||
bool isOffbyDefault() const;
|
||||
bool isActive() const;
|
||||
|
||||
int getFont();
|
||||
void getOriginAndOffset(float *originX, float *originY, int *offsetX, int *offsetY);
|
||||
void getCoords(bool* use_coords, int* coordsX, int* coordsY);
|
||||
int getFont() const;
|
||||
void getOriginAndOffset(float *originX, float *originY, int *offsetX, int *offsetY) const;
|
||||
void getCoords(bool* use_coords, int* coordsX, int* coordsY) const;
|
||||
|
||||
void updateColor(int r, int g, int b, int a = 255);
|
||||
const color& getColor();
|
||||
const color& getColor() const;
|
||||
void lockConfigColor(bool lock);
|
||||
void sexpLockConfigColor(bool lock);
|
||||
void updateActive(bool show);
|
||||
@@ -305,21 +308,21 @@ public:
|
||||
// For flashing gauges in training missions
|
||||
void startFlashSexp();
|
||||
int maybeFlashSexp();
|
||||
bool flashExpiredSexp();
|
||||
bool flashExpiredSexp() const;
|
||||
void resetTimers();
|
||||
|
||||
// For updating custom gauges
|
||||
const char* getCustomGaugeName();
|
||||
const char* getCustomGaugeName() const;
|
||||
void updateCustomGaugeText(const char* txt);
|
||||
void updateCustomGaugeText(const SCP_string& txt);
|
||||
const char* getCustomGaugeText();
|
||||
const char* getCustomGaugeText() const;
|
||||
|
||||
void startPopUp(int time=4000);
|
||||
int popUpActive();
|
||||
int popUpActive() const;
|
||||
|
||||
virtual void preprocess();
|
||||
virtual void render(float frametime);
|
||||
virtual bool canRender();
|
||||
virtual bool canRender() const;
|
||||
virtual void pageIn();
|
||||
virtual void initialize();
|
||||
virtual void onFrame(float frametime);
|
||||
@@ -549,7 +552,7 @@ class HudGaugeMultiMsg: public HudGauge
|
||||
protected:
|
||||
public:
|
||||
HudGaugeMultiMsg();
|
||||
bool canRender() override;
|
||||
bool canRender() const override;
|
||||
void render(float frametime) override;
|
||||
};
|
||||
|
||||
|
||||
@@ -327,8 +327,8 @@ void ssm_create(object *target, vec3d *start, size_t ssm_index, ssm_firing_info
|
||||
// Init the ssm data
|
||||
|
||||
count = Ssm_info[ssm_index].count;
|
||||
if (Ssm_info[ssm_index].max_count != -1) {
|
||||
count += Random::next(count, Ssm_info[ssm_index].max_count);
|
||||
if (Ssm_info[ssm_index].max_count != -1 && (Ssm_info[ssm_index].max_count - count) > 0) {
|
||||
count = Random::next(count, Ssm_info[ssm_index].max_count);
|
||||
}
|
||||
|
||||
// override in multiplayer
|
||||
|
||||
@@ -288,7 +288,7 @@ int draw_subsys_brackets(graphics::line_draw_list* draw_list, ship_subsys* subsy
|
||||
}
|
||||
|
||||
// determine if subsystem is on far or near side of the ship
|
||||
int in_sight = ship_subsystem_in_sight(targetp, subsys, &View_position, &subobj_pos, 0);
|
||||
bool in_sight = ship_subsystem_in_sight(targetp, subsys, &View_position, &subobj_pos, false);
|
||||
|
||||
if (draw)
|
||||
{
|
||||
@@ -761,7 +761,7 @@ void HudGaugeBrackets::renderBoundingBracketsSubobject()
|
||||
}
|
||||
|
||||
// determine if subsystem is on far or near side of the ship
|
||||
Player->subsys_in_view = ship_subsystem_in_sight(targetp, subsys, &View_position, &subobj_pos, 0);
|
||||
Player->subsys_in_view = ship_subsystem_in_sight(targetp, subsys, &View_position, &subobj_pos, false) ? 1 : 0;
|
||||
|
||||
// AL 29-3-98: If subsystem is destroyed, draw gray brackets
|
||||
// Goober5000: this will now execute for fighterbays if the bay has been given a
|
||||
|
||||
@@ -1323,10 +1323,8 @@ void hud_config_button_do(int n)
|
||||
break;
|
||||
}
|
||||
|
||||
if (HC_current_file >= (int)HC_preset_filenames.size()) {
|
||||
if ((++HC_current_file) >= static_cast<int> (HC_preset_filenames.size())) {
|
||||
HC_current_file = 0;
|
||||
} else {
|
||||
HC_current_file++;
|
||||
}
|
||||
|
||||
// load em up
|
||||
|
||||
@@ -506,7 +506,7 @@ int hud_lock_on_subsys_ok()
|
||||
vm_vec_add2(&subobj_pos, &target_objp->pos);
|
||||
|
||||
if ( Player->subsys_in_view < 0 ) {
|
||||
in_sight = ship_subsystem_in_sight(target_objp, subsys, &View_position, &subobj_pos);
|
||||
in_sight = ship_subsystem_in_sight(target_objp, subsys, &View_position, &subobj_pos) ? 1 : 0;
|
||||
} else {
|
||||
in_sight = Player->subsys_in_view;
|
||||
}
|
||||
@@ -640,7 +640,7 @@ void hud_do_lock_indicator(float frametime)
|
||||
vec3d subobj_pos;
|
||||
vm_vec_unrotate(&subobj_pos, &Player->locking_subsys->system_info->pnt, &tobjp->orient);
|
||||
vm_vec_add2(&subobj_pos, &tobjp->pos);
|
||||
int target_subsys_in_sight = ship_subsystem_in_sight(tobjp, Player->locking_subsys, &Player_obj->pos, &subobj_pos);
|
||||
bool target_subsys_in_sight = ship_subsystem_in_sight(tobjp, Player->locking_subsys, &Player_obj->pos, &subobj_pos);
|
||||
|
||||
if (!target_subsys_in_sight || Player->locking_subsys->system_info->type != SUBSYSTEM_ENGINE) {
|
||||
Player->locking_subsys =
|
||||
@@ -1059,7 +1059,7 @@ void hud_lock_determine_lock_target(lock_info *lock_slot, weapon_info *wip)
|
||||
vm_vec_unrotate(&subobj_pos, &Player->locking_subsys->system_info->pnt, &lock_slot->obj->orient);
|
||||
vm_vec_add2(&subobj_pos, &lock_slot->obj->pos);
|
||||
|
||||
int target_subsys_in_sight = ship_subsystem_in_sight(lock_slot->obj, Player_ai->targeted_subsys, &Player_obj->pos, &subobj_pos);
|
||||
bool target_subsys_in_sight = ship_subsystem_in_sight(lock_slot->obj, Player_ai->targeted_subsys, &Player_obj->pos, &subobj_pos);
|
||||
|
||||
if ( !target_subsys_in_sight || Player->locking_subsys->system_info->type != SUBSYSTEM_ENGINE ) {
|
||||
lock_slot->subsys = ship_get_closest_subsys_in_sight(&Ships[lock_slot->obj->instance], SUBSYSTEM_ENGINE, &Player_obj->pos);
|
||||
@@ -1110,7 +1110,7 @@ void hud_lock_determine_lock_target(lock_info *lock_slot, weapon_info *wip)
|
||||
vm_vec_unrotate(&subobj_pos, &Player_ai->targeted_subsys->system_info->pnt, &lock_slot->obj->orient);
|
||||
vm_vec_add2(&subobj_pos, &lock_slot->obj->pos);
|
||||
|
||||
int target_subsys_in_sight = ship_subsystem_in_sight(lock_slot->obj, Player_ai->targeted_subsys, &Player_obj->pos, &subobj_pos);
|
||||
bool target_subsys_in_sight = ship_subsystem_in_sight(lock_slot->obj, Player_ai->targeted_subsys, &Player_obj->pos, &subobj_pos);
|
||||
|
||||
if ( !target_subsys_in_sight || Player_ai->targeted_subsys->system_info->type != SUBSYSTEM_ENGINE ) {
|
||||
lock_slot->subsys = ship_get_closest_subsys_in_sight(&Ships[lock_slot->obj->instance], SUBSYSTEM_ENGINE, &Player_obj->pos);
|
||||
|
||||
@@ -305,7 +305,7 @@ void HudGaugeMessages::processMessageBuffer()
|
||||
ptr = strstr(msg, NOX(": "));
|
||||
if ( ptr ) {
|
||||
int sw;
|
||||
gr_get_string_size(&sw, nullptr, msg, (int)(ptr + 2 - msg));
|
||||
gr_get_string_size(&sw, nullptr, msg, (ptr + 2 - msg));
|
||||
offset = sw;
|
||||
}
|
||||
|
||||
@@ -641,7 +641,7 @@ void hud_add_msg_to_scrollback(const char *text, int source, int t)
|
||||
|
||||
// determine the length of the sender's name for underlining
|
||||
if (ptr) {
|
||||
gr_get_string_size(&w, nullptr, buf, (int)(ptr - buf));
|
||||
gr_get_string_size(&w, nullptr, buf, (ptr - buf));
|
||||
}
|
||||
|
||||
// create the new node for the vector
|
||||
@@ -843,7 +843,7 @@ void hud_initialize_scrollback_lines()
|
||||
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
gr_get_string_size(&width, &height, node_msg.text.c_str(), (int)node_msg.text.length());
|
||||
gr_get_string_size(&width, &height, node_msg.text.c_str(), node_msg.text.length());
|
||||
|
||||
int max_width = Hud_mission_log_list2_coords[gr_screen.res][2];
|
||||
if (width > max_width) {
|
||||
@@ -1264,7 +1264,7 @@ void HudGaugeTalkingHead::pageIn()
|
||||
bm_page_in_aabitmap( Head_frame.first_frame, Head_frame.num_frames );
|
||||
}
|
||||
|
||||
bool HudGaugeTalkingHead::canRender()
|
||||
bool HudGaugeTalkingHead::canRender() const
|
||||
{
|
||||
if (sexp_override) {
|
||||
return false;
|
||||
|
||||
@@ -137,7 +137,7 @@ public:
|
||||
void pageIn() override;
|
||||
void render(float frametime) override;
|
||||
void initialize() override;
|
||||
bool canRender() override;
|
||||
bool canRender() const override;
|
||||
};
|
||||
|
||||
class HudGaugeFixedMessages: public HudGauge
|
||||
|
||||
+37
-1
@@ -1611,6 +1611,7 @@ void load_gauge_lag(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -1666,6 +1667,7 @@ void load_gauge_mini_shields(gauge_settings* settings)
|
||||
hud_gauge->init2DigitOffsets(Mini_2digit_offsets[0], Mini_2digit_offsets[1]);
|
||||
hud_gauge->init3DigitOffsets(Mini_3digit_offsets[0], Mini_3digit_offsets[1]);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -1762,6 +1764,7 @@ void load_gauge_weapon_energy(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initEnergyHeight(Wenergy_h);
|
||||
hud_gauge->initTextOffsets(Wenergy_text_offsets[0], Wenergy_text_offsets[1]);
|
||||
hud_gauge->initAlignments(text_alignment, weapon_alignment);
|
||||
@@ -1915,6 +1918,7 @@ void load_gauge_escort_view(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_top, fname_middle, fname_bottom);
|
||||
hud_gauge->initHiRes(fname_top);
|
||||
hud_gauge->initEntryHeight(entry_h);
|
||||
hud_gauge->initEntryStaggerWidth(entry_stagger_w);
|
||||
hud_gauge->initBottomBgOffset(bottom_bg_offset);
|
||||
@@ -1976,6 +1980,7 @@ void load_gauge_afterburner(gauge_settings* settings)
|
||||
|
||||
hud_gauge->initEnergyHeight(energy_h);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -2018,6 +2023,7 @@ void load_gauge_mission_time(gauge_settings* settings)
|
||||
hud_gauge->initTextOffsets(time_text_offsets[0], time_text_offsets[1]);
|
||||
hud_gauge->initValueOffsets(time_val_offsets[0], time_val_offsets[1]);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -2111,6 +2117,7 @@ void load_gauge_threat_indicator(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_arc, fname_laser, fname_lock);
|
||||
hud_gauge->initHiRes(fname_arc);
|
||||
hud_gauge->initLaserWarnOffsets(Laser_warn_offsets[0], Laser_warn_offsets[1]);
|
||||
hud_gauge->initLockWarnOffsets(Lock_warn_offsets[0], Lock_warn_offsets[1]);
|
||||
|
||||
@@ -2178,6 +2185,7 @@ void load_gauge_center_reticle(gauge_settings* settings)
|
||||
stuff_int(&autoaim_frame);
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initFirepointDisplay(firepoints, scaleX, scaleY, size);
|
||||
hud_gauge->setAutoaimFrame(autoaim_frame);
|
||||
|
||||
@@ -2351,6 +2359,7 @@ void load_gauge_throttle(gauge_settings* settings)
|
||||
hud_gauge->initGlideOffsets(glide_offset[0], glide_offset[1], custom_glide);
|
||||
hud_gauge->initMatchSpeedOffsets(match_speed_offset[0], match_speed_offset[1], custom_match);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->showBackground(show_background);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
@@ -2435,6 +2444,7 @@ void load_gauge_ets_retail(gauge_settings* settings)
|
||||
hud_gauge->initBottomOffsets(bottom_offsets[0], bottom_offsets[1]);
|
||||
hud_gauge->initBarHeight(bar_h);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initGaugePositions(gauge_positions);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
@@ -2502,6 +2512,7 @@ void load_gauge_ets_weapons(gauge_settings* settings)
|
||||
hud_gauge->initBottomOffsets(bottom_offsets[0], bottom_offsets[1]);
|
||||
hud_gauge->initBarHeight(bar_h);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -2565,6 +2576,7 @@ void load_gauge_ets_shields(gauge_settings* settings)
|
||||
|
||||
hud_gauge->initBarHeight(bar_h);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initBottomOffsets(bottom_offsets[0], bottom_offsets[1]);
|
||||
hud_gauge->initLetter(letter);
|
||||
hud_gauge->initLetterOffsets(letter_offsets[0], letter_offsets[1]);
|
||||
@@ -2633,6 +2645,7 @@ void load_gauge_ets_engines(gauge_settings* settings)
|
||||
|
||||
hud_gauge->initBarHeight(bar_h);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initBottomOffsets(bottom_offsets[0], bottom_offsets[1]);
|
||||
hud_gauge->initLetter(letter);
|
||||
hud_gauge->initLetterOffsets(letter_offsets[0], letter_offsets[1]);
|
||||
@@ -2708,6 +2721,7 @@ void load_gauge_extra_target_data(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initBracketOffsets(bracket_offsets[0], bracket_offsets[1]);
|
||||
hud_gauge->initDockOffsets(dock_offsets[0], dock_offsets[1]);
|
||||
hud_gauge->initDockMaxWidth(dock_max_w);
|
||||
@@ -2830,6 +2844,7 @@ void load_gauge_radar_std(gauge_settings* settings)
|
||||
// Only load this if the user hasn't specified a preference
|
||||
if (Cmdline_orb_radar == 0) {
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initBlipRadius(Radar_blip_radius_normal, Radar_blip_radius_target);
|
||||
hud_gauge->initCenterOffsets(Radar_center_offsets[0], Radar_center_offsets[1]);
|
||||
hud_gauge->initDistanceInfinityOffsets(Radar_dist_offsets[2][0], Radar_dist_offsets[2][1]);
|
||||
@@ -2926,6 +2941,7 @@ void load_gauge_radar_orb(gauge_settings* settings)
|
||||
//only load this if the user actually wants to use the orb radar.
|
||||
if (Cmdline_orb_radar == 1) {
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initBlipRadius(Radar_blip_radius_normal, Radar_blip_radius_target);
|
||||
hud_gauge->initCenterOffsets(Radar_center_offsets[0], Radar_center_offsets[1]);
|
||||
hud_gauge->initDistanceInfinityOffsets(Radar_dist_offsets[2][0], Radar_dist_offsets[2][1]);
|
||||
@@ -3126,6 +3142,7 @@ void load_gauge_radar_dradis(gauge_settings* settings)
|
||||
|
||||
hud_gauge->initRadius(Radar_radius[0], Radar_radius[1]);
|
||||
hud_gauge->initBitmaps(xy_fname, xz_yz_fname, sweep_fname, target_fname, unknown_fname);
|
||||
hud_gauge->initHiRes(xy_fname);
|
||||
hud_gauge->initCockpitTarget(display_name, display_offset[0], display_offset[1], display_size[0], display_size[1], canvas_size[0], canvas_size[1]);
|
||||
hud_gauge->initSound(loop_snd, loop_snd_volume, arrival_beep_snd, departure_beep_snd, stealth_arrival_snd, stealth_departure_snd, arrival_beep_delay, departure_beep_delay);
|
||||
hud_gauge->initChase_view_only(settings->chase_view_only);
|
||||
@@ -3345,6 +3362,7 @@ void load_gauge_target_monitor(gauge_settings* settings)
|
||||
hud_gauge->initGaugeWirecolor(wirecolor);
|
||||
hud_gauge->initGaugeWirecolorOverride(wirecoloroverride);
|
||||
hud_gauge->initBitmaps(fname_monitor, fname_monitor_mask, fname_integrity, fname_static);
|
||||
hud_gauge->initHiRes(fname_monitor);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -3429,6 +3447,7 @@ void load_gauge_squad_message(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_top, fname_middle, fname_bottom);
|
||||
hud_gauge->initHiRes(fname_top);
|
||||
hud_gauge->initHeaderOffsets(Header_offsets[0], Header_offsets[1]);
|
||||
hud_gauge->initItemStartOffsets(Item_start_offsets[0], Item_start_offsets[1]);
|
||||
hud_gauge->initMiddleFrameStartOffsetY(Middle_frame_start_offset_y);
|
||||
@@ -3501,6 +3520,7 @@ void load_gauge_objective_notify(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initObjTextOffsetY(Objective_text_offset_y);
|
||||
hud_gauge->initObjValueOffsetY(Objective_text_val_offset_y);
|
||||
hud_gauge->initSubspaceTextOffsetY(Subspace_text_offset_y);
|
||||
@@ -3769,6 +3789,7 @@ void load_gauge_directives(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_top, fname_middle, fname_bottom);
|
||||
hud_gauge->initHiRes(fname_top);
|
||||
hud_gauge->initMiddleFrameOffsetY(middle_frame_offset_y);
|
||||
hud_gauge->initTextHeight(text_h);
|
||||
hud_gauge->initBottomBgOffset(bottom_bg_offset);
|
||||
@@ -3827,6 +3848,7 @@ void load_gauge_talking_head(gauge_settings* settings)
|
||||
hud_gauge->initAnimOffsets(Anim_offsets[0], Anim_offsets[1]);
|
||||
hud_gauge->initAnimSizes(Anim_size[0], Anim_size[1]);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initHeaderOffsets(Header_offsets[0], Header_offsets[1]);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
@@ -3866,6 +3888,7 @@ void load_gauge_countermeasures(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initCountTextOffsets(cm_text_offset[0], cm_text_offset[1]);
|
||||
hud_gauge->initCountValueOffsets(cm_text_val_offset[0], cm_text_val_offset[1]);
|
||||
|
||||
@@ -3924,6 +3947,7 @@ void load_gauge_auto_target(gauge_settings* settings)
|
||||
|
||||
hud_gauge->initAutoTextOffsets(auto_text_offset[0], auto_text_offset[1]);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initTargetTextOffsets(target_text_offset[0], target_text_offset[1]);
|
||||
hud_gauge->initOnColor(on_color[0], on_color[1], on_color[2], on_color[3]);
|
||||
hud_gauge->initOffColor(off_color[0], off_color[1], off_color[2], off_color[3]);
|
||||
@@ -3982,6 +4006,7 @@ void load_gauge_auto_speed(gauge_settings* settings)
|
||||
|
||||
hud_gauge->initAutoTextOffsets(auto_text_offset[0], auto_text_offset[1]);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initSpeedTextOffsets(speed_text_offset[0], speed_text_offset[1]);
|
||||
hud_gauge->initOnColor(on_color[0], on_color[1], on_color[2], on_color[3]);
|
||||
hud_gauge->initOffColor(off_color[0], off_color[1], off_color[2], off_color[3]);
|
||||
@@ -4121,6 +4146,7 @@ void load_gauge_wingman_status(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_left, fname_middle, fname_right, fname_dots);
|
||||
hud_gauge->initHiRes(fname_left);
|
||||
hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
|
||||
hud_gauge->initFixedHeaderPosition(fixed_header_position);
|
||||
hud_gauge->initLeftFrameEndX(left_frame_end_x);
|
||||
@@ -4218,6 +4244,7 @@ void load_gauge_damage(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_top, fname_middle, fname_bottom);
|
||||
hud_gauge->initHiRes(fname_top);
|
||||
hud_gauge->initHullIntegOffsets(hull_integ_offsets[0], hull_integ_offsets[1]);
|
||||
hud_gauge->initHullIntegValueOffsetX(hull_integ_val_offset_x);
|
||||
hud_gauge->initLineHeight(line_h);
|
||||
@@ -4285,6 +4312,7 @@ void load_gauge_support(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
|
||||
hud_gauge->initTextDockOffsetX(text_dock_offset_x);
|
||||
hud_gauge->initTextDockValueOffsetX(text_dock_val_offset_x);
|
||||
@@ -4504,6 +4532,7 @@ void load_gauge_weapon_linking(gauge_settings* settings)
|
||||
hud_gauge->init2SecondaryOffsets(Weapon_link_offsets[LINK_TWO_SECONDARY][0], Weapon_link_offsets[LINK_TWO_SECONDARY][1]);
|
||||
hud_gauge->init3SecondaryOffsets(Weapon_link_offsets[LINK_THREE_SECONDARY][0], Weapon_link_offsets[LINK_THREE_SECONDARY][1]);
|
||||
hud_gauge->initBitmaps(fname_arc, fname_primary_link_1, fname_primary_link_2, fname_secondary_link_1, fname_secondary_link_2, fname_secondary_link_3);
|
||||
hud_gauge->initHiRes(fname_arc);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -4688,10 +4717,11 @@ void load_gauge_lock(gauge_settings* settings)
|
||||
stuff_boolean(&loop_locked_anim);
|
||||
}
|
||||
if(optional_string("Blink Locked Animation:")) {
|
||||
stuff_boolean(&loop_locked_anim);
|
||||
stuff_boolean(&blink_locked_anim);
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_lock, fname_spin);
|
||||
hud_gauge->initHiRes(fname_lock);
|
||||
hud_gauge->initLoopLockedAnim(loop_locked_anim);
|
||||
hud_gauge->initBlinkLockedAnim(blink_locked_anim);
|
||||
hud_gauge->initGaugeHalfSize(Lock_gauge_half_w, Lock_gauge_half_h);
|
||||
@@ -4766,6 +4796,7 @@ void load_gauge_brackets(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initMinSubTargetBoxSizes(min_subtarget_box[0], min_subtarget_box[1]);
|
||||
hud_gauge->initMinTargetBoxSizes(min_target_box[0], min_target_box[1]);
|
||||
|
||||
@@ -4957,6 +4988,7 @@ void load_gauge_lead(gauge_settings* settings)
|
||||
|
||||
hud_gauge->initHalfSize(Lead_indicator_half[0], Lead_indicator_half[1]);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -5015,6 +5047,7 @@ void load_gauge_lead_sight(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -5059,6 +5092,7 @@ void load_gauge_kills(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initTextOffsets(text_offsets[0], text_offsets[1]);
|
||||
hud_gauge->initTextValueOffsets(text_value_offsets[0], text_value_offsets[1]);
|
||||
|
||||
@@ -5299,6 +5333,7 @@ void load_gauge_primary_weapons(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_first, fname_entry, fname_last);
|
||||
hud_gauge->initHiRes(fname_first);
|
||||
hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
|
||||
hud_gauge->initHeaderText(header_text);
|
||||
hud_gauge->initBgFirstHeight(first_bg_h);
|
||||
@@ -5413,6 +5448,7 @@ void load_gauge_secondary_weapons(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_first, fname_entry, fname_last);
|
||||
hud_gauge->initHiRes(fname_first);
|
||||
hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
|
||||
hud_gauge->initHeaderText(header_text);
|
||||
hud_gauge->initBgFirstHeight(first_bg_h);
|
||||
|
||||
@@ -2635,7 +2635,7 @@ bool HudGaugeSquadMessage::maybeFlashPageScroll(bool flash_fast)
|
||||
return draw_bright;
|
||||
}
|
||||
|
||||
bool HudGaugeSquadMessage::canRender()
|
||||
bool HudGaugeSquadMessage::canRender() const
|
||||
{
|
||||
if(hud_disabled_except_messages() && !message_gauge) {
|
||||
return false;
|
||||
|
||||
@@ -213,7 +213,7 @@ public:
|
||||
void initPgDnOffsets(int x, int y);
|
||||
|
||||
void render(float frametime) override;
|
||||
bool canRender() override;
|
||||
bool canRender() const override;
|
||||
void pageIn() override;
|
||||
void initialize() override;
|
||||
void startFlashPageScroll(int duration = 1400);
|
||||
|
||||
+22
-10
@@ -470,7 +470,7 @@ int hud_target_invalid_awacs(object *objp)
|
||||
}
|
||||
|
||||
// check for invalid status
|
||||
if((Player_ship != NULL) && (awacs_get_level(objp, Player_ship) < 1.0f)){
|
||||
if((Player_ship != nullptr) && (awacs_get_level(objp, Player_ship) < 1.0f)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -872,7 +872,7 @@ void hud_target_hotkey_select( int k )
|
||||
|
||||
// a simple walk of the list to get the count
|
||||
for ( hitem = GET_FIRST(plist); hitem != END_OF_LIST(plist); hitem = GET_NEXT(hitem) ){
|
||||
if (awacs_get_level(hitem->objp, Player_ship, 1) > 1) {
|
||||
if (awacs_get_level(hitem->objp, Player_ship, true) > 1.0f) {
|
||||
visible_count++;
|
||||
}
|
||||
}
|
||||
@@ -894,7 +894,7 @@ void hud_target_hotkey_select( int k )
|
||||
first_target = NULL;
|
||||
for ( hitem = GET_FIRST(plist); hitem != END_OF_LIST(plist); hitem = GET_NEXT(hitem) ) {
|
||||
|
||||
if (awacs_get_level(hitem->objp, Player_ship, 1) > 1) {
|
||||
if (awacs_get_level(hitem->objp, Player_ship, true) > 1.0f) {
|
||||
// get the first valid target
|
||||
if (first_target == NULL) {
|
||||
first_target = hitem;
|
||||
@@ -939,7 +939,7 @@ void hud_target_hotkey_select( int k )
|
||||
|
||||
// next is before current target, so search from start of list
|
||||
for ( hitem = GET_FIRST(plist); hitem != END_OF_LIST(plist); hitem = GET_NEXT(hitem) ) {
|
||||
if (awacs_get_level(hitem->objp, Player_ship, 1) > 1) {
|
||||
if (awacs_get_level(hitem->objp, Player_ship, true) > 1.0f) {
|
||||
target = hitem;
|
||||
break;
|
||||
}
|
||||
@@ -1830,7 +1830,7 @@ void hud_target_live_turret(int next_flag, int auto_advance, int only_player_tar
|
||||
distance = vm_vec_normalized_dir(&vec_to_subsys, &gsubpos, &View_position);
|
||||
|
||||
// check if facing and in view
|
||||
int facing = ship_subsystem_in_sight(objp, A, &View_position, &gsubpos, 0);
|
||||
bool facing = ship_subsystem_in_sight(objp, A, &View_position, &gsubpos, false);
|
||||
|
||||
if (!auto_advance && get_closest_turret && !only_player_target) {
|
||||
// if within 3 degrees and not previous subsys, use subsys in front
|
||||
@@ -2334,7 +2334,7 @@ void hud_update_closest_turret()
|
||||
}
|
||||
|
||||
// check if facing and in view
|
||||
int facing = ship_subsystem_in_sight(objp, ss, &View_position, &gsubpos, 0);
|
||||
bool facing = ship_subsystem_in_sight(objp, ss, &View_position, &gsubpos, false);
|
||||
|
||||
if (facing) {
|
||||
new_distance *= 0.5f;
|
||||
@@ -2627,12 +2627,24 @@ void hud_target_in_reticle_old()
|
||||
|
||||
target_obj = hud_reticle_pick_target();
|
||||
if ( target_obj != NULL ) {
|
||||
int oldTargetNum = Player_ai->target_objnum;
|
||||
set_target_objnum( Player_ai, OBJ_INDEX(target_obj) );
|
||||
hud_shield_hit_reset(target_obj);
|
||||
|
||||
if ( target_obj->type == OBJ_SHIP ) {
|
||||
hud_maybe_set_sorted_turret_subsys(&Ships[target_obj->instance]);
|
||||
hud_restore_subsystem_target(&Ships[target_obj->instance]);
|
||||
ship* shipp = &Ships[target_obj->instance];
|
||||
|
||||
// if the player is attempting to target the same ship under their reticule again
|
||||
// then lets select the nearest subsystem for them.
|
||||
if (Automatically_select_subsystem_under_reticle_when_targeting_same_ship &&
|
||||
Ship_info[shipp->ship_info_index].is_big_or_huge() &&
|
||||
oldTargetNum == Player_ai->target_objnum) {
|
||||
hud_target_subsystem_in_reticle();
|
||||
}
|
||||
else {
|
||||
hud_maybe_set_sorted_turret_subsys(shipp);
|
||||
hud_restore_subsystem_target(shipp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -3426,7 +3438,7 @@ void hud_show_selection_set()
|
||||
// Goober5000 - don't draw indicators for non-visible ships, per Mantis #1972
|
||||
// (the only way we could get here is if the hotkey set contained a mix of visible
|
||||
// and invisible ships)
|
||||
if (awacs_get_level(targetp, Player_ship, 1) < 1) {
|
||||
if (awacs_get_level(targetp, Player_ship, true) < 1.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3590,7 +3602,7 @@ void hud_show_hostile_triangle()
|
||||
}
|
||||
|
||||
// check if ship is stealthy
|
||||
if (awacs_get_level(&Objects[sp->objnum], Player_ship, 1) < 1) {
|
||||
if (awacs_get_level(&Objects[sp->objnum], Player_ship, true) < 1.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1906,7 +1906,7 @@ int hud_targetbox_subsystem_in_view(object *target_objp, int *sx, int *sy)
|
||||
|
||||
// is it subsystem in view
|
||||
if ( Player->subsys_in_view == -1 ) {
|
||||
rval = ship_subsystem_in_sight(target_objp, subsys, &View_position, &subobj_pos, 0);
|
||||
rval = ship_subsystem_in_sight(target_objp, subsys, &View_position, &subobj_pos, false) ? 1 : 0;
|
||||
} else {
|
||||
rval = Player->subsys_in_view;
|
||||
}
|
||||
|
||||
+16
-10
@@ -24,6 +24,10 @@ int radar_iff_color[5][2][4];
|
||||
int iff_bright_delta;
|
||||
int *iff_color_brightness = &iff_bright_delta;
|
||||
|
||||
int IFF_COLOR_SELECTION = 0;
|
||||
int IFF_COLOR_MESSAGE = 1;
|
||||
int IFF_COLOR_TAGGED = 2;
|
||||
|
||||
// global only to file
|
||||
SCP_vector <std::pair<color, color>> Iff_colors; // AL 1-2-97: Create two IFF colors, regular and bright
|
||||
|
||||
@@ -249,28 +253,28 @@ void parse_iff_table(const char* filename)
|
||||
if ((optional_string("$Selection Color:")) || (optional_string("$Selection Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
IFF_COLOR_SELECTION = iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
else
|
||||
iff_init_color(0xff, 0xff, 0xff);
|
||||
else if (!Parsing_modular_table)
|
||||
IFF_COLOR_SELECTION = iff_init_color(0xff, 0xff, 0xff);
|
||||
|
||||
// Marks the ship currently saying something
|
||||
if ((optional_string("$Message Color:")) || (optional_string("$Message Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
IFF_COLOR_MESSAGE = iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
else
|
||||
iff_init_color(0x7f, 0x7f, 0x7f);
|
||||
else if (!Parsing_modular_table)
|
||||
IFF_COLOR_MESSAGE = iff_init_color(0x7f, 0x7f, 0x7f);
|
||||
|
||||
// Marks the tagged ships
|
||||
if ((optional_string("$Tagged Color:")) || (optional_string("$Tagged Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
IFF_COLOR_TAGGED = iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
else
|
||||
iff_init_color(0xff, 0xff, 0x00);
|
||||
else if (!Parsing_modular_table)
|
||||
IFF_COLOR_TAGGED = iff_init_color(0xff, 0xff, 0x00);
|
||||
|
||||
// init radar blips colour table
|
||||
int a_bright, a_dim;
|
||||
@@ -579,7 +583,9 @@ int iff_lookup(const char *iff_name)
|
||||
*/
|
||||
int iff_get_attackee_mask(int attacker_team)
|
||||
{
|
||||
Assert(attacker_team >= 0 && attacker_team < (int)Iff_info.size());
|
||||
Assertion(SCP_vector_inbounds(Iff_info, attacker_team), "Attempted to get the attackee mask of an attacker team that is out of bounds");
|
||||
if (!SCP_vector_inbounds(Iff_info, attacker_team))
|
||||
return 0;
|
||||
|
||||
// All teams attack all other teams.
|
||||
if (Mission_all_attack)
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
class object;
|
||||
|
||||
// Goober5000 - new IFF color system
|
||||
#define IFF_COLOR_SELECTION 0
|
||||
#define IFF_COLOR_MESSAGE 1
|
||||
#define IFF_COLOR_TAGGED 2
|
||||
// Now variables so that modular tables can actually affect them. -MageKing17
|
||||
extern int IFF_COLOR_SELECTION;
|
||||
extern int IFF_COLOR_MESSAGE;
|
||||
extern int IFF_COLOR_TAGGED;
|
||||
|
||||
enum IFF_hotkey_team { Default = -1, None = 0, Friendly, Hostile };
|
||||
|
||||
|
||||
+4
-4
@@ -241,7 +241,7 @@ SCP_vector<Joystick*> joystick_enumerator()
|
||||
auto JoystickOption = options::OptionBuilder<Joystick*>("Input.Joystick",
|
||||
std::pair<const char*, int>{"Joystick 0", 1705},
|
||||
std::pair<const char*, int>{"The current joystick 0", 1706})
|
||||
.category("Input") // Category this option shows up in the scripting heirachy
|
||||
.category(std::make_pair("Input", 1827)) // Category this option shows up in the scripting heirachy
|
||||
.deserializer(joystick_deserialize) // callback for json to C++
|
||||
.serializer(joystick_serializer) // callback for C++ to json
|
||||
.display(joystick_display) // callback for constructing the display label
|
||||
@@ -255,7 +255,7 @@ auto JoystickOption = options::OptionBuilder<Joystick*>("Input.Joystick",
|
||||
auto JoystickOption1 = options::OptionBuilder<Joystick*>("Input.Joystick1",
|
||||
std::pair<const char*, int>{"Joystick 1", 1707},
|
||||
std::pair<const char*, int>{"The current joystick 1", 1708})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.deserializer(joystick_deserialize)
|
||||
.serializer(joystick_serializer)
|
||||
.display(joystick_display)
|
||||
@@ -269,7 +269,7 @@ auto JoystickOption1 = options::OptionBuilder<Joystick*>("Input.Joystick1",
|
||||
auto JoystickOption2 = options::OptionBuilder<Joystick*>("Input.Joystick2",
|
||||
std::pair<const char*, int>{"Joystick 2", 1709},
|
||||
std::pair<const char*, int>{"The current joystick 2", 1710})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.deserializer(joystick_deserialize)
|
||||
.serializer(joystick_serializer)
|
||||
.display(joystick_display)
|
||||
@@ -283,7 +283,7 @@ auto JoystickOption2 = options::OptionBuilder<Joystick*>("Input.Joystick2",
|
||||
auto JoystickOption3 = options::OptionBuilder<Joystick*>("Input.Joystick3",
|
||||
std::pair<const char*, int>{"Joystick 3", 1711},
|
||||
std::pair<const char*, int>{"The current joystick 3", 1712})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.deserializer(joystick_deserialize)
|
||||
.serializer(joystick_serializer)
|
||||
.display(joystick_display)
|
||||
|
||||
@@ -49,7 +49,7 @@ static haptic_effect_t pExplode;
|
||||
static auto ForceFeedbackOption = options::OptionBuilder<bool>("Input.ForceFeedback",
|
||||
std::pair<const char*, int>{"Force Feedback", 1728},
|
||||
std::pair<const char*, int>{"Enable or disable force feedback", 1729})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(false)
|
||||
.finish();
|
||||
@@ -57,7 +57,7 @@ static auto ForceFeedbackOption = options::OptionBuilder<bool>("Input.ForceFeedb
|
||||
static auto HitEffectOption = options::OptionBuilder<bool>("Input.HitEffect",
|
||||
std::pair<const char*, int>{"Directional Hit", 1730},
|
||||
std::pair<const char*, int>{"Enable or disable the directional hit effect", 1731})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(false)
|
||||
.finish();
|
||||
@@ -65,7 +65,7 @@ static auto HitEffectOption = options::OptionBuilder<bool>("Input.HitEffect",
|
||||
static auto ForceFeedbackStrength = options::OptionBuilder<float>("Input.FFStrength",
|
||||
std::pair<const char*, int>{"Force Feedback Strength", 1756},
|
||||
std::pair<const char*, int>{"The realtive strength of Force Feedback effects", 1757})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.range(0, 100)
|
||||
.default_val(100)
|
||||
|
||||
+5
-3
@@ -59,12 +59,13 @@ int Mouse_sensitivity = 4;
|
||||
static auto MouseSensitivityOption __UNUSED = options::OptionBuilder<int>("Input.MouseSensitivity",
|
||||
std::pair<const char*, int>{"Sensitivity", 1374},
|
||||
std::pair<const char*, int>{"The sensitivity of the mouse input", 1747})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.range(0, 9)
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(4)
|
||||
.bind_to(&Mouse_sensitivity)
|
||||
.importance(0)
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
bool Use_mouse_to_fly = false;
|
||||
@@ -72,14 +73,15 @@ bool Use_mouse_to_fly = false;
|
||||
static SCP_string mouse_mode_display(bool mode) { return mode ? XSTR("Joy-0", 1699) : XSTR("Mouse", 1774); }
|
||||
|
||||
static auto UseMouseOption __UNUSED = options::OptionBuilder<bool>("Input.UseMouse",
|
||||
std::pair<const char*, int>{"Mouse", 1376},
|
||||
std::pair<const char*, int>{"Mouse", 1373},
|
||||
std::pair<const char*, int>{"Whether or not to use the mouse for flying", 1765})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.display(mouse_mode_display)
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(false)
|
||||
.bind_to(&Use_mouse_to_fly)
|
||||
.importance(1)
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
const std::shared_ptr<scripting::Hook<>> OnMouseWheelHook = scripting::Hook<>::Factory(
|
||||
|
||||
@@ -160,7 +160,7 @@ namespace ltp = lighting_profiles;
|
||||
using namespace ltp;
|
||||
bool graphics_options_changed()
|
||||
{
|
||||
auto stored_settings = getLabManager()->graphicsSettings;
|
||||
const auto& stored_settings = getLabManager()->graphicsSettings;
|
||||
|
||||
if (stored_settings.ambient_factor != ltp::lab_get_ambient())
|
||||
return true;
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
#include "lab/renderer/lab_renderer.h"
|
||||
#include "freespace.h"
|
||||
#include "globalincs/vmallocator.h"
|
||||
#include "lab/labv2_internal.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "graphics/light.h"
|
||||
#include "lab/labv2_internal.h"
|
||||
#include "lab/renderer/lab_renderer.h"
|
||||
#include "lighting/lighting_profiles.h"
|
||||
#include "math/bitarray.h"
|
||||
#include "nebula/neb.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "starfield/starfield.h"
|
||||
#include "starfield/nebula.h"
|
||||
#include "nebula/neb.h"
|
||||
#include "freespace.h"
|
||||
|
||||
#include "missionui/missionscreencommon.h"
|
||||
#include "tracing/tracing.h"
|
||||
@@ -347,7 +348,7 @@ void LabRenderer::useBackground(const SCP_string& mission_name) {
|
||||
(ambient_light_level >> 16) & 0xff);
|
||||
|
||||
strcpy_s(Neb2_texture_name, "");
|
||||
Neb2_poof_flags = 0;
|
||||
clear_all_bits(Neb2_poof_flags.get(), Poof_info.size());
|
||||
bool nebula = false;
|
||||
if (optional_string("+Neb2:")) {
|
||||
nebula = true;
|
||||
@@ -364,8 +365,11 @@ void LabRenderer::useBackground(const SCP_string& mission_name) {
|
||||
}
|
||||
|
||||
if (nebula){
|
||||
// Obsolete and only for backwards compatibility
|
||||
if (optional_string("+Neb2Flags:")) {
|
||||
stuff_int(&Neb2_poof_flags);
|
||||
int temp;
|
||||
stuff_int(&temp);
|
||||
bit_array_set_from_int(Neb2_poof_flags.get(), Poof_info.size(), temp);
|
||||
}
|
||||
// Get poofs by name
|
||||
if (optional_string("+Neb2 Poofs List:")) {
|
||||
|
||||
+44
-10
@@ -107,7 +107,7 @@ static bool DeferredLightingEnabled = true;
|
||||
static auto DeferredLightingOption = options::OptionBuilder<bool>("Graphics.DeferredLighting",
|
||||
std::pair<const char*, int>{"Deferred Lighting", 1782},
|
||||
std::pair<const char*, int>{"Enables or disables deferred lighting", 1783})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.default_val(true)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.bind_to_once(&DeferredLightingEnabled)
|
||||
@@ -176,13 +176,13 @@ static void light_rotate(light * l)
|
||||
}
|
||||
}
|
||||
|
||||
void light_add_directional(const vec3d* dir, const hdr_color* new_color, const float source_radius)
|
||||
void light_add_directional(const vec3d* dir, int sun_index, bool no_glare, const hdr_color* new_color, const float source_radius)
|
||||
{
|
||||
Assert(new_color!= nullptr);
|
||||
light_add_directional(dir, new_color->i(), new_color->r(), new_color->g(), new_color->b(), source_radius);
|
||||
light_add_directional(dir, sun_index, no_glare, new_color->i(), new_color->r(), new_color->g(), new_color->b(), source_radius);
|
||||
}
|
||||
namespace ltp=lighting_profiles;
|
||||
void light_add_directional(const vec3d *dir, float intensity, float r, float g, float b, const float source_radius)
|
||||
void light_add_directional(const vec3d *dir, int sun_index, bool no_glare, float intensity, float r, float g, float b, const float source_radius)
|
||||
{
|
||||
if (Lighting_off) return;
|
||||
|
||||
@@ -191,6 +191,8 @@ void light_add_directional(const vec3d *dir, float intensity, float r, float g,
|
||||
light l;
|
||||
|
||||
l.type = Light_Type::Directional;
|
||||
l.flags = no_glare ? (LF_DEFAULT | LF_NO_GLARE) : LF_DEFAULT;
|
||||
l.sun_index = sun_index;
|
||||
|
||||
vm_vec_copy_scale( &l.vec, dir, -1.0f );
|
||||
|
||||
@@ -233,6 +235,8 @@ void light_add_point(const vec3d *pos, float r1, float r2, float intensity, floa
|
||||
|
||||
Num_lights++;
|
||||
l.type = Light_Type::Point;
|
||||
l.flags = LF_DEFAULT;
|
||||
l.sun_index = -1;
|
||||
l.vec = *pos;
|
||||
l.r = r;
|
||||
l.g = g;
|
||||
@@ -272,6 +276,8 @@ void light_add_tube(const vec3d *p0, const vec3d *p1, float r1, float r2, float
|
||||
Num_lights++;
|
||||
|
||||
l.type = Light_Type::Tube;
|
||||
l.flags = LF_DEFAULT;
|
||||
l.sun_index = -1;
|
||||
l.vec = *p0;
|
||||
l.vec2 = *p1;
|
||||
l.r = r;
|
||||
@@ -317,19 +323,46 @@ int light_get_global_count()
|
||||
* @param pos Position
|
||||
* @param n Light source
|
||||
*
|
||||
* Returns 0 if there is no global light.
|
||||
* Returns false if there is no global light.
|
||||
*/
|
||||
int light_get_global_dir(vec3d *pos, int n)
|
||||
bool light_get_global_dir(vec3d *pos, int n)
|
||||
{
|
||||
if ( (n < 0) || (n >= (int)Static_light.size()) ) {
|
||||
return 0;
|
||||
if (!SCP_vector_inbounds(Static_light, n)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pos) {
|
||||
*pos = Static_light[n].vec;
|
||||
vm_vec_scale( pos, -1.0f );
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool light_has_glare(int n)
|
||||
{
|
||||
if (!SCP_vector_inbounds(Static_light, n)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Static_light[n].flags & LF_NO_GLARE) == 0;
|
||||
}
|
||||
|
||||
int light_get_sun_index(int n)
|
||||
{
|
||||
if (!SCP_vector_inbounds(Static_light, n)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return Static_light[n].sun_index;
|
||||
}
|
||||
|
||||
int light_find_for_sun(int sun_index)
|
||||
{
|
||||
for (size_t n = 0; n < Static_light.size(); ++n)
|
||||
if (Static_light[n].sun_index == sun_index)
|
||||
return static_cast<int>(n);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void light_apply_rgb( ubyte *param_r, ubyte *param_g, ubyte *param_b, const vec3d *pos, const vec3d *norm, float static_light_level )
|
||||
@@ -478,11 +511,12 @@ void light_add_cone(const vec3d *pos, const vec3d *dir, float angle, float inner
|
||||
Num_lights++;
|
||||
|
||||
l.type = Light_Type::Cone;
|
||||
l.flags = dual_cone ? (LF_DEFAULT | LF_DUAL_CONE) : LF_DEFAULT;
|
||||
l.sun_index = -1;
|
||||
l.vec = *pos;
|
||||
l.vec2= *dir;
|
||||
l.cone_angle = angle;
|
||||
l.cone_inner_angle = inner_angle;
|
||||
l.dual_cone = dual_cone;
|
||||
l.r = r;
|
||||
l.g = g;
|
||||
l.b = b;
|
||||
|
||||
@@ -47,11 +47,16 @@ typedef struct light {
|
||||
float r,g,b; // The color components of the light
|
||||
float cone_angle; // angle for cone lights
|
||||
float cone_inner_angle; // the inner angle for calculating falloff
|
||||
bool dual_cone; // should the cone be shining in both directions?
|
||||
int flags; // see below
|
||||
int sun_index; // if this light corresponds to a sun
|
||||
float source_radius; // The actual size of the object or volume emitting the light
|
||||
int instance;
|
||||
} light;
|
||||
|
||||
#define LF_DUAL_CONE (1<<0) // should the cone be shining in both directions?
|
||||
#define LF_NO_GLARE (1<<1) // for example, a sun with $NoGlare
|
||||
#define LF_DEFAULT 0 // no flags by default
|
||||
|
||||
extern SCP_vector<light> Static_light;
|
||||
|
||||
struct light_indexing_info
|
||||
@@ -91,8 +96,8 @@ extern void light_reset();
|
||||
|
||||
//Intensity in lighting inputs multiplies the base colors.
|
||||
|
||||
extern void light_add_directional(const vec3d *dir, const hdr_color *new_color, const float source_radius = 0.0f );
|
||||
extern void light_add_directional(const vec3d *dir, float intensity, float r, float g, float b, const float source_radius = 0.0f);
|
||||
extern void light_add_directional(const vec3d *dir, int sun_index, bool no_glare, const hdr_color *new_color, const float source_radius = 0.0f );
|
||||
extern void light_add_directional(const vec3d *dir, int sun_index, bool no_glare, float intensity, float r, float g, float b, const float source_radius = 0.0f);
|
||||
extern void light_add_point(const vec3d * pos, float r1, float r2, const hdr_color *new_color, const float source_radius = 0.0f);
|
||||
extern void light_add_point(const vec3d * pos, float r1, float r2, float intensity, float r, float g, float b, const float source_radius = 0.0f);
|
||||
extern void light_add_tube(const vec3d *p0, const vec3d *p1, float r1, float r2, const hdr_color *new_color, const float source_radius = 0.0f);
|
||||
@@ -110,8 +115,13 @@ void light_apply_rgb( ubyte *param_r, ubyte *param_g, ubyte *param_b, const vec3
|
||||
extern int light_get_global_count();
|
||||
|
||||
// Fills direction of global light source N in pos.
|
||||
// Returns 0 if there is no global light.
|
||||
extern int light_get_global_dir(vec3d *pos, int n);
|
||||
// Returns false if there is no global light.
|
||||
extern bool light_get_global_dir(vec3d *pos, int n);
|
||||
|
||||
extern bool light_has_glare(int n);
|
||||
|
||||
extern int light_get_sun_index(int n);
|
||||
extern int light_find_for_sun(int sun_index);
|
||||
|
||||
bool light_compare_by_type(const light &a, const light &b);
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ bool *Lcl_unexpected_tstring_check = nullptr;
|
||||
// NOTE: with map storage of XSTR strings, the indexes no longer need to be contiguous,
|
||||
// but internal strings should still increment XSTR_SIZE to avoid collisions.
|
||||
// retail XSTR_SIZE = 1570
|
||||
// #define XSTR_SIZE 1816 // This is the next available ID
|
||||
// #define XSTR_SIZE 1842 // This is the next available ID
|
||||
|
||||
|
||||
// struct to allow for strings.tbl-determined x offset
|
||||
@@ -152,7 +152,7 @@ auto LanguageOption = options::OptionBuilder<int>("Game.Language",
|
||||
return false; //This makes it so that changing the language requires a game restart
|
||||
})
|
||||
.flags({options::OptionFlags::ForceMultiValueSelection})
|
||||
.category("Game")
|
||||
.category(std::make_pair("Game", 1824))
|
||||
.default_val(0)
|
||||
.finish();
|
||||
|
||||
|
||||
+51
-1
@@ -42,8 +42,58 @@
|
||||
#define toggle_bit(array, bitnum) (((ubyte *) array)[(bitnum) >> 3] ^= (1 << ((bitnum) & 7)))
|
||||
|
||||
|
||||
// calculate number of bytes from number of bits
|
||||
// calculates number of bytes from number of bits
|
||||
#define calculate_num_bytes(num_bits) ((num_bits >> 3) + 1)
|
||||
|
||||
// zeroes out all bits in the bit array
|
||||
#define clear_all_bits(array, num_bits) memset(array, 0, calculate_num_bytes(num_bits))
|
||||
|
||||
// tests whether any bit in this bit array is nonzero
|
||||
template <class N_TYPE>
|
||||
bool any_bits_set(void *array, N_TYPE num_bits)
|
||||
{
|
||||
auto bytes = static_cast<ubyte*>(array);
|
||||
N_TYPE num_bytes = calculate_num_bytes(num_bits);
|
||||
for (N_TYPE i = 0; i < num_bytes; ++i)
|
||||
if (bytes[i] != 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// copies a bit array into an int so that they contain equivalent values, up to the capacity of the int type
|
||||
template <class N_TYPE>
|
||||
int bit_array_as_int(void *array, N_TYPE num_bits)
|
||||
{
|
||||
int rval = 0;
|
||||
|
||||
auto bytes = static_cast<ubyte*>(array);
|
||||
N_TYPE num_bytes = calculate_num_bytes(num_bits);
|
||||
for (N_TYPE i = 0; i < num_bytes && i < sizeof(int); ++i)
|
||||
{
|
||||
rval = rval << 3;
|
||||
rval |= bytes[i];
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
// copies an int into a bit array so that they contain equivalent values; any bits in the bit array higher than the capacity of an int are zeroed out
|
||||
template <class N_TYPE>
|
||||
void bit_array_set_from_int(void *array, N_TYPE num_bits, int input)
|
||||
{
|
||||
auto bytes = static_cast<ubyte*>(array);
|
||||
N_TYPE num_bytes = calculate_num_bytes(num_bits);
|
||||
for (N_TYPE i = 0; i < num_bytes; ++i)
|
||||
{
|
||||
if (i < sizeof(int))
|
||||
{
|
||||
bytes[i] = input & 255;
|
||||
input = input >> 3;
|
||||
}
|
||||
else
|
||||
bytes[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // _BIT_ARRAY_H
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
SCP_vector<Curve> Curves;
|
||||
|
||||
int curve_get_by_name(SCP_string& in_name) {
|
||||
int curve_get_by_name(const SCP_string& in_name) {
|
||||
for (int i = 0; i < (int)Curves.size(); i++) {
|
||||
if (lcase_equal(Curves[i].name, in_name))
|
||||
return i;
|
||||
|
||||
+1
-1
@@ -43,6 +43,6 @@ public :
|
||||
|
||||
extern SCP_vector<Curve> Curves;
|
||||
|
||||
extern int curve_get_by_name(SCP_string& in_name);
|
||||
extern int curve_get_by_name(const SCP_string& in_name);
|
||||
extern void curves_init();
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
*/
|
||||
float fl_roundoff(float x, int multiple)
|
||||
{
|
||||
float half = (float) multiple / 2.0f;
|
||||
float half = multiple / 2.0f;
|
||||
|
||||
if (x < 0)
|
||||
half = -half;
|
||||
|
||||
x += half;
|
||||
return (float) (((int) x / multiple) * multiple);
|
||||
return i2fl((fl2i(x) / multiple) * multiple);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+8
-56
@@ -30,67 +30,19 @@ inline bool fl_is_nan(float fl) {
|
||||
#define fl_sqrt(fl) sqrtf(fl)
|
||||
#define fl_isqrt(fl) (1.0f/sqrtf(fl))
|
||||
#define fl_abs(fl) fabsf(fl)
|
||||
#define i2fl(i) ((float)(i))
|
||||
#define fl2i(fl) ((int)(fl))
|
||||
#define fl2ir(fl) ((int)(fl + ((fl < 0.0f) ? -0.5f : 0.5f)))
|
||||
#define flceil(fl) (int)ceil(fl)
|
||||
#define flfloor(fl) (int)floor(fl)
|
||||
#define f2fl(fx) ((float)(fx)/65536.0f)
|
||||
#define f2d(fx) (((double)(fx))/65536.0)
|
||||
#define fl2f(fl) (int)((fl)*65536.0f)
|
||||
#define i2fl(i) (static_cast<float>(i))
|
||||
#define fl2i(fl) (static_cast<int>(fl))
|
||||
#define fl2ir(fl) (static_cast<int>(fl + (((fl) < 0.0f) ? -0.5f : 0.5f)))
|
||||
#define f2fl(fx) (static_cast<float>(fx)/65536.0f)
|
||||
#define f2d(fx) (static_cast<double>(fx)/65536.0)
|
||||
#define fl2f(fl) (static_cast<int>((fl)*65536.0f))
|
||||
#define fl_tan(fl) tanf(fl)
|
||||
|
||||
// convert a measurement in degrees to radians
|
||||
#define fl_radians(fl) ((float)((fl) * (PI / 180.0f)))
|
||||
#define fl_radians(fl) (static_cast<float>((fl) * (PI / 180.0f)))
|
||||
|
||||
// convert a measurement in radians to degrees
|
||||
#define fl_degrees(fl) ((float)((fl) * (180.0f / PI)))
|
||||
|
||||
// use this instead of:
|
||||
// for: (int)floor(x+0.5f) use fl_round_2048(x)
|
||||
// (int)ceil(x-0.5f) use fl_round_2048(x)
|
||||
// (int)floor(x-0.5f) use fl_round_2048(x-1.0f)
|
||||
// (int)floor(x) use fl_round_2048(x-0.5f)
|
||||
// for values in the range -2048 to 2048
|
||||
// use this instead of:
|
||||
// for: (int)floor(x+0.5f) use fl_round_2048(x)
|
||||
// (int)ceil(x-0.5f) use fl_round_2048(x)
|
||||
// (int)floor(x-0.5f) use fl_round_2048(x-1.0f)
|
||||
// (int)floor(x) use fl_round_2048(x-0.5f)
|
||||
// for values in the range -2048 to 2048
|
||||
|
||||
/*
|
||||
extern const float *p_fl_magic;
|
||||
|
||||
inline int fl_round_2048( float x )
|
||||
{
|
||||
double tmp_quad;
|
||||
tmp_quad = x + *p_fl_magic;
|
||||
return *((int *)&tmp_quad);
|
||||
}
|
||||
|
||||
inline float fl_sqrt( float x)
|
||||
{
|
||||
float retval;
|
||||
|
||||
_asm fld x
|
||||
_asm fsqrt
|
||||
_asm fstp retval
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
float fl_isqrt( float x )
|
||||
{
|
||||
float retval;
|
||||
|
||||
_asm fld x
|
||||
_asm fsqrt
|
||||
_asm fstp retval
|
||||
|
||||
return 1.0f / retval;
|
||||
}
|
||||
*/
|
||||
#define fl_degrees(fl) (static_cast<float>((fl) * (180.0f / PI)))
|
||||
|
||||
// sees if a floating point number is within a certain threshold (by default, epsilon) of zero
|
||||
inline bool fl_near_zero(float a, float e = std::numeric_limits<float>::epsilon())
|
||||
|
||||
@@ -1070,6 +1070,9 @@ void barracks_button_pressed(int n)
|
||||
} else {
|
||||
gamesnd_play_iface(InterfaceSounds::SCROLL);
|
||||
|
||||
// we now have a new pilot, so try to load its current campaign, falling back if necessary
|
||||
mission_load_up_campaign(true);
|
||||
|
||||
if (Campaign_file_missing) {
|
||||
popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR( "The currently active campaign cannot be found. Please select another...", 1600));
|
||||
gameseq_post_event(GS_EVENT_CAMPAIGN_ROOM);
|
||||
@@ -1081,6 +1084,9 @@ void barracks_button_pressed(int n)
|
||||
if (Num_pilots && !barracks_pilot_accepted()) {
|
||||
gamesnd_play_iface(InterfaceSounds::COMMIT_PRESSED);
|
||||
|
||||
// we now have a new pilot, so try to load its current campaign, falling back if necessary
|
||||
mission_load_up_campaign(true);
|
||||
|
||||
if (Campaign_file_missing) {
|
||||
popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR( "The currently active campaign cannot be found. Please select another...", 1600));
|
||||
gameseq_post_event(GS_EVENT_CAMPAIGN_ROOM);
|
||||
|
||||
@@ -639,7 +639,7 @@ void credits_init()
|
||||
|
||||
for (iter = Credit_text_parts.begin(); iter != Credit_text_parts.end(); ++iter)
|
||||
{
|
||||
gr_get_string_size(NULL, &temp_h, iter->c_str(), (int)iter->length());
|
||||
gr_get_string_size(NULL, &temp_h, iter->c_str(), iter->length());
|
||||
|
||||
h = h + temp_h;
|
||||
}
|
||||
@@ -855,12 +855,12 @@ void credits_do_frame(float /*frametime*/)
|
||||
length = std::numeric_limits<size_t>::max();
|
||||
}
|
||||
|
||||
gr_get_string_size(&width, &height, iter->c_str() + currentPos, static_cast<int>(length));
|
||||
gr_get_string_size(&width, &height, iter->c_str() + currentPos, length);
|
||||
// Check if the text part is actually visible
|
||||
if (Credit_position + y_offset + height > 0.0f)
|
||||
{
|
||||
float x = static_cast<float>((gr_screen.clip_width_unscaled - width) / 2);
|
||||
gr_string(x, Credit_position + y_offset, iter->c_str() + currentPos, GR_RESIZE_MENU, static_cast<int>(length));
|
||||
gr_string(x, Credit_position + y_offset, iter->c_str() + currentPos, GR_RESIZE_MENU, length);
|
||||
}
|
||||
|
||||
y_offset += height;
|
||||
|
||||
@@ -309,6 +309,8 @@ static int F1_text_done = 0;
|
||||
int Main_hall_help_stamp = -1;
|
||||
void main_hall_process_help_stuff();
|
||||
|
||||
bool Main_hall_use_defaults = true;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// VOICE RECORDING STUFF
|
||||
@@ -906,8 +908,7 @@ void main_hall_do(float frametime)
|
||||
Game_mode = GM_NORMAL;
|
||||
|
||||
// see if we have a missing campaign and force the player to select a new campaign if so
|
||||
if (!(Player->flags & PLAYER_FLAGS_IS_MULTI) && Campaign_file_missing &&
|
||||
!Campaign_room_no_campaigns) {
|
||||
if (!(Player->flags & PLAYER_FLAGS_IS_MULTI) && Campaign_file_missing && !Campaign_room_no_campaigns) {
|
||||
int rc = popup(0,
|
||||
3,
|
||||
XSTR("Go to Campaign Room", 1607),
|
||||
@@ -933,7 +934,6 @@ void main_hall_do(float frametime)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
||||
gameseq_post_event(GS_EVENT_NEW_CAMPAIGN);
|
||||
gamesnd_play_iface(InterfaceSounds::IFACE_MOUSE_CLICK);
|
||||
}
|
||||
@@ -2158,18 +2158,20 @@ void region_info_init(main_hall_defines &m)
|
||||
m.regions.clear();
|
||||
}
|
||||
|
||||
main_hall_region defaults[] = {
|
||||
main_hall_region(0, 0, XSTR( "Exit FreeSpace 2", 353), EXIT_REGION, ""),
|
||||
main_hall_region(1, 'B', XSTR( "Barracks - Manage your FreeSpace 2 pilots", 354), BARRACKS_REGION, ""),
|
||||
main_hall_region(2, 'R', XSTR( "Ready room - Start or continue a campaign", 355), START_REGION, ""),
|
||||
main_hall_region(3, 'T', XSTR( "Tech room - View specifications of FreeSpace 2 ships and weaponry", 356), TECH_ROOM_REGION, ""),
|
||||
main_hall_region(4, 0, XSTR( "Options - Change your FreeSpace 2 options", 357), OPTIONS_REGION, ""),
|
||||
main_hall_region(5, 'C', XSTR( "Campaign Room - View all available campaigns", 358), CAMPAIGN_ROOM_REGION, ""),
|
||||
main_hall_region(6, 'G', "Quick start", QUICK_START_REGION, "")
|
||||
};
|
||||
if (Main_hall_use_defaults) {
|
||||
main_hall_region defaults[] = {
|
||||
main_hall_region(0, 0, XSTR( "Exit FreeSpace 2", 353), EXIT_REGION, ""),
|
||||
main_hall_region(1, 'B', XSTR( "Barracks - Manage your FreeSpace 2 pilots", 354), BARRACKS_REGION, ""),
|
||||
main_hall_region(2, 'R', XSTR( "Ready room - Start or continue a campaign", 355), START_REGION, ""),
|
||||
main_hall_region(3, 'T', XSTR( "Tech room - View specifications of FreeSpace 2 ships and weaponry", 356), TECH_ROOM_REGION, ""),
|
||||
main_hall_region(4, 0, XSTR( "Options - Change your FreeSpace 2 options", 357), OPTIONS_REGION, ""),
|
||||
main_hall_region(5, 'C', XSTR( "Campaign Room - View all available campaigns", 358), CAMPAIGN_ROOM_REGION, ""),
|
||||
main_hall_region(6, 'G', "Quick start", QUICK_START_REGION, "")
|
||||
};
|
||||
|
||||
for (int idx = 0; idx < 7; idx++) {
|
||||
m.regions.push_back(defaults[idx]);
|
||||
for (int idx = 0; idx < 7; idx++) {
|
||||
m.regions.push_back(defaults[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
// XSTR( "Multiplayer - Start or join a multiplayer game", 359)
|
||||
@@ -2216,6 +2218,10 @@ void parse_main_hall_table(const char* filename)
|
||||
|
||||
reset_parse();
|
||||
|
||||
if (optional_string("$Base mainhalls on retail defaults:")) {
|
||||
stuff_boolean(&Main_hall_use_defaults);
|
||||
}
|
||||
|
||||
if (optional_string("$Num Resolutions:")) {
|
||||
stuff_int(&num_resolutions);
|
||||
}
|
||||
|
||||
@@ -1,258 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "freespace.h"
|
||||
#include "gamesequence/gamesequence.h"
|
||||
#include "gamesnd/gamesnd.h"
|
||||
#include "io/key.h"
|
||||
#include "menuui/mainhallmenu.h"
|
||||
#include "menuui/mainhalltemp.h"
|
||||
#include "mission/missioncampaign.h"
|
||||
#include "mission/missionload.h"
|
||||
#include "playerman/player.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------
|
||||
// TEMP MAIN HALL DEFINES/VARS
|
||||
//
|
||||
|
||||
#define MHT_NUM_BUTTONS 6
|
||||
|
||||
const char *Mht_bitmap_fname[GR_NUM_RESOLUTIONS] = {
|
||||
"mht_background", // GR_640
|
||||
"2_mht_background" // GR_1024
|
||||
};
|
||||
|
||||
const char *Mht_bitmap_mask_fname[GR_NUM_RESOLUTIONS] = {
|
||||
"mht_mask", // GR_640
|
||||
"2_mht_mask" // GR_1024
|
||||
};
|
||||
|
||||
// button defs
|
||||
#define MHT_READY_ROOM 0
|
||||
#define MHT_CAMPAIGN_ROOM 1
|
||||
#define MHT_OPTIONS 2
|
||||
#define MHT_TECH_ROOM 3
|
||||
#define MHT_BARRACKS 4
|
||||
#define MHT_EXIT 5
|
||||
|
||||
UI_WINDOW Mht_window; // the window object for the join screen
|
||||
int Mht_bitmap; // the background bitmap
|
||||
|
||||
ui_button_info Mht_buttons[GR_NUM_RESOLUTIONS][MHT_NUM_BUTTONS] = {
|
||||
{ // GR_640
|
||||
ui_button_info( "MHT_00", 15, 194, -1, -1, 2 ), // ready room
|
||||
ui_button_info( "MHT_01", 15, 222, -1, -1, 5 ), // campaigns
|
||||
ui_button_info( "MHT_02", 14, 251, -1, -1, 4 ), // options
|
||||
ui_button_info( "MHT_03", 14, 280, -1, -1, 3 ), // tech room
|
||||
ui_button_info( "MHT_04", 14, 309, -1, -1, 1 ), // barracks
|
||||
ui_button_info( "MHT_05", 16, 339, -1, -1, 0 ), // exit
|
||||
},
|
||||
{ // GR_1024
|
||||
ui_button_info( "2_MHT_00", 25, 312, -1, -1, 2 ), // ready room
|
||||
ui_button_info( "2_MHT_01", 25, 357, -1, -1, 5 ), // campaigns
|
||||
ui_button_info( "2_MHT_02", 24, 403, -1, -1, 4 ), // options
|
||||
ui_button_info( "2_MHT_03", 24, 450, -1, -1, 3 ), // tech room
|
||||
ui_button_info( "2_MHT_04", 25, 497, -1, -1, 1 ), // barracks
|
||||
ui_button_info( "2_MHT_05", 27, 544, -1, -1, 0 ), // exit
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------
|
||||
// TEMP MAIN HALL FUNCTIONS
|
||||
//
|
||||
|
||||
void mht_check_buttons();
|
||||
void mht_button_pressed(int n);
|
||||
void mht_exit_game();
|
||||
|
||||
void mht_init()
|
||||
{
|
||||
int idx;
|
||||
|
||||
// create the interface window
|
||||
Mht_window.create(0, 0, gr_screen.max_w_unscaled,gr_screen.max_h_unscaled, 0);
|
||||
Mht_window.set_mask_bmap(Mht_bitmap_mask_fname[gr_screen.res]);
|
||||
|
||||
// load the background bitmap
|
||||
Mht_bitmap = bm_load(Mht_bitmap_fname[gr_screen.res]);
|
||||
if(Mht_bitmap < 0){
|
||||
// we failed to load the bitmap - this is very bad
|
||||
Int3();
|
||||
}
|
||||
|
||||
// create the interface buttons
|
||||
for(idx=0; idx<MHT_NUM_BUTTONS; idx++){
|
||||
// create the object
|
||||
Mht_buttons[gr_screen.res][idx].button.create(&Mht_window, "", Mht_buttons[gr_screen.res][idx].x, Mht_buttons[gr_screen.res][idx].y, 1, 1, 0, 1);
|
||||
|
||||
// set the sound to play when highlighted
|
||||
Mht_buttons[gr_screen.res][idx].button.set_highlight_action(common_play_highlight_sound);
|
||||
|
||||
// set the ani for the button
|
||||
Mht_buttons[gr_screen.res][idx].button.set_bmaps(Mht_buttons[gr_screen.res][idx].filename);
|
||||
|
||||
// set the hotspot
|
||||
Mht_buttons[gr_screen.res][idx].button.link_hotspot(Mht_buttons[gr_screen.res][idx].hotspot);
|
||||
}
|
||||
|
||||
// remove any multiplayer flags from the game mode
|
||||
Game_mode &= ~(GM_MULTIPLAYER);
|
||||
|
||||
// initialize the music
|
||||
main_hall_start_music();
|
||||
|
||||
// set the game_mode based on the type of player
|
||||
Assert( Player != NULL );
|
||||
if ( Player->flags & PLAYER_FLAGS_IS_MULTI ){
|
||||
Game_mode = GM_MULTIPLAYER;
|
||||
} else {
|
||||
Game_mode = GM_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
void mht_do()
|
||||
{
|
||||
int k = Mht_window.process();
|
||||
|
||||
// need to ensure ambient is playing, since it may be stopped by a playing movie
|
||||
main_hall_start_ambient();
|
||||
|
||||
// process any keypresses
|
||||
switch(k){
|
||||
case KEY_ESC :
|
||||
mht_exit_game();
|
||||
break;
|
||||
|
||||
case KEY_B:
|
||||
gameseq_post_event( GS_EVENT_BARRACKS_MENU );
|
||||
break;
|
||||
|
||||
case KEY_G:
|
||||
if(Player->flags & PLAYER_FLAGS_IS_MULTI){
|
||||
break;
|
||||
}
|
||||
|
||||
if (Num_recent_missions > 0) {
|
||||
strcpy_s( Game_current_mission_filename, Recent_missions[0] );
|
||||
} else {
|
||||
mission_load_up_campaign();
|
||||
strcpy_s( Game_current_mission_filename, Campaign.missions[0].name );
|
||||
}
|
||||
|
||||
Campaign.current_mission = -1;
|
||||
gameseq_post_event(GS_EVENT_START_GAME_QUICK);
|
||||
break;
|
||||
|
||||
case KEY_L:
|
||||
gameseq_post_event( GS_EVENT_LOAD_MISSION_MENU );
|
||||
break;
|
||||
|
||||
case KEY_F2:
|
||||
gameseq_post_event(GS_EVENT_OPTIONS_MENU);
|
||||
break;
|
||||
|
||||
case KEY_M:
|
||||
if (Player->flags & PLAYER_FLAGS_IS_MULTI){
|
||||
main_hall_do_multi_ready();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// process button presses
|
||||
mht_check_buttons();
|
||||
|
||||
// draw the background, etc
|
||||
gr_reset_clip();
|
||||
GR_MAYBE_CLEAR_RES(Mht_bitmap);
|
||||
if(Mht_bitmap != -1){
|
||||
gr_set_bitmap(Mht_bitmap);
|
||||
gr_bitmap(0,0,GR_RESIZE_MENU);
|
||||
}
|
||||
Mht_window.draw();
|
||||
|
||||
// flip the buffer
|
||||
gr_flip();
|
||||
}
|
||||
|
||||
void mht_close()
|
||||
{
|
||||
// unload any bitmaps
|
||||
if(!bm_unload(Mht_bitmap)){
|
||||
nprintf(("General","WARNING : could not unload background bitmap %s\n", Mht_bitmap_fname[gr_screen.res]));
|
||||
}
|
||||
|
||||
// destroy the UI_WINDOW
|
||||
Mht_window.destroy();
|
||||
}
|
||||
|
||||
void mht_check_buttons()
|
||||
{
|
||||
int idx;
|
||||
for(idx=0; idx<MHT_NUM_BUTTONS; idx++){
|
||||
// we only really need to check for one button pressed at a time, so we can break after
|
||||
// finding one.
|
||||
if(Mht_buttons[gr_screen.res][idx].button.pressed()){
|
||||
mht_button_pressed(idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mht_button_pressed(int n)
|
||||
{
|
||||
switch(n){
|
||||
case MHT_READY_ROOM:
|
||||
if (Player->flags & PLAYER_FLAGS_IS_MULTI){
|
||||
main_hall_do_multi_ready();
|
||||
} else {
|
||||
gameseq_post_event(GS_EVENT_NEW_CAMPAIGN);
|
||||
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
}
|
||||
break;
|
||||
|
||||
case MHT_CAMPAIGN_ROOM:
|
||||
gameseq_post_event(GS_EVENT_CAMPAIGN_ROOM);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
|
||||
case MHT_OPTIONS:
|
||||
gameseq_post_event(GS_EVENT_OPTIONS_MENU);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
|
||||
case MHT_TECH_ROOM:
|
||||
gameseq_post_event( GS_EVENT_TECH_MENU );
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
|
||||
case MHT_BARRACKS:
|
||||
gameseq_post_event( GS_EVENT_BARRACKS_MENU );
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
|
||||
case MHT_EXIT:
|
||||
mht_exit_game();
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mht_exit_game()
|
||||
{
|
||||
// stop music first
|
||||
main_hall_stop_music(true);
|
||||
main_hall_stop_ambient();
|
||||
gameseq_post_event(GS_EVENT_QUIT_GAME);
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
*
|
||||
* All source code herein is the property of Volition, Inc. You may not sell
|
||||
* or otherwise commercially exploit the source or things you created based on the
|
||||
* source.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __TEMP_MAIN_HALL_MENU_HEADER_FILE
|
||||
#define __TEMP_MAIN_HALL_MENU_HEADER_FILE
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------
|
||||
// TEMP MAIN HALL DEFINES/VARS
|
||||
//
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------
|
||||
// TEMP MAIN HALL FUNCTIONS
|
||||
//
|
||||
|
||||
// initialize the temporary main hall
|
||||
void mht_init();
|
||||
|
||||
// do a frame for the main hall
|
||||
void mht_do();
|
||||
|
||||
// close the temporary main hall
|
||||
void mht_close();
|
||||
|
||||
#endif
|
||||
+138
-1
@@ -29,6 +29,8 @@
|
||||
#include "missionui/missionscreencommon.h"
|
||||
#include "nebula/neb.h"
|
||||
#include "network/multi.h"
|
||||
#include "options/OptionsManager.h"
|
||||
#include "options/Option.h"
|
||||
#include "osapi/osregistry.h"
|
||||
#include "pilotfile/pilotfile.h"
|
||||
#include "popup/popup.h"
|
||||
@@ -284,6 +286,17 @@ int Options_skills_text_coords[GR_NUM_RESOLUTIONS][4] = {
|
||||
}
|
||||
};
|
||||
|
||||
int Options_scp_string_coords[GR_NUM_RESOLUTIONS][2] = {
|
||||
{
|
||||
265, 18 // GR_640
|
||||
},
|
||||
{
|
||||
465, 25 // GR_1024
|
||||
}
|
||||
};
|
||||
|
||||
std::pair<SCP_string, int> Options_scp_string_text = {"Press F3 to access additional options", 1831};
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------
|
||||
// DETAIL LEVEL OPTIONS definitions BEGIN
|
||||
@@ -666,6 +679,11 @@ void options_cancel_exit()
|
||||
Detail = Detail_original;
|
||||
}
|
||||
|
||||
// We have to discard in game options here
|
||||
if (Using_in_game_options) {
|
||||
options::OptionsManager::instance()->discardChanges();
|
||||
}
|
||||
|
||||
gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
|
||||
}
|
||||
|
||||
@@ -690,6 +708,68 @@ void options_change_gamma(float delta)
|
||||
sprintf(tmp_gamma_string, NOX("%.2f"), gamma);
|
||||
|
||||
os_config_write_string( NULL, NOX("GammaD3D"), tmp_gamma_string );
|
||||
|
||||
if (Using_in_game_options) {
|
||||
const options::OptionBase* thisOpt = options::OptionsManager::instance()->getOptionByKey("Graphics.Gamma");
|
||||
if (thisOpt != nullptr) {
|
||||
auto val = thisOpt->getCurrentValueDescription();
|
||||
SCP_string newVal = std::to_string(gamma); // OptionsManager stores values as serialized strings
|
||||
thisOpt->setValueDescription({val.display, newVal.c_str()});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void options_set_ingame_binary_option(SCP_string key, bool value)
|
||||
{
|
||||
if (!Using_in_game_options) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options::OptionBase* thisOpt = options::OptionsManager::instance()->getOptionByKey(key);
|
||||
if (thisOpt != nullptr) {
|
||||
auto val = thisOpt->getCurrentValueDescription();
|
||||
SCP_string newVal = value ? "true" : "false"; // OptionsManager stores values as serialized strings
|
||||
thisOpt->setValueDescription({val.display, newVal.c_str()});
|
||||
}
|
||||
}
|
||||
|
||||
void options_set_ingame_multi_option(SCP_string key, int value)
|
||||
{
|
||||
if (!Using_in_game_options) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options::OptionBase* thisOpt = options::OptionsManager::instance()->getOptionByKey(key);
|
||||
if (thisOpt != nullptr) {
|
||||
auto values = thisOpt->getValidValues();
|
||||
thisOpt->setValueDescription(values[value]);
|
||||
}
|
||||
}
|
||||
|
||||
void options_set_ingame_range_option(SCP_string key, int value)
|
||||
{
|
||||
if (!Using_in_game_options) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options::OptionBase* thisOpt = options::OptionsManager::instance()->getOptionByKey(key);
|
||||
if (thisOpt != nullptr) {
|
||||
SCP_string newVal = std::to_string(value); // OptionsManager stores values as serialized strings
|
||||
thisOpt->setValueDescription({newVal.c_str(), newVal.c_str()});
|
||||
}
|
||||
}
|
||||
|
||||
void options_set_ingame_range_option(SCP_string key, float value)
|
||||
{
|
||||
if (!Using_in_game_options) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options::OptionBase* thisOpt = options::OptionsManager::instance()->getOptionByKey(key);
|
||||
if (thisOpt != nullptr) {
|
||||
SCP_string newVal = std::to_string(value); // OptionsManager stores values as serialized strings
|
||||
thisOpt->setValueDescription({newVal.c_str(), newVal.c_str()});
|
||||
}
|
||||
}
|
||||
|
||||
void options_button_pressed(int n)
|
||||
@@ -740,6 +820,7 @@ void options_button_pressed(int n)
|
||||
|
||||
// BEGIN - detail level tab buttons
|
||||
|
||||
// Target View Rendering is currently not handled by in-game options, assumes "On"
|
||||
case HUD_TARGETVIEW_RENDER_ON:
|
||||
Detail.targetview_model = 1;
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
@@ -750,6 +831,7 @@ void options_button_pressed(int n)
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
|
||||
// Planets is currently not handled by in-game options, assumes "On"
|
||||
case PLANETS_ON:
|
||||
Detail.planets_suns = 1;
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
@@ -760,6 +842,7 @@ void options_button_pressed(int n)
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
|
||||
// Weapon extras is currently not handled by in-game options, assumes "On"
|
||||
case WEAPON_EXTRAS_ON:
|
||||
Detail.weapon_extras = 1;
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
@@ -798,29 +881,35 @@ void options_button_pressed(int n)
|
||||
|
||||
case GAMMA_DOWN:
|
||||
options_change_gamma(-0.05f);
|
||||
// Gamma in-game change is handled in the above method
|
||||
break;
|
||||
|
||||
case GAMMA_UP:
|
||||
options_change_gamma(0.05f);
|
||||
// Gamma in-game change is handled in the above method
|
||||
break;
|
||||
|
||||
case BRIEF_VOICE_ON:
|
||||
Briefing_voice_enabled = true;
|
||||
options_set_ingame_binary_option("Audio.BriefingVoice", true);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
|
||||
case BRIEF_VOICE_OFF:
|
||||
Briefing_voice_enabled = false;
|
||||
options_set_ingame_binary_option("Audio.BriefingVoice", false);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
|
||||
case MOUSE_ON:
|
||||
Use_mouse_to_fly = 1;
|
||||
options_set_ingame_binary_option("Input.UseMouse", true);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
|
||||
case MOUSE_OFF:
|
||||
Use_mouse_to_fly = 0;
|
||||
options_set_ingame_binary_option("Input.UseMouse", false);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
}
|
||||
@@ -832,6 +921,7 @@ void options_sliders_update()
|
||||
if (Options_sliders[gr_screen.res][OPT_SOUND_VOLUME_SLIDER].slider.pos != Sound_volume_int) {
|
||||
Sound_volume_int = Options_sliders[gr_screen.res][OPT_SOUND_VOLUME_SLIDER].slider.pos;
|
||||
snd_set_effects_volume((float) (Sound_volume_int) / 9.0f);
|
||||
options_set_ingame_range_option("Audio.Effects", Master_sound_volume); // Volume options save the global float, not the range slider position
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
}
|
||||
|
||||
@@ -839,7 +929,7 @@ void options_sliders_update()
|
||||
if (Options_sliders[gr_screen.res][OPT_MUSIC_VOLUME_SLIDER].slider.pos != Music_volume_int) {
|
||||
Music_volume_int = Options_sliders[gr_screen.res][OPT_MUSIC_VOLUME_SLIDER].slider.pos;
|
||||
event_music_set_volume((float) (Music_volume_int) / 9.0f);
|
||||
|
||||
options_set_ingame_range_option("Audio.Music", Master_event_music_volume); // Volume options save the global float, not the range slider position
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
}
|
||||
|
||||
@@ -847,30 +937,48 @@ void options_sliders_update()
|
||||
if (Options_sliders[gr_screen.res][OPT_VOICE_VOLUME_SLIDER].slider.pos != Voice_volume_int) {
|
||||
Voice_volume_int = Options_sliders[gr_screen.res][OPT_VOICE_VOLUME_SLIDER].slider.pos;
|
||||
snd_set_voice_volume((float) (Voice_volume_int) / 9.0f);
|
||||
options_set_ingame_range_option("Audio.Voice", Master_voice_volume); // Volume options save the global float, not the range slider position
|
||||
options_play_voice_clip();
|
||||
}
|
||||
|
||||
if (Mouse_sensitivity != Options_sliders[gr_screen.res][OPT_MOUSE_SENS_SLIDER].slider.pos) {
|
||||
Mouse_sensitivity = Options_sliders[gr_screen.res][OPT_MOUSE_SENS_SLIDER].slider.pos;
|
||||
options_set_ingame_range_option("Input.MouseSensitivity", Mouse_sensitivity);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
}
|
||||
|
||||
if (Joy_sensitivity != Options_sliders[gr_screen.res][OPT_JOY_SENS_SLIDER].slider.pos) {
|
||||
Joy_sensitivity = Options_sliders[gr_screen.res][OPT_JOY_SENS_SLIDER].slider.pos;
|
||||
options_set_ingame_range_option("Input.JoystickSensitivity", Joy_sensitivity);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
}
|
||||
|
||||
if (Joy_dead_zone_size != Options_sliders[gr_screen.res][OPT_JOY_DEADZONE_SLIDER].slider.pos * 5) {
|
||||
Joy_dead_zone_size = Options_sliders[gr_screen.res][OPT_JOY_DEADZONE_SLIDER].slider.pos * 5;
|
||||
options_set_ingame_range_option("Input.JoystickDeadZone", Joy_dead_zone_size);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
}
|
||||
|
||||
if (Game_skill_level != Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.pos) {
|
||||
Game_skill_level = Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.pos;
|
||||
options_set_ingame_range_option("Game.SkillLevel", Game_skill_level);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
}
|
||||
}
|
||||
|
||||
void options_detail_sliders_in_game_update()
|
||||
{
|
||||
// Save in-game options settings
|
||||
options_set_ingame_multi_option("Graphics.Detail", Detail.detail_distance);
|
||||
options_set_ingame_multi_option("Graphics.NebulaDetail", Detail.nebula_detail);
|
||||
options_set_ingame_multi_option("Graphics.Texture", Detail.hardware_textures);
|
||||
options_set_ingame_multi_option("Graphics.Particles", Detail.num_particles);
|
||||
options_set_ingame_multi_option("Graphics.SmallDebris", Detail.num_small_debris);
|
||||
options_set_ingame_multi_option("Graphics.ShieldEffects", Detail.shield_effects);
|
||||
options_set_ingame_multi_option("Graphics.Stars", Detail.num_stars);
|
||||
options_set_ingame_multi_option("Graphics.Lighting", Detail.lighting);
|
||||
}
|
||||
|
||||
void options_accept()
|
||||
{
|
||||
// apply the selected multiplayer options
|
||||
@@ -883,6 +991,15 @@ void options_accept()
|
||||
}
|
||||
}
|
||||
|
||||
// We have to save in game options here
|
||||
if (Using_in_game_options) {
|
||||
// detail sliders are updated every frame but it's silly to run OptionsManager every frame, too
|
||||
// so just set them on Accept and then persist.
|
||||
options_detail_sliders_in_game_update();
|
||||
|
||||
options::OptionsManager::instance()->persistChanges();
|
||||
}
|
||||
|
||||
// If music is zero volume, disable
|
||||
if ( Master_event_music_volume <= 0.0f ) {
|
||||
// event_music_disable();
|
||||
@@ -1178,6 +1295,17 @@ void options_menu_do_frame(float /*frametime*/)
|
||||
|
||||
case KEY_ENTER:
|
||||
break;
|
||||
|
||||
case KEY_F3: // SCP ingame options
|
||||
if (Using_in_game_options) {
|
||||
// Going into F3 Options needs to either discard or save the changes made here.
|
||||
// There's an argument to be made for both but I feel like saving is the better choice - Mjn
|
||||
options::OptionsManager::instance()->persistChanges();
|
||||
|
||||
gamesnd_play_iface(InterfaceSounds::IFACE_MOUSE_CLICK);
|
||||
gameseq_post_event(GS_EVENT_INGAME_OPTIONS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
for (i=0; i<NUM_BUTTONS; i++) {
|
||||
@@ -1275,6 +1403,15 @@ void options_menu_do_frame(float /*frametime*/)
|
||||
if(Tab == MULTIPLAYER_TAB){
|
||||
options_multi_vox_process_waveform();
|
||||
}
|
||||
|
||||
// maybe blit the SCP Options string
|
||||
if (Using_in_game_options) {
|
||||
gr_set_color_fast(&Color_bright_blue);
|
||||
gr_string(Options_scp_string_coords[gr_screen.res][OPTIONS_X_COORD],
|
||||
Options_scp_string_coords[gr_screen.res][OPTIONS_Y_COORD],
|
||||
XSTR(Options_scp_string_text.first.c_str(), Options_scp_string_text.second),
|
||||
GR_RESIZE_MENU);
|
||||
}
|
||||
|
||||
gr_flip();
|
||||
}
|
||||
|
||||
@@ -39,6 +39,9 @@ void options_menu_init();
|
||||
void options_menu_close();
|
||||
void options_menu_do_frame(float frametime);
|
||||
|
||||
// For optionsmenumulti.cpp
|
||||
void options_set_ingame_binary_option(SCP_string key, bool value);
|
||||
|
||||
// kill the options menu
|
||||
void options_cancel_exit();
|
||||
|
||||
|
||||
@@ -1005,8 +1005,10 @@ void options_multi_protocol_button_pressed(int n)
|
||||
|
||||
if(!Om_local_broadcast){
|
||||
Om_local_broadcast = 1;
|
||||
options_set_ingame_binary_option("Multi.LocalBroadcast", true);
|
||||
} else {
|
||||
Om_local_broadcast = 0;
|
||||
options_set_ingame_binary_option("Multi.LocalBroadcast", false);
|
||||
}
|
||||
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
@@ -1048,10 +1050,12 @@ void options_multi_protocol_button_pressed(int n)
|
||||
Om_tracker_login.enable();
|
||||
Om_tracker_passwd.enable();
|
||||
Om_tracker_squad_name.enable();
|
||||
options_set_ingame_binary_option("Multi.TogglePXO", true);
|
||||
} else {
|
||||
Om_tracker_login.disable();
|
||||
Om_tracker_passwd.disable();
|
||||
Om_tracker_squad_name.disable();
|
||||
options_set_ingame_binary_option("Multi.TogglePXO", false);
|
||||
}
|
||||
|
||||
// play a sound
|
||||
@@ -1539,6 +1543,7 @@ void options_multi_gen_button_pressed(int n)
|
||||
if(!Om_gen_xfer_multidata){
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
Om_gen_xfer_multidata = 1;
|
||||
options_set_ingame_binary_option("Multi.TransferMissions", true);
|
||||
} else {
|
||||
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
||||
}
|
||||
@@ -1549,6 +1554,7 @@ void options_multi_gen_button_pressed(int n)
|
||||
if(Om_gen_xfer_multidata){
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
Om_gen_xfer_multidata = 0;
|
||||
options_set_ingame_binary_option("Multi.TransferMissions", false);
|
||||
} else {
|
||||
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
||||
}
|
||||
@@ -1559,6 +1565,7 @@ void options_multi_gen_button_pressed(int n)
|
||||
if(!Om_gen_flush_cache){
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
Om_gen_flush_cache = 1;
|
||||
options_set_ingame_binary_option("Multi.FlushCache", true);
|
||||
} else {
|
||||
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
||||
}
|
||||
@@ -1569,6 +1576,7 @@ void options_multi_gen_button_pressed(int n)
|
||||
if(Om_gen_flush_cache){
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
Om_gen_flush_cache = 0;
|
||||
options_set_ingame_binary_option("Multi.FlushCache", false);
|
||||
} else {
|
||||
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
||||
}
|
||||
|
||||
@@ -917,7 +917,11 @@ int sim_room_button_pressed(int n)
|
||||
|
||||
case CAMPAIGN_TAB:
|
||||
if ( !strlen(Campaign.filename) ) {
|
||||
popup( PF_USE_AFFIRMATIVE_ICON | PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "The currently active campaign cannot be found, unable to switch to campaign mode!", 1612));
|
||||
if (Campaign_load_failure == CAMPAIGN_ERROR_MISSING) {
|
||||
popup(PF_USE_AFFIRMATIVE_ICON | PF_NO_NETWORKING, 1, POPUP_OK, XSTR("The currently active campaign cannot be found. Unable to switch to campaign mode.", 1612));
|
||||
} else {
|
||||
popup(PF_USE_AFFIRMATIVE_ICON | PF_NO_NETWORKING, 1, POPUP_OK, XSTR("The currently active campaign cannot be loaded. Unable to switch to campaign mode.", 1816));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1050,7 +1054,9 @@ void sim_room_init()
|
||||
Campaign.filename[0] = 0;
|
||||
Campaign.num_missions = 0;
|
||||
|
||||
mission_campaign_load_failure_popup();
|
||||
// don't display the popup in the sim room - first because there is already logic to prevent listing campaign missions,
|
||||
// second because there's not much the player can do about it in the sim room, and third because displaying the popup
|
||||
// clears the error code
|
||||
}
|
||||
|
||||
Num_campaign_missions = 0;
|
||||
|
||||
@@ -335,7 +335,7 @@ void techroom_select_new_entry()
|
||||
if (Techroom_model_instance >= 0) {
|
||||
model_delete_instance(Techroom_model_instance);
|
||||
}
|
||||
Techroom_model_instance = model_create_instance(-1, Techroom_modelnum);
|
||||
Techroom_model_instance = model_create_instance(model_objnum_special::OBJNUM_NONE, Techroom_modelnum);
|
||||
|
||||
model_set_up_techroom_instance(sip, Techroom_model_instance);
|
||||
|
||||
@@ -396,7 +396,7 @@ void techroom_select_new_entry()
|
||||
if (Techroom_model_instance >= 0) {
|
||||
model_delete_instance(Techroom_model_instance);
|
||||
}
|
||||
Techroom_model_instance = model_create_instance(-1, Techroom_modelnum);
|
||||
Techroom_model_instance = model_create_instance(model_objnum_special::OBJNUM_NONE, Techroom_modelnum);
|
||||
|
||||
// If this ends up being needed for weapon models, a weapon version
|
||||
// of this method will need to be created. Should only be necessary
|
||||
|
||||
@@ -130,11 +130,12 @@ bool Briefing_voice_enabled = true; // flag which turn on/off voice playback of
|
||||
static auto BriefingVoiceOption __UNUSED = options::OptionBuilder<bool>("Audio.BriefingVoice",
|
||||
std::pair<const char*, int>{"Briefing voice", 1368},
|
||||
std::pair<const char*, int>{"Enable or disable voice playback in the briefing", 1716})
|
||||
.category("Audio")
|
||||
.category(std::make_pair("Audio", 1826))
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(true)
|
||||
.bind_to(&Briefing_voice_enabled)
|
||||
.importance(4)
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
@@ -60,7 +60,7 @@ char *Campaign_names[MAX_CAMPAIGNS] = { NULL };
|
||||
char *Campaign_file_names[MAX_CAMPAIGNS] = { NULL };
|
||||
char *Campaign_descs[MAX_CAMPAIGNS] = { NULL };
|
||||
int Num_campaigns;
|
||||
int Campaign_file_missing;
|
||||
bool Campaign_file_missing = false;
|
||||
int Campaign_load_failure = 0;
|
||||
int Campaign_names_inited = 0;
|
||||
SCP_vector<SCP_string> Ignored_campaigns;
|
||||
@@ -428,7 +428,7 @@ int mission_campaign_load(const char* filename, const char* full_path, player* p
|
||||
char name[NAME_LENGTH], type[NAME_LENGTH], temp[NAME_LENGTH];
|
||||
|
||||
if (campaign_is_ignored(filename)) {
|
||||
Campaign_file_missing = 1;
|
||||
Campaign_file_missing = true;
|
||||
Campaign_load_failure = CAMPAIGN_ERROR_IGNORED;
|
||||
return CAMPAIGN_ERROR_IGNORED;
|
||||
}
|
||||
@@ -634,19 +634,25 @@ int mission_campaign_load(const char* filename, const char* full_path, player* p
|
||||
if ((Game_mode & GM_MULTIPLAYER) && Campaign.num_missions > UINT8_MAX)
|
||||
throw parse::ParseException("Number of campaign missions is too high and breaks multi!");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
catch (const parse::FileOpenException& foe)
|
||||
{
|
||||
mprintf(("Error parsing '%s'\r\nError message = %s.\r\n", filename, e.what()));
|
||||
mprintf(("Error opening '%s'\r\nError message = %s.\r\n", filename, foe.what()));
|
||||
|
||||
Campaign.filename[0] = 0;
|
||||
Campaign.num_missions = 0;
|
||||
|
||||
if (!Fred_running && !(Game_mode & GM_MULTIPLAYER)) {
|
||||
Campaign_file_missing = 1;
|
||||
Campaign_load_failure = CAMPAIGN_ERROR_MISSING;
|
||||
return CAMPAIGN_ERROR_MISSING;
|
||||
}
|
||||
Campaign_file_missing = true;
|
||||
Campaign_load_failure = CAMPAIGN_ERROR_MISSING;
|
||||
return CAMPAIGN_ERROR_MISSING;
|
||||
}
|
||||
catch (const parse::ParseException& pe)
|
||||
{
|
||||
mprintf(("Error parsing '%s'\r\nError message = %s.\r\n", filename, pe.what()));
|
||||
|
||||
Campaign.filename[0] = 0;
|
||||
Campaign.num_missions = 0;
|
||||
|
||||
Campaign_file_missing = true;
|
||||
Campaign_load_failure = CAMPAIGN_ERROR_CORRUPT;
|
||||
return CAMPAIGN_ERROR_CORRUPT;
|
||||
}
|
||||
@@ -681,7 +687,7 @@ int mission_campaign_load(const char* filename, const char* full_path, player* p
|
||||
}
|
||||
|
||||
// all is good here, move along
|
||||
Campaign_file_missing = 0;
|
||||
Campaign_file_missing = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -721,7 +727,7 @@ void mission_campaign_init()
|
||||
{
|
||||
mission_campaign_clear();
|
||||
|
||||
Campaign_file_missing = 0;
|
||||
Campaign_file_missing = false;
|
||||
|
||||
player_loadout_init();
|
||||
}
|
||||
@@ -1539,26 +1545,31 @@ bool campaign_is_ignored(const char *filename)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool campaign_reportable_error(int val)
|
||||
{
|
||||
return val != 0 && val != CAMPAIGN_ERROR_MISSING && val != CAMPAIGN_ERROR_IGNORED;
|
||||
}
|
||||
|
||||
// returns 0: loaded, !0: error
|
||||
int mission_load_up_campaign( player *pl )
|
||||
int mission_load_up_campaign(bool fall_back_from_current)
|
||||
{
|
||||
int rc = -1, idx;
|
||||
|
||||
if ( pl == NULL )
|
||||
pl = Player;
|
||||
auto pl = Player;
|
||||
|
||||
// find best campaign to use:
|
||||
// 1) last used
|
||||
// 2) builtin
|
||||
// 3) anything else
|
||||
// Note that in each step we only fall back when the error is benign, e.g. ignored or missing;
|
||||
// if there's some other real error with the campaign file, we report it.
|
||||
// Also note that if we *have* a current campaign, we shouldn't fall back *at all*, lest we repeatedly
|
||||
// reset what the current campaign is, *unless* we are starting a brand new session or loading a new pilot.
|
||||
|
||||
// last used...
|
||||
if ( strlen(pl->current_campaign) ) {
|
||||
if (!campaign_is_ignored(pl->current_campaign)) {
|
||||
return mission_campaign_load(pl->current_campaign, nullptr, pl);
|
||||
}
|
||||
else {
|
||||
Campaign_file_missing = 1;
|
||||
rc = mission_campaign_load(pl->current_campaign, nullptr, pl);
|
||||
if (rc == 0 || !fall_back_from_current || campaign_reportable_error(rc)) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1566,7 +1577,7 @@ int mission_load_up_campaign( player *pl )
|
||||
rc = mission_campaign_load(Default_campaign_file_name, nullptr, pl);
|
||||
|
||||
// everything else...
|
||||
if (rc < 0) {
|
||||
if (rc < 0 && !campaign_reportable_error(rc)) {
|
||||
// no descriptions, no sorting
|
||||
mission_campaign_build_list(false, false);
|
||||
|
||||
|
||||
Loaded 100 of 345 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user