Ensure proper checks for model_num and instance validity when accessing OBJ_RAW_POF and OBJ_PROP objects. Prevents crashes from out-of-bounds or missing data in Pof_objects and Props.
Reset the selected item when we open a new menu. This keeps the display state and internal state in sync if the player mixes arrow presses and number presses. Follow-up to #7688.
* New guard-range sexp
New guard-range sexp which allows different ranges for different guarders
* cast value
* Clang
* bugfixes
* fix CI
* Address Feedback
* address feedback
* typo
Convert MsgItems from an array to a vector, and remove the associated limit value and counter.
* vectorize msgitems
* appeasement
* leave me alone clang
* remove optional
* cleanup
* changes requested
* clang
* clang what is WRONG with you
* feedback
* remove flag in .h
An operator that isn't enclosed in parentheses could trigger an UNREACHABLE, which crashes in Debug and is undefined behavior in Release. Catch it in a more appropriate way.
TLDR: This is a long description, but it boils down to exposing 2 hardcoded AI values and updating 1 value in the optional 'better collision avoidance' behavior allows mods to substantially fix fighters ramming into capital ships they are attacking.
AI accidentally ramming into big ships while trying to evade fire from a hostile turret or a dogfight makes some sense given a chaotic combat situation. What does not seem good though is AI not being able to attack a large stationary target that is not shooting back and has no fighters around. This is especially evident in mods that use the new strafing AI fields, where AI will fly to a distant point then turn around to do an attack run, then once close enough pick another strafing run to conduct. In these situations, AI will commonly not pull up from the attack run in time, especially for mods that use different speeds or AI damp values compared to retail.
Fortunately, there exposing two values to the AI profiles allows modders to tune these values, the strafe retreat time and strafe retreat distance. By default these values are 2 seconds and 100 meters, which is commonly far too short for mods with higher speeds or larger damp values. Exposing these values allows modders to make the AI far more effective and virtually eliminate ramming into stationary ships they are attacking. For example, on current 26.0 with FotG testing we register 2-4 rams of a stationary target per minute. Using the new exposed values in this branch eliminates the ramming (after 10 minutes of firing no ramming occurs across multiple runs of this and other test missions).
Furthermore, this PR helps `better_collision_avoidance_triggered` function (enabled by using `better collision avoidance` in the `ai_profiles.tbl` fix an edge case with predicting collisions. On current master the `delta_time` value used in this function was `0`, which was only ever used eventually downstream in the `will_collide_with_big_ship` function call. This `will_collide_with_big_ship` function had an early return on line 7620:
```
int will_collide_with_big_ship(object *objp, vec3d *goal_point, object *big_objp, vec3d *collision_point, float delta_time)
{
float radius;
vec3d end_pos;
radius = big_objp->radius + delta_time * objp->phys_info.speed;
if (vm_vec_dist_quick(&big_objp->pos, &objp->pos) > radius) {
return 0;
}
```
This early return and the passing of `0` to the `delta_time` from `better_collision_avoidance_triggered` meant that the early out radius distance was only the big object's radius, and did not project any forward time. In other words, better collision avoidance only actually checked or triggered when the small ship was within the radius distance of the large ship. Thus, with ships that had geometry reach right to the edge of the object radius, it could result in the small ship not having enough time to react to avoid a collision. Notably, all other calls to `will_collide_with_big_ship` use a `delta_time` of 5-10. As such, this PR also fixes that edge case by ensuring the better collision avoidance also incorporates some lead travel time by passing a non-zero value for delta time. Given `better_collision_avoidance_triggered` aggression factor is 3.5 by default, it fit well in testing to pass this value to `delta_time`. That aggression factor is already tuneable for mods, so also using it here provides extra adaptability.
Overall these values and updates were tested and substantially remove collision accidents, especially with ships with high speeds and/or higher damps. The PR boils down to exposing two values to the AI profiles table and updating values in the optional 'better collision avoidance' flag, so it will not affect retail. Happy to discuss as well, thanks!
Seems like props were missing from the object type list, so adding them in this relatively small PR. Happy to edit or do something differently if folks want though!
* Fix two small issues
Fix copy-paste bug where setting `$Ask Help Hull Percent:` never properly got set. Fortunately this does not affect the AI, only when the AI sends a message to the player asking for help.
Fix edge-case issue: in `find_turret_enemy`, the `turret-tgt-ship-tgt` shortcut takes the parent ship's target and indexes Ships[] with it unconditionally, but `aip->target_objnum` could be a weapon or asteroid, which could be at an index higher than the ships index, and then trying to look up team could lead to bad data.
* comment formatting
Bind the existing fsspeech_* wrappers into the ui.Briefing, ui.CommandBriefing,
ui.Debriefing, and ui.TechRoom scripting sections so Lua UIs (e.g. SCPUI, which
overrides the native screens) can drive synthesized speech again.
Each section gets playTextToSpeech, stopTextToSpeech, pauseTextToSpeech,
isTextToSpeechPlaying, and isTextToSpeechEnabled. Briefing/command-brief/debrief
use FSSPEECH_FROM_BRIEFING; the tech room uses FSSPEECH_FROM_TECHROOM. fsspeech_play
already self-gates on the Speech.* options, so these are no-ops when speech is off.
Restore the original flag values that were consolidated in #7588. Since the flags are saved in the mission file as an integer, the original values must be preserved.
Since `MR_ATTACHED_MODEL` was removed in the original PR, that is renamed to `MR_EMPTY_SLOT6`.
The game settings flag '$Hide main Rearm/Repair items in Comms Gauge:' hides the 'Rearm and Repair' lines in the HUD Comms menu from appearing, which is useful for mods that do not have repair ships and thus those lines confuse players. Unfortunately, the newer `COMMS_MENU_SELECT` control bindings do not properly account for hidden menu items, so using those controls on a comms menu with 'Rearm and Repair' hidden means the selection index gets off and also confuses the player.
This PR fixes that by allowing `hud_squadmsg_selection_move_down()` and `hud_squadmsg_selection_move_up()` to skip hidden menu items. Tested and works as expected.
For folks using the COMMS_MENU_SELECT controls, there is also a current UI confusion when the comms menu is first brought up because the first item is selected, but the `Display_selector` does not show. Thus, players are unsure what item is actively selected even though one is actively selected. In the original comms menu select PR this was set to on by default, but then switched to off by default by a different developer a bit later. This choice is especially useful for mods that have many players with gamepads such as Event Horizon. Alternatively, mods that already have many number keys utilized for other gameplay aspects seem to prefer to keep the comms menu visuals as is and only show the selection if the player uses those keys. Given there is clearly arguments for both reasons, ideally modders should be able to choose how it displays for their own mods (always or off for the first pop-up of the Comms menu). Thus, this PR adds that as a cleanup game option, too. This also was tested and works as expected.
* Fix scripting copy-paste bug
The iterators for secondary banks for lua access had a copy-paste bug from primaries, so we should fix that. The early == -1 break masks it whenever a ship uses 3 or fewer secondary banks, which is probably why it went unnoticed.
Also add some additional low-hanging fruit optimizations.
* radar distance and other cleanup
* clang
Convert the allowed-ships and allowed-weapons lists to sets, rather than naive vectors that stored a true/false for every class. Since these are ordered sets, iteration occurs in the same sequence as iteration of `Ship_info` or `Weapon_info`. Associated data structures such as `Granted_ships` and `Granted_weapons` are converted as well.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Use the SDL gamepad API to add full gamepad support. Adds rumble for supported
gamepads and changes the FF in-game options to take immediate effect instead
of requiring a restart.
Additionally this makes changes to allow gamepad triggers to be used as both
an axis and a button. This support is specific to gamepads since we can
explicitly identify the trigger with the API and act on it accordingly. FSO
control config doesn't currently support such an action directly however so
we have to hack it in just a bit. Due to this the control binding will show
the trigger axis name bound to a button control only while a gamepad is
connected, otherwise it shows a button name associated with the trigger.
Following style of 'target radius' and other useful weapon launch curve inputs, this PR adds 'Target Forward Speed' which can be useful to use as an input and then use FoF as an output to do things like make turrets have a tougher time having dynamic FoF depending on target speed.
Convert ship/weapon loadout pools from naive per-class arrays to ordered maps that list loadout entries. Each entry represents a ship/weapon class and its count. An absent entry means the class is not in this mission's loadout. Since these are ordered maps, iteration of the map keys occurs in the same sequence as iteration of `Ship_info` or `Weapon_info`.
Includes several bugfixes:
- `csg_read_loadout` now clears both pools before reading. Previously the pools were only zeroed in `mission_campaign_init`
- `restore_wss_data`: non-transmitted classes are now absent rather than memset to 0
- a copy-paste bug where the weapon pool entries were bounds-checked against MAX_SHIP_CLASSES
- `wss_maybe_restore_loadout`: the pool write-back now preserves loadout membership instead of writing a count for every class
- `ss_dump_to_list`/`ss_swap_list_slot`: returning a slot ship whose class is not in the pool now makes it available instead of silently losing it. Unreachable in retail but reachable via script
- off-by-one errors in the Lua `Ship_Pool`/`Weapon_Pool` indexers
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Refactor `Ship_class_names`, `Iff_info_names`, and `Ai_class_names` to be populated once at parse time, as opposed to ad-hoc and possibly many times.
Also make `Ai_classes` and `Spawn_names` proper SCP_vectors.
Refactor shadow flag handling in shaders to improve compatibility with small-shader mode. Add support for Vulkan's `-no_large_shaders` switch to split model ubershaders for better driver compatibility. Adjust related comments and preprocessor checks for clarity.
Extend the various maps to add a `contains` function, just as several other containers already add `contains`.
Also add `at_or` and `value_or` functions to provide ways to query for map values without inserting anything by default, as `operator[]` does. If the map does not contain the key, the default value is returned. Use `at_or` to return a const reference and `value_or` to return a value. (These are only added to `SCP_map` and `SCP_unordered_map`; a `SCP_multimap` equivalent isn't as clearly useful.)
Also add Class Template Argument Deduction (CTAD) guides, per existing precedent. And delete function overloads that are intrinsic footguns.