Compare commits

...
Author SHA1 Message Date
SirKnightly f25d95041d Automated build commit 2021-01-27 17:07:03 +00:00
m!m 60047116fd Merge pull request #3160 from asarium/ci/disableQt
Disable Qt projects since downloads are broken
2021-01-22 16:54:54 +01:00
asarium 4aa33c7b3e Disable Qt projects since downloads are broken 2021-01-22 16:26:44 +01:00
m!m 373dbeb63f Merge pull request #3159 from Baezon/previous-bank-fix
Fix a bug with previous_bank and ship class swapping
2021-01-21 22:06:30 +01:00
m!m 361cc76c30 Merge pull request #3154 from Goober5000/redo_3149
fix a rare crash in the tech room
2021-01-21 21:47:53 +01:00
Baezon 3f27183d6d also reset previous bank 2021-01-21 01:04:13 -05:00
Goober5000 3d976f53b4 fix a rare crash in the tech room
The tech room loop checked that all the lines could fit in the available screen real estate, but it didn't check to see that the number of lines was less than the array capacity.  Normally this never happened, but certain mods which use smaller fonts will overflow the limit.  This adds a proper bounds check and also increases the bounds so that more of the smaller lines can be used.
2021-01-17 11:21:41 -05:00
m!m e5af389803 Merge pull request #3150 from scp-fs2open/revert-3149-fix_techroom_crash
Revert "fix a rare crash in the tech room"
2021-01-17 17:14:30 +01:00
m!m ba0f2e7f83 Revert "fix a rare crash in the tech room" 2021-01-17 11:55:59 +01:00
Goober5000 f0987a4ad1 Merge pull request #3149 from Goober5000/fix_techroom_crash
fix a rare crash in the tech room
2021-01-17 02:15:55 -05:00
Goober5000 61dd4356f0 fix a rare crash in the tech room
The tech room loop checked that all the lines could fit in the available screen real estate, but it didn't check to see that the number of lines was less than the array capacity.  Normally this never happened, but certain mods which use smaller fonts will overflow the limit.  This adds a proper bounds check and also increases the bounds so that more of the smaller lines can be used.
2021-01-17 01:21:52 -05:00
JohnAFernandez 679f7f20d7 Switch the correct ammo variable.
The previous pr was supposed to fix what ammo capacity the ship was reloaded to, but instead it was changing how much ammo was in the magazine.
2021-01-14 09:23:52 -05:00
Fabian Woltermann a939a73c14 Merge pull request #3139 from z64555/hud_config
More safety checks for the HUD_config struct
2021-01-13 22:20:43 +01:00
Goober5000 3f5ad1239d Merge pull request #3140 from Goober5000/techroom_update
make model_set_up_techroom_instance a bit more robust
2021-01-13 13:51:47 -05:00
z64555 4e715352c9 Increment int strikes per CSG warning, as done in PLR code
* Use ReleaseWarnring instead of Warning
* Use correct upper boundry check logic on HUD_config::mail_color
2021-01-13 12:48:24 -06:00
Goober5000 5f538fa514 make model_set_up_techroom_instance a bit more robust
Follow-up to #3137.  I missed two important details in the first implementation: the triggered animation needs to be an "initial position" type, and `model_update_instance` needs to be run on all subobjects, not just turrets.

This should really fix #3123.  I still can't see the destroyed collector, but the Rahu no longer flickers when it spins around.
2021-01-13 13:17:31 -05:00
Goober5000 506ba911d0 Merge pull request #3137 from Goober5000/tech_room_instance
properly use model instances for tech room and briefing popups
2021-01-13 11:03:25 -05:00
z64555 f44cfa06c8 Adds more safety checks for PLR and CSG reading for the HUD_config structure.
* Adds a #define for the HC_color array size
* Doxy's the HUD_config struct
2021-01-12 23:12:20 -06:00
Goober5000 eeb6f5b091 properly use model instances for tech room and briefing popups
These two situations mostly relied on the obsolete model code which didn't include model instances.  Data for submodel positions and for whether a submodel is blown off are now stored exclusively in model instances, not the model itself.

