Compare commits

...
Author SHA1 Message Date
JohnAFernandez db5a90c955 Ok, that wasn't it. Try reloading UTC time
And getting rid of the workflow dispatch
2024-05-27 14:56:04 -04:00
JohnAFernandez 95f26ef625 account for 0 index 2024-05-27 14:50:13 -04:00
JohnAFernandez bc7654392a POSIX cron syntax 2024-05-27 14:45:55 -04:00
JohnAFernandez 760b035a3a Try again 2024-05-27 14:43:30 -04:00
JohnAFernandez ce2fd88c24 Try this cron expression for testing 2024-05-27 14:40:32 -04:00
JohnAFernandez 3d6c02ffe2 Temporary workflow dispatch 2024-05-27 14:32:08 -04:00
JohnAFernandez 2aae150981 Hopefully Fix coverity scanning 2024-05-27 14:28:03 -04:00
Mike Nelson 620afa0c1e Cockpit fov option (#5924)
* add cockpit fov to in-game options and use a define for the default fov value for both fov options

* Add a controlling toggle option

* constexpr

* localization
2024-03-25 07:28:24 -04:00
Mike Nelson 7fdcd4abc7 Basic implementation of some audio options in-game (#5927)
* Basic implementation of some audio options in-game

* Unused param

* do localization
2024-03-24 21:46:02 -04:00
John Fernandez 18394f7074 Merge pull request #6061 from MjnMixael/fix_api_debrief
Don't init the debrief ui in API mode
2024-03-24 14:55:14 -04:00
mjn-mixael 8bde63a9ae Don't init the debrief ui in API mode 2024-03-23 14:42:22 -05:00
Goober5000 f021e9df8a Merge pull request #6060 from Goober5000/fix_std_move_crash
fix crash caused by using a moved variable
2024-03-23 13:09:14 -04:00
Goober5000 4a1d794a64 fix crash caused by using a moved variable
In #5894, in the `add_dynamic_sexp` function in sexp_lookup.cpp, a call to `sexp->getHelpText()` was moved to the bottom of the function.  Normally this would be fine, except that this occasion caused the `sexp` variable to be accessed after a `std::move`.  The crash can be avoided by moving the last access of the `sexp` variable just a little bit earlier.
2024-03-23 02:04:48 -04:00
Goober5000 fecb9b16af Merge pull request #6014 from Goober5000/sun_light_index_fixes
fix a few lighting bugs
2024-03-22 15:58:42 -04:00
John Fernandez 7e637d5d5a Merge pull request #5893 from JohnAFernandez/Fix-Coverity-Time-T-issues
Fix coverity time t issues
2024-03-22 12:16:29 -04:00
John Fernandez ff5bc2f6a0 Merge pull request #5894 from JohnAFernandez/Coverity-Reference-Issues
Coverity: Change many auto calls to const auto& to avoid unnecessary copies.
2024-03-22 12:09:34 -04:00
John Fernandez c08a669c2e Merge branch 'scp-fs2open:master' into Fix-Coverity-Time-T-issues 2024-03-22 11:51:27 -04:00
John Fernandez 03f6f09c93 Merge branch 'scp-fs2open:master' into Coverity-Reference-Issues 2024-03-22 11:50:46 -04:00
Mike Nelson 74c2a204c7 API to get the PXO urls (#6054)
* API to get the PXO urls

* whitespace
2024-03-22 08:30:33 -04:00
Goober5000 a9ad87ea08 Merge pull request #6023 from Goober5000/preload_weapon_create
add weapon preloader
2024-03-21 14:25:48 -04:00
Goober5000 0a86623e9e Merge pull request #6056 from Goober5000/fix_ai_path_update
update Fix_ai_path_order_bug for new waypoint options
2024-03-21 13:24:41 -04:00
Goober5000 2f957668e3 update Fix_ai_path_order_bug for new waypoint options
When waypoint start index and direction were added in #5698 / 42fc989 et seq., the `Fix_ai_path_order_bug` flag needed to be updated to account for those new options.  This fixes that.

Fixes #6052.
2024-03-21 00:13:05 -04:00
Goober5000 38d9a975ce Merge pull request #6055 from Goober5000/shipB_submodel
add ShipBSubmodel to ship collisions
2024-03-20 22:52:01 -04:00
Goober5000 f26643c43d add ShipBSubmodel to ship collisions
Since the On Ship Collision hook can potentially be called twice, with the ships reversed, it is necessary for both parameters to have submodels specified.  Otherwise +Override would not be able to handle both cases.

Followup to #6035.
2024-03-20 21:15:33 -04:00
Mike Nelson c2cb07ded3 Allow skipping using retail mainhall defaults (#6042) 2024-03-18 07:40:49 -04:00
Goober5000 7a04f76a46 Merge pull request #6049 from Goober5000/gr_string_size
add getStringHeight and getStringSize
2024-03-17 19:55:31 -04:00
Goober5000 006d2a49b1 Merge pull request #6050 from Goober5000/hud_high_contrast
add a HUD virtvar for contrast
2024-03-17 19:55:20 -04:00
Goober5000 a281f35f1a add a HUD virtvar for contrast
Adds a hu.HUDHighContrast virtvar.  Also renames `HUD_contrast` to `HUD_high_contrast` for clarity and makes it a boolean.
2024-03-17 16:18:02 -04:00
wookieejedi 88f7e41d8c Add AI Flag to align to target when guarding stationary ship (#6047)
* Add AI Flag to `align to target when guarding stationary ship`

When a ship is ordered to guard another ship that is stationary and not incredibly large, the AI will fly to a position then turn and face away from the targeted ship. This behavior is not ideal in various scenarios, including both blockade style formations and overall visuals.

The PR adds a flag that tells the AI to align to the target ship it is guarding once the AI has reached it's guarding position in this situation, which allows all the guarding ships to have the same orientation and look much better and work better for directional defenses.

Tested and works as expected. Also changed some `NULL` to `nullptr` in this function for cleanup.

* remove duplicate brackets
2024-03-17 08:16:55 -04:00
Goober5000 f2998a2c69 add getStringHeight and getStringSize
We already have `gr.getStringWidth()`, but these functions are useful too.
2024-03-16 21:15:40 -04:00
Mike Nelson 1b0a3ea6f9 Default framebuffer effects to off (#6046) 2024-03-16 21:14:22 -04:00
Mike Nelson 5e274a008c Add lua function to validate a string as a valid IP (#6043) 2024-03-16 21:14:00 -04:00
Mike Nelson 38be5c248c Convert multi team chat to use a struct/list setup (#5850)
* convert multi team chat to use a struct/list setup

* use the correct array size define

* cleanup local vars & Asserts

* address feedback

* remove uncessary if
2024-03-16 11:10:09 -04:00
Mike Nelson 0450ef0d1a Fix multi option virtvars so they can be read without being set (#6044) 2024-03-16 08:14:19 -04:00
Mike Nelson e6a2a2a7f9 Fix retail options not saving (#6020)
* Make sure retail options are saved properly when Using_in_game_options is true

* don't need this
2024-03-15 15:43:45 -04:00
Goober5000 bbb6a6f199 Merge pull request #6016 from Goober5000/sexp_help_tweak
fix help descriptions for string-greater-than and string-less-than
2024-03-15 13:22:21 -04:00
Goober5000 1c0b58e11b Merge pull request #6041 from Goober5000/support_ship_sexp_update
improve set-support-ship description
2024-03-15 13:19:40 -04:00
Goober5000 0bf0735cd9 Merge pull request #6034 from Baezon/scripted-model-arcs
Add scripted model 'lightning' arcs
2024-03-15 13:03:34 -04:00
Goober5000 cc3791b594 improve set-support-ship description
Per Durandal, a few attributes of this SEXP can be documented a little better.
2024-03-15 13:00:25 -04:00
John Fernandez 799906a921 Merge pull request #6040 from MjnMixael/default_postproc_on
Default post processing to on because so many things require it
2024-03-14 19:45:54 -04:00
mjn-mixael 043e3fab79 Default post processing to on because so many things require it 2024-03-14 17:23:58 -05:00
Mike Nelson 2e34c29215 Scpui multi pxo api (#5845)
* multi pxo api

(cherry picked from commit 9af26da728a19b9d6c890968a314e8e56ecc1ddf)

* multi pxo help api

(cherry picked from commit f4df704576ddb648e9c486907b07ae172c859feb)

* minor fixes

* not extern

* break out chat message data into a table

* address some feedback

* return empty strings if not in multi

* use GetChannelByUser() instead

* once more with feeling

* correct documentation
2024-03-13 15:23:44 -04:00
Goober5000 96228d6e98 Merge pull request #5937 from Goober5000/some_parse_upgrades
some parse upgrades
2024-03-13 12:04:56 -04:00
Asteroth dc4daafd61 fix for a merge mistake 2024-03-12 15:39:00 -04:00
Asteroth 4b37796628 Merge remote-tracking branch 'upstream/master' into scripted-model-arcs 2024-03-12 15:38:13 -04:00
Goober5000 45a434a60a some parse upgrades
Turn `Parse_names` into a vector and add SCP_string overloads of ship registry functions.  Refactor calling code to use registry as appropriate.  Remove an unused overload of `mission_parse_get_parse_object`.
2024-03-12 14:30:07 -04:00
Asteroth 488ec8d5a8 review tweaks 2024-03-12 13:50:38 -04:00
Goober5000 b1460eb3fa Merge pull request #6035 from Goober5000/submodel_collision
enhancements for submodel collisions
2024-03-12 13:42:41 -04:00
Goober5000 671fe21a75 additional collision info
* Add the submodel that was hit to the On Ship Collision scripting hook.  (This will only be non-nil if the ship was the "heavy object".)
* Add a `getModel()` function to the scripted submodel object.
* Fix some incorrect documentation in `OnShipCollision`.
2024-03-12 13:02:58 -04:00
Goober5000 d6606ad642 enhancements for submodel collisions
* Expose NoCollide and NoCollideThisOnly as virtual variables for submodels
* Allow submodels to be optionally specified in object:checkRayCollision
* Be sure to calculate ship-to-ship hit position before the override collision hook is called, in case the hook needs this value.  (The other collision hooks already calculate the hit position before the override hook.)
2024-03-12 13:02:57 -04:00
Taylor Richards d9b2b428a0 remove Docker setup for standalone servers (#6036) 2024-03-12 09:02:34 -04:00
Asteroth e87fcfaf28 add player orders afterburn hard flag (#6019) 2024-03-11 09:25:22 -04:00
Joshua Glatt 65d1b7f99a Handle container data correctly with eval_num() (#6031) 2024-03-10 21:33:58 -07:00
Joshua Glatt 712337a2da fix crash when right-clicking on container modifier (#6030) 2024-03-10 08:12:14 -07:00
Asteroth b9169cc425 add some real docs 2024-03-09 21:27:32 -05:00
Asteroth b7a0124a9b limit damge and emp arcs 2024-03-09 14:00:16 -05:00
Asteroth 27925607b8 add scripted model arcs 2024-03-09 12:46:34 -05:00
Mike Nelson 38d8f17990 Fix message api out of bounds check (#6013) 2024-03-09 11:35:09 -05:00
Mike Nelson 5143855863 Add opf custom string as a lua sexp return type (#5964)
* add opf custom string as a lua sexp return type

* maybe just return the table directly

* break statement
2024-03-08 14:03:43 -05:00
Mike Nelson 648a1d009d Lua method to get the number of object sounds that can be used in tandem with removeSoundByIndex() to effectively silence a ship (#5958) 2024-03-07 21:42:31 -05:00
Goober5000 df531fc595 Merge pull request #6006 from Goober5000/lua_invalid_returns_nil
allow invalid arguments to be nil
2024-03-07 21:32:13 -05:00
Taylor Richards 5802f718f6 clean up and update macOS bundle info (#6028)
- Set app name properly per Apple docs
 - Use correct "FreeSpace Open" name
 - Set version properly per Apple docs
 - Add bundle identifier
 - Update copyright date
 - Remove localized strings since they are all English already
2024-03-06 05:22:59 -05:00
Mike Nelson 7d62d741b9 expose parse skip_to_string (#5936) 2024-03-05 10:48:51 -05:00
Mike Nelson 45258aabb4 allow ba.xstr to lookup from strings.tbl (#5949) 2024-03-05 10:42:29 -05:00
Goober5000 db34b4d53c Merge pull request #5987 from Goober5000/misc_timestamps
make several miscellaneous timestamps type-safe
2024-03-05 00:05:04 -05:00
Mike Nelson 7c2077baf2 Code to check if a medal is rank or badge (#5934) 2024-03-04 07:46:19 -05:00
Mike Nelson eef7623e9f Push back instead of direct assignment (#6024)
* push back instead of direct assignment

* remove i
2024-03-04 18:08:00 +09:00
Goober5000 529ac05034 add a useful function 2024-03-03 11:47:28 -05:00
Goober5000 6ac8559630 Lafiel's template magic to treat all invalid objects as nil 2024-03-03 11:47:28 -05:00
Goober5000 2626e7862b allow invalid arguments to be nil
A design choice very early in FSO's scripting development established that invalid results return invalid objects.  By using a game_settings.tbl flag, this allows invalid results to return nil instead.
2024-03-03 11:47:28 -05:00
John Fernandez b3cd35258c Merge pull request #5849 from MjnMixael/listify_active_games
Make Active_games_head an SCP_list
2024-03-03 11:01:55 -05:00
Goober5000 0fb12b89eb Merge pull request #6012 from Goober5000/more_composition_h
scripting refactor to compose handle types
2024-03-03 10:58:39 -05:00
Mike Nelson c082babd9c Allow lua to lock/unlock cutscenes (#5928)
* allow lua to lock/unlock cutscenes

* fix issue from rebase
2024-03-03 10:48:06 -05:00
Goober5000 d5f3be091c add weapon preloader
`ship-create` has had a preloader for many years, but `weapon-create` and `beam-create` did not.  This remedies that.
2024-03-02 21:25:24 -05:00
wookieejedi 790227a2bf Fix CTD with HUD Preset Switching (#6022)
* Fix CTD with HUD Preset Switching

After #5302 it was discoved that pressing the `Next` button in the HUD presets would cause a CTD.

Thanks for Lafiel for figuring this out
`If HC_current_file is HC_preset_filenames.size() - 1, then it'll oob on a vector access.`

Testing this PR fixes that crash.

* use static cast
2024-03-02 18:20:02 +00:00
Goober5000 803f08f969 Merge pull request #5992 from MageKing17/cleanup/iff-modular-special-colors
Change special IFF color `#define`s into `extern int`s.
2024-03-02 11:36:17 -05:00
Goober5000 f2c40a2669 Merge pull request #5971 from JohnAFernandez/Fix-QT-FRED-Command-Briefing
Fix "missing" command brief data
2024-03-02 11:35:47 -05:00
Goober5000 63756c00af add extra ways to modify background elements in missions (#6005)
* add extra ways to modify background elements in missions

This adds Lua API methods for getting suns and bitaps by index, as well as modifying their scale and position.  This removes the need to completely add and remove a background element that only needs to be modified.

* big pruning of (int) casts
2024-03-02 11:24:58 -05:00
Goober5000 2147571dff make several miscellaneous timestamps type-safe
Trail timestamps and a few top-level timestamps.  Also a few `static` and `constexpr` keywords for good measure.
2024-03-02 00:10:31 -05:00
Goober5000 bb9c76103b Merge pull request #5997 from ferralverrall/user/joverral/subsystem_under_reticule
allow targeting subsystems on already targeted ship under reticule
2024-03-01 15:33:12 -05:00
Goober5000 857e61f638 Merge pull request #5956 from Goober5000/coverity_1
several coverity fixes
2024-03-01 15:33:05 -05:00
Goober5000 58053a02b2 several coverity fixes
Some false positive annotations, some range checks, and commenting dead code.
2024-03-01 13:47:00 -05:00
BMagnu e8ea8733d0 Animation Drivers for Cockpits (#5925)
* Add control_info driver sources

* Properly deal with cockpits and their 'objnum's

* Add driven animation sets to weapons and cockpits

* enumify objnums
2024-03-01 10:03:27 +01:00
Goober5000 184bbb52bb Merge pull request #5974 from Goober5000/coverity_casts
use C++ casts for floating.h and floating.cpp
2024-02-29 20:23:05 -05:00
Goober5000 b00410ab01 Merge pull request #5967 from Goober5000/bitstring_poofs
bitstring poofs
2024-02-29 01:22:50 -05:00
Goober5000 525d8e34d0 Merge pull request #5950 from Goober5000/has_time_elapsed_msecs
add a has-time-elapsed-msecs SEXP
2024-02-29 01:22:37 -05:00
Goober5000 4cdf10b399 Merge pull request #6018 from Goober5000/another_isValid_fix
another isValid fix
2024-02-28 14:10:27 -05:00
Goober5000 c652d5a84c another isValid fix
Another #6009 follow-up, this one from PR #5935.
2024-02-28 12:51:49 -05:00
Goober5000 1a356834b4 Merge pull request #5998 from Goober5000/allow_resetting_ship_type
allow a ship class's type to be set more than once
2024-02-28 12:40:46 -05:00
Goober5000 3f48f7c4ad Merge pull request #5944 from Goober5000/implement_5941
allow finer control of particle rotation randomization
2024-02-28 12:39:13 -05:00
Goober5000 3e8a9d9738 Merge pull request #5935 from Goober5000/ship_to_parsed_ship_api
connect ship and parsed ship in Lua API
2024-02-28 12:39:03 -05:00
Goober5000 592eefb60f scripting refactor to compose handle types
Several handle types in the scripting API used inheritance where composition would be more appropriate.  This refactors those types, as well as removing the various handle types that were just aliases for `model_h`.  These are just the C++-side types; all the Lua types remain as-is.

This also refactors `sound_h` to move the previous `isSoundValid` to `isValid` so that `ade_set_args` will work properly for sounds with the `Lua_API_returns_nil_instead_of_invalid_object` flag.  The subclassing from `sound_entry_h` was removed and the "full validity check" was moved to `isValidWithEntry`.  The Lua side remains unaffected, but additional documentation was added to clarify the usage.

Follow-up to #6009 and prerequisite to #6006 due to the `isValid` refactor for `sound_h`.
2024-02-28 02:51:08 -05:00
Goober5000 373218d7d9 fix help descriptions for string-greater-than and string-less-than 2024-02-28 02:50:41 -05:00
Goober5000 1bdd6c3c4c Merge pull request #6015 from Goober5000/reconcile_isValid
reconcile isValid between PRs
2024-02-28 02:45:59 -05:00
Goober5000 1313434e11 reconcile isValid between PRs
PRs #6009 and #5995 passed CI checking independently of each other, but compilation broke after merging.  This patches things.
2024-02-28 02:01:30 -05:00
Goober5000 bf996313dc Merge pull request #6009 from Goober5000/isValid_refactor
isValid refactor
2024-02-28 01:41:42 -05:00
Goober5000 2eb5a3ecde Merge pull request #5993 from MageKing17/bugfix/ssm-random-count-fix
Fix SSM strikes with a variable count.
2024-02-28 00:04:06 -05:00
Goober5000 1aee2401e5 fix a few lighting bugs
There was confusion in the lighting code between light indexes and sun indexes.  These are usually the same, but not always.  This makes several changes to fix light/sun handling.

1. Clarify the distinction between lights and suns and add a `sun_index` field
2. Add a flags field and assign the `dual_cone` boolean to it, as well as a new glare flag
3. Determine light glare by checking the light flag, not the sun (which never worked in the first place as the `stars_sun_has_glare` function checked bitmaps rather than suns)
2024-02-27 20:21:42 -05:00
Goober5000 f8203e9da3 Merge pull request #5995 from Goober5000/ship_arrival_functions
cover all stages of ship warping in the Lua API
2024-02-27 13:14:13 -05:00
Goober5000 b24bcbcc62 Merge pull request #5886 from Goober5000/is_in_mission_update
make is-in-mission work for wings
2024-02-27 13:13:52 -05:00
Goober5000 0b8c1b6853 Merge pull request #5933 from Goober5000/for_subsystem
add for-subsystems
2024-02-27 13:13:43 -05:00
Goober5000 6ae6c550a7 Merge pull request #6001 from Goober5000/parse_object_team
add Team virtvar to parse objects
2024-02-27 13:12:13 -05:00
Mike Nelson 9c521d04d8 Retail ingame options (#5895)
* Create the ingame options game state

* Base working version of in-game options

* Cleanup + Optimization

* Localization pass

* more cleanup + documentation

* tooltips on option hover

* documentation and better inbounds check

* match case

* format strings instead of direct strings

* unused parameter

* address feedback

* localization id conflict with master

* Add this line back in

* pass the new option flags as well

* resolve xstr id conflict
2024-02-27 13:09:34 -05:00
Goober5000 c6c9945e50 check objh specifically for validity 2024-02-27 12:19:04 -05:00
mjn-mixael 8dfeca4ac3 address feedback 2024-02-26 22:30:59 -06:00
mjn-mixael bb4898cb04 assertion error 2024-02-26 22:30:59 -06:00
mjn-mixael 6e38656658 Convert Active_games_head to an SCP_list to prepare for the SCPUI API 2024-02-26 22:30:59 -06:00
Goober5000 e72dd4c2ca Merge pull request #6007 from BMagnu/collision_4096_fix
Fix broken collision pair caching
2024-02-26 19:23:40 -05:00
Goober5000 be8725c6c6 change isSubsytemValid to isValid 2024-02-26 16:19:53 -05:00
Goober5000 15c921223b compose object_h within the structs/classes that use it 2024-02-26 16:19:53 -05:00
Goober5000 ec241fcab3 standardize on isValid() and make validity member functions const 2024-02-26 15:56:41 -05:00
Birk Magnussen 0e00ab670c Add comment on MAX_OBJECTS 2024-02-26 21:07:37 +01:00
Birk Magnussen 1f9a2ca4ce Increase collision pair cache bitshift 2024-02-26 20:53:46 +01:00
Goober5000 0d697672dc Merge pull request #5943 from Goober5000/fix_time_to_goal
fix time-to-goal edge cases
2024-02-26 12:56:05 -05:00
Goober5000 1fe62ea8d1 Merge pull request #5996 from Goober5000/fix_ship_name_in_use_bug
fix "this ship name is already in use" bug
2024-02-26 12:26:15 -05:00
Goober5000 687694c732 Merge pull request #5884 from Goober5000/str_wrap_followup
str_wrap_to_width followup
2024-02-26 12:19:45 -05:00
Goober5000 9093af9b95 Merge pull request #5881 from Goober5000/hud_gauge_filename
add method for determining whether the HUD is hi-res
2024-02-26 12:19:37 -05:00
Goober5000 3b0dca6cd9 Merge pull request #6003 from Goober5000/version_24_1
bump version to 24.1
2024-02-26 03:03:48 -05:00
Goober5000 817b7dc975 bump version to 24.1 2024-02-26 00:49:25 -05:00
Goober5000 d4d7c8dbd2 add Team virtvar to parse objects
Previously, Team was an attribute available on ships, but not parsed ships.
2024-02-22 23:08:59 -05:00
Goober5000 bb89553b0a allow a ship class's type to be set more than once
There was an extra check during ship class parsing that prevented a ship class's type from being set if it had been set already.  This dates back to commit 5f3a6ec7 and was added as a parsing safeguard rather than as part of any modular table checks.  Since the parsing has changed, this extra check is no longer applicable.  Removing the check allows a ship class with a different type to be created using an existing ship class as a template.
2024-02-21 22:05:34 -05:00
joverral e4acd15a1e fix the string too! 2024-02-21 16:48:53 -08:00
joverral d16f46fb1c name change per feedback 2024-02-21 16:42:30 -08:00
joverral 77ad3ba0aa Fixes per feedback 2024-02-21 10:25:52 -08:00
Goober5000 da31995331 fix "this ship name is already in use" bug
This rather insidious FRED bug was all down to an improper check for the current ship.  It is possible for multiple objects of different types to be selected at the same time.  If, for example, a waypoint and ship are selected, and the waypoint was selected first, the waypoint will be what `cur_object_index` refers to.  Since the ship is the one and only ship selected, it will be what `single_ship` refers to.  Therefore, to avoid flagging its own ship name as a duplicate, the loop should exclude the single ship, not the current object.

The bug can be reliably triggered by selecting a waypoint, then adding a ship to the selection, then switching the focus to another application and back to FRED.  This finally squashes the bug.
2024-02-21 02:00:06 -05:00
joverral 25d326567e allow targeting subsystems on already targeted ship under reticule 2024-02-20 18:07:13 -08:00
Goober5000 03696d07ca cover all stages of ship warping in the Lua API
This improves the ability of Lua to check for ship arrival status:

1. Deprecates the `isWarpingIn` function, which can be misleading, and replaces it with the equivalent `isWarpingStage1`
2. Adds an `isWarpingStage2` function to fill a gap in functionality
3. Adds an `isArrivingWarp` function (complementing the existing `isDepartingWarp` function) to cover both stage 1 and stage 2
2024-02-19 22:08:15 -05:00
MageKing17 0528538a6f Fix SSM strikes with a variable count.
In #2464, a somewhat hard-to-understand equation involving taking the modulo of a random number was replaced with a function that would do those calculations instead. The problem is that the function performed the *entire* formula, while the code it replaced was only operating on the *difference* between the two numbers. Fortunately, this is as easy to fix as changing a `+=` into just an `=`.
2024-02-19 01:02:11 -08:00
MageKing17 a7b795e965 Change special IFF color #defines into extern ints.
Before this commit, `IFF_COLOR_SELECTION`, `IFF_COLOR_MESSAGE`, and `IFF_COLOR_TAGGED` were hardcoded indices into the `Iff_colors` vector. This could cause problems if any of these three colors were set to the same RGB values (since `iff_init_color()` doesn't create a new entry if the color already exists in the vector), and if a modular table tried to change any of these colors nothing would happen (since it would just create a new entry in `Iff_colors` without doing anything to the hardcoded indices).

This commit instead changes the `#define`s into `extern int`s, and assigns the return value of `iff_init_color()` to those global variables upon parsing the special color values, meaning that any combination of the three can be set to the same color without causing issues, and modular tables can actually modify them.

Potential clutter from unused values in the `Iff_colors` vector is basically unchanged (technically slightly worse if a modular table overrides any of these special colors with a color that doesn't already exist in the vector), but should maybe be looked at in the future.
2024-02-13 13:51:09 -08:00
Goober5000 9b78fad1c5 address feedback 2024-02-07 15:29:13 -05:00
Goober5000 f4d7b45e4d bitstring poofs
Change `Neb2_poof_flags` to use a bit string of unlimited length to allow for an arbitrary number of nebula poofs.
2024-02-04 19:07:29 -05:00
Goober5000 d23e4b8e87 use C++ casts for floating.h and floating.cpp
Change the casts used in the convenience #defines in floating.h.  Since these #defines are used pretty widely, this should reduce the count of C-style casts in the codebase by quite a bit.

Also change the casts in floating.cpp while we're at it, and remove some obsolete or unused code.
2024-02-04 18:33:25 -05:00
John Fernandez d83de47ef2 Fix wave filename copy. 2024-02-03 15:33:53 -05:00
JohnAFernandez 59435abfb2 fix missing command brief data
This fixes command briefing data apparently disappearing.  The ui was not being properly initialized because model_changed was being called before the ui was initialized, leading to default values.

This also fixes a few other minor issues.
2024-02-03 00:55:19 -05:00
Goober5000 bf13ce54a8 add method for determining whether the HUD is hi-res
Check the filenames used to initialize HUD gauges and mark the gauge as hi-res if the filename starts with 2_.  Also add a script method to return this value.

Additionally, make accessor methods `const`.
2024-01-29 22:07:54 -05:00
Goober5000 fcd3264fad implement C-str version of str_wrap_to_width 2024-01-29 22:07:37 -05:00
Goober5000 e33419c48d refactor str_wrap_to_width to use string starting offsets and lengths 2024-01-29 22:07:37 -05:00
Goober5000 a73df5bcb4 int to size_t 2024-01-29 22:07:37 -05:00
Goober5000 4e707fc8e9 make is-in-mission work for wings
Since its creation, the `is-in-mission` sexp operator has only checked for ships.  But mission designers might assume this also works for wings, leading to a situation where the sexp always returns false because no ship can have the same name as a wing.  Fortunately wing functionality can be added to this sexp without affecting ship functionality.
2024-01-29 22:07:18 -05:00
Goober5000 2e7057ed8d add for-subsystems
This is a new argument provider that lists all the subsystems of a ship, optionally restricted to one or more subsystem types.
2024-01-29 22:06:31 -05:00
Goober5000 ba9285e09a connect ship and parsed ship in Lua API
Add `getShip()` to parsed ships and `getParsedShip()` to ships to allow the two APIs to connect to one another.
2024-01-29 22:06:15 -05:00
Goober5000 138eddfbd2 fix time-to-goal edge cases
This fixes a few items that were revealed in the course of Dark Visor's SEXP documentation PR.  The EXITED status should return NAN_FOREVER, not just NAN.  The CANT_EVAL value is never returned from the sexp on account of ship status, due to the preceding check, and is not an appropriate return value anyway; so that is removed.  Finally, for a ship that can't move, the NAN return value is better than CANT_EVAL, since it represents the numeric situation more accurately and can also be checked by `is-nan`.
2024-01-29 22:05:38 -05:00
Goober5000 66be185d0c allow finer control of particle rotation randomization
This adds a new field to particle effects so that particle rotation can be configured on a per-type basis, not just on a blanket basis.  Implements #5941.
2024-01-29 22:05:23 -05:00
Goober5000 0c355efaa2 add a has-time-elapsed-msecs SEXP
Also fix a small mistake in the SEXP help.  The `sexp_has_time_elapsed()` function has been moved to take advantage of the existing time functions.
2024-01-29 22:05:00 -05:00
John Fernandez 38cd1bff86 Restore accidental const removals 2023-12-21 16:33:31 -05:00
John Fernandez 71ee9501f9 Turns out coverity was optimistic 2023-12-20 21:05:36 -05:00
John Fernandez 221670589e Undo Overzealous changes 2023-12-20 20:30:40 -05:00
John Fernandez 9a47a664f7 Whoops, no std::move here 2023-12-20 19:54:13 -05:00
John Fernandez 7b7b19b71b Change many references to const auto&
A few uses of auto were also removed, where using a direct function call was superior.
2023-12-20 19:43:11 -05:00
John Fernandez 666b9a5751 Missed another conversion specifier 2023-12-20 16:21:35 -05:00
John Fernandez 8421d8d8e6 Adjust conversion specifiers 2023-12-20 16:14:55 -05:00
John Fernandez 63ed4c8254 Remove this time tracking
It is no longer used and has low resolution compared to the current method used elsewhere.
2023-12-20 16:06:49 -05:00
John Fernandez 3124c55642 Change various varibales to time_t
These variables were previously int's or uint's
2023-12-20 16:06:49 -05:00
277 changed files with 5424 additions and 2945 deletions

No files matched your search

-53
View File
@@ -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 }}
+10 -9
View File
@@ -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!
# 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: "5 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,19 +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: Checkout
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
@@ -46,8 +47,8 @@ jobs:
- name: Configure CMake for FSO
env:
CONFIGURATION: Release
compiler: gcc-9
CONFIGURATION: FastDebug
COMPILER: gcc-9
ENABLE_QTFRED: OFF
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
};
+4
View File
@@ -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))
{
+19 -12
View File
@@ -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);
}
@@ -10891,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);
@@ -10907,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) {
@@ -12610,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;
}
}
@@ -13898,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 ) {
@@ -13910,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;
@@ -13922,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
+3
View File
@@ -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
+1 -1
View File
@@ -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;
}
+4 -3
View File
@@ -2536,9 +2536,10 @@ void ai_turret_execute_behavior(const 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);
+56 -16
View File
@@ -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);
@@ -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);
}
+2
View File
@@ -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&);
+1 -1
View File
@@ -1900,7 +1900,7 @@ bool SetCmdlineParams()
if (val > 0.1) {
VIEWER_ZOOM_DEFAULT = val;
} else {
VIEWER_ZOOM_DEFAULT = 0.75f;
VIEWER_ZOOM_DEFAULT = DEFAULT_FOV;
}
}
+2 -2
View File
@@ -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
+4 -2
View File
@@ -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.
+2 -2
View File
@@ -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]) {
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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,
+4 -2
View File
@@ -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
+2
View File
@@ -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++
};
+2 -1
View File
@@ -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 {
+1 -1
View File
@@ -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{};
+1
View File
@@ -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)
+1 -1
View File
@@ -442,7 +442,7 @@ public:
class camera *getCamera();
size_t getIndex();
int getSignature();
bool isValid();
bool isValid() const;
};
#include "globalincs/vmallocator.h"
+12 -6
View File
@@ -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:
+3 -3
View File
@@ -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();
}
+15 -13
View File
@@ -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)
+1 -1
View File
@@ -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();
+2 -2
View File
@@ -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]));
+5 -5
View File
@@ -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--;
+1 -1
View File
@@ -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;
+6 -6
View File
@@ -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);
+2 -2
View File
@@ -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)
+3 -2
View File
@@ -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
+3 -3
View File
@@ -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();
+2 -2
View File
@@ -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);
}
+1 -1
View File
@@ -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();
+2 -2
View File
@@ -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)
{
+47 -38
View File
@@ -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
@@ -3310,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;
@@ -3350,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;
}
@@ -3861,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()
@@ -3985,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;
}
+24 -21
View File
@@ -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
@@ -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;
};
+1 -1
View File
@@ -328,7 +328,7 @@ void ssm_create(object *target, vec3d *start, size_t ssm_index, ssm_firing_info
count = Ssm_info[ssm_index].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);
count = Random::next(count, Ssm_info[ssm_index].max_count);
}
// override in multiplayer
+1 -3
View File
@@ -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
+4 -4
View File
@@ -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;
+1 -1
View File
@@ -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
+36
View File
@@ -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));
}
@@ -4692,6 +4721,7 @@ void load_gauge_lock(gauge_settings* settings)
}
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);
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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);
+14 -2
View File
@@ -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 {
+16 -10
View File
@@ -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)
+4 -3
View File
@@ -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
View File
@@ -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)
+3 -3
View File
@@ -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)
+4 -2
View File
@@ -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;
@@ -74,12 +75,13 @@ static SCP_string mouse_mode_display(bool mode) { return mode ? XSTR("Joy-0", 16
static auto UseMouseOption __UNUSED = options::OptionBuilder<bool>("Input.UseMouse",
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(
+1 -1
View File
@@ -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;
+10 -6
View File
@@ -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
View File
@@ -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;
+15 -5
View File
@@ -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);
+2 -2
View File
@@ -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 1817 // 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
View File
@@ -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
View File
@@ -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
View File
@@ -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();
+2 -2
View File
@@ -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
View File
@@ -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())
+3 -3
View File
@@ -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;
+19 -11
View File
@@ -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
@@ -2156,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)
@@ -2214,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);
}
+138 -1
View File
@@ -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();
}
+3
View File
@@ -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();
+8
View File
@@ -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);
}
+2 -2
View File
@@ -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
+2 -1
View File
@@ -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();
// --------------------------------------------------------------------------------------
+8 -8
View File
@@ -49,18 +49,18 @@ static int Key_sets[MAX_KEYED_TARGETS] = {
static int Hotkey_bits[MAX_SHIPS]; // bitfield indicating which hotkeys are used by each ship
static int Hotkey_sets_saved; // have we saved the sets for this mission
static bool Hotkey_sets_saved; // have we saved the sets for this mission
static int Mission_hotkey_save_timestamp; // timestamp used to tell us when we can save
#define HOTKEY_SAVE_TIME 15000 // save sets this number of milliseconds into the mission
static TIMESTAMP Mission_hotkey_save_timestamp; // timestamp used to tell us when we can save
constexpr int HOTKEY_SAVE_TIME = 15 * MILLISECONDS_PER_SECOND; // save sets this number of milliseconds into the mission
typedef struct {
int setnum;
char name[NAME_LENGTH];
} HK_save_info;
HK_save_info Hotkey_saved_info[MAX_HOTKEY_TARGET_ITEMS];
int Num_hotkeys_saved;
static HK_save_info Hotkey_saved_info[MAX_HOTKEY_TARGET_ITEMS];
static int Num_hotkeys_saved;
static const char *Hotkey_background_fname[GR_NUM_RESOLUTIONS] = {
@@ -317,8 +317,8 @@ void mission_hotkey_set_defaults(bool restore)
}
// set the variable letting us know that we should save the hotkey sets
Hotkey_sets_saved = 0;
Mission_hotkey_save_timestamp = timestamp(HOTKEY_SAVE_TIME);
Hotkey_sets_saved = false;
Mission_hotkey_save_timestamp = _timestamp(HOTKEY_SAVE_TIME);
// if we have hotkeys saved from the previous run of this mission, then simply keep the cleared
// sets, and let the restore code take care of it! This works because this function is currently
@@ -425,7 +425,7 @@ void mission_hotkey_maybe_save_sets()
}
}
Hotkey_sets_saved = 1;
Hotkey_sets_saved = true;
}
// function which gets called from MissionParse to maybe add a ship or wing to a hotkey set.
+2 -2
View File
@@ -110,7 +110,7 @@ int Num_messages_playing; // number of is a message currently playing?
pmessage Playing_messages[MAX_PLAYING_MESSAGES];
int Message_shipnum; // ship number of who is sending message to player -- used outside this module
int Message_expire; // timestamp to extend the duration of message brackets when not using voice files
static TIMESTAMP Message_expire; // timestamp to extend the duration of message brackets when not using voice files
// variables to control message queuing. All new messages to the player are queued. The array
// will be ordered by priority, then time submitted.
@@ -1708,7 +1708,7 @@ void message_queue_process()
// translate tokens in message to the real things
buf = message_translate_tokens(q->special_message ? q->special_message.get() : m->message);
Message_expire = timestamp(static_cast<int>(42 * buf.size()));
Message_expire = _timestamp(static_cast<int>(42 * buf.size()));
// play wave first, since need to know duration for picking anim start frame
if(message_play_wave(q) == false) {
+90 -95
View File
@@ -36,6 +36,7 @@
#include "lighting/lighting.h"
#include "lighting/lighting_profiles.h"
#include "localization/localize.h"
#include "math/bitarray.h"
#include "math/fvi.h"
#include "math/staticrand.h"
#include "mission/missionbriefcommon.h"
@@ -162,8 +163,7 @@ p_object *Player_start_pobject;
// name of all ships to use while parsing a mission (since a ship might be referenced by
// something before that ship has even been loaded yet)
char Parse_names[MAX_SHIPS + MAX_WINGS][NAME_LENGTH];
size_t Num_parse_names;
SCP_vector<SCP_string> Parse_names;
SCP_vector<texture_replace> Fred_texture_replacements;
@@ -486,6 +486,16 @@ const std::shared_ptr<scripting::Hook<scripting::hooks::ShipDepartConditions>> O
const std::shared_ptr<scripting::Hook<>> OnLoadoutAboutToParseHook = scripting::Hook<>::Factory("On Loadout About To Parse",
"Called during mission load just before parsing the team loadout.",{});
mission_custom_string* get_custom_string_by_name(SCP_string name) {
for (size_t i = 0; i < The_mission.custom_strings.size(); i++) {
if (The_mission.custom_strings[i].name == name) {
return &The_mission.custom_strings[i];
}
}
return nullptr;
}
// Goober5000
void parse_custom_bitmap(const char *expected_string_640, const char *expected_string_1024, char *string_field_640, char *string_field_1024)
{
@@ -2929,7 +2939,7 @@ int parse_object(mission *pm, int /*flag*/, p_object *p_objp)
required_string("$Name:");
stuff_string(p_objp->name, F_NAME, NAME_LENGTH);
if (mission_parse_get_parse_object(p_objp->name))
if (mission_parse_find_parse_object(p_objp->name))
error_display(0, NOX("Redundant ship name: %s\n"), p_objp->name);
// if this name has a hash, create a default display name
@@ -3714,7 +3724,7 @@ void parse_common_object_data(p_object *p_objp)
if (optional_string("+Cargo Name:")) {
char cargo_name[NAME_LENGTH];
stuff_string(cargo_name, F_NAME, NAME_LENGTH);
int index = string_lookup(cargo_name, Cargo_names, Num_cargo, "cargo", 0);
int index = string_lookup(cargo_name, Cargo_names, Num_cargo, "cargo", false);
if (index == -1) {
if (Num_cargo < MAX_CARGO) {
index = Num_cargo;
@@ -4044,21 +4054,8 @@ void swap_parse_object(p_object *p_obj, int new_ship_class)
}
}
p_object *mission_parse_get_parse_object(ushort net_signature)
{
SCP_vector<p_object>::iterator ii;
// look for original ships
for (ii = Parse_objects.begin(); ii != Parse_objects.end(); ++ii)
if (ii->net_signature == net_signature)
return &(*ii);
// boo
return NULL;
}
// Goober5000 - also get it by name
p_object *mission_parse_get_parse_object(const char *name)
// Goober5000 - this needs to search the vector instead of using the registry, because it can be used during parsing before the registry is populated
p_object *mission_parse_find_parse_object(const char *name)
{
SCP_vector<p_object>::iterator ii;
@@ -4128,21 +4125,17 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, bool force_create,
// if wing is coming from docking bay, then be sure that ship we are arriving from actually exists
// (or will exist).
if ( wingp->arrival_location == ARRIVE_FROM_DOCK_BAY ) {
int shipnum;
char *name;
Assert( wingp->arrival_anchor >= 0 );
name = Parse_names[wingp->arrival_anchor];
auto anchor_ship_entry = ship_registry_get(Parse_names[wingp->arrival_anchor]);
// see if ship is yet to arrive. If so, then return 0 so we can evaluate again later.
if (!anchor_ship_entry || anchor_ship_entry->status == ShipStatus::NOT_YET_PRESENT)
return 0;
// see if ship is in mission.
shipnum = ship_name_lookup( name );
if ( shipnum == -1 ) {
if (!anchor_ship_entry->has_shipp()) {
int num_remaining;
// see if ship is yet to arrive. If so, then return 0 so we can evaluate again later.
if (mission_check_ship_yet_to_arrive(name))
return 0;
// since this wing cannot arrive from this place, we need to mark the wing as destroyed and
// set the wing variables appropriately. Good for directives.
@@ -4155,21 +4148,24 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, bool force_create,
wingp->total_arrived_count += num_remaining;
wingp->current_wave = wingp->num_waves;
if ( mission_log_get_time(LOG_SHIP_DESTROYED, name, NULL, NULL) || mission_log_get_time(LOG_SELF_DESTRUCTED, name, NULL, NULL) ) {
if ( mission_log_get_time(LOG_SHIP_DESTROYED, anchor_ship_entry->name, nullptr, nullptr) || mission_log_get_time(LOG_SELF_DESTRUCTED, anchor_ship_entry->name, nullptr, nullptr) ) {
wingp->total_destroyed += num_remaining;
} else if ( mission_log_get_time(LOG_SHIP_DEPARTED, name, NULL, NULL) ) {
} else if ( mission_log_get_time(LOG_SHIP_DEPARTED, anchor_ship_entry->name, nullptr, nullptr) ) {
wingp->total_departed += num_remaining;
} else {
wingp->total_vanished += num_remaining;
}
mission_parse_mark_non_arrival(wingp); // Goober5000
WarningEx(LOCATION, "Warning: Wing %s cannot arrive from docking bay of destroyed or departed %s.\n", wingp->name, anchor_ship_entry->name);
return 0;
}
// Goober5000 - check status of fighterbays - if they're destroyed, we can't launch - but we want to reeval later
if (ship_fighterbays_all_destroyed(&Ships[shipnum]))
if (ship_fighterbays_all_destroyed(anchor_ship_entry->shipp())) {
WarningEx(LOCATION, "Warning: Wing %s cannot arrive from destroyed docking bay of %s.\n", wingp->name, anchor_ship_entry->name);
return 0;
}
}
if ( num_to_create == 0 )
@@ -4872,7 +4868,8 @@ void resolve_path_masks(int anchor, int *path_mask)
// get anchor ship
Assert(!(anchor & SPECIAL_ARRIVAL_ANCHOR_FLAG));
parent_pobjp = mission_parse_get_parse_object(Parse_names[anchor]);
auto parent_ship_entry = ship_registry_get(Parse_names[anchor]);
parent_pobjp = parent_ship_entry->p_objp();
// Load the anchor ship model with subsystems and all; it'll need to be done for this mission anyway
ship_info *sip = &Ship_info[parent_pobjp->ship_class];
@@ -4956,6 +4953,17 @@ void post_process_ships_wings()
}
}
// Goober5000 - add all the parse objects to the ship registry. This must be done before any other parse object processing.
for (auto &p_obj : Parse_objects)
{
ship_registry_entry entry(p_obj.name);
entry.status = ShipStatus::NOT_YET_PRESENT;
entry.pobj_num = POBJ_INDEX(&p_obj);
Ship_registry.push_back(entry);
Ship_registry_map[p_obj.name] = static_cast<int>(Ship_registry.size() - 1);
}
// Goober5000 - resolve the path masks. Needs to be done early because
// mission_parse_maybe_create_parse_object relies on it.
post_process_path_stuff();
@@ -4965,18 +4973,9 @@ void post_process_ships_wings()
// both ships and wings have been parsed.
mission_parse_set_up_initial_docks();
// Goober5000 - now add all the parse objects to the ship registry. This must be done before
// any ships are created from the parse objects.
// Might as well do any post-processing for parse objects here too.
// Goober5000 - Now do any post-processing for parse objects.
for (auto &p_obj : Parse_objects)
{
ship_registry_entry entry(p_obj.name);
entry.status = ShipStatus::NOT_YET_PRESENT;
entry.pobj_num = POBJ_INDEX(&p_obj);
Ship_registry.push_back(entry);
Ship_registry_map[p_obj.name] = static_cast<int>(Ship_registry.size() - 1);
// set a flag if this parse object is in a starting wing
if (p_obj.wingnum >= 0)
{
@@ -5494,7 +5493,7 @@ void parse_reinforcement(mission *pm)
}
// sanity check on the names of reinforcements
rforce_obj = mission_parse_get_parse_object(ptr->name);
rforce_obj = mission_parse_find_parse_object(ptr->name);
if (rforce_obj == NULL) {
if ((instance = wing_name_lookup(ptr->name, 1)) == -1) {
@@ -5664,7 +5663,7 @@ void parse_bitmaps(mission *pm)
// all poofs on by default
for (size_t i = 0; i < Poof_info.size(); i++)
Neb2_poof_flags += (1 << i);
set_bit(Neb2_poof_flags.get(), i);
bool nebula = false;
if (optional_string("+Neb2:")) {
nebula = true;
@@ -5682,7 +5681,9 @@ void parse_bitmaps(mission *pm)
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
@@ -6275,9 +6276,10 @@ bool post_process_mission(mission *pm)
post_process_ships_wings();
// the player_start_shipname had better exist at this point!
Player_start_shipnum = ship_name_lookup( Player_start_shipname );
auto player_start_entry = ship_registry_get(Player_start_shipname);
Player_start_shipnum = player_start_entry->shipnum;
Assert( Player_start_shipnum != -1 );
Player_start_pobject = mission_parse_get_parse_object( Player_start_shipname );
Player_start_pobject = player_start_entry->p_objp();
Assert( Player_start_pobject != NULL );
// Assign objnum, shipnum, etc. to the player structure
@@ -6327,10 +6329,13 @@ bool post_process_mission(mission *pm)
// convert all ship name indices to ship indices now that mission has been loaded
if (Fred_running) {
for (i=0; i<(int)Num_parse_names; i++) {
indices[i] = ship_name_lookup(Parse_names[i], 1);
i = 0;
for (const auto &parse_name: Parse_names) {
auto ship_entry = ship_registry_get(parse_name);
indices[i] = ship_entry ? ship_entry->shipnum : -1;
if (indices[i] < 0)
Warning(LOCATION, "Ship name \"%s\" referenced, but this ship doesn't exist", Parse_names[i]);
Warning(LOCATION, "Ship name \"%s\" referenced, but this ship doesn't exist", parse_name.c_str());
i++;
}
for (i=0; i<MAX_SHIPS; i++) {
@@ -6689,7 +6694,6 @@ void mission_init(mission *pm)
mission_parse_reset_callsign();
ai_lua_reset_general_orders();
Num_parse_names = 0;
Num_path_restrictions = 0;
Num_ai_dock_names = 0;
ai_clear_goal_target_names();
@@ -7094,18 +7098,17 @@ void mission_parse_set_up_initial_docks()
// build trees
for (i = 0; i < Total_initially_docked; i++)
{
char *docker_point, *dockee_point;
p_object *docker, *dockee;
// resolve the docker and dockee
docker = mission_parse_get_parse_object(Initially_docked[i].docker);
if (docker == NULL)
auto docker_entry = ship_registry_get(Initially_docked[i].docker);
auto docker = docker_entry ? docker_entry->p_objp_or_null() : nullptr;
if (docker == nullptr)
{
Warning(LOCATION, "Could not resolve initially docked object '%s'!", Initially_docked[i].docker);
continue;
}
dockee = mission_parse_get_parse_object(Initially_docked[i].dockee);
if (dockee == NULL)
auto dockee_entry = ship_registry_get(Initially_docked[i].dockee);
auto dockee = dockee_entry ? dockee_entry->p_objp_or_null() : nullptr;
if (dockee == nullptr)
{
Warning(LOCATION, "Could not resolve docking target '%s' of initially docked object '%s'!", Initially_docked[i].dockee, Initially_docked[i].docker);
continue;
@@ -7118,8 +7121,8 @@ void mission_parse_set_up_initial_docks()
continue;
// resolve the dockpoints
docker_point = Initially_docked[i].docker_point;
dockee_point = Initially_docked[i].dockee_point;
auto docker_point = Initially_docked[i].docker_point;
auto dockee_point = Initially_docked[i].dockee_point;
// docker point in use?
if (dock_find_object_at_dockpoint(docker, docker_point) != NULL)
@@ -7356,7 +7359,8 @@ int mission_set_arrival_location(int anchor, int location, int dist, int objnum,
// ship name lookup on the anchor
else
{
shipnum = ship_name_lookup(Parse_names[anchor]);
auto anchor_entry = ship_registry_get(Parse_names[anchor]);
shipnum = anchor_entry ? anchor_entry->shipnum : -1;
}
// if we didn't get an object from one of the above functions, then make the object
@@ -7539,27 +7543,23 @@ int mission_did_ship_arrive(p_object *objp, bool force_arrival)
// check to see if this ship is to arrive via a docking bay. If so, and the ship to arrive from
// doesn't exist, don't create.
if ( objp->arrival_location == ARRIVE_FROM_DOCK_BAY ) {
int shipnum;
char *name;
Assert( objp->arrival_anchor >= 0 );
name = Parse_names[objp->arrival_anchor];
// see if ship is in mission.
shipnum = ship_name_lookup( name );
if ( shipnum == -1 ) {
// see if ship is yet to arrive. If so, then return -1 so we can evaluate again later.
if (mission_check_ship_yet_to_arrive(name))
return -1;
auto anchor_ship_entry = ship_registry_get(Parse_names[objp->arrival_anchor]);
// see if ship is yet to arrive. If so, then return -1 so we can evaluate again later.
if (!anchor_ship_entry || anchor_ship_entry->status == ShipStatus::NOT_YET_PRESENT)
return -1;
// see if ship is in mission.
if (!anchor_ship_entry->has_shipp()) {
mission_parse_mark_non_arrival(objp); // Goober5000
WarningEx(LOCATION, "Warning: Ship %s cannot arrive from docking bay of destroyed or departed %s.\n", objp->name, name);
WarningEx(LOCATION, "Warning: Ship %s cannot arrive from docking bay of destroyed or departed %s.\n", objp->name, anchor_ship_entry->name);
return -1;
}
// Goober5000: aha - also don't create if fighterbay is destroyed
if (ship_fighterbays_all_destroyed(&Ships[shipnum])) {
WarningEx(LOCATION, "Warning: Ship %s cannot arrive from destroyed docking bay of %s.\n", objp->name, name);
// Goober5000 - check status of fighterbays - if they're destroyed, we can't launch - but we want to reeval later
if (ship_fighterbays_all_destroyed(anchor_ship_entry->shipp())) {
WarningEx(LOCATION, "Warning: Ship %s cannot arrive from destroyed docking bay of %s.\n", objp->name, anchor_ship_entry->name);
return -1;
}
}
@@ -7949,37 +7949,33 @@ int mission_do_departure(object *objp, bool goal_is_to_warp)
// just make it warp out like anything else.
if (location == DEPART_AT_DOCK_BAY)
{
int anchor_shipnum;
char *name;
Assert(anchor >= 0);
name = Parse_names[anchor];
auto anchor_ship_entry = ship_registry_get(Parse_names[anchor]);
// see if ship is yet to arrive. If so, then warp.
if (mission_check_ship_yet_to_arrive(name))
if (!anchor_ship_entry || anchor_ship_entry->status == ShipStatus::NOT_YET_PRESENT)
{
mprintf(("Anchor ship %s hasn't arrived yet! Trying to warp...\n", name));
mprintf(("Anchor ship %s hasn't arrived yet! Trying to warp...\n", Parse_names[anchor].c_str()));
goto try_to_warp;
}
// see if ship is in mission. If not, then we can assume it was destroyed or departed since
// it is not on the arrival list (as shown by above if statement).
anchor_shipnum = ship_name_lookup(name);
if (anchor_shipnum < 0)
if (!anchor_ship_entry->has_shipp())
{
mprintf(("Anchor ship %s not found! Trying to warp...\n", name));
mprintf(("Anchor ship %s not found! Trying to warp...\n", anchor_ship_entry->name));
goto try_to_warp;
}
// see if we can actually depart to the ship
if (!ship_useful_for_departure(anchor_shipnum, shipp->departure_path_mask))
if (!ship_useful_for_departure(anchor_ship_entry->shipnum, shipp->departure_path_mask))
{
mprintf(("Anchor ship %s not suitable for departure (dying, departing, bays destroyed, etc.). Trying to warp...\n", name));
mprintf(("Anchor ship %s not suitable for departure (dying, departing, bays destroyed, etc.). Trying to warp...\n", anchor_ship_entry->name));
goto try_to_warp;
}
// find a path
if (ai_acquire_depart_path(objp, Ships[anchor_shipnum].objnum, path_mask) >= 0)
if (ai_acquire_depart_path(objp, anchor_ship_entry->objnum, path_mask) >= 0)
{
MONITOR_INC(NumShipDepartures,1);
@@ -8236,16 +8232,15 @@ subsys_status *parse_get_subsys_status(p_object *pobjp, const char *subsys_name)
// find (or add) the name in the list and return an index to it.
int get_parse_name_index(const char *name)
{
int i;
int i, count = static_cast<int>(Parse_names.size());
for (i=0; i<(int)Num_parse_names; i++)
if (!stricmp(name, Parse_names[i]))
for (i=0; i<count; ++i)
if (!stricmp(name, Parse_names[i].c_str()))
return i;
Assert(i < MAX_SHIPS + MAX_WINGS);
Assert(strlen(name) < NAME_LENGTH);
strcpy_s(Parse_names[i], name);
return (int)Num_parse_names++;
Parse_names.push_back(name);
return i;
}
// Goober5000
+6 -5
View File
@@ -453,6 +453,8 @@ typedef struct team_data {
#define MAX_SHIP_LIST 16
extern team_data Team_data[MAX_TVT_TEAMS];
extern int Num_teams;
extern subsys_status *Subsys_status;
extern int Subsys_index;
@@ -461,9 +463,7 @@ extern matrix Parse_viewer_orient;
extern fix Mission_end_time;
extern char Parse_names[MAX_SHIPS + MAX_WINGS][NAME_LENGTH];
extern size_t Num_parse_names;
extern int Num_teams;
extern SCP_vector<SCP_string> Parse_names;
extern char Player_start_shipname[NAME_LENGTH];
extern int Player_start_shipnum;
@@ -483,8 +483,7 @@ bool parse_main(const char *mission_name, int flags = 0);
p_object *mission_parse_get_arrival_ship(ushort net_signature);
p_object *mission_parse_get_arrival_ship(const char *name);
bool mission_check_ship_yet_to_arrive(const char *name);
p_object *mission_parse_get_parse_object(ushort net_signature);
p_object *mission_parse_get_parse_object(const char *name);
p_object *mission_parse_find_parse_object(const char *name);
int parse_create_object(p_object *objp, bool standalone_ship = false);
void resolve_parse_flags(object *objp, flagset<Mission::Parse_Object_Flags> &parse_flags);
@@ -554,6 +553,8 @@ void clear_texture_replacements();
// Goober5000
subsys_status *parse_get_subsys_status(p_object *pobjp, const char *subsys_name);
// MjnMixael
mission_custom_string* get_custom_string_by_name(SCP_string name);
#endif
+2 -2
View File
@@ -187,7 +187,7 @@ void HudGaugeDirectives::initBitmaps(char *fname_top, char *fname_middle, char *
}
}
bool HudGaugeDirectives::canRender()
bool HudGaugeDirectives::canRender() const
{
if (sexp_override) {
return false;
@@ -1050,7 +1050,7 @@ HudGauge(HUD_OBJECT_TRAINING_MESSAGES, HUD_DIRECTIVES_VIEW, false, true, VM_EXTE
{
}
bool HudGaugeTrainingMessages::canRender()
bool HudGaugeTrainingMessages::canRender() const
{
if (hud_disabled() && !hud_disabled_except_messages()) {
return false;
+2 -2
View File
@@ -70,7 +70,7 @@ public:
void initKeyLineXOffset(int offset);
void render(float frametime) override;
void pageIn() override;
bool canRender() override;
bool canRender() const override;
};
class HudGaugeTrainingMessages: public HudGauge
@@ -80,7 +80,7 @@ public:
HudGaugeTrainingMessages();
void render(float frametime) override;
void pageIn() override;
bool canRender() override;
bool canRender() const override;
};
#endif /* __MISSIONTRAINING_H__ */
+98 -199
View File
@@ -230,8 +230,7 @@ int Chat_scroll_down_coord[2];
// what chars other than letters and number's we'll toss
#define CHATBOX_INVALID_CHARS NOX("~`") // this is primarily so that we don't interfere with the voice recording keys
// common defines and data
#define CHATBOX_STRING_LEN (CALLSIGN_LEN + CHATBOX_MAX_LEN + 32)
// common defines and
UI_WINDOW Chat_window;
UI_INPUTBOX Chat_inputbox;
UI_BUTTON Chat_enter_text;
@@ -275,17 +274,12 @@ int Chatbox_created = 0;
///////////////////////////////////////////////////////////
// Chat window text
///////////////////////////////////////////////////////////
#define MAX_BRIEF_CHAT_LINES 60 // how many lines we can store in the scrollback buffer
#define BRIEF_DISPLAY_SPACING 2 // pixel spacing between chat lines
// the first byte of the text string will be the net player id of the
char Brief_chat_lines[MAX_BRIEF_CHAT_LINES][CHATBOX_STRING_LEN];
int Brief_chat_indents[MAX_BRIEF_CHAT_LINES];
// the first byte of the text string will be the net player id of the
SCP_list<brief_chat> Brief_chat;
int Brief_chat_next_index[MAX_BRIEF_CHAT_LINES];
int Brief_chat_prev_index[MAX_BRIEF_CHAT_LINES];
int Num_brief_chat_lines;
int Brief_current_add_line;
// the index of the chat line we will start rendering at
int Brief_start_display_index;
// chatbox line recall data
@@ -304,7 +298,6 @@ void chatbox_set_mode(int mode_flags);
void chatbox_toggle_size();
void chatbox_toggle_size_adjust_lines();
void chat_autosplit_line(char *msg,char *remainder);
int chatbox_num_displayed_lines();
void chatbox_recall_add(char *string);
void chatbox_recall_up();
void chatbox_recall_down();
@@ -666,11 +659,9 @@ void chatbox_clear()
{
// only do this if we have valid data
if(Chatbox_created){
// clear all chat data
memset(Brief_chat_lines,0,(MAX_BRIEF_CHAT_LINES * (CHATBOX_MAX_LEN + 2)));
// clear all chat data
Brief_chat.clear();
Brief_start_display_index=0;
Num_brief_chat_lines=0;
Brief_current_add_line=0;
// clear all line recall data
Chatbox_recall_count = 0;
@@ -708,15 +699,11 @@ void chatbox_render()
// try and scroll the chatbox up. return 0 or 1 on fail or success
int chatbox_scroll_up()
{
if(Num_brief_chat_lines > Chatbox_max_lines){
int prev = Brief_chat_prev_index[Brief_start_display_index];
// check to make sure we won't be going "up" above the "beginning" of the text array
if(Brief_chat_prev_index[Brief_current_add_line] != prev && !(Num_brief_chat_lines < MAX_BRIEF_CHAT_LINES && Brief_start_display_index==0)){
Brief_start_display_index = prev;
if (static_cast<int>(Brief_chat.size()) > Chatbox_max_lines) {
if (Brief_start_display_index > 0) {
Brief_start_display_index--;
return 1;
}
}
}
return 0;
}
@@ -724,50 +711,18 @@ int chatbox_scroll_up()
// try and scroll the chatbox down, return 0 or 1 on fail or success
int chatbox_scroll_down()
{
int idx;
int next;
if(Num_brief_chat_lines > Chatbox_max_lines){
// yuck. There's got to be a better way to do this.
next = Brief_chat_next_index[Brief_start_display_index];
for(idx = 1;idx <= Chatbox_max_lines; idx++){
next = Brief_chat_next_index[next];
}
// check to make sure we won't be going "down" below the "bottom" of the text array
if(Brief_chat_next_index[Brief_current_add_line] != next){
Brief_start_display_index = Brief_chat_next_index[Brief_start_display_index];
if (static_cast<int>(Brief_chat.size()) > Chatbox_max_lines) {
if (Brief_start_display_index < (static_cast<int>(Brief_chat.size()) - Chatbox_max_lines)) {
Brief_start_display_index++;
return 1;
}
}
return 0;
}
// quick explanation as to how the scrolling works :
// Brief_chat_next_index is an array A of size n, where A[i] = i+1 and A[n] = 0
// Brief_chat_prev_index is an array A of size n, where A[i] = i-1 and A[0] = n
// in other words, if you increment an integer i = A[i], you get the next index (or the prev)
// with wrapping. In this way, as chat lines are entered, they are continuously wrapped
// around the Brief_chat_lines array so we can keep it at a fixed size. These arrays are used
// for both entering new chat strings as well as moving the Brief_start_display_index
// integer, which is self-explanatory
void chatbox_chat_init()
{
int idx;
chatbox_clear();
// setup the wraparound arrays
for(idx=0;idx<MAX_BRIEF_CHAT_LINES;idx++){
Brief_chat_next_index[idx] = idx+1;
}
Brief_chat_next_index[MAX_BRIEF_CHAT_LINES-1]=0;
for(idx=MAX_BRIEF_CHAT_LINES-1; idx > 0 ; idx--){
Brief_chat_prev_index[idx] = idx - 1;
}
Brief_chat_prev_index[0] = MAX_BRIEF_CHAT_LINES-1;
chatbox_clear();
// initialize the line recall data
Chatbox_recall_count = 0;
@@ -776,91 +731,63 @@ void chatbox_chat_init()
memset(Chatbox_recall_lines,0,CHATBOX_MAX_RECALL_LINES * (CHATBOX_MAX_LEN + 2));
}
void chat_box_add_chat_to_list(brief_chat& chat)
{
if (Brief_chat.size() >= MAX_BRIEF_CHAT_LINES) {
Brief_chat.erase(Brief_chat.begin());
}
Brief_chat.push_back(chat);
}
// int Test_color = 0;
void chatbox_add_line(const char *msg, int pid, int add_id)
{
int backup;
int n_lines,idx;
int n_chars[3];
const char *p_str[3]; // for the initial line (unindented)
char msg_extra[CHATBOX_STRING_LEN];
{
if(!Chatbox_created){
return;
}
brief_chat chat;
chat.indent = false;
chat.player_id = pid;
// maybe stick on who sent the message
if(add_id){
if(MULTI_STANDALONE(Net_players[pid])){
sprintf(msg_extra, NOX("%s %s"), NOX("<SERVER>"), msg );
strcpy_s(chat.callsign, "<SERVER>");
} else {
sprintf(msg_extra, NOX("%s: %s"), Net_players[pid].m_player->short_callsign, msg );
strcpy_s(chat.callsign, Net_players[pid].m_player->short_callsign);
}
} else {
strcpy_s(msg_extra,msg);
chat.callsign[0] = '\0';
}
Assert(strlen(msg_extra) < (CHATBOX_STRING_LEN - 2));
// split the text up into as many lines as necessary
n_lines = split_str(msg_extra, Chatbox_disp_w, n_chars, p_str, 3, CHATBOX_STRING_LEN);
Assert(n_lines != -1);
// setup the first line -- be sure to clear out the line
memset( Brief_chat_lines[Brief_current_add_line], 0, CHATBOX_STRING_LEN );
// add the player id #
Brief_chat_lines[Brief_current_add_line][0] = (char)(pid % 16);
// Brief_chat_lines[Brief_current_add_line][0] = (char)Test_color;
// Test_color = (Test_color == MAX_PLAYERS - 1) ? 0 : Test_color++;
// set the indent to 0
Brief_chat_indents[Brief_current_add_line] = 0;
int n_chars[3];
const char* p_str[3]; // for the initial line (unindented)
int n_lines = split_str(msg, Chatbox_disp_w, n_chars, p_str, 3, CHATBOX_STRING_LEN);
Assertion(n_lines != -1, "Chat split string returned an invalid number of lines, please report!");
// copy in the chars
strncpy(&Brief_chat_lines[Brief_current_add_line][1],p_str[0],CHATBOX_STRING_LEN - 1);
if(n_chars[0] >= CHATBOX_STRING_LEN){
Brief_chat_lines[Brief_current_add_line][CHATBOX_STRING_LEN - 1] = '\0';
} else {
Brief_chat_lines[Brief_current_add_line][n_chars[0] + 1] = '\0';
}
// increment the total line count if we haven't reached the max already
if(Num_brief_chat_lines<MAX_BRIEF_CHAT_LINES){
Num_brief_chat_lines++;
}
// get the index of the next string to add text to
Brief_current_add_line = Brief_chat_next_index[Brief_current_add_line];
strcpy_s(chat.text, p_str[0]);
chat_box_add_chat_to_list(chat);
// if we have more than 1 line, re-split everything so that the rest are indented
if(n_lines > 1){
// split up the string after the first break-marker
char msg_extra[CHATBOX_STRING_LEN];
n_lines = split_str(msg_extra + n_chars[0],Chatbox_disp_w - CHAT_LINE_INDENT,n_chars,p_str,3, CHATBOX_STRING_LEN);
Assert(n_lines != -1);
Assertion(n_lines != -1, "Chat split string returned an invalid number of lines, please report!");
// setup these remaining lines
for(idx=0;idx<n_lines;idx++){
// add the player id#
Brief_chat_lines[Brief_current_add_line][0] = (char)(pid % 16);
for(int idx=0;idx<n_lines;idx++){
brief_chat i_chat;
i_chat.player_id = pid;
i_chat.indent = true;
strcpy_s(i_chat.text, p_str[idx]);
// add the proper indent
Brief_chat_indents[Brief_current_add_line] = CHAT_LINE_INDENT;
// copy in the line text itself
strncpy(&Brief_chat_lines[Brief_current_add_line][1],p_str[idx],CHATBOX_STRING_LEN-1);
if(n_chars[idx] >= CHATBOX_STRING_LEN){
Brief_chat_lines[Brief_current_add_line][CHATBOX_STRING_LEN - 1] = '\0';
} else {
Brief_chat_lines[Brief_current_add_line][n_chars[idx] + 1] = '\0';
}
// increment the total line count if we haven't reached the max already
if(Num_brief_chat_lines<MAX_BRIEF_CHAT_LINES){
Num_brief_chat_lines++;
}
// get the index of the next line to add text to
Brief_current_add_line = Brief_chat_next_index[Brief_current_add_line];
chat_box_add_chat_to_list(i_chat);
}
}
@@ -873,11 +800,8 @@ void chatbox_add_line(const char *msg, int pid, int add_id)
// if this line of text is from the player himself, automatically go to the bottom of
// the chat list
if(pid == MY_NET_PLAYER_NUM){
if(Num_brief_chat_lines > Chatbox_max_lines){
Brief_start_display_index = Brief_current_add_line;
for(backup = 1;backup <= Chatbox_max_lines;backup++){
Brief_start_display_index = Brief_chat_prev_index[Brief_start_display_index];
}
if (static_cast<int>(Brief_chat.size()) > Chatbox_max_lines) {
Brief_start_display_index = (static_cast<int>(Brief_chat.size()) - Chatbox_max_lines);
}
}
// if we have enough lines of text to require scrolling, scroll down by one.
@@ -888,54 +812,69 @@ void chatbox_add_line(const char *msg, int pid, int add_id)
void chatbox_render_chat_lines()
{
int started_at,player_num,count,ly,line_height;
started_at = Brief_start_display_index;
count = 0;
ly = Chatbox_begin_y;
line_height = gr_get_font_height() + 1;
while((count < Chatbox_max_lines) && (count < Num_brief_chat_lines)){
// determine what player this chat line came from, and set the appropriate text color
player_num = Brief_chat_lines[started_at][0];
// print the line out
gr_set_color_fast(Color_netplayer[player_num]);
int count = 0;
int ly = Chatbox_begin_y;
int line_height = gr_get_font_height() + 1;
// draw the first line (no indent)
gr_string(Chatbox_begin_x + Brief_chat_indents[started_at],ly,&Brief_chat_lines[started_at][1],GR_RESIZE_MENU);
if (Brief_chat.empty()) {
return;
}
Assertion(Brief_start_display_index >= 0 && Brief_start_display_index < static_cast<int>(Brief_chat.size()),
"Chat display index is invalid, please report!");
auto chat = Brief_chat.begin();
std::advance(chat, Brief_start_display_index);
while (chat != Brief_chat.end() && count < Chatbox_max_lines) {
char msg[CHATBOX_STRING_LEN];
// add the player callsign
sprintf(msg, "%s %s", chat->callsign, chat->text);
Assertion(strlen(msg) < (CHATBOX_STRING_LEN - 2), "Chat string is too long, please report!");
// print the line out
gr_set_color_fast(Color_netplayer[chat->player_id]);
// draw the first line (no indent)
int indent = 0;
if (chat->indent) {
indent = CHAT_LINE_INDENT;
}
gr_string(Chatbox_begin_x + indent, ly, msg, GR_RESIZE_MENU);
// if we're in a team vs. team game, blit the player color icon
if(Netgame.type_flags & NG_TYPE_TEAM){
switch(Net_players[player_num].p_info.team){
case 0 :
if (Netgame.type_flags & NG_TYPE_TEAM) {
switch (Net_players[chat->player_id].p_info.team) {
case 0:
// if he's a team captain
if(Net_players[player_num].flags & NETINFO_FLAG_TEAM_CAPTAIN){
if(Multi_common_icons[MICON_TEAM0_SELECT] != -1){
if (Net_players[chat->player_id].flags & NETINFO_FLAG_TEAM_CAPTAIN) {
if (Multi_common_icons[MICON_TEAM0_SELECT] != -1) {
gr_set_bitmap(Multi_common_icons[MICON_TEAM0_SELECT]);
gr_bitmap(Chatbox_icon_x,ly-2,GR_RESIZE_MENU);
}
gr_bitmap(Chatbox_icon_x, ly - 2, GR_RESIZE_MENU);
}
}
// just you're average peon
else {
if(Multi_common_icons[MICON_TEAM0] != -1){
if (Multi_common_icons[MICON_TEAM0] != -1) {
gr_set_bitmap(Multi_common_icons[MICON_TEAM0]);
gr_bitmap(Chatbox_icon_x,ly-2,GR_RESIZE_MENU);
gr_bitmap(Chatbox_icon_x, ly - 2, GR_RESIZE_MENU);
}
}
break;
case 1 :
case 1:
// if he's a team captain
if(Net_players[player_num].flags & NETINFO_FLAG_TEAM_CAPTAIN){
if(Multi_common_icons[MICON_TEAM1_SELECT] != -1){
if (Net_players[chat->player_id].flags & NETINFO_FLAG_TEAM_CAPTAIN) {
if (Multi_common_icons[MICON_TEAM1_SELECT] != -1) {
gr_set_bitmap(Multi_common_icons[MICON_TEAM1_SELECT]);
gr_bitmap(Chatbox_icon_x,ly-2,GR_RESIZE_MENU);
gr_bitmap(Chatbox_icon_x, ly - 2, GR_RESIZE_MENU);
}
}
// just your average peon
else {
if(Multi_common_icons[MICON_TEAM1] != -1){
if (Multi_common_icons[MICON_TEAM1] != -1) {
gr_set_bitmap(Multi_common_icons[MICON_TEAM1]);
gr_bitmap(Chatbox_icon_x,ly-2,GR_RESIZE_MENU);
gr_bitmap(Chatbox_icon_x, ly - 2, GR_RESIZE_MENU);
}
}
break;
@@ -943,11 +882,9 @@ void chatbox_render_chat_lines()
}
// increment the count and line position
count++;
count++;
++chat;
ly += line_height;
// increment the started at index
started_at = Brief_chat_next_index[started_at];
}
}
@@ -971,52 +908,14 @@ void chatbox_toggle_size()
void chatbox_toggle_size_adjust_lines()
{
int count_diff;
// if the chatbox is now big, move the starting display index _up_ as far as possible
if(Chatbox_mode_flags & CHATBOX_FLAG_BIG){
// if we've wrapped around or we have more chatlines then we can display, move back as far as we can
if((Num_brief_chat_lines > MAX_BRIEF_CHAT_LINES) || (Num_brief_chat_lines > Chatbox_max_lines)){
count_diff = Chatbox_max_lines - chatbox_num_displayed_lines();
while(count_diff > 0){
Brief_start_display_index = Brief_chat_prev_index[Brief_start_display_index];
count_diff--;
}
}
// otherwise start displaying from position 0
else {
Brief_start_display_index = 0;
}
if ((static_cast<int>(Brief_chat.size()) > Chatbox_max_lines)) {
Brief_start_display_index = (static_cast<int>(Brief_chat.size()) - Chatbox_max_lines);
}
// if the chatbox is now small, move the starting display index down as far as we need
else if(Chatbox_mode_flags & CHATBOX_FLAG_SMALL){
count_diff = chatbox_num_displayed_lines();
// if we were displaying more lines than we can now
if(count_diff > Chatbox_max_lines){
count_diff -= Chatbox_max_lines;
while(count_diff > 0){
Brief_start_display_index = Brief_chat_next_index[Brief_start_display_index];
count_diff--;
}
}
else {
Brief_start_display_index = 0;
}
}
int chatbox_num_displayed_lines()
{
int idx = Brief_start_display_index;
int count;
// count the lines up
count = 0;
while(idx != Brief_current_add_line){
idx = Brief_chat_next_index[idx];
count++;
}
return count;
}
// force the chatbox to go into small mode (if its in large mode) - will not wotk if in multi paused chatbox mode
void chatbox_force_small()
{
+13
View File
@@ -12,10 +12,14 @@
#ifndef __FREESPACE_CHATBOX_H__
#define __FREESPACE_CHATBOX_H__
#include "globalincs/globals.h"
// prototype
struct net_player;
#define CHATBOX_MAX_LEN 125 // max length of the actual text string
#define CHATBOX_STRING_LEN (CALLSIGN_LEN + CHATBOX_MAX_LEN + 32)
#define MAX_BRIEF_CHAT_LINES 60 // how many lines we can store in the scrollback buffer
// chatbox flags for creation/switching between modes
#define CHATBOX_FLAG_SMALL (1<<0) // small chatbox
@@ -25,6 +29,15 @@ struct net_player;
#define CHATBOX_FLAG_BUTTONS (1<<4) // the chatbox should be drawing/checking its own buttons
// NOTE : CHATBOX_FLAG_BUTTONS requires that CHATBOX_FLAG_DRAW_BOX is also set!
typedef struct brief_chat {
int player_id; // the net player id
bool indent; // true if the line should be indented
char text[CHATBOX_MAX_LEN]; // the text of the message
char callsign[CALLSIGN_LEN]; // the player's callsign
} brief_chat;
extern SCP_list<brief_chat> Brief_chat;
// initialize all chatbox details with the given mode flags
int chatbox_create(int mode_flags = (CHATBOX_FLAG_SMALL | CHATBOX_FLAG_DRAW_BOX | CHATBOX_FLAG_BUTTONS));
+1 -1
View File
@@ -1396,7 +1396,7 @@ int brief_setup_closeup(brief_icon *bi, bool api_access)
Closeup_icon->modelnum = model_load(pof_filename, 0, nullptr);
} else {
Closeup_icon->modelnum = model_load(sip, true);
Closeup_icon->model_instance_num = model_create_instance(-1, Closeup_icon->modelnum);
Closeup_icon->model_instance_num = model_create_instance(model_objnum_special::OBJNUM_NONE, Closeup_icon->modelnum);
model_set_up_techroom_instance(sip, Closeup_icon->model_instance_num);
}
}
+3 -1
View File
@@ -1963,7 +1963,9 @@ void debrief_init(bool API_Access)
// be backed out if used chooses to replace them.
scoring_level_close();
debrief_ui_init(); // init UI items
if (!API_Access) {
debrief_ui_init(); // init UI items
}
debrief_award_init();
show_stats_init();
debrief_voice_init();
+3 -3
View File
@@ -1960,13 +1960,13 @@ void common_setup_room_lights()
light_reset();
auto tempv = vm_vec_new(-1.0f,0.3f,-1.0f);
auto tempc = hdr_color(1.0f,0.95f,0.9f, 0.0f, 1.5f);
light_add_directional(&tempv,&tempc);
light_add_directional(&tempv,-1,false,&tempc);
tempv.xyz={-0.4f,0.4f,1.1f};
tempc = hdr_color(0.788f,0.886f,1.0f,0.0f,1.5f);
light_add_directional(&tempv,&tempc);
light_add_directional(&tempv,-1,false,&tempc);
tempv.xyz={0.4f,0.1f,0.4f};
tempc = hdr_color(1.0f,1.0f,1.0f,0.0f,0.4f);
light_add_directional(&tempv,&tempc);
light_add_directional(&tempv,-1,false,&tempc);
gr_set_ambient_light(53, 53, 53);
light_rotate_all();
}
+9 -8
View File
@@ -2352,12 +2352,12 @@ void wl_render_weapon_desc(float frametime)
if (!Weapon_desc_wipe_done) {
// draw mid-wipe version
// decide which char is last (and bright)
int bright_char_index = (int)(Weapon_desc_wipe_time_elapsed * WEAPON_DESC_MAX_LENGTH / WEAPON_DESC_WIPE_TIME);
int i, w, h, curr_len;
size_t bright_char_index = (size_t)(Weapon_desc_wipe_time_elapsed * WEAPON_DESC_MAX_LENGTH / WEAPON_DESC_WIPE_TIME);
int i, w, h;
// draw weapon title (above weapon anim)
for (i=0; i<2; i++) {
curr_len = (int)strlen(Weapon_desc_lines[i]);
size_t curr_len = strlen(Weapon_desc_lines[i]);
if (bright_char_index < curr_len) {
// save bright char and plunk in some nulls to shorten string
@@ -2385,7 +2385,7 @@ void wl_render_weapon_desc(float frametime)
// draw weapon desc (below weapon anim)
for (i=2; i<WEAPON_DESC_MAX_LINES; i++) {
curr_len = (int)strlen(Weapon_desc_lines[i]);
size_t curr_len = strlen(Weapon_desc_lines[i]);
if (bright_char_index < curr_len) {
// save bright char and plunk in some nulls to shorten string
@@ -2439,9 +2439,10 @@ void wl_render_weapon_desc(float frametime)
*/
void wl_weapon_desc_start_wipe()
{
int currchar_src = 0, currline_dest = 2, currchar_dest = 0, i;
size_t currchar_src = 0;
int currline_dest = 2, currchar_dest = 0, i;
int w, h;
int title_len = (int)strlen(Weapon_info[Selected_wl_class].title);
size_t title_len = strlen(Weapon_info[Selected_wl_class].title);
// init wipe vars
Weapon_desc_wipe_time_elapsed = 0.0f;
@@ -2452,7 +2453,7 @@ void wl_weapon_desc_start_wipe()
gr_get_string_size(&w, &h, Weapon_info[Selected_wl_class].title, title_len);
if (w > Weapon_title_max_width[gr_screen.res]) {
// split
currchar_src = (int)(((float)title_len / (float)w) * Weapon_title_max_width[gr_screen.res]); // char to start space search at
currchar_src = (size_t)(((float)title_len / (float)w) * Weapon_title_max_width[gr_screen.res]); // char to start space search at
while (Weapon_desc_lines[0][currchar_src] != ' ') {
currchar_src--;
if (currchar_src <= 0) {
@@ -2960,7 +2961,7 @@ void wl_render_icon_count(int num, int x, int y)
Assert(number_to_draw >= 0);
sprintf(buf, "%d", number_to_draw);
gr_get_string_size(&num_w, &num_h, buf, (int)strlen(buf));
gr_get_string_size(&num_w, &num_h, buf, strlen(buf));
// render
gr_set_color_fast(&Color_white);
+15 -2
View File
@@ -48,6 +48,7 @@ bool Enable_external_default_scripts;
int Default_detail_level;
bool Full_color_head_anis;
bool Dont_automatically_select_turret_when_targeting_ship;
bool Automatically_select_subsystem_under_reticle_when_targeting_same_ship;
bool Always_reset_selected_wep_on_loadout_open;
bool Weapons_inherit_parent_collision_group;
bool Flight_controls_follow_eyepoint_orientation;
@@ -149,11 +150,12 @@ bool Randomize_particle_rotation;
bool Calculate_subsystem_hitpoints_after_parsing;
bool Disable_internal_loadout_restoration_system;
bool Contrails_use_absolute_speed;
bool Lua_API_returns_nil_instead_of_invalid_object;
static auto DiscordOption __UNUSED = options::OptionBuilder<bool>("Game.Discord",
std::pair<const char*, int>{"Discord Presence", 1754},
std::pair<const char*, int>{"Toggle Discord Rich Presence", 1755})
.category("Game")
.category(std::make_pair("Game", 1824))
.default_val(Discord_presence)
.level(options::ExpertLevel::Advanced)
.importance(55)
@@ -296,6 +298,11 @@ void parse_mod_table(const char *filename)
stuff_boolean(&Disable_internal_loadout_restoration_system);
}
if (optional_string("$Lua API returns nil instead of invalid object:")) {
stuff_boolean(&Lua_API_returns_nil_instead_of_invalid_object);
mprintf(("Game Settings Table: Lua API returns nil instead of invalid object: %s\n", Lua_API_returns_nil_instead_of_invalid_object ? "yes" : "no"));
}
optional_string("#LOCALIZATION SETTINGS");
if (optional_string("$Use tabled strings for the default language:")) {
@@ -418,6 +425,10 @@ void parse_mod_table(const char *filename)
stuff_boolean(&Dont_automatically_select_turret_when_targeting_ship);
}
if (optional_string("$Auto select subsystem under reticle when targeting same ship:")) {
stuff_boolean(&Automatically_select_subsystem_under_reticle_when_targeting_same_ship);
}
if (optional_string("$Supernova hits at zero:")) {
stuff_boolean(&Supernova_hits_at_zero);
if (Supernova_hits_at_zero) {
@@ -1443,6 +1454,7 @@ void mod_table_reset()
Default_detail_level = 3; // "very high" seems a reasonable default in 2012 -zookeeper
Full_color_head_anis = false;
Dont_automatically_select_turret_when_targeting_ship = false;
Automatically_select_subsystem_under_reticle_when_targeting_same_ship = false;
Always_reset_selected_wep_on_loadout_open = false;
Weapons_inherit_parent_collision_group = false;
Flight_controls_follow_eyepoint_orientation = false;
@@ -1474,7 +1486,7 @@ void mod_table_reset()
Window_icon_path = "app_icon_sse";
Disable_built_in_translations = false;
Weapon_shockwaves_respect_huge = false;
Using_in_game_options = false;
Using_in_game_options = true;
Dinky_shockwave_default_multiplier = 1.0f;
Shockwaves_always_damage_bombs = false;
Shockwaves_damage_all_obj_types_once = false;
@@ -1551,6 +1563,7 @@ void mod_table_reset()
Calculate_subsystem_hitpoints_after_parsing = false;
Disable_internal_loadout_restoration_system = false;
Contrails_use_absolute_speed = false;
Lua_API_returns_nil_instead_of_invalid_object = false;
}
void mod_table_set_version_flags()
+2
View File
@@ -56,6 +56,7 @@ extern bool Enable_external_default_scripts;
extern int Default_detail_level;
extern bool Full_color_head_anis;
extern bool Dont_automatically_select_turret_when_targeting_ship;
extern bool Automatically_select_subsystem_under_reticle_when_targeting_same_ship;
extern bool Always_reset_selected_wep_on_loadout_open;
extern bool Weapons_inherit_parent_collision_group;
extern bool Flight_controls_follow_eyepoint_orientation;
@@ -158,6 +159,7 @@ extern bool Randomize_particle_rotation;
extern bool Calculate_subsystem_hitpoints_after_parsing;
extern bool Disable_internal_loadout_restoration_system;
extern bool Contrails_use_absolute_speed;
extern bool Lua_API_returns_nil_instead_of_invalid_object;
void mod_table_init();
void mod_table_post_process();
+11 -5
View File
@@ -262,7 +262,7 @@ namespace animation {
//We are in multiplayer. Send animation to server to start. Server starts animation online, and sends start request back (which'll have multiOverride == true).
//If we _are_ the server, also just start the animation
object* objp = pmi->objnum > -1 ? &Objects[pmi->objnum] : nullptr;
object* objp = pmi->objnum >= 0 ? &Objects[pmi->objnum] : nullptr;
if(objp != nullptr)
send_animation_triggered_packet(id, objp, 0, direction, force, instant, pause);
@@ -1446,9 +1446,8 @@ namespace animation {
ModelAnimationParseHelper::parseAnimsetInfo(set, 's', sip->name);
}
void ModelAnimationParseHelper::parseAnimsetInfoDrivers(ModelAnimationSet& set, ship_info* sip) {
void ModelAnimationParseHelper::parseAnimsetInfoDrivers(ModelAnimationSet& set, char uniquePrefix, const SCP_string& parentName, std::function<std::function<float(polymodel_instance *)>()> driverSourceParser) {
set.m_animationSet.clear();
set.changeShipName(sip->name);
while(optional_string("+Driver Set:")) {
decltype(ModelAnimation::m_driver) driver;
@@ -1457,7 +1456,7 @@ namespace animation {
if (optional_string("+Time Remap:")) {
required_string("+Source:");
std::function<float(polymodel_instance *)> remap_driver_source = parse_ship_property_driver_source();
std::function<float(polymodel_instance *)> remap_driver_source = driverSourceParser();
if (!remap_driver_source) {
error_display(0, "Unknown driver specifier encountered! Driver will be disabled!");
continue;
@@ -1550,7 +1549,7 @@ namespace animation {
auto animIt = s_animationsById.find(request);
if (animIt != s_animationsById.end()) {
const ParsedModelAnimation& foundAnim = animIt->second;
auto anim = set.emplace(foundAnim.anim, request, foundAnim.name, foundAnim.type, foundAnim.subtype, ModelAnimationParseHelper::getUniqueAnimationID(animIt->first, 's', sip->name));
auto anim = set.emplace(foundAnim.anim, request, foundAnim.name, foundAnim.type, foundAnim.subtype, ModelAnimationParseHelper::getUniqueAnimationID(animIt->first, uniquePrefix, parentName));
if (driver)
anim->m_driver = driver;
@@ -1564,6 +1563,13 @@ namespace animation {
}
}
void ModelAnimationParseHelper::parseAnimsetInfoDrivers(ModelAnimationSet& set, ship_info* sip) {
set.m_animationSet.clear();
set.changeShipName(sip->name);
parseAnimsetInfoDrivers(set, 's', sip->name, parse_ship_property_driver_source);
}
void ModelAnimationParseHelper::parseMoveablesetInfo(ModelAnimationSet& set) {
SCP_vector<SCP_string> requestedAnimations;
stuff_string_list(requestedAnimations);
+2
View File
@@ -416,6 +416,8 @@ namespace animation {
static void parseAnimsetInfo(ModelAnimationSet& set, ship_info* sip);
static void parseAnimsetInfo(ModelAnimationSet& set, char uniqueTypePrefix, const SCP_string& uniqueParentName);
static void parseAnimsetInfoDrivers(ModelAnimationSet& set, ship_info* sip);
static void parseAnimsetInfoDrivers(ModelAnimationSet& set, char uniquePrefix, const SCP_string& parentName, std::function<std::function<float(polymodel_instance *)>()> driverSourceParser);
static void parseMoveablesetInfo(ModelAnimationSet& set);
//Parses the legacy animation table in ships.tbl of a single subsystem. Currently initial animations only
static void parseLegacyAnimationTable(model_subsystem* sp, ship_info* sip);
+44 -12
View File
@@ -2,12 +2,24 @@
#include "hud/hudets.h"
#include "model/animation/modelanimation.h"
#include "playerman/player.h"
#include "ship/ship.h"
namespace animation {
template<float control_info::* ci_property>
static float get_player_ci_property(polymodel_instance* /*pmi*/){
return Player->ci.*ci_property;
}
std::function<float(polymodel_instance*)> parse_generic_property_driver_source() {
switch(optional_string_one_of(1,
"Random"
switch(optional_string_one_of(7,
"Random",
"ControlAccelForward",
"ControlAccelLateral",
"ControlAccelVertical",
"ControlRotationPitch",
"ControlRotationBank",
"ControlRotationHeading"
)){
case 0: {
float min, max;
@@ -22,22 +34,40 @@ namespace animation {
return static_cast<float>(std::mt19937(seed ^ pmi->objnum)()) / static_cast<float>(std::mt19937::max()) * (max - min) + min;
};
}
case 1:
return get_player_ci_property<&control_info::forward>;
case 2:
return get_player_ci_property<&control_info::sideways>;
case 3:
return get_player_ci_property<&control_info::vertical>;
case 4:
return get_player_ci_property<&control_info::pitch>;
case 5:
return get_player_ci_property<&control_info::bank>;
case 6:
return get_player_ci_property<&control_info::heading>;
default:
return {};
}
}
static int get_pmi_objnum(const polymodel_instance* pmi) {
return pmi->objnum == model_objnum_special::OBJNUM_COCKPIT ? Player->objnum : pmi->objnum;
}
template<typename property, property object::* property_ptr, float property::* subproperty_ptr>
static float get_object_subproperty_float(polymodel_instance* pmi){
Assertion(pmi->objnum >= 0, "Invalid object used in animation property driver!");
return Objects[pmi->objnum].*property_ptr.*subproperty_ptr;
int objnum = get_pmi_objnum(pmi);
Assertion(objnum >= 0, "Invalid object used in animation property driver!");
return Objects[objnum].*property_ptr.*subproperty_ptr;
}
template<matrix object::* property_ptr, float angles::* angle>
static float get_object_matrix_angle(polymodel_instance* pmi){
Assertion(pmi->objnum >= 0, "Invalid object used in animation property driver!");
int objnum = get_pmi_objnum(pmi);
Assertion(objnum >= 0, "Invalid object used in animation property driver!");
angles a;
vm_extract_angles_matrix(&a, &(Objects[pmi->objnum].*property_ptr));
vm_extract_angles_matrix(&a, &(Objects[objnum].*property_ptr));
return a.*angle;
}
@@ -70,16 +100,18 @@ namespace animation {
template<typename property, property ship::* property_ptr, float property::* subproperty_ptr>
static float get_ship_subproperty_float(polymodel_instance* pmi){
Assertion(pmi->objnum >= 0, "Invalid object used in animation property driver!");
Assertion(Objects[pmi->objnum].type == OBJ_SHIP, "Non-ship object used in ship animation property driver!");
return Ships[Objects[pmi->objnum].instance].*property_ptr.*subproperty_ptr;
int objnum = get_pmi_objnum(pmi);
Assertion(objnum >= 0, "Invalid object used in animation property driver!");
Assertion(Objects[objnum].type == OBJ_SHIP, "Non-ship object used in ship animation property driver!");
return Ships[Objects[objnum].instance].*property_ptr.*subproperty_ptr;
}
template<int ship::* ets_property>
static float get_ship_ets_property(polymodel_instance* pmi){
Assertion(pmi->objnum >= 0, "Invalid object used in animation property driver!");
Assertion(Objects[pmi->objnum].type == OBJ_SHIP, "Non-ship object used in ship animation property driver!");
return Energy_levels[Ships[Objects[pmi->objnum].instance].*ets_property];
int objnum = get_pmi_objnum(pmi);
Assertion(objnum >= 0, "Invalid object used in animation property driver!");
Assertion(Objects[objnum].type == OBJ_SHIP, "Non-ship object used in ship animation property driver!");
return Energy_levels[Ships[Objects[objnum].instance].*ets_property];
}
std::function<float(polymodel_instance*)> parse_ship_property_driver_source() {
+6 -1
View File
@@ -73,6 +73,8 @@ extern int model_render_flags_size;
enum class modelread_status { FAIL, SUCCESS_REAL, SUCCESS_VIRTUAL };
enum model_objnum_special : int { OBJNUM_NONE = -1, OBJNUM_COCKPIT = -2, OBJNUM_SPECIAL_MIN = -3};
// Goober5000
extern const char *Subsystem_types[SUBSYSTEM_MAX];
@@ -119,6 +121,7 @@ struct submodel_instance
color arc_primary_color_1[MAX_ARC_EFFECTS];
color arc_primary_color_2[MAX_ARC_EFFECTS];
color arc_secondary_color[MAX_ARC_EFFECTS];
float arc_width[MAX_ARC_EFFECTS]; // only used for MARC_TYPE_SHIP and MARC_TYPE_SCRIPTED
vec3d arc_pts[MAX_ARC_EFFECTS][2];
ubyte arc_type[MAX_ARC_EFFECTS]; // see MARC_TYPE_* defines
@@ -133,6 +136,7 @@ struct submodel_instance
memset(&arc_primary_color_2, 0, MAX_ARC_EFFECTS * sizeof(color));
memset(&arc_secondary_color, 0, MAX_ARC_EFFECTS * sizeof(color));
memset(&arc_type, 0, MAX_ARC_EFFECTS * sizeof(ubyte));
memset(&arc_width, 0, MAX_ARC_EFFECTS * sizeof(float));
}
};
@@ -266,6 +270,7 @@ typedef struct model_special {
#define MARC_TYPE_DAMAGED 0 // blue lightning arcs for when the ship is damaged
#define MARC_TYPE_EMP 1 // EMP blast type arcs
#define MARC_TYPE_SHIP 2 // arcing lightning thats intrinsically part of the ship
#define MARC_TYPE_SCRIPTED 3 // an arc created via script
#define MAX_LIVE_DEBRIS 7
@@ -1190,7 +1195,7 @@ void model_replicate_submodel_instance(polymodel *pm, polymodel_instance *pmi, i
// Adds an electrical arcing effect to a submodel
void model_instance_clear_arcs(polymodel *pm, polymodel_instance *pmi);
void model_instance_add_arc(polymodel *pm, polymodel_instance *pmi, int sub_model_num, vec3d *v1, vec3d *v2, int arc_type, color *primary_color_1 = nullptr, color *primary_color_2 = nullptr, color *secondary_color = nullptr);
void model_instance_add_arc(polymodel *pm, polymodel_instance *pmi, int sub_model_num, vec3d *v1, vec3d *v2, int arc_type, color *primary_color_1 = nullptr, color *primary_color_2 = nullptr, color *secondary_color = nullptr, float width = 0.0f);
// Gets two random points on the surface of a submodel
extern vec3d submodel_get_random_point(int model_num, int submodel_num, int seed = -1);
+6 -8
View File
@@ -1198,15 +1198,13 @@ int model_collide(mc_info *mc_info_obj)
}
if ( Mc->flags & MC_SUBMODEL ) {
// Check only one subobject
mc_check_subobj( Mc->submodel_num );
// Check submodel and any children
} else if (Mc->flags & MC_SUBMODEL_INSTANCE) {
// Check only one subobject; or check submodel and any children
if ( (Mc->flags & MC_SUBMODEL) || (Mc->flags & MC_SUBMODEL_INSTANCE) ) {
// note: within this function, MC_SUBMODEL will return after one check; but MC_SUBMODEL_INSTANCE will not
mc_check_subobj(Mc->submodel_num);
} else {
// Check all the the highest detail model polygons and subobjects for intersections
}
// Check all the the highest detail model polygons and subobjects for intersections
else {
// Don't check it or its children if it is destroyed
if ( Mc_pmi ) {
if ( !Mc_pmi->submodel[Mc_pm->detail[0]].blown_off ) {
+4 -3
View File
@@ -3538,7 +3538,7 @@ int model_load(const char* filename, int n_subsystems, model_subsystem* subsyst
int model_create_instance(int objnum, int model_num)
{
Assertion(objnum >= -1 && objnum < MAX_OBJECTS, "objnum must be -1 or a valid object index!");
Assertion(objnum > OBJNUM_SPECIAL_MIN && objnum < MAX_OBJECTS, "objnum must be -1 (none), -2 (player cockpit) or a valid object index!");
// this will also run a bunch of Assertions
auto pm = model_get(model_num);
@@ -5155,7 +5155,7 @@ void model_instance_clear_arcs(polymodel *pm, polymodel_instance *pmi)
}
// Adds an electrical arcing effect to a submodel
void model_instance_add_arc(polymodel *pm, polymodel_instance *pmi, int sub_model_num, vec3d *v1, vec3d *v2, int arc_type, color *primary_color_1, color *primary_color_2, color *secondary_color )
void model_instance_add_arc(polymodel *pm, polymodel_instance *pmi, int sub_model_num, vec3d *v1, vec3d *v2, int arc_type, color *primary_color_1, color *primary_color_2, color *secondary_color, float width )
{
Assert(pm->id == pmi->model_num);
@@ -5175,10 +5175,11 @@ void model_instance_add_arc(polymodel *pm, polymodel_instance *pmi, int sub_mode
smi->arc_pts[smi->num_arcs][0] = *v1;
smi->arc_pts[smi->num_arcs][1] = *v2;
if (arc_type == MARC_TYPE_SHIP) {
if (arc_type == MARC_TYPE_SHIP || arc_type == MARC_TYPE_SCRIPTED) {
smi->arc_primary_color_1[smi->num_arcs] = *primary_color_1;
smi->arc_primary_color_2[smi->num_arcs] = *primary_color_2;
smi->arc_secondary_color[smi->num_arcs] = *secondary_color;
smi->arc_width[smi->num_arcs] = width;
}
smi->num_arcs++;
+3 -10
View File
@@ -862,6 +862,7 @@ void model_render_add_lightning(model_draw_list *scene, const model_render_param
break;
case MARC_TYPE_SCRIPTED:
case MARC_TYPE_SHIP:
if ( Random::flip_coin() ) {
primary = smi->arc_primary_color_1[i];
@@ -870,16 +871,8 @@ void model_render_add_lightning(model_draw_list *scene, const model_render_param
}
secondary = smi->arc_secondary_color[i];
// try and scale the size a bit so that it looks equally well on smaller vessels
width = Arc_width_default_damage;
if (pm->rad < Arc_width_no_multiply_over_radius_damage) {
width *= (pm->rad * Arc_width_radius_multiplier_damage);
if (width < Arc_width_minimum_damage) {
width = Arc_width_minimum_damage;
}
}
width = smi->arc_width[i];
break;
@@ -3189,7 +3182,7 @@ bool render_tech_model(tech_render_type model_type, int x1, int y1, int x2, int
// Create an instance for ships that can be used to clear out destroyed subobjects from rendering
if (model_type == TECH_SHIP) {
model_instance = model_create_instance(-1, model_num);
model_instance = model_create_instance(model_objnum_special::OBJNUM_NONE, model_num);
model_set_up_techroom_instance(&Ship_info[class_idx], model_instance);
}
+29 -48
View File
@@ -15,6 +15,7 @@
#include "debugconsole/console.h"
#include "freespace.h"
#include "jpgutils/jpgutils.h"
#include "math/bitarray.h"
#include "mission/missionparse.h"
#include "nebula/neb.h"
#include "object/object.h"
@@ -59,15 +60,15 @@ SCP_vector<poof_info> Poof_info;
float Poof_dist_threshold;
vec3d Poof_last_gen_pos;
float Poof_accum[MAX_NEB2_POOFS];
SCP_vector<float> Poof_accum;
float Poof_density_multiplier;
const float UPKEEP_DIST_MULT = 1.2f;
const float PROBABLY_TOO_MANY_POOFS = 100000.0f;
// array of neb2 poofs
int32_t Neb2_poof_flags = 0;
// bit array of neb2 poofs
std::unique_ptr<ubyte> Neb2_poof_flags;
// array of neb2 bitmaps
SCP_vector<SCP_string> Neb2_bitmap_filenames;
@@ -137,7 +138,7 @@ const SCP_vector<std::pair<int, std::pair<const char*, int>>> DetailLevelValues
const auto NebulaDetailOption __UNUSED = options::OptionBuilder<int>("Graphics.NebulaDetail",
std::pair<const char*, int>{"Nebula Detail", 1361},
std::pair<const char*, int>{"Detail level of nebulas", 1697})
.category("Graphics")
.category(std::make_pair("Graphics", 1825))
.values(DetailLevelValues)
.default_val(MAX_DETAIL_LEVEL)
.importance(7)
@@ -145,6 +146,7 @@ const auto NebulaDetailOption __UNUSED = options::OptionBuilder<int>("Graphics.N
Detail.nebula_detail = val;
return true;
})
.flags({options::OptionFlags::RetailBuiltinOption})
.finish();
// --------------------------------------------------------------------------------------------------------
@@ -166,7 +168,7 @@ void neb2_get_eye_orient(matrix *eye_matrix);
static poof_info* get_nebula_poof_pointer(char* nebula_name)
{
for (int i = 0; i < (int)Poof_info.size(); i++) {
for (size_t i = 0; i < Poof_info.size(); i++) {
if (!stricmp(nebula_name, Poof_info[i].name)) {
return &Poof_info[i];
}
@@ -224,11 +226,7 @@ void parse_nebula_table(const char* filename)
generic_anim_init(&pooft.bitmap, name);
if (Poof_info.size() < MAX_NEB2_POOFS) {
Poof_info.push_back(pooft);
} else {
Warning(LOCATION, "More than 32 poofs are defined! Skipping poof %s\n", pooft.name);
}
Poof_info.push_back(pooft);
} else if (optional_string("$Name:")) { // new style
stuff_string(pooft.name, F_NAME, NAME_LENGTH);
@@ -257,17 +255,8 @@ void parse_nebula_table(const char* filename)
}
continue;
}
// Check if we're at max poofs. If so, then log and continue.
if (Poof_info.size() < MAX_NEB2_POOFS) {
Poof_info.push_back(pooft);
poofp = &Poof_info[Poof_info.size() - 1];
} else {
Warning(LOCATION, "More than 32 poofs are defined! Skipping poof %s\n", pooft.name);
if (!skip_to_start_of_string_either("$Name:", "#end")) {
error_display(1, "Missing [#end] or [$Name] after nebula poof %s", pooft.name);
}
continue;
}
Poof_info.push_back(pooft);
poofp = &Poof_info[Poof_info.size() - 1];
}
if (poof_new) {
@@ -322,9 +311,6 @@ void parse_nebula_table(const char* filename)
poofp->alpha = ::util::parseUniformRange<float>(0.0f, 1.0f);
}
}
else {
WarningEx(LOCATION, "nebula.tbl\nExceeded maximum number of nebula poofs (%d)!\nSkipping %s.", (int)MAX_NEB2_POOFS, name);
}
}
}
catch (const parse::ParseException& e)
@@ -337,29 +323,35 @@ void parse_nebula_table(const char* filename)
// initialize neb2 stuff at game startup
void neb2_init()
{
// first parse the default table
parse_nebula_table("nebula.tbl");
// parse any modular tables
parse_modular_table("*-neb.tbm", parse_nebula_table);
// align Poof_accum with Poof_info
Poof_accum.resize(Poof_info.size());
// set up bit string
Neb2_poof_flags.reset(new ubyte[calculate_num_bytes(Poof_info.size())]);
clear_all_bits(Neb2_poof_flags.get(), Poof_info.size());
}
// set the bits for poofs from a list of poof names
void neb2_set_poof_bits(const SCP_vector<SCP_string>& list)
{
Neb2_poof_flags = 0; //Make absolutely sure flags are zero'd before we start adding to it-Mjn
clear_all_bits(Neb2_poof_flags.get(), Poof_info.size()); //Make absolutely sure flags are zero'd before we start adding to it-Mjn
for (const SCP_string& thisPoof : list) {
for (int i = 0; i < (int)Poof_info.size(); i++) {
for (size_t i = 0; i < Poof_info.size(); i++) {
if (lcase_equal(Poof_info[i].name, thisPoof)) {
Neb2_poof_flags |= (1 << i);
set_bit(Neb2_poof_flags.get(), i);
}
}
}
}
bool poof_is_used(size_t idx) {
return (Neb2_poof_flags & (1 << idx)) != 0;
return get_bit(Neb2_poof_flags.get(), idx) != 0;
}
void neb2_get_fog_color(ubyte *r, ubyte *g, ubyte *b)
@@ -376,7 +368,7 @@ void neb2_pre_level_init()
Neb2_fog_far_mult = 1.0f;
strcpy_s(Neb2_texture_name, "");
Neb2_poof_flags = 0;
clear_all_bits(Neb2_poof_flags.get(), Poof_info.size());
strcpy_s(Mission_parse_storm_name, "none");
}
@@ -389,7 +381,7 @@ void neb2_level_init()
float nNf_near, nNf_density;
void neb2_poof_setup() {
if (!Neb2_poof_flags)
if (!any_bits_set(Neb2_poof_flags.get(), Poof_info.size()))
return;
// make the total density of poofs be the average of all poofs, and each poofs density is its relative proportion compared to others
@@ -515,17 +507,6 @@ void neb2_post_level_init(bool fog_color_override)
Neb2_awacs = -1.0f;
}
// truncate the poof flags down to the poofs we have
if (Poof_info.size() < MAX_NEB2_POOFS) {
int available_poofs_mask = (1 << Poof_info.size()) - 1;
// check for negative here too, because if we're not at max, 32, then we're gauranteed not to have the sign bit
if (Neb2_poof_flags > available_poofs_mask || Neb2_poof_flags < 0)
Warning(LOCATION, "One or more invalid nebula poofs detected!");
Neb2_poof_flags = Neb2_poof_flags & available_poofs_mask;
}
// set the mission fog near dist and density
float fog_far;
neb2_get_adjusted_fog_values(&nNf_near, &fog_far, &nNf_density, nullptr);
@@ -789,7 +770,7 @@ void neb2_calc_poof_fades() {
if (pinfo->fade_in) {
// Make sure to enable this poof type if we're fading it in
if (pinfo->fade_multiplier < 0) {
Neb2_poof_flags |= (1 << i);
set_bit(Neb2_poof_flags.get(), i);
neb2_poof_setup();
}
pinfo->fade_multiplier = 0.0f + ((float)elapsedTime / pinfo->fade_duration);
@@ -802,7 +783,7 @@ void neb2_calc_poof_fades() {
// turn off any faded out poof types
if (!pinfo->fade_in) {
Neb2_poof_flags &= ~(1 << i);
clear_bit(Neb2_poof_flags.get(), i);
neb2_poof_setup();
}
@@ -822,8 +803,8 @@ void neb2_calc_poof_fades() {
void neb2_toggle_poof(int poof_idx, bool enabling) {
if (enabling) Neb2_poof_flags |= (1 << poof_idx);
else Neb2_poof_flags &= ~(1 << poof_idx);
if (enabling) set_bit(Neb2_poof_flags.get(), poof_idx);
else clear_bit(Neb2_poof_flags.get(), poof_idx);
Neb2_poofs.clear();
@@ -1243,10 +1224,10 @@ DCF(neb2_select, "Enables/disables a poof bitmap")
dc_stuff_int(&bmap);
if ( (bmap >= 0) && (bmap < (int)Poof_info.size()) ) {
if ( (bmap >= 0) && (bmap < static_cast<int>(Poof_info.size())) ) {
dc_stuff_boolean(&val_b);
val_b ? (Neb2_poof_flags |= (1<<bmap)) : (Neb2_poof_flags &= ~(1<<bmap));
val_b ? (set_bit(Neb2_poof_flags.get(), bmap)) : (clear_bit(Neb2_poof_flags.get(), bmap));
}
}
+1 -2
View File
@@ -55,8 +55,7 @@ extern float Neb2_fog_visibility_shockwave;
extern float Neb2_fog_visibility_fireball_const;
extern float Neb2_fog_visibility_fireball_scaled_factor;
extern int Neb2_poof_flags;
const size_t MAX_NEB2_POOFS = 32;
extern std::unique_ptr<ubyte> Neb2_poof_flags;
// pof texture filenames
extern SCP_vector<SCP_string> Neb2_bitmap_filenames;
+2 -2
View File
@@ -1305,7 +1305,7 @@ char *GetTrackerIdByUser(char *nickname)
return NULL;
}
char *GetChannelByUser(char *nickname)
char *GetChannelByUser(const char *nickname)
{
char szWhoisCmd[100];
@@ -1332,5 +1332,5 @@ char *GetChannelByUser(char *nickname)
SendChatString(szWhoisCmd,1);
GettingUserChannel = 1;
}
return NULL;
return nullptr;
}
+4 -1
View File
@@ -50,6 +50,9 @@ typedef struct _Chat_command {
_Chat_command *next;
} Chat_command;
// For returning a player's channel when searching by player name
extern char User_req_channel[100];
//Prototypes
void ChatInit(void);
int ConnectToChatServer(char *serveraddr, char *nickname, char *trackerid);
@@ -61,7 +64,7 @@ char *GetChatUserList();
int SetNewChatChannel(char *channel);
char *GetChannelList(void);
char *GetTrackerIdByUser(char *nickname);
char *GetChannelByUser(char *nickname);
char *GetChannelByUser(const char *nickname);
char *ChatGetString(void);
const char *GetWordNum(int num, const char *l_String);
+7 -8
View File
@@ -119,8 +119,7 @@ int Multi_button_info_ok = 0; // flag saying it is ok to apply critical
int Multi_button_info_id = 0; // identifier of the stored button info to be applying
// misc data
active_game* Active_game_head; // linked list of active games displayed on Join screen
int Active_game_count; // for interface screens as well
SCP_list<active_game> Active_games; // list of active games displayed on the Join screen
CFILE* Multi_chat_stream; // for streaming multiplayer chat strings to a file
int Multi_connection_speed; // connection speed of this machine.
int Multi_num_players_at_start = 0; // the # of players present (kept track of only on the server) at the very start of the mission
@@ -131,9 +130,9 @@ server_item* Game_server_head; // list of permanent game servers to be qu
// timestamp data
int Netgame_send_time = -1; // timestamp used to send netgame info to players before misison starts
int State_send_time = -1; // timestamp used to send state information to the host before a mission starts
time_t State_send_time = -1; // timestamp used to send state information to the host before a mission starts
int Gameinfo_send_time = -1; // timestamp used by master to send game information to clients
int Next_ping_time = -1; // when we should next ping all
time_t Next_ping_time = -1; // when we should next ping all
int Multi_server_check_count = 0; // var to keep track of reentrancy when checking server status
int Next_bytes_time = -1; // bytes sent
@@ -249,7 +248,7 @@ void multi_vars_init()
Multi_current_file_checksum = 0;
Multi_current_file_length = -1;
Active_game_head = NULL;
Active_games.clear();
Game_server_head = NULL;
// only the server should ever care about this
@@ -1199,7 +1198,7 @@ void multi_do_frame()
// ping everyone
multi_ping_send_all();
Next_ping_time = (int) time(NULL);
Next_ping_time = time(NULL);
}
// if I am the master, and we are not yet actually playing the mission, send off netgame
@@ -1219,7 +1218,7 @@ void multi_do_frame()
send_netplayer_update_packet();
}
State_send_time = (int) time(NULL);
State_send_time = time(NULL);
}
}
}
@@ -1404,7 +1403,7 @@ void multi_pause_do_frame()
if((Next_ping_time < 0) || ((time(NULL) - Next_ping_time) > PING_SEND_TIME) ){
multi_ping_send_all();
Next_ping_time = (int) time(NULL);
Next_ping_time = time(NULL);
}
// periodically send a client update packet to all clients
+3 -7
View File
@@ -414,7 +414,7 @@ typedef struct net_player_server_info {
UI_TIMESTAMP kick_timestamp; // timestamp with which we'll disconnect a player if he hasn't reponded to a kick packet
int kick_reason; // reason he was kicked
UI_TIMESTAMP voice_token_timestamp; // timestamp set when a player loses a token (so we can prevent him from getting it again too quickly)
int reliable_connect_time; // after sending an accept packet, wait for this long for the guy to connect on the reliable socket
time_t reliable_connect_time; // after sending an accept packet, wait for this long for the guy to connect on the reliable socket
// weapon select/linking information (maintained on the server and passed on respawn to all clients)
char cur_primary_bank; // currently selected primary bank
@@ -465,7 +465,7 @@ typedef struct net_player_server_info {
num_last_buttons = 0;
xfer_handle = -1;
kick_reason = 0;
reliable_connect_time = 0;
reliable_connect_time = -1;
cur_primary_bank = 0;
cur_secondary_bank = 0;
@@ -643,7 +643,6 @@ typedef struct netgame_info {
#define AG_FLAG_STATE_MASK (AG_FLAG_FORMING|AG_FLAG_BRIEFING|AG_FLAG_DEBRIEF|AG_FLAG_PAUSE|AG_FLAG_IN_MISSION)
typedef struct active_game {
active_game *next, *prev; // next and previous elements in the list
UI_TIMESTAMP heard_from_timer; // when we last heard from the game
char name[MAX_GAMENAME_LEN+1];
@@ -656,8 +655,6 @@ typedef struct active_game {
ping_struct ping; // ping time to the server
void init() {
next = nullptr;
prev = nullptr;
num_players = 0;
flags = 0;
version = 0;
@@ -890,8 +887,7 @@ extern int Multi_button_info_id; // identifier of the stored button inf
#define HEADER_LENGTH 1 // 1 byte (packet type)
// misc data
extern active_game* Active_game_head; // linked list of active games displayed on Join screen
extern int Active_game_count; // for interface screens as well
extern SCP_list<active_game> Active_games; // list of active games displayed on the Join screen
extern CFILE* Multi_chat_stream; // for streaming multiplayer chat strings to a file
extern int Multi_num_players_at_start; // the # of players present (kept track of only on the server) at the very start of the mission
extern short Multi_id_num; // for assigning player id #'s
+4 -7
View File
@@ -1028,13 +1028,10 @@ void process_ingame_ships_packet( ubyte *data, header *hinfo )
GET_INT(Wings[wing_data].current_wave);
}
// lookup ship in the original ships array
p_objp = mission_parse_get_parse_object(ship_name);
if(p_objp == NULL){
// if this ship is part of wing not on its current wave, look for its "original" by subtracting out wave #
p_objp = mission_parse_get_arrival_ship(ship_name);
}
if(p_objp == NULL){
// lookup ship in the registry
auto entry = ship_registry_get(ship_name);
p_objp = entry ? entry->p_objp_or_null() : nullptr;
if (p_objp == nullptr) {
mprintf(("ABORTING in-game join since FSO couldn't find ship %s in either arrival list or in mission!\n", ship_name));
multi_quit_game(PROMPT_NONE, MULTI_END_NOTIFY_NONE, MULTI_END_ERROR_INGAME_BOGUS);
return;
Loaded 100 of 277 files, more files were not shown because too many files have changed in this diff. Show more