Don't try to shoot with empty gun #77624
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
None
Purpose of change
Fix #77602, i.e. segmentation fault when trying to evaluate dispersion from an empty gun.
Describe the solution
Change npc_attack_gun::can_use to reject gun usage when a gun is empty, not only when it can't be wielded.
This causes the gun not to be attempted to be evaluated for firing performance down the line.
Describe alternatives you've considered
Testing
Loaded the save in the bug report and verified that not only didn't it blow up, but Liam did actually reload a gun (don't know if "varmint gun" is the same as the "Ruger" seen with the debugger), so the rejection doesn't seem to block gun usage to the degree that there is no attempt at reloading.
Additional context
The comment for the item::ammo_data() function is dangerously misleading. It claims it will return a nullptr if the gun isn't loaded, but that's a partial lie, as it happily returns data involving an empty magazine (although it probably rejects a direct loaded gun that's empty. Thus, anyone trusting enough to believe this may get a nasty surprise (segfault) when faced with an empty magazine and trying to use the ammo pointer that was promised to lead somewhere (it didn't matter here, as the ammo_data() results wasn't checked anyway).
Needs to be reviewed by competent reviewers. I THINK it's reasonable to bail out early, but it's possible this may lead to things that should be attempted being untried. Seeing the companion reload indicates at least one such possible failure seems to not happen in absolutely all cases.