Refine the yell (C) menu for interactions with NPCs and follower orders #30358
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
SUMMARY: Interface "Refine the yell (C) menu for interactions with NPCs and follower orders"
Purpose of change
The current
C
yell menu is fairly critical in managing follower NPCs, in addition to the basic task of communicating with other NPCs, but it is somewhat clunky.For one, the "talk to NPC" function can end up swamping the menu itself with many NPCs if you're in a crowded area (such as the Refugee Center), pushing potentially critical follower commands further down the list (and generally making the list more cumbersome to read through).
For another, there's an inflexibility in the current "temporary command" framework that both limits the commands you can give a follower, as well as makes it somewhat opaque exactly what happens when you give each command.
Describe the solution
The primary concern with this change was consistency and readability, so I stated with giving the Yell menu sub-menus.
Now whenever you go to talk to an NPC, assign followers the guard task, or ask guards to begin following you again, if there's more than one option in any of those categories, you're given a menu to select which person you're interacting with.
If there's only one person in that category (only one NPC to talk to, only one follower in your team, or only one guard in view), then that option in that menu will directly select that NPC so that you don't need to open a sub-menu.
The "wake up", "prepare for danger", and "relax" commands remain in the menu and work as before (affecting your entire current team), but other commands now belong in the "Temporary Orders" sub menu.
The Temporary Orders menu does two things:
One, it gives a list of all of the current options you have for issuing (or retracting) specific rule overrides, including an option to clear all current overrides.
Two, at the bottom of the menu it shows all of the overrides currently affecting one member of your team, giving you more clarity about exactly how your orders are currently affecting at least one person (with a disclaimer that followers could potentially have different overrides). In particular this lets you see the effects of the "Prepare For Danger" command in the main Yell menu.
I also added a new ally rule,
FORBID_ENGAGE
, which functions equivalent to the "none" engagement rule, and exists purely for temporary override purposes.In service of all of this, I had to make some changes to a few things.
uilist now has the ability to specify
footer_text
, which is essentially identical to descriptions, except iffooter_text
is specified, it is used in lieu of any potential item descriptions. I basically just added three ternaries wherever.desc
got used inui.cpp
The various text lines for ally rules got moved to
talk_tags.json
, as "snippets". This allowed there to be canonical translatable lines of text for conversations that also could be used in the temporary orders menu without risk of the text falling out of sync.A couple of additional methods were added to
npc_follower_rules
to simplify the specific access pattern the temporary orders interface uses (and to reduce boilerplate).One noteworthy additional change: discussions with mlangsdorf made it clear that the ally rule called
AVOID_COMBAT
actually has nothing to do with avoiding combat, and is completely independent of engagement rules. Instead, that flag tells the NPC to stick close to the player even if there's hostiles nearby that they want to engage with without actually keeping them from fighting (if the hostile is in range).Accordingly, it's been renamed
FOLLOW_CLOSE
, and all related text has been updated to reflect this. Additionally, migration code was added tosavegame_json.cpp
to mlangsdorf's specifications.Describe alternatives you've considered
There's still an awful lot that could be done to clean up the switch block in
game::chat
that, frankly, I ran out of energy doing. There's a bit of repetition I'm unhappy with, but trying to make that work in a c++ fashion unassisted is beyond me at the moment.There are still a few potential override options that could be added to the temporary orders menu, but I wasn't sure which ones might be genuinely useful on a regular basis (and I didn't want to just throw all of them in there; that would get noisy).
It's possible my changes to
ui.cpp
could have been done more cleanly, but I wasn't sure how to do that without having to re-architect a lot of logic that I'm not confident tampering with blithely. The other other alternative would have been to use the existing "description" framework, but that requires adding the footer text to every single entry. This strikes me as silly.I could've not renamed
AVOID_COMBAT
, but I felt the name was entirely too misleading for the actual effect.Additional context
It wouldn't be an interface PR from me without pictures, would it?
The new menu with only one NPC around, who happens to be a follower.
Same menu, with only one NPC around, who happens to be a guard.
Temporary order menu, with only one NPC in your party:
Temporary order menu, after issuing the "Prepare for danger" command:
The new yell menu with two NPCs nearby, one guarding, one following:
After selecting "Talk to ..."
Both NPCs in your party:
Telling someone to guard:
Temporary order menu, with disclaimer about different followers' rules:
Old yell menu, for comparison: