-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Crafting menu shows range of possible nutrients for food crafts #36172
Crafting menu shows range of possible nutrients for food crafts #36172
Conversation
as we are trying to deprecate player, i humbly request the scope of player::compute_nutrient_range() be moved to the appropriate class, probably Character here. |
This looks great, I've been looking forward to this change! It is not only good for players, but also will be helpful for debugging/balancing. The only thing I have to say is that you are not taking account for the
It's not trivial to fix, unfortunately. The only quick fix I can think of is to take |
It depends on other functions that are still in |
397be7e
to
e384f42
Compare
@DaviBones I think I found a reasonable solution to the I added a set of |
Looks great! As an aside, I struggle to think of an instance where we'll want to use |
|
||
bool nutrients::operator==( const nutrients &r ) const | ||
{ | ||
if( kcal != r.kcal ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do wonder why return kcal == r.kcal && vitamins == r.vitamins;
does not work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because non-entries in the vitamins map have to be considered equivalent to zero entries.
Mostly I did it that way for maintenance reasons. If in the future anyone alters the way these flags work they are likely to grep the code for |
e384f42
to
857f9b4
Compare
Recipe loops are problematic (see last commit). There are none now in the core game, but mods might add them. This code detects recipe loops and marks the items contained within them. Such loops are considered an error reported via debugmsg. This implementation is a little slower than I would prefer. A slightly more advanced cycle-finding algorithm could be used to make it faster.
These functions calculate the range of possible nutrients a particular item or recipe might produce, depending on which ingredients are used within it.
08e0832
to
09c237d
Compare
Currently item info for items with variable nutrient content simply list the default values with a disclaimer that they might be inaccurate. In fact the default values are more or less the only values that *won't* occur when you craft the recipe. Instead, calculate and display the range of possible values for the nutrient content.
If we use any namespace, it should be cata (or a subnamespace thereof). It doesn't make sense to be adding other top-level namespaces.
Use a O(V+E) cycle-finding algorithm, and factor it out appropriately to clarify the code.
To predict nutrient content we need to also predict changes to the item flags that occur when cooking. Implement that, and add a test to verify that it works correctly for cooked wild veggies.
The nutrient predictions were based on a list of recipes cached in each item. It turns out that list could end up with invalid recipe_ids if those recipes became blacklisted. Detect that case and avoid adding such recipes to the list.
09c237d
to
065d355
Compare
I think this is good to go now. |
Summary
SUMMARY: Interface "Crafting menu shows range of possible nutrients for food crafts"
Purpose of change
Fixes #28180.
Currently when crafting a comestible the crafting GUI declares a particular calorie and vitamin content for it. But the true value that will result depends on the ingredients used. This is unhelpful and can be confusing for players.
Describe the solution
This turns out to be quite tricky in practice, for a few reasons:
NUTRIENT_OVERRIDE
.The solution has a number of components:
debugmsg
so they can be dealt with.player::compute_nutrient_range
functions. One overload for a specific recipe, and another for a generic item intended to take into account all recipes.item::foodinfo
to display the new values. To avoid infinite recursion we don't try to calculate the ranges for any items which were earlier detected to lie on problematic recipe loops.Describe alternatives you've considered
When the player has specific ingredients on hand, it might be nice to see the (range of) actual values that would result from those, rather than the complete range of all possibilities. I decided not to do that because we need to support the more generic situation (where not all ingredients are present) anyway, so that made sense to implement first. The other feature can be added later (but it won't be trivial!).
We could display the "true" nutritional content rather than the effective content based on player traits. That would allow simplification, but it would be a change from prior behaviour, and probably less helpful.
We could make it clearer that the displayed values are dependent on player traits; I suspect most players don't realise this.
Currently the nutrient values displayed are always per-charge, whereas most of the values displayed in this are increase with charges. This can be a bit deceptive, and we might want to clarify or change this, but I think that should be a separate PR.
Testing
New unit tests, and lots of staring at recipe values. Found and fixed various unreasonable-looking values. Some issues were a result of poor recipe design, others were algorithmic issues in my code. I've fixed all the ones I found, but I would not be surprised to hear that I missed some corner cases.
@DaviBones would appreciate you taking a look at this since you've also been working on & finding bugs in this part of the code recently.
Additional context