Skip to content

Commit 0fdd052

Browse files
committed
fix: scale proc food servings and migrate sandwich recipe ids
Assisted-by: openai/gpt-5.4 on opencode Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
1 parent b8c34e3 commit 0fdd052

File tree

5 files changed

+108
-6
lines changed

5 files changed

+108
-6
lines changed

src/proc_item.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ auto payload_servings( const item &it, const proc::payload &data ) -> int
6767
if( data.servings > 0 ) {
6868
return data.servings;
6969
}
70-
return it.count_by_charges() ? default_stack_servings( it.typeId() ) : 1;
70+
return it.is_comestible() && it.count_by_charges() ? default_stack_servings( it.typeId() ) : 0;
7171
}
7272

7373
auto scaled_payload_total( const item &it, const proc::payload &data, const int total ) -> int
@@ -1084,15 +1084,16 @@ auto proc::make_item( const schema &sch, const std::vector<part_fact> &facts,
10841084
full.data.name = !sch.cat.empty() ? sch.cat + " " + sch.id.str() : sch.id.str();
10851085
}
10861086

1087-
if( result->count_by_charges() ) {
1087+
if( result->is_comestible() && result->count_by_charges() ) {
10881088
result->charges = scaled_food_servings( *result, full.data );
10891089
}
10901090

10911091
auto out_payload = payload{};
10921092
out_payload.id = sch.id;
10931093
out_payload.mode = mode;
10941094
out_payload.blob = full.data;
1095-
out_payload.servings = result->count_by_charges() ? std::max( result->charges, 1 ) : 1;
1095+
out_payload.servings = result->is_comestible() && result->count_by_charges() ?
1096+
std::max( result->charges, 1 ) : 0;
10961097
out_payload.fp = fast_fp( sch, full.data, facts );
10971098
if( mode == hist::compact ) {
10981099
out_payload.parts = !opts.slots.empty() ? make_compact_parts( facts, opts.slots ) :

src/recipe_dictionary.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static DynamicDataLoader::deferred_json deferred;
5656
template<>
5757
const recipe &string_id<recipe>::obj() const
5858
{
59-
const auto iter = recipe_dict.recipes.find( *this );
59+
const auto iter = recipe_dict.recipes.find( recipe_dictionary::migrate_id( *this ) );
6060
if( iter != recipe_dict.recipes.end() ) {
6161
if( iter->second.obsolete ) {
6262
return null_recipe;
@@ -72,7 +72,27 @@ const recipe &string_id<recipe>::obj() const
7272
template<>
7373
bool string_id<recipe>::is_valid() const
7474
{
75-
return recipe_dict.recipes.contains( *this );
75+
return recipe_dict.recipes.contains( recipe_dictionary::migrate_id( *this ) );
76+
}
77+
78+
auto recipe_dictionary::migrate_id( const recipe_id &id ) -> recipe_id
79+
{
80+
if( id.is_null() || item_controller == nullptr ) {
81+
return id;
82+
}
83+
84+
if( const auto iter = recipe_dict.recipes.find( id ); iter != recipe_dict.recipes.end() ) {
85+
if( !iter->second.obsolete ) {
86+
return id;
87+
}
88+
const auto migrated_result_id = item_controller->migrate_id( iter->second.result() );
89+
const auto migrated_result_recipe_id = recipe_id( migrated_result_id.str() );
90+
return recipe_dict.recipes.contains( migrated_result_recipe_id ) ? migrated_result_recipe_id : id;
91+
}
92+
93+
const auto migrated_item_id = item_controller->migrate_id( itype_id( id.str() ) );
94+
const auto migrated_id = recipe_id( migrated_item_id.str() );
95+
return recipe_dict.recipes.contains( migrated_id ) ? migrated_id : id;
7696
}
7797

7898
const recipe &recipe_dictionary::get_uncraft( const itype_id &id )

src/recipe_dictionary.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class recipe_dictionary
4040

4141
/** Returns disassembly recipe (or null recipe if no match) */
4242
static const recipe &get_uncraft( const itype_id &id );
43+
static auto migrate_id( const recipe_id &id ) -> recipe_id;
4344

4445
static void load_recipe( const JsonObject &jo, const std::string &src );
4546
static void load_uncraft( const JsonObject &jo, const std::string &src );
@@ -186,4 +187,3 @@ class recipe_subset
186187
void serialize( const recipe_subset &value, JsonOut &jsout );
187188
void deserialize( recipe_subset &value, JsonIn &jsin );
188189

189-

tests/proc_make_test.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,57 @@ TEST_CASE( "proc_food_remaining_size_tracks_servings", "[proc][make][food]" )
161161
CHECK( proc::blob_kcal( *made ) == starting_kcal );
162162
}
163163

164+
TEST_CASE( "proc_make_item_scales_stew_servings_with_total_size", "[proc][make][food]" )
165+
{
166+
auto sch = proc::schema{};
167+
sch.id = proc::schema_id( "stew" );
168+
sch.cat = "food";
169+
sch.res = itype_id( "stew_generic" );
170+
sch.slots = {
171+
proc::slot_data{ .id = proc::slot_id( "base" ), .role = "base", .min = 1, .max = 1, .ok = {}, .no = {} },
172+
proc::slot_data{ .id = proc::slot_id( "veg" ), .role = "veg", .min = 1, .max = 4, .rep = true, .ok = {}, .no = {} }
173+
};
174+
175+
auto broth = proc::part_fact{};
176+
broth.ix = 1;
177+
broth.id = itype_id( "broth" );
178+
broth.kcal = 600;
179+
broth.mass_g = 2200;
180+
broth.volume_ml = 2200;
181+
182+
auto carrot = proc::part_fact{};
183+
carrot.ix = 2;
184+
carrot.id = itype_id( "carrot" );
185+
carrot.kcal = 300;
186+
carrot.mass_g = 1800;
187+
carrot.volume_ml = 1800;
188+
189+
auto opts = proc::make_opts{};
190+
opts.mode = proc::hist::none;
191+
opts.slots = { proc::slot_id( "base" ), proc::slot_id( "veg" ) };
192+
const auto made = proc::make_item( sch, { broth, carrot }, opts );
193+
194+
const auto base = item( "stew_generic", calendar::turn );
195+
const auto ceil_div = []( const int value, const int divisor ) {
196+
return value <= 0 ? 0 : ( value + divisor - 1 ) / divisor;
197+
};
198+
const auto base_servings = std::max( base.charges, 1 );
199+
const auto expected_servings = std::max( {
200+
base_servings,
201+
ceil_div( ( broth.mass_g + carrot.mass_g ) * base_servings,
202+
std::max( units::to_gram( base.weight() ), 1L ) ),
203+
ceil_div( ( broth.volume_ml + carrot.volume_ml ) * base_servings,
204+
std::max( units::to_milliliter( base.volume() ), 1 ) )
205+
} );
206+
207+
REQUIRE( proc::read_payload( *made ) );
208+
CHECK( made->charges == expected_servings );
209+
CHECK( proc::read_payload( *made )->servings == expected_servings );
210+
CHECK( made->charges > base_servings );
211+
CHECK( made->weight() == units::from_gram( 4000 ) );
212+
CHECK( made->volume() == units::from_milliliter( 4000 ) );
213+
}
214+
164215
TEST_CASE( "proc_food_uses_blob_nutrition_and_component_hash", "[proc][make][food]" )
165216
{
166217
auto sch = proc::schema{};

tests/proc_payload_test.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,36 @@ TEST_CASE( "legacy_sandwiches_gain_proc_payload_on_save_load", "[proc][payload][
290290
} );
291291
}
292292

293+
TEST_CASE( "legacy_sandwich_recipe_ids_migrate_to_proc_recipe", "[proc][payload][migration]" )
294+
{
295+
const auto proc_recipe = recipe_id( "sandwich_generic" );
296+
REQUIRE( proc_recipe.is_valid() );
297+
298+
for( const auto &legacy_id : {
299+
recipe_id( "blt" ),
300+
recipe_id( "sandwich_t" ),
301+
recipe_id( "sandwich_veggy" ),
302+
recipe_id( "sandwich_cheese" ),
303+
recipe_id( "sandwich_sauce" ),
304+
recipe_id( "sandwich_honey" ),
305+
recipe_id( "sandwich_jam" ),
306+
recipe_id( "sandwich_pb" ),
307+
recipe_id( "sandwich_pbj" ),
308+
recipe_id( "sandwich_pbh" ),
309+
recipe_id( "sandwich_pbm" ),
310+
recipe_id( "sandwich_deluxe" ),
311+
recipe_id( "sandwich_okay" ),
312+
recipe_id( "sandwich_deluxe_nocheese" ),
313+
recipe_id( "fish_sandwich" ),
314+
recipe_id( "sandwich_cucumber" ),
315+
} ) {
316+
INFO( legacy_id.str() );
317+
CHECK( legacy_id.is_valid() );
318+
CHECK( legacy_id.obj().ident() == proc_recipe );
319+
CHECK( legacy_id.obj().result() == itype_id( "sandwich_generic" ) );
320+
}
321+
}
322+
293323
TEST_CASE( "legacy_sandwiches_migrate_to_proc_sandwich_items", "[proc][payload][migration]" )
294324
{
295325
const auto cases = std::vector<itype_id> {

0 commit comments

Comments
 (0)