CleverRaven / Cataclysm-DDA

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

Crafting canned food in glass jars doesn't seal the container on output #76780

Open the-unknownperson opened 1 month ago

the-unknownperson commented 1 month ago

Describe the bug

Described in the title: I tried to craft "canned heart" in a 3L glass jar expecting it to be sealed as an output, however it wasn't. Possibly also the same issue for other recipes (0.5L and 3L glass jar variants of canned goods and soups/broths). Works normally for tin cans however.

Attach save file

Lantana-trimmed.tar.gz

Steps to reproduce

  1. Craft "canned heart" or any other recipe involving canning glass jars
  2. Proceed with the process with the ingredients and tools provided
  3. Finishing result does not have the jar (sealed).

Expected behavior

I expected the glass jar to be (sealed) upon finishing cooking, but the output showed that the container wasn't.

Screenshots

https://github.com/user-attachments/assets/77a379dc-786d-4414-b826-fd36f0788856

Versions and configuration

Additional context

No response

PatrikLundell commented 1 month ago

/Confirmed

At a guess, the logic replacing the base recipe's tin can with a glass jar doesn't carry over the base recipe's specification that the container should be sealed.

Note that while the container is named "jar_glass_sealed" it isn't actually sealed (and there is no corresponding item without the "sealed" suffix). It's just a glass jar that can be sealed.

HadeanLake commented 1 month ago

I noticed, unsealed cans are only 80% full by volume. Do they have to be(from realism perpective)? 2024-10-02-174014_1920x1080_scrot

Apparently, that is what causes them to be not sealed. I increased amount of heart that goes into the jar and it fixed the issue:

--- a/data/json/recipes/food/canned.json
+++ b/data/json/recipes/food/canned.json
@@ -838,11 +838,11 @@
     "//1": "pressure canning is measured in 0.5 liter quantities, so 1u of canning_high_heat.",
     "book_learn": [ [ "cookbook", 6 ], [ "manual_canning", 4 ] ],
     "container": "jar_glass_sealed",
-    "charges": 8,
+    "charges": 10,
     "components": [
       [ [ "water_clean", 1 ] ],
       [ [ "jar_glass_sealed", 1 ] ],
-      [ [ "heart", 8 ], [ "human_heart", 8 ], [ "demihuman_heart", 8 ] ]
+      [ [ "heart", 10 ], [ "human_heart", 10 ], [ "demihuman_heart", 10 ] ]
     ]
   },
   {
PatrikLundell commented 1 month ago

Good find! I have some vague (but unreliable) recollection that this has been discussed previously.

I suspect script savvy people may come up with a script that can highlight recipes that are supposed to produced sealed contents but doesn't actually do it. That would presumably require knowledge of how full the container has to be to be sealed (90% wasn't enough according to my experiment with producing 9 charges of heart for the half liter jar).

SurFlurer commented 1 month ago

how full the container has to be to be sealed

AFAIK the container need to be exactly full ( remaining volume == 0_ml ) to be sealable, which was an obstacle to my attempt to fix some sealed containers without massive json changes, after the charge removal one year ago. However things have changed, and most comestibles now have appropriate volumes to exactly fill up jars and cans.

Psithief commented 1 month ago

This explains a lot, thank you all.

HadeanLake commented 1 month ago

I was checking sealable but not sealed situations in recipes with this:

diff --git a/src/recipe.cpp b/src/recipe.cpp
index 06a6e97b29..5fa16dac8f 100644
--- a/src/recipe.cpp
+++ b/src/recipe.cpp
@@ -605,6 +605,18 @@ void recipe::finalize()
             container_variant = item::find_type( result_ )->default_container_variant.value();
         }
     }
+    int makes = charges.has_value() ? charges.value() : 1;
+    int charge_volume = item::find_type( result_ )->volume.value();
+    units::volume volume_to_contain = units::from_milliliter( charge_volume * makes );
+    units::volume container_capacity = item_contents( item::find_type(
+                                           container )->pockets ).total_container_capacity();
+    if( contained && sealed ) {
+        if( volume_to_contain < container_capacity ) {
+            debugmsg( "Recipe %s puts item %s in sealable container %s but does not fill it %d * %d = %d < %d",
+                      id.str(), result_.str(), container.str(), charge_volume, makes, volume_to_contain.value(),
+                      container_capacity.value() );
+        }
+    }

     std::set<proficiency_id> required;
     std::set<proficiency_id> used;   

and discovered that some items have volume that makes it impossible to seal them E.g. cured_roe has volume of 62ml. 8 charges of it will have volume of 496ml and thus will not fit perfectly into 500ml container. So item::seal() should check if container has maximum amount of charges that would fit in it? Will cause issues if more than one type of item in container to be sealed. Or just pass 'seal_it_anyway = true' into it from where item was crafted by character, not spawned in someones fridge possibly half-eaten? Or both? So that if vac-sealed bag of 8 roe spawns sealed in fridge if it spawned with 8 items?

https://github.com/CleverRaven/Cataclysm-DDA/blob/a9f6b508ff01650ced9e65761a62cf8ade5c37f9/src/item.cpp#L9715-L9720 this was changed in #46359

SamGondra commented 2 weeks ago

canned liver is still having this problem. (both 0.5 and 3 l variants)