CleverRaven / Cataclysm-DDA

Cataclysm - Dark Days Ahead. A turn-based survival game set in a post-apocalyptic world.
http://cataclysmdda.org
Other
10.34k stars 4.15k forks source link

flour is triggering grain-intolerance even when made from non-grain materials #52226

Open atealein opened 3 years ago

atealein commented 3 years ago

Describe the bug

We have a number of non-grain related sources of flour now - cattail rhizome, acorns, chestnuts, starch from potato or dalia roots, etc. However, the "flour" item seems to obtain material of "wheat" regardless of its components and is always marked as health hazard to eat. The item carries information about the components which it was created from, but this seems to be used only for the calories information and not for the material or other flags.

Steps To Reproduce

  1. Give yourself grain intolerance mutation
  2. Get/spawn some roasted cattail rhizomes, make them into flour
  3. Observe the red tag of the warning for health hazard food
  4. Cook something with it, still has the same warning

Expected behavior

I expect that the material, especially one linked to potential intolerances, will be inherited or obtained directly from the components in the item. This would allow people to make grain-free bread and other food that will not trigger their intolerances.

Screenshots

Screenshot from 2021-10-10 21-58-43 Three different types of flour made from wheat, cattail and chestnuts in that order.

Versions and configuration

experimental, Linux, 208638b curses version

Additional context

I am still trying to track down where the flags/materials get inherited from so any suggestion to where in the code I should look at is appreciated.

kwl01skz commented 3 years ago

I guess I know what the problem is and I'll try to solve it.

kwl01skz commented 3 years ago

The "material" of "flour" contains "wheat", which makes it cause grain-intolerance.

data/json/items/comestibles/wheat.json Line 124

    "id": "flour",
    "name": { "str_sp": "flour" },
......
    "material": [ "wheat", "powder" ],

data/json/mutations.json Line 1279

  {
    "type": "mutation",
    "id": "ANTIWHEAT",
    "name": { "str": "Grain Intolerance" },
    "points": -2,
    "description": "You have a rare allergy that prevents you from eating wheat.  It's possible for you to eat wheat-based products, but you will suffer morale penalties and obtain less nutrition from them.",
    "vitamins_absorb_multi": [ [ "wheat", [ [ "vitA", 0 ], [ "vitB", 0 ], [ "vitC", 0 ], [ "calcium", 0 ], [ "iron", 0 ] ] ] ],
    "starting_trait": true
  },

This trait affects and only affects material containing "wheat". Such as "oats" and "wheat". But this list does not include barley, although it also contains gluten (in reality). At the same time, some foods made of wheat will not cause allergies because the "material" do not contain "wheat". Such as "vodka" "malting_grain". At the same time, some foods that may not contain gluten have been forcibly added with the symbol of "wheat", such as haggis.

Option 1

Following the code of "human flesh", we re wrote a copy of "flag gluten" and applied it to "barley", "wheat" and "oat", so that this flag can be inherited by the product when it is used as raw material, and remove "wheat" from "flour" and other foods. This requires some CPP code. On the other hand. Can we use gluten free to "flour" to make the same delicious bread / pizza / cake? Should we add another item "no gluten flour"?

Option 2 Only change the "wheat" component to "gluten" and add it to "barley". Add a "gluten free flour" project, which is made of raw materials that do not contain "gluten". It only needs to modify JSON, but it's not smart enough. For example, "haggis" can be made of buckwheat or oats, which may or may not contain gluten. We can't distinguish it.

atealein commented 3 years ago

I am actually happy to add the explicit gluten-free flour item because i think it will avoid errors when we are crafting cake and have few different types of gluten-free and gluten flour and the crafter selects at random which one to use. But are we sure that other products (cake etc) crafted with it will inherit the correct material? Because I can see in data/json/comestibles/wheat.json that all sort of products created from baking are explicitly listed with "material": ["wheat"]; So even making the "nonwheat" flour, these will remain with hardcoded material.

Edit: I like your Option 1 better. It seems to be where the game is developing towards, having different flags that are then inherited from the ingredients. It will allow also recipes like "cake" to include flags for "gluten" and "dairy" or not depending on what is used. But I got no idea how the CPP code has to be adjusted.

I think adding a "gluten-free flour" and additionally having the flag of "gluten" in the material, instead of hardcoded is optimal solution.

Edit2: and yes, it is possible to make gluten free cakes/pizza/bread that are also delicious :D I personally have a recipe where I use chickpeas flour because it adds a nice nutty flavor even though I got no issues with tolerances :D and the calories will be adjusted based on igredients so that can be solved/balanced at the source.

estebandellasilva commented 3 years ago

I may be wrong but looking at some recipes you cannot replace normal flour with gluten free flour without changing the outcome. If the recipe will be the same with gulten free flour then gluten free flour should be changed to a little that you have to add a thickener oder binder before it would be able to be used in those recipes. (from reading around it seems like there are ready to use mixes of gluten free allpurpose flour, but if you only have gluten free flour you need to add a binder or thickener like xanthan gum or starches) Gluten Free flour should not be able to be used until you have created this replacement flour.

