diff --git a/src/bionics.cpp b/src/bionics.cpp index 753c2454159f0..341ae23218c12 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -132,7 +132,7 @@ void force_comedown( effect &eff ) // share functions.... bool player::activate_bionic( int b, bool eff_only ) { - bionic &bio = my_bionics[b]; + bionic &bio = ( *my_bionics )[b]; // Preserve the fake weapon used to initiate bionic gun firing static item bio_gun( weapon ); @@ -191,14 +191,14 @@ bool player::activate_bionic( int b, bool eff_only ) weapon = item( bionics[bio.id].fake_item ); weapon.invlet = '#'; } else if( bio.id == "bio_ears" && has_active_bionic( bionic_id( "bio_earplugs" ) ) ) { - for( auto &i : my_bionics ) { + for( auto &i : *my_bionics ) { if( i.id == "bio_earplugs" ) { i.powered = false; add_msg( m_info, _( "Your %s automatically turn off." ), bionics[i.id].name.c_str() ); } } } else if( bio.id == "bio_earplugs" && has_active_bionic( bionic_id( "bio_ears" ) ) ) { - for( auto &i : my_bionics ) { + for( auto &i : *my_bionics ) { if( i.id == "bio_ears" ) { i.powered = false; add_msg( m_info, _( "Your %s automatically turns off." ), bionics[i.id].name.c_str() ); @@ -554,7 +554,7 @@ bool player::activate_bionic( int b, bool eff_only ) bool player::deactivate_bionic( int b, bool eff_only ) { - bionic &bio = my_bionics[b]; + bionic &bio = ( *my_bionics )[b]; // Just do the effect, no stat changing or messages if( !eff_only ) { @@ -659,7 +659,7 @@ bool attempt_recharge( player &p, bionic &bio, int &amount, int factor = 1, int void player::process_bionic( int b ) { - bionic &bio = my_bionics[b]; + bionic &bio = ( *my_bionics )[b]; // Only powered bionics should be processed if( !bio.powered ) { return; @@ -895,8 +895,8 @@ bool player::uninstall_bionic( bionic_id const &b_id, int skill_level ) // Surgery is imminent, retract claws or blade if active if( skill_level == -1 ) { - for( size_t i = 0; i < my_bionics.size(); i++ ) { - const auto &bio = my_bionics[ i ]; + for( size_t i = 0; i < my_bionics->size(); i++ ) { + const auto &bio = ( *my_bionics )[ i ]; if( bio.powered && bio.info().weapon_bionic ) { deactivate_bionic( i ); } @@ -1243,7 +1243,7 @@ std::string list_occupied_bps( const bionic_id &bio_id, const std::string &intro int player::get_used_bionics_slots( const body_part bp ) const { int used_slots = 0; - for( auto &bio : my_bionics ) { + for( auto &bio : *my_bionics ) { auto search = bionics[bio.id].occupied_bodyparts.find( bp ); if( search != bionics[bio.id].occupied_bodyparts.end() ) { used_slots += search->second; @@ -1326,9 +1326,9 @@ void player::add_bionic( bionic_id const &b ) return; } - my_bionics.push_back( bionic( b, get_free_invlet( *this ) ) ); + my_bionics->push_back( bionic( b, get_free_invlet( *this ) ) ); if( b == "bio_tools" || b == "bio_ears" ) { - activate_bionic( my_bionics.size() - 1 ); + activate_bionic( my_bionics->size() - 1 ); } for( const auto &inc_bid : bionics[b].included_bionics ) { @@ -1340,8 +1340,8 @@ void player::add_bionic( bionic_id const &b ) void player::remove_bionic( bionic_id const &b ) { - std::vector new_my_bionics; - for( auto &i : my_bionics ) { + bionic_collection new_my_bionics; + for( auto &i : *my_bionics ) { if( b == i.id ) { continue; } @@ -1353,13 +1353,13 @@ void player::remove_bionic( bionic_id const &b ) new_my_bionics.push_back( bionic( i.id, i.invlet ) ); } - my_bionics = new_my_bionics; + *my_bionics = new_my_bionics; recalc_sight_limits(); } int player::num_bionics() const { - return my_bionics.size(); + return my_bionics->size(); } std::pair player::amount_of_storage_bionics() const @@ -1367,7 +1367,7 @@ std::pair player::amount_of_storage_bionics() const int lvl = max_power_level; // exclude amount of power capacity obtained via non-power-storage CBMs - for( auto it : my_bionics ) { + for( auto it : *my_bionics ) { lvl -= bionics[it.id].capacity; } @@ -1397,7 +1397,7 @@ std::pair player::amount_of_storage_bionics() const bionic &player::bionic_at_index( int i ) { - return my_bionics[i]; + return ( *my_bionics )[i]; } @@ -1408,7 +1408,7 @@ bool player::remove_random_bionic() const int numb = num_bionics(); if( numb ) { int rem = rng( 0, num_bionics() - 1 ); - const auto bionic = my_bionics[rem]; + const auto bionic = ( *my_bionics )[rem]; remove_bionic( bionic.id ); add_msg( m_bad, _( "Your %s fails, and is destroyed!" ), bionics[ bionic.id ].name.c_str() ); recalc_sight_limits(); diff --git a/src/bionics.h b/src/bionics.h index 5574ff49f3412..4f9c503dd8b72 100644 --- a/src/bionics.h +++ b/src/bionics.h @@ -103,6 +103,12 @@ struct bionic : public JsonSerializer, public JsonDeserializer { void deserialize( JsonIn &jsin ) override; }; +// A simpler wrapper to allow forward declarations of it. std::vector can not +// be forward declared without a *definition* of bionic, but this wrapper can. +class bionic_collection : public std::vector +{ +}; + void check_bionics(); void reset_bionics(); void load_bionic( JsonObject &jsobj ); // load a bionic from JSON diff --git a/src/bionics_ui.cpp b/src/bionics_ui.cpp index e4c52106286ba..bbe1adc63c7f1 100644 --- a/src/bionics_ui.cpp +++ b/src/bionics_ui.cpp @@ -32,7 +32,7 @@ enum bionic_menu_mode { bionic *player::bionic_by_invlet( const long ch ) { - for( auto &elem : my_bionics ) { + for( auto &elem : *my_bionics ) { if( elem.invlet == ch ) { return &elem; } @@ -276,7 +276,7 @@ nc_color get_bionic_text_color( bionic const &bio, bool const isHighlightedBioni return type; } -std::vector< bionic *>filtered_bionics( std::vector &all_bionics, bionic_tab_mode mode ) +std::vector< bionic *>filtered_bionics( bionic_collection &all_bionics, bionic_tab_mode mode ) { std::vector< bionic *>filtered_entries; for( auto &elem : all_bionics ) { @@ -289,8 +289,8 @@ std::vector< bionic *>filtered_bionics( std::vector &all_bionics, bionic void player::power_bionics() { - std::vector passive = filtered_bionics( my_bionics, TAB_PASSIVE ); - std::vector active = filtered_bionics( my_bionics, TAB_ACTIVE ); + std::vector passive = filtered_bionics( *my_bionics, TAB_PASSIVE ); + std::vector active = filtered_bionics( *my_bionics, TAB_ACTIVE ); bionic *bio_last = NULL; bionic_tab_mode tab_mode = TAB_ACTIVE; @@ -310,7 +310,7 @@ void player::power_bionics() const int HEIGHT = std::min( TERMY, std::max( FULL_SCREEN_HEIGHT, TITLE_HEIGHT + TITLE_TAB_HEIGHT + - ( int )my_bionics.size() + 2 ) ); + ( int )my_bionics->size() + 2 ) ); const int WIDTH = FULL_SCREEN_WIDTH + ( TERMX - FULL_SCREEN_WIDTH ) / 2; const int START_X = ( TERMX - WIDTH ) / 2; const int START_Y = ( TERMY - HEIGHT ) / 2; @@ -368,8 +368,8 @@ void player::power_bionics() for( ;; ) { if( recalc ) { - passive = filtered_bionics( my_bionics, TAB_PASSIVE ); - active = filtered_bionics( my_bionics, TAB_ACTIVE ); + passive = filtered_bionics( *my_bionics, TAB_PASSIVE ); + active = filtered_bionics( *my_bionics, TAB_ACTIVE ); if( active.empty() && !passive.empty() ) { tab_mode = TAB_PASSIVE; @@ -590,7 +590,7 @@ void player::power_bionics() } if( menu_mode == ACTIVATING ) { if( bio_data.activated ) { - int b = tmp - &my_bionics[0]; + int b = tmp - &( *my_bionics )[0]; if( tmp->powered ) { deactivate_bionic( b ); } else { diff --git a/src/character.cpp b/src/character.cpp index 11b7311ffb84e..dbb18ab6cb3dd 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -1,6 +1,7 @@ #include "character.h" #include "game.h" #include "map.h" +#include "bionics.h" #include "map_selector.h" #include "vehicle_selector.h" #include "debug.h" @@ -132,6 +133,8 @@ Character::Character() : Creature(), visitable() path_settings = pathfinding_settings{ 0, 1000, 1000, 0, true, false, true }; } +Character::~Character() = default; + field_id Character::bloodType() const { if (has_trait( trait_ACIDBLOOD )) @@ -614,7 +617,7 @@ float Character::get_vision_threshold( float light_level ) const { bool Character::has_bionic(const bionic_id &b) const { - for (auto &i : my_bionics) { + for (auto &i : *my_bionics) { if (i.id == b) { return true; } @@ -624,7 +627,7 @@ bool Character::has_bionic(const bionic_id &b) const bool Character::has_active_bionic(const bionic_id &b) const { - for (auto &i : my_bionics) { + for (auto &i : *my_bionics) { if (i.id == b) { return (i.powered); } diff --git a/src/character.h b/src/character.h index 81dd64d8d3bbe..c0f66f78e1657 100644 --- a/src/character.h +++ b/src/character.h @@ -5,7 +5,7 @@ #include "visitable.h" #include "creature.h" #include "inventory.h" -#include "bionics.h" +#include "copyable_unique_ptr.h" #include "skill.h" #include "map_selector.h" #include "pathfinding.h" @@ -20,6 +20,9 @@ class field_entry; class vehicle; struct resistances; struct mutation_branch; +class bionic_collection; +struct bionic_data; +using bionic_id = string_id; enum vision_modes { DEBUG_NIGHTVISION, @@ -71,7 +74,7 @@ struct aim_type { class Character : public Creature, public visitable { public: - ~Character() override { }; + ~Character() override; field_id bloodType() const override; field_id gibType() const override; @@ -602,7 +605,7 @@ class Character : public Creature, public visitable item weapon; item ret_null; // Null item, sometimes returns by weapon() etc - std::vector my_bionics; + copyable_unique_ptr my_bionics; protected: void on_stat_change( const std::string &, int ) override {}; diff --git a/src/crafting.cpp b/src/crafting.cpp index d9512d31aa46b..eb4b5aa770cd0 100644 --- a/src/crafting.cpp +++ b/src/crafting.cpp @@ -6,6 +6,7 @@ #include "game.h" #include "game_inventory.h" #include "input.h" +#include "bionics.h" #include "inventory.h" #include "itype.h" #include "json.h" @@ -285,7 +286,7 @@ const inventory &player::crafting_inventory() cached_crafting_inventory += inv; cached_crafting_inventory += weapon; cached_crafting_inventory += worn; - for( const auto &bio : my_bionics ) { + for( const auto &bio : *my_bionics ) { const auto &bio_data = bio.info(); if( ( !bio_data.activated || bio.powered ) && !bio_data.fake_item.empty() ) { diff --git a/src/game.cpp b/src/game.cpp index 146062080f4c2..11c63f641cd3f 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -11,6 +11,7 @@ #include "veh_type.h" #include "options.h" #include "auto_pickup.h" +#include "bionics.h" #include "gamemode.h" #include "mapbuffer.h" #include "map_item_stack.h" diff --git a/src/item_factory.cpp b/src/item_factory.cpp index d0e736661c21a..dc25b3296aab2 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -2,7 +2,6 @@ #include "addiction.h" #include "artifact.h" -#include "bionics.h" #include "catacharset.h" #include "construction.h" #include "crafting.h" diff --git a/src/melee.cpp b/src/melee.cpp index e3ee2bb46dc3d..0965d2e137c49 100644 --- a/src/melee.cpp +++ b/src/melee.cpp @@ -1,5 +1,4 @@ #include "player.h" -#include "bionics.h" #include "debug.h" #include "game.h" #include "game_inventory.h" diff --git a/src/mission_companion.cpp b/src/mission_companion.cpp index 323517fb99e11..cdb88a6db1ee1 100644 --- a/src/mission_companion.cpp +++ b/src/mission_companion.cpp @@ -5,6 +5,7 @@ #include "dialogue.h" #include "rng.h" #include "line.h" +#include "bionics.h" #include "debug.h" #include "catacharset.h" #include "messages.h" @@ -101,7 +102,7 @@ void talk_function::bionic_install(npc &p) void talk_function::bionic_remove(npc &p) { - std::vector all_bio = g->u.my_bionics; + bionic_collection all_bio = *g->u.my_bionics; if (all_bio.size() == 0){ popup(_("You don't have any bionics installed...")); return; diff --git a/src/newcharacter.cpp b/src/newcharacter.cpp index ced63ef9a693e..abec0e4cfdfc6 100644 --- a/src/newcharacter.cpp +++ b/src/newcharacter.cpp @@ -6,6 +6,7 @@ #include "start_location.h" #include "input.h" #include "output.h" +#include "bionics.h" #include "rng.h" #include "game.h" #include "name.h" diff --git a/src/player.cpp b/src/player.cpp index bf2d3d5e33a70..2c45efbb8a777 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -2416,8 +2416,8 @@ void player::memorial( std::ostream &memorial_file, std::string epitaph ) //Bionics memorial_file << _( "Bionics:" ) << eol; int total_bionics = 0; - for( size_t i = 0; i < my_bionics.size(); ++i ) { - memorial_file << indent << ( i + 1 ) << ": " << my_bionics[i].id->name << eol; + for( size_t i = 0; i < my_bionics->size(); ++i ) { + memorial_file << indent << ( i + 1 ) << ": " << (*my_bionics)[i].id->name << eol; total_bionics++; } if( total_bionics == 0 ) { @@ -5390,8 +5390,8 @@ void player::suffer() } } - for (size_t i = 0; i < my_bionics.size(); i++) { - if (my_bionics[i].powered) { + for (size_t i = 0; i < my_bionics->size(); i++) { + if ((*my_bionics)[i].powered) { process_bionic(i); } } @@ -6755,7 +6755,7 @@ int player::invlet_to_position( const long linvlet ) const } bool player::can_interface_armor() const { - bool okay = std::any_of( my_bionics.begin(), my_bionics.end(), + bool okay = std::any_of( my_bionics->begin(), my_bionics->end(), []( const bionic &b ) { return b.powered && b.info().armor_interface; } ); return okay; } @@ -11371,7 +11371,7 @@ void player::place_corpse() for( auto itm : tmp ) { g->m.add_item_or_charges( pos(), *itm ); } - for( auto & bio : my_bionics ) { + for( auto & bio : *my_bionics ) { if( item::type_is_defined( bio.id.str() ) ) { body.put_in( item( bio.id.str(), calendar::turn ) ); } diff --git a/src/player.h b/src/player.h index 8c94e428f3505..ed4b3e54738d4 100644 --- a/src/player.h +++ b/src/player.h @@ -20,7 +20,7 @@ static const std::string DEFAULT_HOTKEYS("1234567890abcdefghijklmnopqrstuvwxyz"); enum action_id : int; - +struct bionic; class dispersion_sources; class monster; class game; diff --git a/src/profession.cpp b/src/profession.cpp index a0790c3a3903e..d4ff34cc9afd5 100644 --- a/src/profession.cpp +++ b/src/profession.cpp @@ -6,7 +6,6 @@ #include "debug.h" #include "json.h" #include "player.h" -#include "bionics.h" #include "text_snippets.h" #include "rng.h" #include "translations.h" diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 4236dc0a71cd0..54bc943b0b13f 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -315,7 +315,7 @@ void Character::load(JsonObject &data) } } - data.read( "my_bionics", my_bionics ); + data.read( "my_bionics", *my_bionics ); for( auto &w : worn ) { w.on_takeoff( *this ); @@ -406,7 +406,7 @@ void Character::store(JsonOut &json) const json.member( "mutations", my_mutations ); // "Fracking Toasters" - Saul Tigh, toaster - json.member( "my_bionics", my_bionics ); + json.member( "my_bionics", *my_bionics ); // skills json.member( "skills" ); diff --git a/src/scenario.cpp b/src/scenario.cpp index 91a08c7e60521..1ba72eb9436a5 100644 --- a/src/scenario.cpp +++ b/src/scenario.cpp @@ -7,7 +7,6 @@ #include "debug.h" #include "json.h" #include "player.h" -#include "bionics.h" #include "game.h" #include "translations.h" #include "pldata.h" diff --git a/src/visitable.cpp b/src/visitable.cpp index c33bd0f7420cc..698f1537f8972 100644 --- a/src/visitable.cpp +++ b/src/visitable.cpp @@ -7,6 +7,7 @@ #include "character.h" #include "map_selector.h" #include "vehicle_selector.h" +#include "bionics.h" #include "map.h" #include "submap.h" #include "vehicle.h" @@ -184,7 +185,7 @@ bool visitable::has_quality( const quality_id &qual, int level, int q { auto self = static_cast( this ); - for( const auto &bio : self->my_bionics ) { + for( const auto &bio : *self->my_bionics ) { if( bio.get_quality( qual ) >= level ) { if( qty <= 1 ) { return true; @@ -243,7 +244,7 @@ int visitable::max_quality( const quality_id &qual ) const auto self = static_cast( this ); - for( const auto &bio : self->my_bionics ) { + for( const auto &bio : *self->my_bionics ) { res = std::max( res, bio.get_quality( qual ) ); } diff --git a/tests/bionics_test.cpp b/tests/bionics_test.cpp index 426e7f4def431..e3ec66f37b187 100644 --- a/tests/bionics_test.cpp +++ b/tests/bionics_test.cpp @@ -5,11 +5,12 @@ #include "ammo.h" #include "itype.h" #include "game.h" +#include "bionics.h" #include "player.h" void clear_bionics( player &p ) { - p.my_bionics.clear(); + p.my_bionics->clear(); p.power_level = 0; p.max_power_level = 0; @@ -27,8 +28,8 @@ void give_and_activate( player &p, bionic_id const &bioid ) // get bionic's index - might not be "last added" due to "integrated" ones int bioindex = -1; - for( size_t i = 0; i < p.my_bionics.size(); i++ ) { - const auto &bio = p.my_bionics[ i ]; + for( size_t i = 0; i < p.my_bionics->size(); i++ ) { + const auto &bio = ( *p.my_bionics )[ i ]; if( bio.id == bioid ) { bioindex = i; }