diff --git a/data/json/bionics.json b/data/json/bionics.json index e6008da202e5..913ca83862aa 100644 --- a/data/json/bionics.json +++ b/data/json/bionics.json @@ -526,7 +526,8 @@ "flags": [ "BIONIC_TOGGLED", "BIONIC_NPC_USABLE" ], "act_cost": "10 kJ", "react_cost": "10 kJ", - "time": 1 + "time": 1, + "required_bionic": "bio_weight" }, { "id": "bio_infolink", diff --git a/src/bionics.cpp b/src/bionics.cpp index 3fdf8473a66d..4c18a5961354 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -313,6 +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, "upgraded_bionic", upgraded_bionic, strict ); assign( jsobj, "available_upgrades", available_upgrades, strict ); assign( jsobj, "flags", flags, strict ); @@ -410,6 +411,14 @@ 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()); + } + } + for( const bionic_id &it : available_upgrades ) { if( !it.is_valid() ) { rep.warn( "specifies unknown upgrade \"%s\"", it.str() ); @@ -2036,6 +2045,13 @@ bool Character::can_uninstall_bionic( const bionic_id &b_id, player &installer, } } + for (const bionic_id &bid : get_bionics()) { + if (bid->required_bionic && bid->required_bionic == b_id) { + popup(_("%s cannot be removed because installed bionic %s requires it."), + b_id->name, bid->name); + } + } + if( b_id == bio_eye_optic ) { popup( _( "The Telescopic Lenses are part of %s eyes now. Removing them would leave %s blind." ), disp_name( true ), disp_name() ); @@ -2279,6 +2295,11 @@ 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; + } + std::vector conflicting_muts; for( const trait_id &mid : bioid->canceled_mutations ) { if( has_trait( mid ) ) { diff --git a/src/bionics.h b/src/bionics.h index 78208bfb99c5..a3a478383162 100644 --- a/src/bionics.h +++ b/src/bionics.h @@ -134,6 +134,11 @@ struct bionic_data { * Upgrades available for this bionic (opposite to @ref upgraded_bionic). */ std::set 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. + */ + bionic_id required_bionic; std::set flags; bool has_flag( const flag_id &flag ) const; diff --git a/src/item.cpp b/src/item.cpp index 6daf7c5bd204..c4fd3729ba8c 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -3382,6 +3382,13 @@ void item::bionic_info( std::vector &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)); + } + + insert_separation_line(info); + if( !bid->encumbrance.empty() ) { info.emplace_back( "DESCRIPTION", _( "Encumbrance: " ), iteminfo::no_newline );