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

feat(content): Allow multiple required bionics #5496

Merged
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
2 changes: 1 addition & 1 deletion data/json/bionics.json
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@
"act_cost": "10 kJ",
"react_cost": "10 kJ",
"time": 1,
"required_bionic": "bio_weight"
"required_bionics": [ "bio_weight" ]
},
{
"id": "bio_infolink",
Expand Down
2 changes: 1 addition & 1 deletion doc/src/content/docs/en/mod/json/reference/json_info.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ the appropriate JSON file.
| react_cost | (_optional_) How many kJ it costs over time to keep this bionic active, does nothing without a non-zero "time". Strings can be used "1 kJ"/"1000 J"/"1000000 mJ" (default: `0`) |
| time | (_optional_) How long, when activated, between drawing cost. If 0, it draws power once. (default: `0`) |
| upgraded_bionic | (_optional_) Bionic that can be upgraded by installing this one. |
| required_bionic | (_optional_) Bionic which is required to install this bionic, and which cannot be uninstalled if this bionic is installed |
| required_bionics | (_optional_) Bionics which are required to install this bionic, and which cannot be uninstalled if this bionic is installed |
| available_upgrades | (_optional_) Upgrades available for this bionic, i.e. the list of bionics |
| having this one referenced by `upgraded_bionic`. | |
| and how much this bionic encumber them. | |
Expand Down
54 changes: 41 additions & 13 deletions src/bionics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ void bionic_data::load( const JsonObject &jsobj, const std::string &src )
assign( jsobj, "enchantments", enchantments, strict );
assign_map_from_array( jsobj, "learned_spells", learned_spells, strict );
assign( jsobj, "included_bionics", included_bionics, strict );
assign( jsobj, "required_bionic", required_bionic, strict );
assign( jsobj, "required_bionics", required_bionics, strict );
assign( jsobj, "upgraded_bionic", upgraded_bionic, strict );
assign( jsobj, "available_upgrades", available_upgrades, strict );
assign( jsobj, "flags", flags, strict );
Expand Down Expand Up @@ -411,11 +411,13 @@ void bionic_data::check() const
rep.warn( "upgrades undefined bionic \"%s\"", upgraded_bionic.str() );
}
}
if( required_bionic ) {
if( required_bionic == id ) {
rep.warn( "The CBM %s requires itself as a prerequisite for installation", required_bionic.str() );
} else if( !required_bionic.is_valid() ) {
rep.warn( "The CBM %s requires undefined bionic %s", id.str(), required_bionic.str() );
if( !required_bionics.empty() ) {
for( const bionic_id &it : required_bionics ) {
if( it == id ) {
rep.warn( "The CBM %s requires itself as a prerequisite for installation", it.str() );
} else if( !it.is_valid() ) {
rep.warn( "The CBM %s requires undefined bionic %s", id.str(), it.str() );
}
}
}

Expand Down Expand Up @@ -2045,13 +2047,28 @@ bool Character::can_uninstall_bionic( const bionic_id &b_id, player &installer,
}
}

// make sure the bionic you are removing is not required by other installed bionics
std::vector<std::string> dependent_bionics;
for( const bionic_id &bid : get_bionics() ) {
if( bid->required_bionic == b_id ) {
popup( _( "%s cannot be removed because installed bionic %s requires it." ),
b_id->name, bid->name );
return false;
// look at required bionics for every installed bionic
for( const bionic_id &req_bid : bid->required_bionics ) {
if( req_bid == b_id ) {
dependent_bionics.push_back( "" + bid->name );
}
}
}
if( !dependent_bionics.empty() ) {
std::string concatenated_list_of_dependent_bionics;
for( const std::string &req_bionic : dependent_bionics ) {
concatenated_list_of_dependent_bionics += " " + req_bionic;
if( req_bionic != dependent_bionics.back() ) {
concatenated_list_of_dependent_bionics += ",";
}
}
popup( _( "%s cannot be removed because it is required by the following bionics:%s." ),
b_id->name, concatenated_list_of_dependent_bionics );
return false;
}

if( b_id == bio_eye_optic ) {
popup( _( "The Telescopic Lenses are part of %s eyes now. Removing them would leave %s blind." ),
Expand Down Expand Up @@ -2296,9 +2313,20 @@ bool Character::can_install_bionics( const itype &type, player &installer, bool
}
int chance_of_success = bionic_manip_cos( adjusted_skill, difficult );

if( bioid->required_bionic && !has_bionic( bioid->required_bionic ) ) {
popup( _( "CBM requires prior installation of %s." ), bioid->required_bionic.obj().name );
return false;
if( !bioid->required_bionics.empty() ) {
std::string list_of_missing_required_bionics;
for( const bionic_id &req_bid : bioid->required_bionics ) {
if( !has_bionic( req_bid ) ) {
list_of_missing_required_bionics += " " + req_bid->name;
if( req_bid != bioid->required_bionics.back() ) {
list_of_missing_required_bionics += ",";
}
}
}
if( !list_of_missing_required_bionics.empty() ) {
popup( _( "CBM requires prior installation of%s." ), list_of_missing_required_bionics );
return false;
}
}

std::vector<std::string> conflicting_muts;
Expand Down
6 changes: 3 additions & 3 deletions src/bionics.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,10 @@ struct bionic_data {
*/
std::set<bionic_id> available_upgrades;
/**
* Id of another bionic which this bionic needs to have installed to be installed.
* Also prevents that bionic from being removed while this bionic is installed.
* Id of other bionics which this bionic needs to have installed to be installed.
* Also prevents those bionics from being removed while this bionic is installed.
*/
bionic_id required_bionic;
std::vector<bionic_id> required_bionics;

std::set<flag_id> flags;
bool has_flag( const flag_id &flag ) const;
Expand Down
8 changes: 5 additions & 3 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3385,9 +3385,11 @@ void item::bionic_info( std::vector<iteminfo> &info, const iteminfo_query *parts

insert_separation_line( info );

if( bid->required_bionic ) {
info.emplace_back( "CBM", string_format( "* This CBM requires another CBM to also be installed: %s",
bid->required_bionic->name ) );
if( !bid->required_bionics.empty() ) {
for( const bionic_id &req_bid : bid->required_bionics ) {
info.emplace_back( "CBM", string_format( "* This CBM requires another CBM to also be installed: %s",
req_bid->name ) );
}
}

insert_separation_line( info );
Expand Down
Loading