Skip to content

Commit 9e161f1

Browse files
fix: decouple proc sword results from display names
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 73c31d5 commit 9e161f1

File tree

5 files changed

+80
-30
lines changed

5 files changed

+80
-30
lines changed

data/json/procgen.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ end
3030

3131
function procgen.gear.make(params)
3232
local blob = params.blob or {}
33-
local result = params.schema_res or "proc_sword_generic"
34-
if params.schema_id == "sword" then result = sword_result_from_name(blob.name) end
33+
local result = params.result_override or params.schema_res or "proc_sword_generic"
34+
if params.schema_id == "sword" and not params.result_override then result = sword_result_from_name(blob.name) end
3535
return {
3636
result = result,
3737
name = blob.name,

src/proc_builder.cpp

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,43 @@ auto picked_facts_for_role( const proc::schema &sch, const std::vector<proc::par
441441
return ret;
442442
}
443443

444+
struct sword_variant_data {
445+
std::string name;
446+
itype_id result = itype_id::NULL_ID();
447+
};
448+
449+
auto sword_variant( const proc::schema &sch, const std::vector<proc::part_fact> &facts,
450+
const std::vector<proc::craft_pick> &picks ) -> sword_variant_data
451+
{
452+
const auto blade_facts = picked_facts_for_role( sch, facts, picks, "blade" );
453+
const auto reinforcement_facts = picked_facts_for_role( sch, facts, picks, "reinforcement" );
454+
455+
if( has_itype( reinforcement_facts, itype_id( "nail" ) ) ) {
456+
return { .name = "nail sword", .result = itype_id( "sword_nail" ) };
457+
}
458+
if( has_itype( reinforcement_facts, itype_id( "scrap" ) ) ||
459+
has_itype( blade_facts, itype_id( "scrap" ) ) ) {
460+
return { .name = "crude sword", .result = itype_id( "sword_crude" ) };
461+
}
462+
if( std::ranges::any_of( blade_facts, [&]( const proc::part_fact & fact ) {
463+
return has_material( fact, material_id( "steel" ) ) || has_material( fact,
464+
material_id( "iron" ) );
465+
} ) ) {
466+
return { .name = "hand-forged sword", .result = itype_id( "sword_metal" ) };
467+
}
468+
if( std::ranges::any_of( blade_facts, [&]( const proc::part_fact & fact ) {
469+
return has_material( fact, material_id( "bone" ) );
470+
} ) ) {
471+
return { .name = "bone sword", .result = itype_id( "sword_bone" ) };
472+
}
473+
if( std::ranges::any_of( blade_facts, [&]( const proc::part_fact & fact ) {
474+
return has_material( fact, material_id( "wood" ) );
475+
} ) ) {
476+
return { .name = "2-by-sword", .result = itype_id( "sword_wood" ) };
477+
}
478+
return { .name = "sword", .result = itype_id( "proc_sword_generic" ) };
479+
}
480+
444481
auto sandwich_condiment_name( const std::vector<proc::part_fact> &facts ) -> std::string
445482
{
446483
if( !facts_have_tag( facts, "cond" ) ) {
@@ -520,32 +557,7 @@ auto sandwich_vegetable_name( const std::vector<proc::part_fact> &facts ) -> std
520557
auto sword_name( const proc::schema &sch, const std::vector<proc::part_fact> &facts,
521558
const std::vector<proc::craft_pick> &picks ) -> std::string
522559
{
523-
const auto blade_facts = picked_facts_for_role( sch, facts, picks, "blade" );
524-
const auto reinforcement_facts = picked_facts_for_role( sch, facts, picks, "reinforcement" );
525-
526-
if( has_itype( reinforcement_facts, itype_id( "nail" ) ) ) {
527-
return "nail sword";
528-
}
529-
if( has_itype( reinforcement_facts, itype_id( "scrap" ) ) ||
530-
has_itype( blade_facts, itype_id( "scrap" ) ) ) {
531-
return "crude sword";
532-
}
533-
if( std::ranges::any_of( blade_facts, [&]( const proc::part_fact & fact ) {
534-
return has_material( fact, material_id( "steel" ) ) || has_material( fact, material_id( "iron" ) );
535-
} ) ) {
536-
return "hand-forged sword";
537-
}
538-
if( std::ranges::any_of( blade_facts, [&]( const proc::part_fact & fact ) {
539-
return has_material( fact, material_id( "bone" ) );
540-
} ) ) {
541-
return "bone sword";
542-
}
543-
if( std::ranges::any_of( blade_facts, [&]( const proc::part_fact & fact ) {
544-
return has_material( fact, material_id( "wood" ) );
545-
} ) ) {
546-
return "2-by-sword";
547-
}
548-
return "sword";
560+
return sword_variant( sch, facts, picks ).name;
549561
}
550562

551563
auto sword_description( const proc::schema &sch, const std::vector<proc::part_fact> &facts,
@@ -915,6 +927,15 @@ auto proc::rebuild_fast( const builder_state &state ) -> fast_blob
915927
return preview_blob( state.sch, facts, selected_picks( state, state.sch ) );
916928
}
917929

930+
auto proc::preview_result_override( const schema &sch, const std::vector<part_fact> &facts,
931+
const std::vector<craft_pick> &picks ) -> std::optional<itype_id>
932+
{
933+
if( sch.id != schema_id( "sword" ) ) {
934+
return std::nullopt;
935+
}
936+
return sword_variant( sch, facts, picks ).result;
937+
}
938+
918939
auto proc::debug_part_fact( const schema &sch, const item &it,
919940
const part_ix ix ) -> std::optional<part_fact>
920941
{

src/proc_builder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ auto remove_last_pick( builder_state &state, const slot_id &slot ) -> bool;
4848
auto selected_picks( const builder_state &state, const schema &sch ) -> std::vector<craft_pick>;
4949
auto selected_facts( const builder_state &state ) -> std::vector<part_fact>;
5050
auto rebuild_fast( const builder_state &state ) -> fast_blob;
51+
auto preview_result_override( const schema &sch, const std::vector<part_fact> &facts,
52+
const std::vector<craft_pick> &picks ) -> std::optional<itype_id>;
5153
auto debug_part_fact( const schema &sch, const item &it,
5254
part_ix ix ) -> std::optional<part_fact>;
5355
auto fast_fp( const schema &sch, const fast_blob &blob,

src/proc_item.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,8 @@ auto blob_table( sol::state &lua, const proc::fast_blob &blob ) -> sol::table
478478

479479
auto call_lua_blob( const std::string &path, const proc::schema &sch,
480480
const std::vector<proc::part_fact> &facts, const proc::fast_blob &blob,
481-
cata::lua_state *state ) -> std::optional<sol::table>
481+
cata::lua_state *state,
482+
const std::optional<itype_id> &result_override = std::nullopt ) -> std::optional<sol::table>
482483
{
483484
auto *active = active_lua_state( state );
484485
if( active == nullptr ) {
@@ -493,6 +494,9 @@ auto call_lua_blob( const std::string &path, const proc::schema &sch,
493494
auto params = lua.create_table();
494495
params["schema_id"] = sch.id.str();
495496
params["schema_res"] = sch.res.str();
497+
if( result_override.has_value() ) {
498+
params["result_override"] = result_override->str();
499+
}
496500
params["blob"] = blob_table( lua, blob );
497501

498502
auto facts_tbl = lua.create_table();
@@ -1058,12 +1062,15 @@ auto proc::make_item( const schema &sch, const std::vector<part_fact> &facts,
10581062
const make_opts &opts ) -> detached_ptr<item>
10591063
{
10601064
auto preview = fast_blob{};
1065+
auto result_override = std::optional<itype_id> {};
10611066
if( !opts.slots.empty() ) {
10621067
auto state = build_state( sch, facts );
10631068
const auto count = std::min( facts.size(), opts.slots.size() );
10641069
std::ranges::for_each( std::views::iota( size_t{ 0 }, count ), [&]( const size_t idx ) {
10651070
state.chosen[opts.slots[idx]].push_back( facts[idx].ix );
10661071
} );
1072+
const auto picks = selected_picks( state, sch );
1073+
result_override = proc::preview_result_override( sch, facts, picks );
10671074
preview = rebuild_fast( state );
10681075
} else {
10691076
std::ranges::for_each( facts, [&]( const part_fact & fact ) {
@@ -1079,7 +1086,8 @@ auto proc::make_item( const schema &sch, const std::vector<part_fact> &facts,
10791086
auto mode = opts.mode;
10801087
auto result = item::spawn( sch.res, calendar::turn );
10811088

1082-
if( const auto tbl = call_lua_blob( sch.lua.make, sch, facts, full.data, opts.state ) ) {
1089+
if( const auto tbl = call_lua_blob( sch.lua.make, sch, facts, full.data, opts.state,
1090+
result_override ) ) {
10831091
parse_blob_into( full.data, *tbl );
10841092
const auto result_id = tbl->get_or<std::string>( "result", "" );
10851093
if( !result_id.empty() ) {

tests/proc_weapon_make_test.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,23 @@ TEST_CASE( "proc_make_item_converts_proc_swords_to_legacy_variants", "[proc][mak
147147
CHECK( made->typeId() == itype_id( "sword_bone" ) );
148148
CHECK( made->type_name() == "bone sword" );
149149
}
150+
151+
SECTION( "result variant does not depend on localized sword names" ) {
152+
state.lua.script( R"(
153+
procgen.test = procgen.test or {}
154+
function procgen.test.rename(params)
155+
local blob = params.blob or {}
156+
blob.name = "mystery sword"
157+
return blob
158+
end
159+
)" );
160+
161+
auto renamed = sch;
162+
renamed.lua.full = "procgen.test.rename";
163+
164+
opts.slots = { proc::slot_id( "blade" ), proc::slot_id( "handle" ), proc::slot_id( "grip" ) };
165+
const auto made = proc::make_item( renamed, { steel_blade, handle, grip }, opts );
166+
CHECK( made->typeId() == itype_id( "sword_metal" ) );
167+
CHECK( made->type_name() == "mystery sword" );
168+
}
150169
}

0 commit comments

Comments
 (0)