This fixes #3124.
2021-01-12 23:15:37 -05:00
Fabian Woltermann 18cb07dc72 Merge pull request #3134 from EatThePath/tube-light-attenuation-recalc
Properly recalculate tube light attenuation
2021-01-11 20:28:19 +01:00
JohnAFernandez 3a4df0d89a Send them to Github instead of Mantis 2021-01-11 14:06:03 -05:00
JohnAFernandez d33f9db1f0 Move Standalone Running statement to after the init of Debug Statements 2021-01-11 14:05:01 -05:00
JohnAFernandez 75b26ef94b Fix unfocused multi interpolation inaccuracies (#3129)
Remove One Source of Client and Server having Different Timing

Multiplayer *must not* have its time affected by being in the background, because their clocks will come out of sync and movement from an out of focus multiplayer instance will appear to move in slow motion.  This fixes the timing discrepancy by only doing os_sleep when unfocused when in single player.
2021-01-11 14:04:23 -05:00
JohnAFernandez 398f4d9053 Remove Unused ClientDamage Commandline Option (#3132)
This option was likely part of an attempt to fix multi that never went anywhere. We now have rollback, which is on by default.
2021-01-11 14:02:52 -05:00
David Gibson 069947e397 Added a recalculation of tube light attenuation in fragment shader after proper distance is determined. fixes slash beam and penetration lighting issues 2021-01-11 11:55:45 -06:00
Fabian Woltermann 580d67eca7 Merge pull request #3133 from Baezon/slow-weapon-collide-fix
Fix collision culling for slow/accelerating weapons
2021-01-11 09:15:53 +01:00
Baezon 4bf93e08df fix collision culling for slow weapons 2021-01-11 00:45:42 -05:00
Fabian Woltermann 6c475130d1 Merge pull request #3126 from The-E/fix/ambient_light_in_lab
When setting the ambient factor in the lab, recalculate ambient lighting
2021-01-10 20:11:13 +01:00
Fabian Woltermann 6f0dec4169 When setting the ambient factor in the lab, recalculate ambient lighting 2021-01-10 19:44:24 +01:00
Goober5000 3b99402a0a Merge pull request #3121 from Goober5000/background_warning
make FRED validate all backgrounds, not just the active one
2021-01-10 09:21:45 -05:00
Fabian Woltermann 6c6ade116f Merge pull request #3120 from Goober5000/fix_3101
fix 3101
2021-01-10 12:43:47 +01:00
Fabian Woltermann 4f6c834587 Merge pull request #3122 from Baezon/glowpoint-timing-fix
Fix a bug with glowpoint timing
2021-01-10 12:42:42 +01:00
Baezon c486843e5f fix a bug with glowpoint timing 2021-01-10 03:11:25 -05:00
Goober5000 ec93ac4c0e fix 3101
Always update the ship class and loadout information in a ship's parse object, even if it is present at mission start.
2021-01-10 01:53:14 -05:00
Goober5000 2307d05086 make FRED validate all backgrounds, not just the active one
The background validation checks are somewhat convoluted, and misleading with multiple backgrounds, so this PR disables the standard main-background check if FRED is running.  It then adds a new FRED-specific background check that covers all backgrounds.

Additionally, this PR fixes a bug in an error message in `stars_get_first_valid_background`.

Fixes #3116.
2021-01-10 01:48:43 -05:00
Goober5000 d3d48ee6fa Merge pull request #3093 from Baezon/script-target-bracket-fix
Fix a crash with scripted targeting brackets
2021-01-08 18:13:44 -05:00
Baezon ac7bdbf269 fix bug in scripted targeting brackets 2021-01-08 17:30:28 -05:00
Goober5000 ddf00588d6 Merge pull request #3076 from Goober5000/hash_stuff
preprocess alt names before mission start
2021-01-08 16:03:10 -05:00
m!m 85a2a8f11e Merge pull request #3092 from Goober5000/strtof_patch
interim patch for get_user_vec3d_value
2021-01-08 10:47:42 +01:00
Goober5000 e76fdea8b9 interim patch for get_user_vec3d_value
As described in #3079, the old parsing of fvec and uvec used strtod and some POFs rely on this format.  This is a quickfix that uses the new parsing method for only `get_user_vec3d_value`.
2021-01-07 18:08:27 -05:00
Goober5000 726ce953c7 Merge pull request #3089 from Goober5000/fix_submodel_debris
de-parent live debris
2021-01-07 15:24:49 -05:00
JohnAFernandez a545a4ec27 Merge pull request #3087 from Baezon/lock-restriction-safety
Safety for lock restriction handling
2021-01-07 15:01:31 -05:00
Fabian Woltermann fc0662a9c4 Merge pull request #3080 from JohnAFernandez/Vectorize-Tech-Lists
Vectorize tech lists
2021-01-07 15:16:09 +01:00
JohnAFernandez e5685ded86 Keep the lists from being cleared early by removing unneeded the loops. 2021-01-07 00:33:21 -05:00
JohnAFernandez 226cbf1204 The true fix, check the correct value 2021-01-07 00:32:52 -05:00
Goober5000 043466309a de-parent live debris
It appears that live debris is not supposed to have a parent submodel; see the retail NTF Boadicea.  This removes the parent from any live debris that might have it.

This should fix #3078.
2021-01-07 00:02:49 -05:00
Baezon 766624600d update name 2021-01-06 18:04:59 -05:00
Baezon dab9a41f45 remove redundant check 2021-01-06 17:45:32 -05:00
m!m 51d8ab13d8 Merge pull request #3088 from EatThePath/fix-empty-secondaries-locking
off-by-one fix in early exit update_aspect_lock_information()
2021-01-06 23:25:53 +01:00
Baezon b93d30e12b unused variable 2021-01-06 14:46:44 -05:00
David Gibson 945db25578 corrected off-by-one issue in the early exit condition of update_aspect_lock_information() 2021-01-06 13:46:05 -06:00
Baezon 67de007ecb lock restrictions safety 2021-01-06 14:28:27 -05:00
JohnAFernandez e9a9b3b978 Merge pull request #3085 from Baezon/docking-collision-bugfix
Safety for check_for_docking_collision
2021-01-06 14:03:00 -05:00
Baezon e10522a2c7 safety for check_for_docking_collision 2021-01-06 13:18:27 -05:00
JohnAFernandez 9f33b432fc Simply this check 2021-01-05 00:07:07 -05:00
JohnAFernandez 7a0578a797 Ok CI, I'll use nullptr 2021-01-04 22:14:36 -05:00
JohnAFernandez b81825326c Signed Vs Unsigned
AKA C'Mon CI!
2021-01-03 21:54:31 -05:00
JohnAFernandez b8c2c975c0 Change to a pointer
So that we can release bitmaps and animations properly.
2021-01-03 21:36:50 -05:00
JohnAFernandez dc0272e664 Fixes Part 1 2021-01-03 20:56:30 -05:00
JohnAFernandez 3e329d64dd Check the correct value in the animation code 2021-01-03 15:15:51 -05:00
JohnAFernandez 882ac2b1a1 Possibly Fix Memory Corruption Issue
Remove Unused Var
2021-01-03 15:14:11 -05:00
Goober5000 b3153df6be preprocess alt names before mission start
For compatibility purposes some mods want alt names to truncate at the hash symbol. But we can't actually do that at mission load,
since we have to save them again in FRED. So this commit processes the names just before the mission starts.

To further complicate things, some mods actually want the hash to be displayed. So this commit introduces the double-hash as an escape sequence for a single hash.
2021-01-02 14:31:59 -05:00
39 changed files with 626 additions and 518 deletions

No files matched your search

+37 -37
View File
@@ -17,18 +17,18 @@ jobs:
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/linux_build:sha-a8ca321
steps:
- name: Cache Qt
id: cache-qt-lin
uses: actions/cache@v1
with:
path: ${{ github.workspace }}/../Qt
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
- name: Install Qt
uses: jurplel/install-qt-action@v2
with:
version: ${{ env.QT_VERSION }}
dir: ${{ github.workspace }}/..
cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
# - name: Cache Qt
# id: cache-qt-lin
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt
# uses: jurplel/install-qt-action@v2
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
- uses: actions/checkout@v1
name: Checkout
@@ -107,30 +107,30 @@ jobs:
name: Checkout
with:
submodules: true
- name: Cache Qt
id: cache-qt-win
uses: actions/cache@v1
with:
path: ${{ github.workspace }}/../Qt
key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
- name: Install Qt (32 bit)
uses: jurplel/install-qt-action@v2
if: ${{ matrix.arch == 'Win32' }}
with:
version: ${{ env.QT_VERSION }}
dir: ${{ github.workspace }}/..
arch: win32_msvc2017
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
aqtversion: ==0.8
- name: Install Qt (64 bit)
uses: jurplel/install-qt-action@v2
if: ${{ matrix.arch == 'x64' }}
with:
version: ${{ env.QT_VERSION }}
dir: ${{ github.workspace }}/..
arch: win64_msvc2017_64
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
aqtversion: ==0.8
# - name: Cache Qt
# id: cache-qt-win
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt (32 bit)
# uses: jurplel/install-qt-action@v2
# if: ${{ matrix.arch == 'Win32' }}
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# arch: win32_msvc2017
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
# aqtversion: ==0.8
# - name: Install Qt (64 bit)
# uses: jurplel/install-qt-action@v2
# if: ${{ matrix.arch == 'x64' }}
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# arch: win64_msvc2017_64
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
# aqtversion: ==0.8
- name: Configure CMake
env:
@@ -144,7 +144,7 @@ jobs:
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
-DFSO_BUILD_QTFRED=ON -DFSO_BUILD_TESTS=ON \
-DFSO_BUILD_QTFRED=OFF -DFSO_BUILD_TESTS=ON \
-DFSO_INSTALL_DEBUG_FILES="ON" -A "$ARCHITECTURE" \
-G "Visual Studio 16 2019" -T "v142" ..
- name: Compile
+37 -37
View File
@@ -41,18 +41,18 @@ jobs:
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/linux_build:sha-a8ca321
steps:
- name: Cache Qt
id: cache-qt-lin
uses: actions/cache@v1
with:
path: ${{ github.workspace }}/../Qt
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
- name: Install Qt
uses: jurplel/install-qt-action@v2
with:
version: ${{ env.QT_VERSION }}
dir: ${{ github.workspace }}/..
cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
# - name: Cache Qt
# id: cache-qt-lin
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt
# uses: jurplel/install-qt-action@v2
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
- uses: actions/checkout@v1
name: Checkout
@@ -142,30 +142,30 @@ jobs:
name: Checkout
with:
submodules: true
- name: Cache Qt
id: cache-qt-win
uses: actions/cache@v1
with:
path: ${{ github.workspace }}/../Qt
key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
- name: Install Qt (32 bit)
uses: jurplel/install-qt-action@v2
if: ${{ matrix.arch == 'Win32' }}
with:
version: ${{ env.QT_VERSION }}
dir: ${{ github.workspace }}/..
arch: win32_msvc2017
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
aqtversion: ==0.8
- name: Install Qt (64 bit)
uses: jurplel/install-qt-action@v2
if: ${{ matrix.arch == 'x64' }}
with:
version: ${{ env.QT_VERSION }}
dir: ${{ github.workspace }}/..
arch: win64_msvc2017_64
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
aqtversion: ==0.8
# - name: Cache Qt
# id: cache-qt-win
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt (32 bit)
# uses: jurplel/install-qt-action@v2
# if: ${{ matrix.arch == 'Win32' }}
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# arch: win32_msvc2017
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
# aqtversion: ==0.8
# - name: Install Qt (64 bit)
# uses: jurplel/install-qt-action@v2
# if: ${{ matrix.arch == 'x64' }}
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# arch: win64_msvc2017_64
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
# aqtversion: ==0.8
- name: Configure CMake
env:
@@ -179,7 +179,7 @@ jobs:
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
-DFSO_BUILD_QTFRED=ON -DFSO_BUILD_TESTS=ON \
-DFSO_BUILD_QTFRED=OFF -DFSO_BUILD_TESTS=ON \
-DFSO_INSTALL_DEBUG_FILES="ON" -A "$ARCHITECTURE" \
-G "Visual Studio 16 2019" -T "v142" ..
- name: Compile
+38 -38
View File
@@ -24,19 +24,19 @@ jobs:
runs-on: ubuntu-latest
container: ghcr.io/scp-fs2open/linux_build:sha-e977d36
steps:
- name: Cache Qt
id: cache-qt-lin
uses: actions/cache@v1
with:
path: ${{ github.workspace }}/../Qt
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
- name: Install Qt
uses: jurplel/install-qt-action@v2
with:
version: ${{ env.QT_VERSION }}
dir: ${{ github.workspace }}/..
cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
setup-python: 'false'
# - name: Cache Qt
# id: cache-qt-lin
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt
# uses: jurplel/install-qt-action@v2
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
# setup-python: 'false'
- uses: actions/checkout@v1
name: Checkout
@@ -83,30 +83,30 @@ jobs:
name: Checkout
with:
submodules: true
- name: Cache Qt
id: cache-qt-win
uses: actions/cache@v1
with:
path: ${{ github.workspace }}/../Qt
key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
- name: Install Qt (32 bit)
uses: jurplel/install-qt-action@v2
if: ${{ matrix.compiler == 'MSVC' && matrix.arch == 'Win32' }}
with:
version: ${{ env.QT_VERSION }}
dir: ${{ github.workspace }}/..
arch: win32_msvc2017
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
aqtversion: ==0.8
- name: Install Qt (64 bit)
uses: jurplel/install-qt-action@v2
if: ${{ matrix.compiler == 'MSVC' && matrix.arch == 'x64' }}
with:
version: ${{ env.QT_VERSION }}
dir: ${{ github.workspace }}/..
arch: win64_msvc2017_64
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
aqtversion: ==0.8
# - name: Cache Qt
# id: cache-qt-win
# uses: actions/cache@v1
# with:
# path: ${{ github.workspace }}/../Qt
# key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
# - name: Install Qt (32 bit)
# uses: jurplel/install-qt-action@v2
# if: ${{ matrix.compiler == 'MSVC' && matrix.arch == 'Win32' }}
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# arch: win32_msvc2017
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
# aqtversion: ==0.8
# - name: Install Qt (64 bit)
# uses: jurplel/install-qt-action@v2
# if: ${{ matrix.compiler == 'MSVC' && matrix.arch == 'x64' }}
# with:
# version: ${{ env.QT_VERSION }}
# dir: ${{ github.workspace }}/..
# arch: win64_msvc2017_64
# cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
# aqtversion: ==0.8
- name: Configure CMake
env:
@@ -124,7 +124,7 @@ jobs:
else
cmake -DFSO_USE_SPEECH="ON" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
-DMSVC_SIMD_INSTRUCTIONS=SSE2 -DFSO_BUILD_FRED2="ON" -G "Visual Studio 16 2019" \
-DFSO_BUILD_QTFRED=ON -T "v142" -A "$ARCHITECTURE" ..
-DFSO_BUILD_QTFRED=OFF -T "v142" -A "$ARCHITECTURE" ..
fi
- name: Compile
working-directory: ./build
+1 -1
View File
@@ -32,4 +32,4 @@ export LD_LIBRARY_PATH
cmake -G Ninja -DFSO_FATAL_WARNINGS=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON $CMAKE_OPTIONS \
-DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_BUILD_APPIMAGE=ON -DCMAKE_BUILD_TYPE=$CONFIGURATION \
-DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFSO_BUILD_QTFRED=ON ..
-DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFSO_BUILD_QTFRED=OFF ..
+2 -2
View File
@@ -7840,7 +7840,7 @@ void update_aspect_lock_information(ai_info *aip, vec3d *vec_to_enemy, float dis
object *aiobjp = &Objects[shipp->objnum];
// AL 3-7-98: This probably should never happen, but check to ensure that current_secondary_bank is valid
if ( (swp->current_secondary_bank < 0) || (swp->current_secondary_bank > swp->num_secondary_banks) ) {
if ( (swp->current_secondary_bank < 0) || (swp->current_secondary_bank >= swp->num_secondary_banks) ) {
return;
}
@@ -9065,7 +9065,7 @@ void ai_chase()
}
}
if (timestamp_elapsed(swp->next_secondary_fire_stamp[current_bank]) && weapon_can_lock_on_ship(swip, En_objp->instance)) {
if (timestamp_elapsed(swp->next_secondary_fire_stamp[current_bank]) && weapon_target_satisfies_lock_restrictions(swip, En_objp)) {
if (current_bank >= 0) {
float firing_range;
+1 -9
View File
@@ -274,7 +274,6 @@ cmdline_parm gameclosed_arg("-closed", NULL, AT_NONE); // Cmdline_closed_game
cmdline_parm gamerestricted_arg("-restricted", NULL, AT_NONE); // Cmdline_restricted_game
cmdline_parm port_arg("-port", "Multiplayer network port", AT_INT);
cmdline_parm multilog_arg("-multilog", NULL, AT_NONE); // Cmdline_multi_log
cmdline_parm client_dodamage("-clientdamage", NULL, AT_NONE); // Cmdline_client_dodamage
cmdline_parm pof_spew("-pofspew", NULL, AT_NONE); // Cmdline_spew_pof_info
cmdline_parm weapon_spew("-weaponspew", nullptr, AT_STRING); // Cmdline_spew_weapon_stats
cmdline_parm mouse_coords("-coords", NULL, AT_NONE); // Cmdline_mouse_coords
@@ -287,7 +286,6 @@ char *Cmdline_game_password = NULL;
char *Cmdline_rank_above = NULL;
char *Cmdline_rank_below = NULL;
int Cmdline_cd_check = 1;
int Cmdline_client_dodamage = 0;
int Cmdline_closed_game = 0;
int Cmdline_freespace_no_music = 0;
int Cmdline_freespace_no_sound = 0;
@@ -812,7 +810,7 @@ void os_validate_parms(int argc, char *argv[])
if (!stricmp(token, "-help") || !stricmp(token, "--help") || !stricmp(token, "-h") || !stricmp(token, "-?")) {
printf("FreeSpace 2 Open, version %s\n", FS_VERSION_FULL);
printf("Website: http://scp.indiegames.us\n");
printf("Mantis (bug reporting): http://scp.indiegames.us/mantis/\n\n");
printf("Github (bug reporting): https://github.com/scp-fs2open/fs2open.github.com/issues\n\n");
printf("Usage: fs2_open [options]\n");
// not the prettiest thing but the job gets done
@@ -1663,12 +1661,6 @@ bool SetCmdlineParams()
Cmdline_multi_log = 1;
}
// maybe use old-school client damage
if(client_dodamage.found()){
Cmdline_client_dodamage = 1;
}
// spew pof info
if(pof_spew.found()){
Cmdline_spew_pof_info = 1;
-1
View File
@@ -30,7 +30,6 @@ extern char *Cmdline_game_password;
extern char *Cmdline_rank_above;
extern char *Cmdline_rank_below;
extern int Cmdline_cd_check;
extern int Cmdline_client_dodamage;
extern int Cmdline_closed_game;
extern int Cmdline_freespace_no_music;
extern int Cmdline_freespace_no_sound;
@@ -74,6 +74,7 @@ void GetLightInfo(vec3 position, out vec3 lightDir, out float attenuation)
if(dist > lightRadius) {
discard;
}
attenuation = 1.0 - clamp(dist / lightRadius, 0.0, 1.0);
} else if (lightType == LT_CONE) {
float coneDot = dot(normalize(-lightDir), coneDir);
if(dualCone) {
+1 -1
View File
@@ -566,7 +566,7 @@ typedef struct hc_col {
ubyte r, g, b;
} hc_col;
hc_col HC_colors[3] =
hc_col HC_colors[HUD_COLOR_SIZE] =
{
{0, 255, 0}, // Green - get RGB from Adam so it matches palette?-??.pcx
{67, 123, 203}, // Blue - get RGB from Adam so it matches palette?-??.pcx
+15 -11
View File
@@ -21,6 +21,7 @@ struct ai_info;
#define HUD_COLOR_GREEN 0
#define HUD_COLOR_BLUE 1
#define HUD_COLOR_AMBER 2
#define HUD_COLOR_SIZE 3 // Number of default colors. Keep this up to date.
// specify the max distance that the radar should detect objects
// Index in Radar_ranges[] array to get values
@@ -45,19 +46,22 @@ extern int HUD_default_popup_mask2;
extern int HUD_config_default_flags;
extern int HUD_config_default_flags2;
/**
* @brief Contains core HUD configuration data
* @note Is not default init'd. Assumes new player, PLR, or CSG reads will correctly set data.
*/
typedef struct HUD_CONFIG_TYPE {
int show_flags; // whether to show gauge
int show_flags2; // whether to show gauge
int popup_flags; // whether gauge is popup
int popup_flags2; // whether gauge is popup
int rp_flags; // see RP_ flags above
int rp_dist; // one of RR_ #defines above
int is_observer; // 1 or 0, observer mode or not, respectively
int main_color; // the main color
ubyte num_msg_window_lines;
int show_flags; //!< bitfield, whether to show gauge (0 ~ 31)
int show_flags2; //!< bitfield, whether to show gauge (32 ~ 63)
int popup_flags; //!< bitfield, whether gauge is popup (0 ~ 31)
int popup_flags2; //!< bitfield, whether gauge is popup (32 ~ 63)
int rp_flags; //!< one of RP_ #defines in hudconfig.h; Chiefly shows/hides non-ship objects
int rp_dist; //!< one of RR_ #defines above; Is the maxium radar view distance setting
int is_observer; //!< 1 or 0, observer mode or not, respectively
int main_color; //!< the default HUD_COLOR selection for all gauges; each gauge may override this with a custom RGB
ubyte num_msg_window_lines; //!< Number of message lines. (Deprecated by HudGaugeMessages::Max_lines)
// colors for all the gauges
color clr[NUM_HUD_GAUGES];
color clr[NUM_HUD_GAUGES]; //!< colors for all the gauges
} HUD_CONFIG_TYPE;
extern HUD_CONFIG_TYPE HUD_config;
+3 -3
View File
@@ -924,7 +924,7 @@ void hud_lock_acquire_uncaged_target(lock_info *current_lock, weapon_info *wip)
continue;
}*/
if (!weapon_can_lock_on_ship(wip, A->instance)) {
if (!weapon_target_satisfies_lock_restrictions(wip, A)) {
continue;
}
@@ -1042,7 +1042,7 @@ void hud_lock_determine_lock_target(lock_info *lock_slot, weapon_info *wip)
return;
}
if ( !weapon_can_lock_on_ship(wip, lock_slot->obj->instance) ) {
if ( !weapon_target_satisfies_lock_restrictions(wip, lock_slot->obj) ) {
ship_clear_lock(lock_slot);
return;
}
@@ -1110,7 +1110,7 @@ void hud_lock_determine_lock_target(lock_info *lock_slot, weapon_info *wip)
return;
}
if ( !weapon_can_lock_on_ship(wip, lock_slot->obj->instance) ) {
if ( !weapon_target_satisfies_lock_restrictions(wip, lock_slot->obj) ) {
ship_clear_lock(lock_slot);
return;
}
+6 -5
View File
@@ -5323,17 +5323,18 @@ SCP_string hud_get_ship_class(const ship *shipp)
// try to get alt name
if (Fred_running) {
ship_class_text = Fred_alt_names[shipp-Ships];
if (ship_class_text.empty()) {
ship_class_text = Ship_info[shipp->ship_info_index].get_display_name();
}
} else {
if (shipp->alt_type_index >= 0) {
ship_class_text = mission_parse_lookup_alt_index(shipp->alt_type_index);
} else {
ship_class_text = Ship_info[shipp->ship_info_index].get_display_name();
}
}
// maybe get ship class
if (ship_class_text.empty()) {
ship_class_text = Ship_info[shipp->ship_info_index].get_display_name();
}
if (!Disable_built_in_translations) {
// handle translation
if (Lcl_gr) {
+2
View File
@@ -133,6 +133,8 @@ public:
int setAmbientFactor(int factor) {
ambientFactor = factor;
Cmdline_ambient_factor = factor;
gr_calculate_ambient_factor();
return factor;
}
+122 -226
View File
@@ -5,7 +5,8 @@
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
*/
@@ -42,7 +43,7 @@
#define NUM_BUTTONS 16
#define NUM_TABS 3
#define LIST_BUTTONS_MAX 42
#define LIST_BUTTONS_MAX 50
#define SHIPS_DATA_MODE (1<<0)
#define WEAPONS_DATA_MODE (1<<1)
@@ -235,14 +236,10 @@ typedef struct {
int textures_loaded; // if the model has textures loaded for it or not (hacky mem management)
} tech_list_entry;
static tech_list_entry *Ship_list = nullptr;
static int Ship_list_size = 0;
static tech_list_entry *Weapon_list = nullptr;
static int Weapon_list_size = 0;
static tech_list_entry *Intel_list = nullptr;
static int Intel_list_size = 0;
static tech_list_entry *Current_list; // points to currently valid display list
static int Current_list_size = 0;
static SCP_vector<tech_list_entry> Ship_list;
static SCP_vector<tech_list_entry> Weapon_list;
static SCP_vector<tech_list_entry> Intel_list;
static SCP_vector<tech_list_entry>* Current_list = &Ship_list; // A pointer to the current display list
// slider stuff
static UI_SLIDER2 Tech_slider;
@@ -274,64 +271,63 @@ void techroom_init_desc(const char *src, int w)
void techroom_unload_animation()
{
int i;
//clear everything, just in case, it will get loaded when needed later
if (Weapon_list != NULL) {
for (i = 0; i < Weapon_list_size; i++) {
if (Weapon_list[i].animation.num_frames != 0) {
generic_anim_unload(&Weapon_list[i].animation);
}
for (auto& list_entry : Weapon_list) {
if (list_entry.animation.type != BM_TYPE_NONE && list_entry.has_anim != 0) {
generic_anim_unload(&list_entry.animation);
}
if (Weapon_list[i].bitmap >= 0) {
bm_release(Weapon_list[i].bitmap);
Weapon_list[i].bitmap = -1;
}
if (list_entry.bitmap >= 0) {
bm_release(list_entry.bitmap);
list_entry.bitmap = -1;
}
}
for (i = 0; i < Intel_list_size; i++) {
if (Intel_list[i].animation.num_frames != 0) {
generic_anim_unload(&Intel_list[i].animation);
for (auto & intel_entry : Intel_list) {
if (intel_entry.animation.type != BM_TYPE_NONE && intel_entry.has_anim != 0) {
generic_anim_unload(&intel_entry.animation);
}
if (Intel_list[i].bitmap >= 0) {
bm_release(Intel_list[i].bitmap);
Intel_list[i].bitmap = -1;
if (intel_entry.bitmap >= 0) {
bm_release(intel_entry.bitmap);
intel_entry.bitmap = -1;
}
}
}
void techroom_select_new_entry()
{
Assert(Current_list != NULL);
if (Current_list == NULL || Current_list_size <= 0) {
if (Current_list->empty()) {
Cur_entry_index = Cur_entry = -1;
techroom_init_desc(NULL,0);
techroom_init_desc(nullptr,0);
return;
}
Cur_entry_index = Current_list[Cur_entry].index;
Assert(Cur_entry < static_cast<int>(Current_list->size()));
Cur_entry_index = Current_list->at(Cur_entry).index;
Assert( Cur_entry_index >= 0 );
// if we are in the ships tab, load the ship model
if (Tab == SHIPS_DATA_TAB) {
ship_info *sip = &Ship_info[Cur_entry_index];
int i = 0;
// little memory management, kinda hacky but it should keep the techroom at around
// 100meg rather than the 700+ it can get to with all ships loaded - taylor
for (int i=0; i<Current_list_size; i++) {
if ((Current_list[i].model_num > -1) && (Current_list[i].textures_loaded)) {
for (auto & list_entry : *Current_list) {
if ((list_entry.model_num > -1) && (list_entry.textures_loaded)) {
// don't unload any spot within 5 of current
if ( (i < Cur_entry + 5) && (i > Cur_entry - 5) )
if ((i < Cur_entry + 5) && (i > Cur_entry - 5) )
continue;
mprintf(("TECH ROOM: Dumping excess ship textures...\n"));
model_page_out_textures(Current_list[i].model_num);
model_page_out_textures(list_entry.model_num);
Current_list[i].textures_loaded = 0;
list_entry.textures_loaded = 0;
}
i++;
}
Techroom_ship_modelnum = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
@@ -341,12 +337,14 @@ void techroom_select_new_entry()
}
Techroom_ship_model_instance = model_create_instance(true, Techroom_ship_modelnum);
Current_list[Cur_entry].model_num = Techroom_ship_modelnum;
model_set_up_techroom_instance(sip, Techroom_ship_model_instance);
Current_list->at(Cur_entry).model_num = Techroom_ship_modelnum;
// page in ship textures properly (takes care of nondimming pixels)
model_page_in_textures(Techroom_ship_modelnum, Cur_entry_index);
Current_list[Cur_entry].textures_loaded = 1;
Current_list->at(Cur_entry).textures_loaded = 1;
} else {
Techroom_ship_modelnum = -1;
@@ -358,19 +356,19 @@ void techroom_select_new_entry()
Trackball_mode = 0;
// load animation here, we now only have one loaded
int stream_result = generic_anim_init_and_stream(&Current_list[Cur_entry].animation, Current_list[Cur_entry].tech_anim_filename, bm_get_type(Tech_background_bitmap), true);
int stream_result = generic_anim_init_and_stream(&Current_list->at(Cur_entry).animation, Current_list->at(Cur_entry).tech_anim_filename, bm_get_type(Tech_background_bitmap), true);
if (stream_result >= 0) {
Current_list[Cur_entry].has_anim = 1;
Current_list->at(Cur_entry).has_anim = 1;
} else {
// we've failed to load any animation
// load an image and treat it like a 1 frame animation
Current_list[Cur_entry].bitmap = bm_load(Current_list[Cur_entry].tech_anim_filename);
Current_list->at(Cur_entry).bitmap = bm_load(Current_list->at(Cur_entry).tech_anim_filename);
}
}
techroom_init_desc(Current_list[Cur_entry].desc, Tech_desc_coords[gr_screen.res][SHIP_W_COORD]);
fsspeech_play(FSSPEECH_FROM_TECHROOM, Current_list[Cur_entry].desc);
techroom_init_desc(Current_list->at(Cur_entry).desc, Tech_desc_coords[gr_screen.res][SHIP_W_COORD]);
fsspeech_play(FSSPEECH_FROM_TECHROOM, Current_list->at(Cur_entry).desc);
}
// write out the current description in the bottom window
@@ -432,7 +430,7 @@ void tech_common_render()
y = 0;
z = List_offset;
while (y + font_height <= Tech_list_coords[gr_screen.res][SHIP_H_COORD]) {
if (z >= Current_list_size) {
if ((z - List_offset) >= LIST_BUTTONS_MAX || z >= static_cast<int>(Current_list->size())) {
break;
}
@@ -445,7 +443,7 @@ void tech_common_render()
}
memset( buf, 0, sizeof(buf) );
strncpy(buf, Current_list[z].name, sizeof(buf) - 1);
strncpy(buf, Current_list->at(z).name, sizeof(buf) - 1);
if (Lcl_gr && !Disable_built_in_translations)
lcl_translate_ship_name_gr(buf);
@@ -467,8 +465,6 @@ void tech_common_render()
}
}
void light_set_all_relevent();
void techroom_ships_render(float frametime)
{
// render all the common stuff
@@ -480,7 +476,6 @@ void techroom_ships_render(float frametime)
// now render the trackball ship, which is unique to the ships tab
float rev_rate = REVOLUTION_RATE;
angles rot_angles, view_angles;
int i, j;
ship_info *sip = &Ship_info[Cur_entry_index];
model_render_params render_info;
@@ -551,31 +546,6 @@ void techroom_ships_render(float frametime)
model_clear_instance(Techroom_ship_modelnum);
render_info.set_detail_level_lock(0);
polymodel *pm = model_get(Techroom_ship_modelnum);
polymodel_instance *pmi = model_get_instance(Techroom_ship_model_instance);
for (i = 0; i < sip->n_subsystems; i++) {
model_subsystem *msp = &sip->subsystems[i];
if (msp->type == SUBSYSTEM_TURRET) {
float p = 0.0f;
float h = 0.0f;
for (j = 0; j < msp->n_triggers; j++) {
// special case for turrets
p = msp->triggers[j].angle.xyz.x;
h = msp->triggers[j].angle.xyz.y;
}
if ( msp->subobj_num >= 0 ) {
model_set_instance_techroom(pm, pmi, msp->subobj_num, 0.0f, h );
}
if ( (msp->subobj_num != msp->turret_gun_sobj) && (msp->turret_gun_sobj >= 0) ) {
model_set_instance_techroom(pm, pmi, msp->turret_gun_sobj, p, 0.0f );
}
}
}
if (sip->replacement_textures.size() > 0)
{
render_info.set_replacement_textures(Techroom_ship_modelnum, sip->replacement_textures);
@@ -585,10 +555,12 @@ void techroom_ships_render(float frametime)
{
gr_reset_clip();
auto pm = model_get(Techroom_ship_modelnum);
shadows_start_render(&Eye_matrix, &Eye_position, Proj_fov, gr_screen.clip_aspect, -sip->closeup_pos.xyz.z + pm->rad, -sip->closeup_pos.xyz.z + pm->rad + 200.0f, -sip->closeup_pos.xyz.z + pm->rad + 2000.0f, -sip->closeup_pos.xyz.z + pm->rad + 10000.0f);
render_info.set_flags(MR_NO_TEXTURING | MR_NO_LIGHTING | MR_AUTOCENTER);
model_render_immediate(&render_info, Techroom_ship_modelnum, &Techroom_ship_orient, &vmd_zero_vector);
model_render_immediate(&render_info, Techroom_ship_modelnum, Techroom_ship_model_instance, &Techroom_ship_orient, &vmd_zero_vector);
shadows_end_render();
gr_set_clip(Tech_ship_display_coords[gr_screen.res][SHIP_X_COORD], Tech_ship_display_coords[gr_screen.res][SHIP_Y_COORD], Tech_ship_display_coords[gr_screen.res][SHIP_W_COORD], Tech_ship_display_coords[gr_screen.res][SHIP_H_COORD], GR_RESIZE_MENU);
@@ -604,7 +576,7 @@ void techroom_ships_render(float frametime)
render_info.set_flags(render_flags);
model_render_immediate(&render_info, Techroom_ship_modelnum, &Techroom_ship_orient, &vmd_zero_vector);
model_render_immediate(&render_info, Techroom_ship_modelnum, Techroom_ship_model_instance, &Techroom_ship_orient, &vmd_zero_vector);
Glowpoint_use_depth_buffer = true;
@@ -626,7 +598,7 @@ void tech_prev_entry()
Cur_entry--;
if (Cur_entry < 0) {
Cur_entry = Current_list_size - 1;
Cur_entry = static_cast<int>(Current_list->size() - 1);
// scroll to end of list
List_offset = Cur_entry - Tech_list_coords[gr_screen.res][SHIP_H_COORD] / gr_get_font_height() + 1;
@@ -654,7 +626,7 @@ void tech_next_entry()
techroom_unload_animation();
Cur_entry++;
if (Cur_entry >= Current_list_size) {
if (Cur_entry >= static_cast<int>(Current_list->size())) {
Cur_entry = 0;
// scroll to beginning of list
@@ -710,7 +682,7 @@ void tech_scroll_list_up()
void tech_scroll_list_down()
{
if (List_offset + Tech_list_coords[gr_screen.res][SHIP_H_COORD] / gr_get_font_height() < Current_list_size) {
if (List_offset + Tech_list_coords[gr_screen.res][SHIP_H_COORD] / gr_get_font_height() < static_cast<int>(Current_list->size())) {
List_offset++;
gamesnd_play_iface(InterfaceSounds::SCROLL);
} else {
@@ -735,27 +707,27 @@ void techroom_anim_render(float frametime)
tech_common_render();
// exit now if there are no entries to show
if (Current_list_size == 0 || Cur_entry < 0)
if (Current_list->empty() || Cur_entry < 0 || Cur_entry >= static_cast<int>(Current_list->size()))
return;
// render the animation
if(Current_list[Cur_entry].animation.num_frames > 0)
if(Current_list->at(Cur_entry).animation.num_frames > 0)
{
//grab dimensions
bm_get_info((Current_list[Cur_entry].animation.streaming) ? Current_list[Cur_entry].animation.bitmap_id : Current_list[Cur_entry].animation.first_frame, &x, &y, NULL, NULL, NULL);
bm_get_info((Current_list->at(Cur_entry).animation.streaming) ? Current_list->at(Cur_entry).animation.bitmap_id : Current_list->at(Cur_entry).animation.first_frame, &x, &y, nullptr, nullptr, nullptr);
//get the centre point - adjust
x = Tech_ani_centre_coords[gr_screen.res][0] - x / 2;
y = Tech_ani_centre_coords[gr_screen.res][1] - y / 2;
generic_anim_render(&Current_list[Cur_entry].animation, frametime, x, y, true);
generic_anim_render(&Current_list->at(Cur_entry).animation, frametime, x, y, true);
}
// if our active item has a bitmap instead of an animation, draw it
else if((Cur_entry >= 0) && (Current_list[Cur_entry].bitmap >= 0)){
else if((Cur_entry >= 0) && (Current_list->at(Cur_entry).bitmap >= 0)){
//grab dimensions
bm_get_info(Current_list[Cur_entry].bitmap, &x, &y, NULL, NULL, NULL);
bm_get_info(Current_list->at(Cur_entry).bitmap, &x, &y, nullptr, nullptr, nullptr);
//get the centre point - adjust
x = Tech_ani_centre_coords[gr_screen.res][0] - x / 2;
y = Tech_ani_centre_coords[gr_screen.res][1] - y / 2;
gr_set_bitmap(Current_list[Cur_entry].bitmap);
gr_set_bitmap(Current_list->at(Cur_entry).bitmap);
gr_bitmap(x, y, GR_RESIZE_MENU);
}
}
@@ -792,50 +764,40 @@ void techroom_change_tab(int num)
// load ship info if necessary
if ( !Ships_loaded ) {
if (Ship_list == NULL) {
Ship_list = new tech_list_entry[Ship_info.size()];
if (Ship_list.empty()) {
Ship_list.reserve(Ship_info.size());
}
Ship_list_size = 0;
tech_list_entry temp_entry;
// we always initially set these values, so keep them outside the loop.
temp_entry.bitmap = -1;
temp_entry.animation.num_frames = 0; // no anim for ships
temp_entry.has_anim = 0; // no anim for ships
temp_entry.model_num = -1;
temp_entry.textures_loaded = 0;
for (auto it = Ship_info.begin(); it != Ship_info.end(); ++it)
{
if (Techroom_show_all || (it->flags & si_mask).any_set())
{
// this ship should be displayed, fill out the entry struct
Ship_list[Ship_list_size].bitmap = -1;
Ship_list[Ship_list_size].index = (int)std::distance(Ship_info.begin(), it);
Ship_list[Ship_list_size].animation.num_frames = 0; // no anim for ships
Ship_list[Ship_list_size].has_anim = 0; // no anim for ships
Ship_list[Ship_list_size].name = *it->tech_title ? it->tech_title : it->get_display_name();
Ship_list[Ship_list_size].desc = it->tech_desc;
Ship_list[Ship_list_size].model_num = -1;
Ship_list[Ship_list_size].textures_loaded = 0;
temp_entry.index = (int)std::distance(Ship_info.begin(), it);
temp_entry.name = *it->tech_title ? it->tech_title : it->get_display_name();
temp_entry.desc = it->tech_desc;
Ship_list_size++;
Ship_list.push_back(temp_entry);
}
}
// make sure that at least the default entry is cleared out if we didn't grab anything
if (!Ship_info.empty() && !Ship_list_size) {
Ship_list[0].index = -1;
Ship_list[0].desc = NULL;
Ship_list[0].name = NULL;
Ship_list[0].bitmap = -1;
Ship_list[0].has_anim = 0;
Ship_list[0].animation.num_frames = 0;
Ship_list[0].model_num = -1;
Ship_list[0].textures_loaded = 0;
}
Ships_loaded = true;
}
Current_list = Ship_list;
Current_list_size = Ship_list_size;
Current_list = &Ship_list;
font_height = gr_get_font_height();
max_num_entries_viewable = Tech_list_coords[gr_screen.res][SHIP_H_COORD] / font_height;
Tech_slider.set_numberItems(Current_list_size > max_num_entries_viewable ? Current_list_size-max_num_entries_viewable : 0);
Tech_slider.set_numberItems((int)Current_list->size() > max_num_entries_viewable ? (int)Current_list->size()-max_num_entries_viewable : 0);
// no anim to start here
break;
@@ -844,57 +806,45 @@ void techroom_change_tab(int num)
// load weapon info & anims if necessary
if ( !Weapons_loaded ) {
if (Weapon_list == NULL) {
Weapon_list = new tech_list_entry[Weapon_info.size()];
}
Weapon_list_size = 0;
Weapon_list.reserve(Weapon_info.size());
wi_mask.set(multi ? Weapon::Info_Flags::Player_allowed : Weapon::Info_Flags::In_tech_database);
wi_mask.set(Weapon::Info_Flags::Default_in_tech_database);
int i = 0;
tech_list_entry temp_entry;
// we always initially set these values, so keep them outside the loop.
temp_entry.has_anim = 1;
temp_entry.bitmap = -1;
temp_entry.animation.num_frames = 0;
temp_entry.model_num = -1;
temp_entry.textures_loaded = 0;
for (auto &wi : Weapon_info)
{
if (Techroom_show_all || (wi.wi_flags & wi_mask).any_set())
{
// we have a weapon that should be in the tech db, so fill out the entry struct
Weapon_list[Weapon_list_size].index = i;
Weapon_list[Weapon_list_size].desc = wi.tech_desc;
Weapon_list[Weapon_list_size].has_anim = 1;
Weapon_list[Weapon_list_size].name = wi.tech_title[0] ? wi.tech_title : wi.get_display_name();
Weapon_list[Weapon_list_size].bitmap = -1;
Weapon_list[Weapon_list_size].animation.num_frames = 0;
Weapon_list[Weapon_list_size].model_num = -1;
Weapon_list[Weapon_list_size].textures_loaded = 0;
// we have a weapon that should be in the tech db, so fill out specific info
temp_entry.index = i;
temp_entry.desc = wi.tech_desc;
temp_entry.name = wi.tech_title[0] ? wi.tech_title : wi.get_display_name();
// copy the weapon animation filename
strncpy(Weapon_list[Weapon_list_size].tech_anim_filename, wi.tech_anim_filename, MAX_FILENAME_LEN - 1);
++Weapon_list_size;
strncpy(temp_entry.tech_anim_filename, wi.tech_anim_filename, MAX_FILENAME_LEN - 1);
Weapon_list.push_back(temp_entry);
}
++i;
}
// make sure that at least the default entry is cleared out if we didn't grab anything
if (!Weapon_info.empty() && !Weapon_list_size) {
Weapon_list[0].index = -1;
Weapon_list[0].desc = NULL;
Weapon_list[0].name = NULL;
Weapon_list[0].bitmap = -1;
Weapon_list[0].has_anim = 0;
Weapon_list[0].animation.num_frames = 0;
Weapon_list[0].model_num = -1;
Weapon_list[0].textures_loaded = 0;
}
Weapons_loaded = true;
}
Current_list = Weapon_list;
Current_list_size = Weapon_list_size;
Current_list = &Weapon_list;
font_height = gr_get_font_height();
max_num_entries_viewable = Tech_list_coords[gr_screen.res][SHIP_H_COORD] / font_height;
Tech_slider.set_numberItems(Current_list_size > max_num_entries_viewable ? Current_list_size-max_num_entries_viewable : 0);
Tech_slider.set_numberItems(static_cast<int>(Current_list->size()) > max_num_entries_viewable ? static_cast<int>(Current_list->size())-max_num_entries_viewable : 0);
break;
@@ -902,60 +852,46 @@ void techroom_change_tab(int num)
// load intel if necessary
if ( !Intel_loaded ) {
if (Intel_list == nullptr) {
Intel_list = new tech_list_entry[Intel_info.size()];
if (Intel_list.empty()) {
Intel_list.reserve(Intel_info.size());
}
Intel_list_size = 0;
int i = 0;
tech_list_entry temp_entry;
// we always initially set these values, so keep them outside the loop.
temp_entry.has_anim = 0;
temp_entry.model_num = -1;
temp_entry.textures_loaded = 0;
for (auto &ii : Intel_info) {
if (Techroom_show_all || (ii.flags & IIF_IN_TECH_DATABASE)) {
// leave option for no animation if string == "none"
if (!strcmp(ii.anim_filename, "none")) {
Intel_list[Intel_list_size].has_anim = 0;
Intel_list[Intel_list_size].animation.num_frames = 0;
temp_entry.animation.num_frames = 0;
} else {
// try and load as an animation
Intel_list[Intel_list_size].has_anim = 0;
Intel_list[Intel_list_size].bitmap = -1;
strncpy(Intel_list[Intel_list_size].tech_anim_filename, ii.anim_filename, NAME_LENGTH - 1);
temp_entry.bitmap = -1;
strncpy(temp_entry.tech_anim_filename, ii.anim_filename, NAME_LENGTH - 1);
}
Intel_list[Intel_list_size].desc = ii.desc.c_str();
Intel_list[Intel_list_size].index = i;
Intel_list[Intel_list_size].name = ii.name;
Intel_list[Intel_list_size].model_num = -1;
Intel_list[Intel_list_size].textures_loaded = 0;
temp_entry.desc = ii.desc.c_str();
temp_entry.index = i;
temp_entry.name = ii.name;
Intel_list_size++;
Intel_list.push_back(temp_entry);
}
++i;
}
// make sure that at least the default entry is cleared out if we didn't grab anything
if (!Intel_info.empty() && !Intel_list_size) {
Intel_list[0].index = -1;
Intel_list[0].desc = NULL;
Intel_list[0].name = NULL;
Intel_list[0].bitmap = -1;
Intel_list[0].has_anim = 0;
Intel_list[0].animation.num_frames = 0;
Intel_list[0].model_num = -1;
Intel_list[0].textures_loaded = 0;
}
Intel_loaded = true;
}
// index lookup on intel is a pretty pointless, but it keeps everything
// consistent and doesn't really hurt anything
Current_list = Intel_list;
Current_list_size = Intel_list_size;
Current_list = &Intel_list;
font_height = gr_get_font_height();
max_num_entries_viewable = Tech_list_coords[gr_screen.res][SHIP_H_COORD] / font_height;
Tech_slider.set_numberItems(Current_list_size > max_num_entries_viewable ? Current_list_size-max_num_entries_viewable : 0);
Tech_slider.set_numberItems(static_cast<int>(Current_list->size()) > max_num_entries_viewable ? static_cast<int>(Current_list->size())-max_num_entries_viewable : 0);
break;
}
@@ -1123,7 +1059,7 @@ void techroom_intel_reset()
void techroom_init()
{
int i, idx;
int i;
techroom_buttons *b;
Ships_loaded = false;
@@ -1212,9 +1148,9 @@ void techroom_init()
Tech_slider.create(&Ui_window, Tech_slider_coords[gr_screen.res][SHIP_X_COORD], Tech_slider_coords[gr_screen.res][SHIP_Y_COORD], Tech_slider_coords[gr_screen.res][SHIP_W_COORD], Tech_slider_coords[gr_screen.res][SHIP_H_COORD], (int)Ship_info.size(), Tech_slider_filename[gr_screen.res], &tech_scroll_list_up, &tech_scroll_list_down, &tech_ship_scroll_capture);
// zero intel anim/bitmap stuff
for(idx=0; idx<Intel_list_size; idx++){
Intel_list[idx].animation.num_frames = 0;
Intel_list[idx].bitmap = -1;
for(auto & intel_item : Intel_list){
intel_item.animation.num_frames = 0;
intel_item.bitmap = -1;
}
mprintf(("Techroom successfully initialized, now changing tab...\n"));
@@ -1223,63 +1159,23 @@ void techroom_init()
void techroom_lists_reset()
{
int i;
//unload the current animation, we load another one for the new current entry
if(Tab != SHIPS_DATA_TAB)
if (Tab != SHIPS_DATA_TAB)
techroom_unload_animation();
Current_list = NULL;
Current_list_size = 0;
model_free_all();
Techroom_ship_modelnum = -1;
Techroom_ship_model_instance = -1;
if (Ship_list != NULL) {
delete[] Ship_list;
Ship_list = NULL;
}
Ship_list_size = 0;
// This can be cleared immediately because there are no anims or bitmaps associated.
Ship_list.clear();
Ships_loaded = false;
if (Weapon_list != NULL) {
for (i = 0; i < Weapon_list_size; i++) {
if (Weapon_list[i].animation.num_frames != 0) {
generic_anim_unload(&Weapon_list[i].animation);
}
if (Weapon_list[i].bitmap >= 0) {
bm_release(Weapon_list[i].bitmap);
Weapon_list[i].bitmap = -1;
}
}
delete[] Weapon_list;
Weapon_list = NULL;
}
Weapon_list_size = 0;
// now that we're sure all the bitmaps are released, clear the vectors.
Weapon_list.clear();
Weapons_loaded = false;
if (Intel_list != nullptr) {
for (i = 0; i < Intel_list_size; i++) {
if (Intel_list[i].animation.num_frames != 0) {
generic_anim_unload(&Intel_list[i].animation);
}
if (Intel_list[i].bitmap >= 0) {
bm_release(Intel_list[i].bitmap);
Intel_list[i].bitmap = -1;
}
}
delete[] Intel_list;
Intel_list = nullptr;
}
Intel_list_size = 0;
Intel_list.clear();
Intel_loaded = false;
}
+1
View File
@@ -463,6 +463,7 @@ void mission_brief_common_reset()
memset( Briefings[i].stages[j].icons, 0, sizeof(brief_icon) * MAX_STAGE_ICONS );
Briefings[i].stages[j].icons->ship_class = -1;
Briefings[i].stages[j].icons->modelnum = -1;
Briefings[i].stages[j].icons->model_instance_num = -1;
Briefings[i].stages[j].icons->bitmap_id = -1;
}
+1
View File
@@ -114,6 +114,7 @@ typedef struct brief_icon {
int hold_x, hold_y; // 2D screen position of icon, used to place animations
int ship_class;
int modelnum;
int model_instance_num;
float radius;
int type; // ICON_* defines from MissionBriefCommon.h
int bitmap_id;
+29
View File
@@ -1509,6 +1509,8 @@ void parse_briefing(mission * /*pm*/, int flags)
find_and_stuff("$team:", &bi->team, F_NAME, temp_team_names, Num_iffs, "team name");
find_and_stuff("$class:", &bi->ship_class, F_NAME, Ship_class_names, Ship_info.size(), "ship class");
bi->modelnum = -1;
bi->model_instance_num = -1;
// Goober5000 - import
if (flags & MPF_IMPORT_FSM)
@@ -8085,6 +8087,33 @@ void mission_parse_reset_alt()
Mission_alt_type_count = 0;
}
// For compatibility purposes some mods want alt names to truncate at the hash symbol. But we can't actually do that at mission load,
// since we have to save them again in FRED. So this function processes the names just before the mission starts.
// To further complicate things, some mods actually want the hash to be displayed. So this function uses the double-hash as an escape sequence for a single hash.
void mission_process_alt_types()
{
for (int i = 0; i < Mission_alt_type_count; ++i)
{
// truncate at a single hash
end_string_at_first_hash_symbol(Mission_alt_types[i], true);
// consolidate double hashes
auto src = Mission_alt_types[i];
auto dest = src;
while (*src)
{
if (*src == '#' && *(src + 1) == '#')
dest--;
++src;
++dest;
if (src != dest)
*dest = *src;
}
}
}
/**
* Callsign stuff
*/
+1 -3
View File
@@ -518,9 +518,6 @@ int get_parse_name_index(const char *name);
// called from freespace game level loop
void mission_parse_eval_stuff();
// function to set the ramaing time left in the mission
void mission_parse_set_end_time( int seconds );
// code to bring in a repair ship.
void mission_bring_in_support_ship( object *requester_objp );
int mission_is_support_ship_arriving( void );
@@ -535,6 +532,7 @@ const char *mission_parse_lookup_alt_index(int index);
int mission_parse_add_alt(const char *name);
void mission_parse_remove_alt(const char *name);
void mission_parse_reset_alt();
void mission_process_alt_types();
// callsign stuff
int mission_parse_lookup_callsign(const char *name);
+14 -26
View File
@@ -704,8 +704,13 @@ brief_icon *brief_get_closeup_icon()
// stop showing the closeup view of an icon
void brief_turn_off_closeup_icon()
{
// turn off closup
// turn off closeup
if ( Closeup_icon != NULL ) {
if (Closeup_icon->model_instance_num >= 0) {
model_delete_instance(Closeup_icon->model_instance_num);
Closeup_icon->model_instance_num = -1;
}
gamesnd_play_iface(InterfaceSounds::BRIEF_ICON_SELECT);
Closeup_icon = NULL;
Closeup_close_button.disable();
@@ -1075,7 +1080,7 @@ void brief_render_closeup(int ship_class, float frametime)
render_info.set_flags(MR_AUTOCENTER);
}
model_render_immediate( &render_info, Closeup_icon->modelnum, &Closeup_orient, &Closeup_pos );
model_render_immediate( &render_info, Closeup_icon->modelnum, Closeup_icon->model_instance_num, &Closeup_orient, &Closeup_pos );
The_mission.flags.set(Mission::Mission_Flags::Fullneb, neb_restore);
@@ -1198,28 +1203,6 @@ void brief_set_closeup_pos(brief_icon * /*bi*/)
Closeup_x1 = (int)std::lround(320 - Closeup_coords[gr_screen.res][BRIEF_W_COORD]/2.0f);
}
void brief_get_closeup_ship_modelnum(brief_icon *ci)
{
object *objp;
ship *sp;
// find the model number for the ship to display
for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
if ( objp == &obj_used_list || objp->type != OBJ_SHIP ) {
continue;
}
sp = &Ships[objp->instance];
if ( sp->ship_info_index == ci->ship_class ) {
ci->ship_class = sp->ship_info_index;
ci->modelnum = Ship_info[sp->ship_info_index].model_num;
ci->radius = objp->radius;
break;
}
}
}
// -------------------------------------------------------------------------------------
// brief_setup_closeup()
//
@@ -1234,6 +1217,7 @@ int brief_setup_closeup(brief_icon *bi)
Closeup_icon = bi;
Closeup_icon->ship_class = bi->ship_class;
Closeup_icon->modelnum = -1;
Closeup_icon->model_instance_num = -1;
Closeup_one_revolution_time = ONE_REV_TIME;
@@ -1270,7 +1254,6 @@ int brief_setup_closeup(brief_icon *bi)
Closeup_zoom = 0.5f;
break;
default:
brief_get_closeup_ship_modelnum(Closeup_icon);
Assert( Closeup_icon->ship_class != -1 );
sip = &Ship_info[Closeup_icon->ship_class];
@@ -1284,12 +1267,17 @@ int brief_setup_closeup(brief_icon *bi)
break;
}
if ( Closeup_icon->modelnum == -1 ) {
if ( Closeup_icon->modelnum < 0 ) {
if ( sip == NULL ) {
Closeup_icon->modelnum = model_load(pof_filename, 0, NULL);
} else {
Closeup_icon->modelnum = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
Closeup_icon->model_instance_num = model_create_instance(true, Closeup_icon->modelnum);
model_set_up_techroom_instance(sip, Closeup_icon->model_instance_num);
}
}
if ( Closeup_icon->modelnum >= 0 ) {
Closeup_icon->radius = model_get_radius(Closeup_icon->modelnum);
}
+13 -14
View File
@@ -2414,12 +2414,10 @@ int create_wings()
ss_wing_info *wb;
ss_slot_info *ws;
wing *wp;
p_object *p_objp;
int shipnum, objnum, slot_index;
int cleanup_ship_index[MAX_WING_SLOTS];
int i,j,k;
int found_pobj;
Assert( (Ss_wings != NULL) && (Wss_slots != NULL) );
@@ -2451,21 +2449,22 @@ int create_wings()
objnum = OBJ_INDEX(Player_obj);
shipnum = Objects[objnum].instance;
} else {
if ( wb->is_late) {
found_pobj = 0;
for ( p_objp = GET_FIRST(&Ship_arrival_list); p_objp != END_OF_LIST(&Ship_arrival_list); p_objp = GET_NEXT(p_objp) ) {
if ( p_objp->wingnum == WING_INDEX(wp) ) {
if ( ws->sa_index == POBJ_INDEX(p_objp) ) {
p_objp->ship_class = Wss_slots[slot_index].ship_class;
wl_update_parse_object_weapons(p_objp, &Wss_slots[i*MAX_WING_SLOTS+j]);
found_pobj = 1;
break;
}
// We should always update the parse object information, even if the ship is present at start,
// because the wing might have more than one wave or scripting functions might need accurate data
bool found_pobj = false;
for ( auto &p_obj: Parse_objects ) {
if ( p_obj.wingnum == WING_INDEX(wp) ) {
if ( p_obj.pos_in_wing == j ) {
p_obj.ship_class = Wss_slots[slot_index].ship_class;
wl_update_parse_object_weapons(&p_obj, &Wss_slots[i*MAX_WING_SLOTS+j]);
found_pobj = true;
break;
}
}
Assert(found_pobj);
}
else {
Assert(found_pobj);
if (!wb->is_late) {
// AL 10/04/97
// Change the ship type of the ship if different than current.
// NOTE: This will reset the weapons for this ship. I think this is
+3 -2
View File
@@ -22,6 +22,7 @@
#include "model/model_flags.h"
class object;
class ship_info;
class model_render_params;
extern flag_def_list model_render_flags[];
@@ -803,7 +804,7 @@ polymodel *model_get(int model_num);
polymodel_instance* model_get_instance(int model_instance_num);
// routine to copy susbsystems. Must be called when subsystems sets are the same -- see ship.cpp
// routine to copy subsystems. Must be called when subsystems sets are the same -- see ship.cpp
void model_copy_subsystems(int n_subsystems, model_subsystem *d_sp, model_subsystem *s_sp);
// If MR_FLAG_OUTLINE bit set this color will be used for outlines.
@@ -968,7 +969,7 @@ extern void model_clear_instance(int model_num);
extern void model_set_submodel_turn_info(submodel_instance *smi, float turn_rate, float turn_accel);
// Sets the submodel instance data in a submodel
extern void model_set_instance_techroom(polymodel *pm, polymodel_instance *pmi, int submodel_num, float angle_1, float angle_2);
extern void model_set_up_techroom_instance(ship_info *sip, int model_instance_num);
void model_update_instance(int model_instance_num, int submodel_num, flagset<Ship::Subsystem_Flags>& flags);
void model_update_instance(polymodel *pm, polymodel_instance *pmi, int submodel_num, flagset<Ship::Subsystem_Flags>& flags);
+86 -21
View File
@@ -462,6 +462,55 @@ void get_user_prop_value(char *buf, char *value)
*p1 = c;
}
// Stuff a floating point value pointed at by Mp.
// Advances past float characters.
int stuff_float_temp(float *f, bool optional)
{
char *str_start = Mp;
char *str_end;
// since strtof ignores white space anyway, might as well make it explicit
ignore_white_space();
auto result = strtof(Mp, &str_end);
bool success = false, comma = false;
int retval = 0;
// no float found?
if (result == 0.0f && str_end == Mp)
{
if (!optional)
error_display(1, "Expecting float, found [%.32s].\n", next_tokens());
}
else
{
*f = result;
success = true;
}
if (success)
Mp = str_end;
if (*Mp == ',')
{
comma = true;
Mp++;
}
if (optional && !success)
Mp = str_start;
if (success)
retval = 2;
else if (optional)
retval = comma ? 1 : 0;
else
skip_token();
diag_printf("Stuffed float: %f\n", *f);
return retval;
}
// routine to parse out a vec3d from a user property field of an object
bool get_user_vec3d_value(char *buf, vec3d *value, bool require_brackets)
{
@@ -494,11 +543,11 @@ bool get_user_vec3d_value(char *buf, vec3d *value, bool require_brackets)
}
// get comma-separated floats
if (stuff_float_optional(&f1) != 2)
if (stuff_float_temp(&f1, true) != 2)
break;
if (stuff_float_optional(&f2) != 2)
if (stuff_float_temp(&f2, true) != 2)
break;
if (stuff_float_optional(&f3) != 2)
if (stuff_float_temp(&f3, true) != 2)
break;
if (require_brackets)
@@ -2722,6 +2771,9 @@ int model_load(const char *filename, int n_subsystems, model_subsystem *subsyst
Assert(pm->submodel[i].num_live_debris < MAX_LIVE_DEBRIS);
pm->submodel[i].live_debris[pm->submodel[i].num_live_debris++] = j;
pm->submodel[j].is_live_debris = 1;
// make sure live debris doesn't have a parent
pm->submodel[j].parent = -1;
}
}
@@ -4448,28 +4500,41 @@ void model_set_submodel_turn_info(submodel_instance *smi, float turn_rate, float
smi->turn_accel = turn_accel;
}
// Sets the submodel instance data in a submodel (for all detail levels)
// Techroom version uses two floats of setting rotation angles (for turrets)
// instead of using larger but largely unused structures for storing the same data
void model_set_instance_techroom(polymodel *pm, polymodel_instance *pmi, int sub_model_num, float angle_1, float angle_2)
// Sets the submodel instance data when a tech room model instance is created.
// This only needs to be done at creation, not every frame.
void model_set_up_techroom_instance(ship_info *sip, int model_instance_num)
{
Assert( sub_model_num >= 0 );
Assert( sub_model_num < pm->n_models );
auto pmi = model_get_instance(model_instance_num);
auto pm = model_get(pmi->model_num);
flagset<Ship::Subsystem_Flags> empty;
if ( sub_model_num < 0 ) return;
if ( sub_model_num >= pm->n_models ) return;
bsp_info *sm = &pm->submodel[sub_model_num];
auto smi = &pmi->submodel[sub_model_num];
for (int i = 0; i < sip->n_subsystems; ++i)
{
model_subsystem *msp = &sip->subsystems[i];
// If submodel isn't yet blown off and has a -destroyed replacement model, we prevent
// the replacement model from being drawn by marking it as having been blown off
if ( sm->my_replacement > -1 && sm->my_replacement != sub_model_num) {
pmi->submodel[sm->my_replacement].blown_off = true;
for (int j = 0; j < msp->n_triggers; ++j)
{
if (msp->triggers[j].type == AnimationTriggerType::Initial)
{
// special case for turrets
if (msp->type == SUBSYSTEM_TURRET)
{
if (msp->subobj_num >= 0)
pmi->submodel[msp->subobj_num].angs.h = msp->triggers[j].angle.xyz.y;
if ((msp->subobj_num != msp->turret_gun_sobj) && (msp->turret_gun_sobj >= 0))
pmi->submodel[msp->turret_gun_sobj].angs.p = msp->triggers[j].angle.xyz.x;
}
// we can't support non-turrets, as in modelanim, because we need a ship subsystem but we don't actually have a ship
}
}
if (msp->subobj_num >= 0)
model_update_instance(pm, pmi, msp->subobj_num, empty);
if (msp->turret_gun_sobj >= 0)
model_update_instance(pm, pmi, msp->turret_gun_sobj, empty);
}
// Set the angles
smi->angs.p = angle_1;
smi->angs.h = angle_2;
}
void model_update_instance(int model_instance_num, int submodel_num, flagset<Ship::Subsystem_Flags>& flags)
+11 -11
View File
@@ -1896,18 +1896,18 @@ void model_render_set_glow_points(polymodel *pm, int objnum)
bank->glow_timestamp=time;
}
if ( ( gpo && gpo->off_time_override ) ? gpo->off_time : bank->off_time ) {
if ( bank->is_on ) {
if( ((gpo && gpo->on_time_override) ? gpo->on_time : bank->on_time) > ((time - ((gpo && gpo->disp_time_override) ? gpo->disp_time : bank->disp_time)) % (((gpo && gpo->on_time_override) ? gpo->on_time : bank->on_time) + ((gpo && gpo->off_time_override) ? gpo->off_time : bank->off_time))) ){
int on_time = (gpo && gpo->on_time_override) ? gpo->on_time : bank->on_time;
int off_time = (gpo && gpo->off_time_override) ? gpo->off_time : bank->off_time;
int disp_time = (gpo && gpo->disp_time_override) ? gpo->disp_time : bank->disp_time;
if (off_time) {
bool glow_state = ((time - disp_time) % (on_time + off_time)) < on_time;
if ( glow_state != bank->is_on )
bank->glow_timestamp = time;
bank->is_on = 0;
}
} else {
if( ((gpo && gpo->off_time_override)?gpo->off_time:bank->off_time) < ((time - ((gpo && gpo->disp_time_override)?gpo->disp_time:bank->disp_time)) % (((gpo && gpo->on_time_override)?gpo->on_time:bank->on_time) + ((gpo && gpo->off_time_override)?gpo->off_time:bank->off_time))) ){
bank->glow_timestamp = time;
bank->is_on = 1;
}
}
bank->is_on = glow_state;
}
}
}
+4 -6
View File
@@ -69,16 +69,14 @@ static bool check_for_docking_collision(object *objp1, object *objp2)
}
if (aip1->mode == AIM_DOCK) {
if (dock_check_find_docked_object(&Objects[aip1->goal_objnum], objp2)){
if (aip1->mode == AIM_DOCK && aip1->goal_objnum >= 0 && aip1->goal_objnum < MAX_OBJECTS) {
if (dock_check_find_docked_object(&Objects[aip1->goal_objnum], objp2))
return true;
}
}
if (aip2->mode == AIM_DOCK) {
if (dock_check_find_docked_object(&Objects[aip2->goal_objnum], objp1)){
if (aip2->mode == AIM_DOCK && aip2->goal_objnum >= 0 && aip2->goal_objnum < MAX_OBJECTS) {
if (dock_check_find_docked_object(&Objects[aip2->goal_objnum], objp1))
return true;
}
}
return false;
+18 -9
View File
@@ -268,30 +268,39 @@ int weapon_will_never_hit( object *obj_weapon, object *other, obj_pair * current
// look for two time solutions to Xw = Xs, where Xw = Xw0 + Vwt*t Xs = Xs + Vs*(t+dt), where Vs*dt = radius of ship
// Since direction of Vs is unknown, solve for (Vs*t) and find norm of both sides
if ( !(wip->wi_flags[Weapon::Info_Flags::Turns]) ) {
vec3d delta_x, laser_vel;
vec3d delta_x, weapon_vel;
float a,b,c, delta_x_dot_vl, delta_t;
float root1, root2, root, earliest_time;
if (max_vel_weapon == max_vel_other) {
vm_vec_sub( &delta_x, &obj_weapon->pos, &other->pos );
weapon_vel = obj_weapon->phys_info.vel;
float weapon_speed = vm_vec_mag(&weapon_vel);
if (weapon_speed == max_vel_other) {
// this will give us NAN using the below formula, so check every frame
current_pair->next_check_time = timestamp(0);
return 0;
}
vm_vec_sub( &delta_x, &obj_weapon->pos, &other->pos );
laser_vel = obj_weapon->phys_info.vel;
// vm_vec_copy_scale( &laser_vel, &weapon->orient.vec.fvec, max_vel_weapon );
delta_t = (other->radius + 10.0f) / max_vel_other; // time to get from center to radius of other obj
delta_x_dot_vl = vm_vec_dot( &delta_x, &laser_vel );
delta_x_dot_vl = vm_vec_dot( &delta_x, &weapon_vel);
a = max_vel_weapon*max_vel_weapon - max_vel_other*max_vel_other;
a = weapon_speed * weapon_speed - max_vel_other*max_vel_other;
b = 2.0f * (delta_x_dot_vl - max_vel_other*max_vel_other*delta_t);
c = vm_vec_mag_squared( &delta_x ) - max_vel_other*max_vel_other*delta_t*delta_t;
float discriminant = b*b - 4.0f*a*c;
if ( discriminant < 0) {
// never hit
return 1;
// neither entity passes the other
if (c < 0) {
// ship outpaces weapon
current_pair->next_check_time = timestamp(0); // check next time
return 0;
} else {
// weapon outpaces ship; will never hit
return 1;
}
} else {
root = fl_sqrt( discriminant );
root1 = (-b + root) / (2.0f * a) * 1000.0f; // get time in ms
@@ -299,7 +308,7 @@ int weapon_will_never_hit( object *obj_weapon, object *other, obj_pair * current
}
// standard algorithm
if (max_vel_weapon > max_vel_other) {
if (weapon_speed > max_vel_other) {
// find earliest positive time
if ( root1 > root2 ) {
float temp = root1;
+60 -11
View File
@@ -4004,12 +4004,12 @@ void sprintf(SCP_string &dest, const char *format, ...)
}
// Goober5000
bool end_string_at_first_hash_symbol(char *src)
bool end_string_at_first_hash_symbol(char *src, bool ignore_doubled_hash)
{
char *p;
Assert(src);
p = get_pointer_to_first_hash_symbol(src);
p = get_pointer_to_first_hash_symbol(src, ignore_doubled_hash);
if (p)
{
while ((p != src) && (*(p-1) == ' '))
@@ -4023,9 +4023,9 @@ bool end_string_at_first_hash_symbol(char *src)
}
// Goober5000
bool end_string_at_first_hash_symbol(SCP_string &src)
bool end_string_at_first_hash_symbol(SCP_string &src, bool ignore_doubled_hash)
{
int index = get_index_of_first_hash_symbol(src);
int index = get_index_of_first_hash_symbol(src, ignore_doubled_hash);
if (index >= 0)
{
while (index > 0 && src[index-1] == ' ')
@@ -4039,24 +4039,73 @@ bool end_string_at_first_hash_symbol(SCP_string &src)
}
// Goober5000
char *get_pointer_to_first_hash_symbol(char *src)
char *get_pointer_to_first_hash_symbol(char *src, bool ignore_doubled_hash)
{
Assert(src);
return strchr(src, '#');
if (ignore_doubled_hash)
{
for (auto ch = src; *ch; ++ch)
{
if (*ch == '#')
{
if (*(ch + 1) == '#')
++ch;
else
return ch;
}
}
return nullptr;
}
else
return strchr(src, '#');
}
// Goober5000
const char *get_pointer_to_first_hash_symbol(const char *src)
const char *get_pointer_to_first_hash_symbol(const char *src, bool ignore_doubled_hash)
{
Assert(src);
return strchr(src, '#');
if (ignore_doubled_hash)
{
for (auto ch = src; *ch; ++ch)
{
if (*ch == '#')
{
if (*(ch + 1) == '#')
++ch;
else
return ch;
}
}
return nullptr;
}
else
return strchr(src, '#');
}
// Goober5000
int get_index_of_first_hash_symbol(SCP_string &src)
int get_index_of_first_hash_symbol(SCP_string &src, bool ignore_doubled_hash)
{
size_t pos = src.find('#');
return (pos == SCP_string::npos) ? -1 : (int)pos;
if (ignore_doubled_hash)
{
for (auto ch = src.begin(); ch != src.end(); ++ch)
{
if (*ch == '#')
{
if ((ch + 1) != src.end() && *(ch + 1) == '#')
++ch;
else
return (int)std::distance(src.begin(), ch);
}
}
return -1;
}
else
{
size_t pos = src.find('#');
return (pos == SCP_string::npos) ? -1 : (int)pos;
}
}
// Goober5000
+5 -5
View File
@@ -67,11 +67,11 @@ extern int Token_found_flag;
#define SEXP_ERROR_CHECK_MODE 2
// Goober5000 - this seems to be a pretty universal function
extern bool end_string_at_first_hash_symbol(char *src);
extern bool end_string_at_first_hash_symbol(SCP_string &src);
extern char *get_pointer_to_first_hash_symbol(char *src);
extern const char *get_pointer_to_first_hash_symbol(const char *src);
extern int get_index_of_first_hash_symbol(SCP_string &src);
extern bool end_string_at_first_hash_symbol(char *src, bool ignore_doubled_hash = false);
extern bool end_string_at_first_hash_symbol(SCP_string &src, bool ignore_doubled_hash = false);
extern char *get_pointer_to_first_hash_symbol(char *src, bool ignore_doubled_hash = false);
extern const char *get_pointer_to_first_hash_symbol(const char *src, bool ignore_doubled_hash = false);
extern int get_index_of_first_hash_symbol(SCP_string &src, bool ignore_doubled_hash = false);
// white space
extern int is_white_space(char ch);
+16 -3
View File
@@ -966,6 +966,7 @@ void pilotfile::csg_write_redalert()
void pilotfile::csg_read_hud()
{
int idx;
int strikes = 0;
// flags
HUD_config.show_flags = cfread_int(cfp);
@@ -980,16 +981,28 @@ void pilotfile::csg_read_hud()
HUD_config.rp_flags = cfread_int(cfp);
HUD_config.rp_dist = cfread_int(cfp);
if (HUD_config.rp_dist < 0 || HUD_config.rp_dist >= RR_MAX_RANGES) {
Warning(LOCATION, "Campaign file has invalid radar range %d, setting to default.\n", HUD_config.rp_dist);
ReleaseWarning(LOCATION, "Campaign file has invalid radar range %d, setting to default.\n", HUD_config.rp_dist);
HUD_config.rp_dist = RR_INFINITY;
strikes++;
}
// basic colors
HUD_config.main_color = cfread_int(cfp);
HUD_color_alpha = cfread_int(cfp);
if (HUD_config.main_color < 0 || HUD_config.main_color >= HUD_COLOR_SIZE) {
ReleaseWarning(LOCATION, "Campaign file has invalid main color selection %i, setting to default.\n", HUD_config.main_color);
HUD_config.main_color = HUD_COLOR_GREEN;
strikes++;
}
if (HUD_color_alpha < HUD_COLOR_ALPHA_USER_MIN) {
HUD_color_alpha = cfread_int(cfp);
if (HUD_color_alpha < HUD_COLOR_ALPHA_USER_MIN || HUD_color_alpha > HUD_COLOR_ALPHA_USER_MAX) {
ReleaseWarning(LOCATION, "Campaign file has invalid alpha color %i, setting to default.\n", HUD_color_alpha);
HUD_color_alpha = HUD_COLOR_ALPHA_DEFAULT;
strikes++;
}
if (strikes == 3) {
ReleaseWarning(LOCATION, "Campaign file has too many hud config errors, and is likely corrupted. Please verify and save your settings in the hud config menu.");
}
hud_config_record_color(HUD_config.main_color);
+17 -3
View File
@@ -172,6 +172,7 @@ void pilotfile::plr_write_info()
void pilotfile::plr_read_hud()
{
int strikes = 0;
// flags
HUD_config.show_flags = handler->readInt("show_flags");
HUD_config.show_flags2 = handler->readInt("show_flags2");
@@ -185,15 +186,28 @@ void pilotfile::plr_read_hud()
HUD_config.rp_flags = handler->readInt("rp_flags");
HUD_config.rp_dist = handler->readInt("rp_dist");
if (HUD_config.rp_dist < 0 || HUD_config.rp_dist >= RR_MAX_RANGES) {
Warning(LOCATION, "Player file has invalid radar range %d, setting to default.\n", HUD_config.rp_dist);
ReleaseWarning(LOCATION, "Player file has invalid radar range %d, setting to default.\n", HUD_config.rp_dist);
HUD_config.rp_dist = RR_INFINITY;
strikes++;
}
// basic colors
HUD_config.main_color = handler->readInt("main_color");
HUD_color_alpha = handler->readInt("color_alpha");
if (HUD_config.main_color < 0 || HUD_config.main_color >= HUD_COLOR_SIZE) {
ReleaseWarning(LOCATION, "Player file has invalid main color selection %i, setting to default.\n", HUD_config.main_color);
HUD_config.main_color = HUD_COLOR_GREEN;
strikes++;
}
if (HUD_color_alpha < HUD_COLOR_ALPHA_USER_MIN) {
HUD_color_alpha = handler->readInt("color_alpha");
if (HUD_color_alpha < HUD_COLOR_ALPHA_USER_MIN || HUD_color_alpha > HUD_COLOR_ALPHA_USER_MAX) {
ReleaseWarning(LOCATION, "Player file has invalid alpha color %i, setting to default.\n", HUD_color_alpha);
HUD_color_alpha = HUD_COLOR_ALPHA_DEFAULT;
strikes++;
}
if (strikes == 3) {
ReleaseWarning(LOCATION, "Player file has too many hud config errors, and is likely corrupted. Please verify and save your settings in the hud config menu.");
}
hud_config_set_color(HUD_config.main_color);
+9 -2
View File
@@ -899,9 +899,16 @@ ADE_FUNC(drawTargetingBrackets, l_Graphics, "object Object, [boolean draw=true,
}
break;
case OBJ_WEAPON:
Assert(Weapon_info[Weapons[targetp->instance].weapon_info_index].subtype == WP_MISSILE);
modelnum = Weapon_info[Weapons[targetp->instance].weapon_info_index].model_num;
bound_rc = model_find_2d_bound_min( modelnum, &targetp->orient, &targetp->pos,&x1,&y1,&x2,&y2 );
if (modelnum != -1)
bound_rc = model_find_2d_bound_min(modelnum, &targetp->orient, &targetp->pos, &x1, &y1, &x2, &y2);
else {
vertex vtx;
g3_rotate_vertex(&vtx, &targetp->pos);
g3_project_vertex(&vtx);
x1 = x2 = (int)vtx.screen.xyw.x;
y1 = y2 = (int)vtx.screen.xyw.y;
}
break;
case OBJ_ASTEROID:
pof = Asteroids[targetp->instance].asteroid_subtype;
+2 -2
View File
@@ -216,7 +216,7 @@ ADE_VIRTVAR(WeaponClass, l_WeaponBank, "weaponclass", "Class of weapon mounted i
if(ADE_SETTING_VAR && weaponclass > -1) {
bh->sw->primary_bank_weapons[bh->bank] = weaponclass;
if (Weapon_info[weaponclass].wi_flags[Weapon::Info_Flags::Ballistic]) {
bh->sw->primary_bank_ammo[bh->bank] = (int)std::lround(bh->sw->primary_bank_capacity[bh->bank] / Weapon_info[weaponclass].cargo_size);
bh->sw->primary_bank_start_ammo[bh->bank] = (int)std::lround(bh->sw->primary_bank_capacity[bh->bank] / Weapon_info[weaponclass].cargo_size);
}
}
@@ -224,7 +224,7 @@ ADE_VIRTVAR(WeaponClass, l_WeaponBank, "weaponclass", "Class of weapon mounted i
case SWH_SECONDARY:
if(ADE_SETTING_VAR && weaponclass > -1) {
bh->sw->secondary_bank_weapons[bh->bank] = weaponclass;
bh->sw->secondary_bank_ammo[bh->bank] = (int)std::lround(bh->sw->secondary_bank_capacity[bh->bank] / Weapon_info[weaponclass].cargo_size);
bh->sw->secondary_bank_start_ammo[bh->bank] = (int)std::lround(bh->sw->secondary_bank_capacity[bh->bank] / Weapon_info[weaponclass].cargo_size);
}
return ade_set_args(L, "o", l_Weaponclass.Set(bh->sw->secondary_bank_weapons[bh->bank]));
+2
View File
@@ -10657,10 +10657,12 @@ void change_ship_type(int n, int ship_type, int by_sexp)
if ( by_sexp ) {
if (sip_orig->num_primary_banks > sip->num_primary_banks) {
sp->weapons.current_primary_bank = 0;
sp->weapons.previous_primary_bank = 0;
}
if (sip_orig->num_secondary_banks > sip->num_secondary_banks) {
sp->weapons.current_secondary_bank = 0;
sp->weapons.previous_secondary_bank = 0;
}
// While we're at it, let's copy over the ETS settings too
+1 -1
View File
@@ -285,7 +285,7 @@ void shipfx_blow_off_subsystem(object *ship_objp, ship *ship_p, ship_subsys *sub
shipfx_blow_up_model(ship_objp, psub->subobj_num, 50, &subobj_pos );
// create live debris objects, if any
// TODO: some MULITPLAYER implcations here!!
// TODO: some MULTIPLAYER implcations here!!
shipfx_subsystem_maybe_create_live_debris(ship_objp, ship_p, subsys, exp_center, 1.0f);
int fireball_type = fireball_ship_explosion_type(&Ship_info[ship_p->ship_info_index]);
+33 -3
View File
@@ -918,6 +918,32 @@ void stars_post_level_init()
// FRED doesn't do normal page_in stuff so we need to load up the bitmaps here instead
if (Fred_running) {
stars_load_all_bitmaps();
// see whether we are missing any suns or bitmaps
for (i = 0; i < (int)Backgrounds.size(); ++i) {
SCP_string failed_suns;
for (auto &sun : Backgrounds[i].suns) {
if (stars_find_sun(sun.filename) < 0) {
failed_suns += sun.filename;
failed_suns += "\n";
}
}
SCP_string failed_bitmaps;
for (auto &bitmap : Backgrounds[i].bitmaps) {
if (stars_find_bitmap(bitmap.filename) < 0) {
failed_bitmaps += bitmap.filename;
failed_bitmaps += "\n";
}
}
if (!failed_suns.empty()) {
Warning(LOCATION, "In Background %d, failed to load the following suns:\n%s", (i + 1), failed_suns.c_str());
}
if (!failed_bitmaps.empty()) {
Warning(LOCATION, "In Background %d, failed to load the following bitmaps:\n%s", (i + 1), failed_bitmaps.c_str());
}
}
}
starfield_generate_bitmap_buffers();
@@ -2279,7 +2305,9 @@ int stars_add_sun_entry(starfield_list_entry *sun_ptr)
idx = stars_find_sun(sun_ptr->filename);
if (idx == -1) {
Warning(LOCATION, "Trying to add a sun '%s' that does not exist in stars.tbl!", sun_ptr->filename);
if (!Fred_running) {
Warning(LOCATION, "Trying to add a sun '%s' that does not exist in stars.tbl!", sun_ptr->filename);
}
return -1;
}
@@ -2373,7 +2401,9 @@ int stars_add_bitmap_entry(starfield_list_entry *sle)
idx = stars_find_bitmap(sle->filename);
if (idx == -1) {
Warning(LOCATION, "Trying to add a bitmap '%s' that does not exist in stars.tbl!", sle->filename);
if (!Fred_running) {
Warning(LOCATION, "Trying to add a bitmap '%s' that does not exist in stars.tbl!", sle->filename);
}
return -1;
}
@@ -2676,7 +2706,7 @@ int stars_get_first_valid_background()
if (stars_find_bitmap(background->bitmaps[j].filename) < 0)
{
mprintf(("Failed to load bitmap %s for background %d, falling back to background %d\n",
background->suns[j].filename, i + 1, i + 2));
background->bitmaps[j].filename, i + 1, i + 2));
valid = false;
break;
}
+2 -2
View File
@@ -676,8 +676,8 @@ void shield_impact_explosion(vec3d *hitpos, object *objp, float radius, int idx)
// Swifty - return number of max simultaneous locks
int weapon_get_max_missile_seekers(weapon_info *wip);
// return if this weapon can lock on this ship, based on its type, class, species or iff
bool weapon_can_lock_on_ship(weapon_info *wip, int ship_num);
// return if this weapon can lock on this target, based on its type, class, species or iff
bool weapon_target_satisfies_lock_restrictions(weapon_info *wip, object* target);
// return if this weapon has iff restrictions, and should ignore normal iff targeting restrictions
bool weapon_has_iff_restrictions(weapon_info* wip);
+10 -12
View File
@@ -4093,9 +4093,8 @@ void find_homing_object(object *weapon_objp, int num)
continue;
homing_object_team = obj_team(objp);
bool can_lock_on_ship = objp->type != OBJ_SHIP || weapon_can_lock_on_ship(wip, objp->instance);
bool can_attack = weapon_has_iff_restrictions(wip) || iff_x_attacks_y(wp->team, homing_object_team);
if (can_lock_on_ship && can_attack)
if (weapon_target_satisfies_lock_restrictions(wip, objp) && can_attack)
{
if ( objp->type == OBJ_SHIP )
{
@@ -5353,13 +5352,9 @@ void weapon_set_tracking_info(int weapon_objnum, int parent_objnum, int target_o
if ( parent_objp == NULL || Ships[parent_objp->instance].ai_index >= 0 ) {
int target_team = -1;
int target_ship_num = -1;
if ( target_objnum >= 0 ) {
int obj_type = Objects[target_objnum].type;
if (obj_type == OBJ_SHIP)
target_ship_num = Objects[target_objnum].instance;
if ( (obj_type == OBJ_SHIP) || (obj_type == OBJ_WEAPON) ) {
target_team = obj_team(&Objects[target_objnum]);
@@ -5381,7 +5376,7 @@ void weapon_set_tracking_info(int weapon_objnum, int parent_objnum, int target_o
targeting_same = 0;
}
bool can_lock = weapon_has_iff_restrictions(wip) && target_ship_num >= 0 ? weapon_can_lock_on_ship(wip, target_ship_num) :
bool can_lock = (weapon_has_iff_restrictions(wip) && target_objnum >= 0) ? weapon_target_satisfies_lock_restrictions(wip, &Objects[target_objnum]) :
(!targeting_same || (MULTI_DOGFIGHT && (target_team == Iff_traitor)));
// Cyborg17 - exclude all invalid object numbers here since in multi, the lock slots can get out of sync.
@@ -8691,16 +8686,19 @@ int weapon_get_max_missile_seekers(weapon_info *wip)
}
// returns whether a homing weapon can home on a particular ship
bool weapon_can_lock_on_ship(weapon_info* wip, int ship_num)
bool weapon_target_satisfies_lock_restrictions(weapon_info* wip, object* target)
{
if (target->type != OBJ_SHIP)
return true;
auto& restrictions = wip->ship_restrict;
// if you didn't specify any restrictions, you can always lock
if (restrictions.empty()) return true;
int type_num = Ship_info[Ships[ship_num].ship_info_index].class_type;
int class_num = Ships[ship_num].ship_info_index;
int species_num = Ship_info[Ships[ship_num].ship_info_index].species;
int iff_num = Ships[ship_num].team;
int type_num = Ship_info[Ships[target->instance].ship_info_index].class_type;
int class_num = Ships[target->instance].ship_info_index;
int species_num = Ship_info[Ships[target->instance].ship_info_index].species;
int iff_num = Ships[target->instance].team;
// otherwise, you're good as long as it matches one of the allowances in the restriction list
return std::any_of(restrictions.begin(), restrictions.end(),
+4
View File
@@ -1044,6 +1044,10 @@ void briefing_editor_dlg::OnMakeIcon()
biconp->pos = pos;
biconp->flags = 0;
biconp->id = Cur_brief_id++;
biconp->modelnum = -1;
biconp->model_instance_num = -1;
if (ship >= 0) {
biconp->ship_class = Ships[ship].ship_info_index;
ship_info* sip = &Ship_info[Ships[ship].ship_info_index];
+13 -11
View File
@@ -1314,6 +1314,8 @@ void game_post_level_init()
freespace_mission_load_stuff();
mission_process_alt_types();
// m!m Make hv.Player available in "On Mission Start" hook
if(Player_obj)
Script_system.SetHookObject("Player", Player_obj);
@@ -1614,6 +1616,11 @@ void game_init()
outwnd_init();
}
// Cyborg17 -- This section used to be in game_main(), but in a section before outwnd_init()
if (Is_standalone){
nprintf(("Network", "Standalone running\n"));
}
// init os stuff next
os_init( Osreg_class_name, Window_title.c_str(), Osreg_app_name );
@@ -4355,16 +4362,16 @@ int game_poll()
{
if (!Cmdline_no_unfocus_pause)
{
if (!os_foreground()) {
// If we're in a single player game, pause it.
// Cyborg17 - Multiplayer *must not* have its time affected by being in the background.
// otherwise, ship interpolation will become inaccurate.
if (!os_foreground() && !(Game_mode & GM_MULTIPLAYER)) {
game_stop_time();
os_sleep(1);
game_start_time();
if ((gameseq_get_state() == GS_STATE_GAME_PLAY) && (!popup_active()) && (!popupdead_is_active())) {
game_process_pause_key();
// If we're in a single player game, pause it.
if (!(Game_mode & GM_MULTIPLAYER)){
if ((gameseq_get_state() == GS_STATE_GAME_PLAY) && (!popup_active()) && (!popupdead_is_active())) {
game_process_pause_key();
}
}
}
}
@@ -6463,11 +6470,6 @@ int game_main(int argc, char *argv[])
return 1;
}
if (Is_standalone){
nprintf(("Network", "Standalone running\n"));
}
game_init();
// if networking is unavailable then standalone is useless, so just fail
+5
View File
@@ -0,0 +1,5 @@
set(FSO_VERSION_MAJOR 21)
set(FSO_VERSION_MINOR 0)
set(FSO_VERSION_BUILD 0)
set(FSO_VERSION_REVISION 0)
set(FSO_VERSION_REVISION_STR )