Skip to content
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

Misc. fixes for vehicle part variants #55543

Merged
merged 3 commits into from
Feb 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions data/json/vehicleparts/windshields.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@
"copy-from": "windshield_abstract",
"id": "windshield_full",
"looks_like": "windshield",
"type": "vehicle_part"
"type": "vehicle_part",
"name": { "str": "full windshield" }
},
{
"abstract": "reinforced_windshield_abstract",
Expand Down Expand Up @@ -104,6 +105,7 @@
"copy-from": "reinforced_windshield_abstract",
"id": "reinforced_windshield_full",
"looks_like": "reinforced_windshield",
"type": "vehicle_part"
"type": "vehicle_part",
"name": { "str": "reinforced full windshield" }
}
]
129 changes: 89 additions & 40 deletions src/veh_interact.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1021,40 +1021,34 @@ void veh_interact::do_install()
" Continue?" ) ) ) {
return;
}
const auto &shapes =
vpart_shapes[ sel_vpart_info->name() + sel_vpart_info->base_item.str() ];
auto &shapes = vpart_shapes[ sel_vpart_info->name() + sel_vpart_info->base_item.str() ];
// Don't include appliances in variant list
for( auto iter = shapes.begin(); iter != shapes.end(); ) {
if( ( *iter )->has_flag( VPFLAG_APPLIANCE ) ) {
shapes.erase( iter );
} else {
iter++;
}
}
int selected_shape = -1;
// more than one shape available, display selection
// more than one base variant available with the same name
size_t num_vpart_shapes = shapes.size();
size_t num_shapes_total = num_vpart_shapes + sel_vpart_info->symbols.size();
if( num_shapes_total > 1 ) {
if( num_vpart_shapes > 1 ) {
std::vector<uilist_entry> shape_ui_entries;
for( size_t i = 0; i < shapes.size(); i++ ) {
uilist_entry entry( i, true, 0, shapes[i]->name() );
// use the id to distinguish between them
std::string vpname =
string_format( "%s (%s)", shapes[i]->name(), shapes[i]->get_id().str() );
uilist_entry entry( i, true, 0, vpname );
entry.extratxt.left = 1;
entry.extratxt.sym = special_symbol( shapes[i]->sym );
entry.extratxt.color = shapes[i]->color;
shape_ui_entries.push_back( entry );
}
size_t j = num_vpart_shapes;
for( const auto &vp_variant : sel_vpart_info->symbols ) {
std::string disp_name = sel_vpart_info->name();
for( const auto &vp_variant_pair : vpart_variants ) {
if( vp_variant_pair.first == vp_variant.first ) {
disp_name += " " + vp_variant_pair.second;
break;
}
}
uilist_entry entry( j, true, 0, disp_name );
entry.extratxt.left = 1;
entry.extratxt.sym = special_symbol( vp_variant.second );
entry.extratxt.color = sel_vpart_info->color;
shape_ui_entries.push_back( entry );
j += 1;
}
sort_uilist_entries_by_line_drawing( shape_ui_entries );
uilist smenu;
smenu.settext( _( "Choose shape:" ) );
//~ Choose a base variant for a vehicle part
smenu.settext( _( "Choose base:" ) );
smenu.entries = shape_ui_entries;
smenu.w_width_setup = [this]() {
return getmaxx( w_list );
Expand All @@ -1070,25 +1064,70 @@ void veh_interact::do_install()
} else { // only one shape available, default to first one
selected_shape = 0;
}
if( selected_shape >= 0 &&
static_cast<size_t>( selected_shape ) < num_shapes_total ) {
if( static_cast<size_t>( selected_shape ) < num_vpart_shapes ) {
sel_vpart_info = shapes[selected_shape];
sel_vpart_variant.clear();
} else {
size_t offset = static_cast<size_t>( selected_shape ) - num_vpart_shapes;
size_t j = 0;
if( selected_shape >= 0 && static_cast<size_t>( selected_shape ) < num_vpart_shapes ) {
sel_vpart_info = shapes[selected_shape];
sel_vpart_variant.clear();
selected_shape = 0;
// more than one shape available, display selection
size_t num_shapes_total = sel_vpart_info->symbols.size();
if( num_shapes_total > 0 ) {
std::vector<uilist_entry> shape_ui_entries;
size_t j = 1;
for( const auto &vp_variant : sel_vpart_info->symbols ) {
if( j == offset ) {
sel_vpart_variant = vp_variant.first;
break;
} else {
j += 1;
std::string disp_name = sel_vpart_info->name();
for( const auto &vp_variant_pair : vpart_variants ) {
if( vp_variant_pair.first == vp_variant.first ) {
disp_name += " " + vp_variant_pair.second;
break;
}
}
uilist_entry entry( j, true, 0, disp_name );
entry.extratxt.left = 1;
entry.extratxt.sym = special_symbol( vp_variant.second );
entry.extratxt.color = sel_vpart_info->color;
shape_ui_entries.push_back( entry );
j += 1;
}
sort_uilist_entries_by_line_drawing( shape_ui_entries );
//~ Option to select the default vehicle part, no variant
uilist_entry def_entry( 0, true, 0, _( "No variant (use default)" ) );
def_entry.extratxt.left = 1;
def_entry.extratxt.sym = ' ';
def_entry.extratxt.color = c_white;
shape_ui_entries.push_back( def_entry );
uilist smenu;
//~ Choose a variant shape for a vehicle part
smenu.settext( _( "Choose shape:" ) );
smenu.entries = shape_ui_entries;
smenu.w_width_setup = [this]() {
return getmaxx( w_list );
};
smenu.w_x_setup = [this]( const int ) {
return getbegx( w_list );
};
smenu.w_y_setup = [this]( const int ) {
return getbegy( w_list );
};
smenu.query();
selected_shape = smenu.ret;
}
if( selected_shape >= 0 && ( num_shapes_total == 0 ||
static_cast<size_t>( selected_shape ) < num_shapes_total ) ) {
int offset = selected_shape - 1;
if( offset >= 0 ) {
int j = 0;
for( const auto &vp_variant : sel_vpart_info->symbols ) {
if( j == offset ) {
sel_vpart_variant = vp_variant.first;
break;
} else {
j += 1;
}
}
}
sel_cmd = 'i';
return;
}
sel_cmd = 'i';
return;
}
}
} else if( action == "QUIT" ) {
Expand Down Expand Up @@ -2014,7 +2053,15 @@ void veh_interact::do_change_shape()
break;
} else if( action == "CONFIRM" || action == "CHANGE_SHAPE" ) {
using v_shapes = std::vector<const vpart_info *, std::allocator<const vpart_info *>>;
const v_shapes &shapes = vpart_shapes[ sel_vpart_info->name() + sel_vpart_info->base_item.str() ];
v_shapes &shapes = vpart_shapes[ sel_vpart_info->name() + sel_vpart_info->base_item.str() ];
// Don't include appliances in variant list
for( auto iter = shapes.begin(); iter != shapes.end(); ) {
if( ( *iter )->has_flag( VPFLAG_APPLIANCE ) ) {
shapes.erase( iter );
} else {
iter++;
}
}
if( shapes.empty() ) {
break;
}
Expand All @@ -2035,7 +2082,9 @@ void veh_interact::do_change_shape()
int default_selection = 0;
std::vector<std::string> variants;
for( const vpart_info *const shape : shapes ) {
uilist_entry entry( shape->name() );
// more than one base variant available with the same name, use id to distinguish between them
std::string vpname = string_format( "%s (%s)", shape->name(), shape->get_id().str() );
uilist_entry entry( vpname );
entry.retval = ret_code++;
entry.extratxt.left = 1;
entry.extratxt.sym = special_symbol( shape->sym );
Expand Down