kwl01skz commented 3 years ago
  {
    "type": "mutation",
    "id": "CANNIBAL",
    "name": { "str": "Cannibal" },
    "points": 2,
    "//": "Feral humans vastly increase the cannibal meat supply, therefore this trait needs to increase in cost.",
    "description": "For your whole life you've been forbidden from indulging in your peculiar tastes.  Now the world's ended, and you'll be damned if anyone is going to tell you that you can't eat people.",
    "starting_trait": true,
    "valid": false,
    "cancels": [ "VEGETARIAN", "HERBIVORE", "RUMINANT", "GRAZER" ],
    "flags": [ "CANNIBAL" ]
  },
  {
    "type": "mutation",
    "id": "STRICT_HUMANITARIAN",
    "name": { "str": "Strict Humanitarian" },
    "points": 1,
    "description": "You're convinced that these things that look vaguely human from elsewhere are definitely not people.  Therefore it's okay to eat them, right?",
    "starting_trait": true,
    "valid": false,
    "cancels": [ "VEGETARIAN", "HERBIVORE", "RUMINANT", "GRAZER" ],
    "flags": [ "STRICT_HUMANITARIAN" ]
  },

There is a flag called "STRICT_HUMANITARIAN", which is placed on various demihuman meat, and the food produced by these meat will inherit this flag. Similar to it is flag "CANNIBALISM". It is used for human bones. Search CPP for these flags to find the code that handles them.

kwl01skz commented 3 years ago

The allergen code is here:

item_factory.cpp Line 2500


// Adds allergy flags to items with allergenic materials
// Set for all items (not just food and clothing) to avoid edge cases
void Item_factory::set_allergy_flags( itype &item_template )
{
    static const std::pair<material_id, flag_id> all_pairs[] = {
        // First allergens:
        // An item is an allergen even if it has trace amounts of allergenic material
        { material_id( "hflesh" ), flag_CANNIBALISM },

        { material_id( "hflesh" ), flag_ALLERGEN_MEAT },
        { material_id( "iflesh" ), flag_ALLERGEN_MEAT },
        { material_id( "flesh" ), flag_ALLERGEN_MEAT },
        { material_id( "wheat" ), flag_ALLERGEN_WHEAT },
        { material_id( "fruit" ), flag_ALLERGEN_FRUIT },
        { material_id( "veggy" ), flag_ALLERGEN_VEGGY },
        { material_id( "bean" ), flag_ALLERGEN_VEGGY },
        { material_id( "tomato" ), flag_ALLERGEN_VEGGY },
        { material_id( "garlic" ), flag_ALLERGEN_VEGGY },
        { material_id( "nut" ), flag_ALLERGEN_NUT },
        { material_id( "mushroom" ), flag_ALLERGEN_VEGGY },
        { material_id( "milk" ), flag_ALLERGEN_MILK },
        { material_id( "egg" ), flag_ALLERGEN_EGG },
        { material_id( "junk" ), flag_ALLERGEN_JUNK },
        // Not food, but we can keep it here
        { material_id( "wool" ), flag_ALLERGEN_WOOL },
        // Now "made of". Those flags should not be passed
        { material_id( "flesh" ), flag_CARNIVORE_OK },
        { material_id( "hflesh" ), flag_CARNIVORE_OK },
        { material_id( "iflesh" ), flag_CARNIVORE_OK },
        { material_id( "milk" ), flag_CARNIVORE_OK },
        { material_id( "egg" ), flag_CARNIVORE_OK },
        { material_id( "honey" ), flag_URSINE_HONEY }
    };
atealein commented 3 years ago

I may be wrong but looking at some recipes you cannot replace normal flour with gluten free flour without changing the outcome. If the recipe will be the same with gulten free flour then gluten free flour should be changed to a little that you have to add a thickener oder binder before it would be able to be used in those recipes. (from reading around it seems like there are ready to use mixes of gluten free allpurpose flour, but if you only have gluten free flour you need to add a binder or thickener like xanthan gum or starches) Gluten Free flour should not be able to be used until you have created this replacement flour.

Right now the flour recipes are quite simplified, for example you can make flour directly only from starch, and starch from for example potatoes or dahlia root. But also in real life not all gluten free flour requires thickeners. It depends on the type of flour and the specific recipe and that will be simplified in the game.

Most of the gluten free flour found in the stores is from crops/cultures that are easy to grow in conventional agriculture. Stuff like chestnut or acorn flour is not mass produced because it requires a lot of manual labor which increases production costs and price, but in our case is what a survivor would have access and time to do.

We could make the gluten free flour recipe to require some sort of flour agent (which can have a lot of alternatives) and some sort of thickening agent (if only starch is the option that has a bunch of alternatives for producing too). This way by the time it gets to the recipes like "cake" it will be considered equal alternative to the normal flour. Would that be reasonable?