diff --git a/plugins/stockpiles.cpp b/plugins/stockpiles.cpp index cb4406264..9bb507df4 100644 --- a/plugins/stockpiles.cpp +++ b/plugins/stockpiles.cpp @@ -25,6 +25,7 @@ #include "df/ui.h" #include "df/building_stockpilest.h" +#include "df/stockpile_settings.h" #include "df/global_objects.h" #include "df/viewscreen_dwarfmodest.h" #include @@ -38,14 +39,16 @@ #include #include - -#include "stockpiles.pb.h" - +// protobuf +#include "proto/stockpiles.pb.h" #include +// os #include +// stl #include +#include using std::vector; using std::string; @@ -216,6 +219,7 @@ static df::creature_raw* find_creature ( int32_t idx ) /** * Retrieve creature index from id string + * @return -1 if not found */ static int16_t find_creature ( const std::string &creature_id ) { @@ -232,6 +236,7 @@ static df::plant_raw* find_plant ( size_t idx ) /** * Retrieve plant index from id string + * @return -1 if not found */ static size_t find_plant ( const std::string &plant_id ) { @@ -281,7 +286,7 @@ public: else { food_mat.material.decode ( type, main_idx ); - out << " type(" << type << ") index("<< main_idx <<")" <::size_type idx ) @@ -299,6 +304,11 @@ public: return std::string(); } + static size_t food_max_size ( organic_mat_category::organic_mat_category mat_category ) + { + return world->raws.mat_table.organic_types[mat_category].size(); + } + static void food_build_map ( std::ostream &out ) { if ( index_built ) @@ -319,7 +329,7 @@ public: index_built = true; } - static int food_idx_by_token ( std::ostream &out, organic_mat_category::organic_mat_category mat_category, const std::string & token ) + static int16_t food_idx_by_token ( std::ostream &out, organic_mat_category::organic_mat_category mat_category, const std::string & token ) { int16_t food_idx = -1; df::world_raws &raws = world->raws; @@ -417,7 +427,7 @@ public: * @param out for debugging * @param stockpile stockpile to read or write settings to */ - StockpileSerializer ( building_stockpilest const * stockpile ) + StockpileSerializer ( building_stockpilest * stockpile ) : mDebug ( false ) , mOut ( 0 ) , mNull() @@ -491,7 +501,7 @@ private: bool mDebug; std::ostream * mOut; NullStream mNull; - building_stockpilest const * mPile; + building_stockpilest * mPile; StockpileSettings mBuffer; std::map mOtherMatsFurniture; std::map mOtherMatsFinishedGoods; @@ -572,7 +582,7 @@ private: * Find an enum's value based off the string label. * @param traits the enum's trait struct * @param token the string value in key_table - * @return the enum's value + * @return the enum's value, -1 if not found */ template static typename df::enum_traits::base_type linear_index ( std::ostream & out, df::enum_traits traits, const std::string &token ) @@ -608,16 +618,18 @@ private: { // exporting FuncWriteExport set_value; - vector stockpile_values; + std::vector * stockpile_values; // importing FuncReadImport get_value; size_t serialized_count; + bool valid = false; - food_pair ( FuncWriteExport s, const vector& sp_v, FuncReadImport g, size_t count ) + food_pair ( FuncWriteExport s, std::vector* sp_v, FuncReadImport g, size_t count ) : set_value ( s ) , stockpile_values ( sp_v ) , get_value ( g ) - ,serialized_count ( count ) + , serialized_count ( count ) + , valid ( true ) {} food_pair() {} }; @@ -635,16 +647,21 @@ private: * * The unserialization process is the same in reverse. */ - void serialize_list_organic_mat ( FuncWriteExport add_value, const vector & list, organic_mat_category::organic_mat_category cat ) + void serialize_list_organic_mat ( FuncWriteExport add_value, const std::vector * list, organic_mat_category::organic_mat_category cat ) { - for ( size_t i = 0; i < list.size(); ++i ) + if ( !list ) { - if ( list.at ( i ) ) + debug() << "serialize_list_organic_mat: list null" << endl; + } + for ( size_t i = 0; i < list->size(); ++i ) + { + if ( list->at ( i ) ) { std::string token = OrganicMatLookup::food_token_by_idx ( debug(), cat, i ); if ( !token.empty() ) { add_value ( token ); + debug() << " organic_material " << i << " is " << token << endl; } else { @@ -657,24 +674,34 @@ private: /** * @see serialize_list_organic_mat */ - void unserialize_list_organic_mat ( FuncReadImport get_value, size_t list_size, organic_mat_category::organic_mat_category cat ) + void unserialize_list_organic_mat ( FuncReadImport get_value, size_t list_size, std::vector *pile_list, organic_mat_category::organic_mat_category cat ) { if ( list_size > 0 ) { + pile_list->resize ( OrganicMatLookup::food_max_size ( cat ), '\0' ); for ( size_t i = 0; i < list_size; ++i ) { std::string token = get_value ( i ); - int idx = OrganicMatLookup::food_idx_by_token ( debug(), cat, token ); + int16_t idx = OrganicMatLookup::food_idx_by_token ( debug(), cat, token ); debug() << " organic_material " << idx << " is " << token << endl; - //mPile->settings.food.meat.at(idx) = (char) 1; + if ( idx >= pile_list->size() ) + { + debug() << "error organic mat index too large! idx[" << idx << "] max_size[" << pile_list->size() << "]" << endl; + continue; + } + pile_list->at ( idx ) = 1; } } + else + { + pile_list->clear(); + } } /** * @see serialize_list_organic_mat */ - void serialize_list_item_type ( FuncItemAllowed is_allowed, FuncWriteExport add_value, std::vector list ) + void serialize_list_item_type ( FuncItemAllowed is_allowed, FuncWriteExport add_value, const std::vector &list ) { using df::enums::item_type::item_type; df::enum_traits type_traits; @@ -695,25 +722,39 @@ private: /** * @see serialize_list_organic_mat */ - void unserialize_list_item_type ( FuncItemAllowed is_allowed, FuncReadImport read_value, int32_t list_size ) + void unserialize_list_item_type ( FuncItemAllowed is_allowed, FuncReadImport read_value, int32_t list_size, std::vector *pile_list ) { - using df::enums::item_type::item_type; - df::enum_traits type_traits; - for ( int32_t i = 0; i < list_size; ++i ) + if ( list_size > 0 ) { - const std::string token = read_value ( i ); - // subtract one because item_type starts at -1 - const df::enum_traits::base_type idx = linear_index ( debug(), type_traits, token ) - 1; - const item_type type = ( item_type ) idx; - if ( !is_allowed ( type ) ) continue; - debug() << " item_type " << idx << " is " << token << endl; + using df::enums::item_type::item_type; + df::enum_traits type_traits; + pile_list->resize ( 112, '\0' ); // TODO remove hardcoded list size value + for ( int32_t i = 0; i < list_size; ++i ) + { + const std::string token = read_value ( i ); + // subtract one because item_type starts at -1 + const df::enum_traits::base_type idx = linear_index ( debug(), type_traits, token ) - 1; + const item_type type = ( item_type ) idx; + if ( !is_allowed ( type ) ) continue; + debug() << " item_type " << idx << " is " << token << endl; + if ( idx >= pile_list->size() ) + { + debug() << "error item_type index too large! idx[" << idx << "] max_size[" << pile_list->size() << "]" << endl; + continue; + } + pile_list->at ( idx ) = 1; + } + } + else + { + pile_list->clear(); } } /** * @see serialize_list_organic_mat */ - void serialize_list_material ( FuncMaterialAllowed is_allowed, FuncWriteExport add_value, std::vector list ) + void serialize_list_material ( FuncMaterialAllowed is_allowed, FuncWriteExport add_value, const std::vector &list ) { MaterialInfo mi; for ( size_t i = 0; i < list.size(); ++i ) @@ -731,19 +772,33 @@ private: /** * @see serialize_list_organic_mat */ - void unserialize_list_material ( FuncMaterialAllowed is_allowed, FuncReadImport read_value, int32_t list_size ) + void unserialize_list_material ( FuncMaterialAllowed is_allowed, FuncReadImport read_value, int32_t list_size, std::vector *pile_list ) { - for ( int i = 0; i < list_size; ++i ) + if ( list_size > 0 ) { - const std::string token = read_value ( i ); - MaterialInfo mi; - mi.find ( token ); - if ( !is_allowed ( mi ) ) continue; - debug() << " material " << mi.index << " is " << token << endl; + std::set idx_set; + pile_list->resize ( world->raws.inorganics.size(), '\0' ); + for ( int i = 0; i < list_size; ++i ) + { + const std::string token = read_value ( i ); + MaterialInfo mi; + mi.find ( token ); + if ( !is_allowed ( mi ) ) continue; + debug() << " material " << mi.index << " is " << token << endl; + if ( mi.index >= pile_list->size() ) + { + debug() << "error material index too large! idx[" << mi.index << "] max_size[" << pile_list->size() << "]" << endl; + continue; + } + pile_list->at ( mi.index ) = 1; + } + } + else + { + pile_list->clear(); } } - /** * @see serialize_list_organic_mat */ @@ -762,23 +817,39 @@ private: } } + /** + * Set all values in a bool[7] to false + */ + void quality_clear ( bool ( &pile_list ) [7] ) + { + std::fill ( pile_list, pile_list+7, false ); + } + /** * @see serialize_list_organic_mat */ - void unserialize_list_quality ( FuncReadImport read_value, int32_t list_size ) + void unserialize_list_quality ( FuncReadImport read_value, int32_t list_size, bool ( &pile_list ) [7] ) { - using df::enums::item_quality::item_quality; - df::enum_traits quality_traits; - for ( int i = 0; i < list_size; ++i ) + if ( list_size > 0 && list_size < 7 ) { - const std::string quality = read_value ( i ); - df::enum_traits::base_type idx = linear_index ( debug(), quality_traits, quality ); - if ( idx < 0 ) + using df::enums::item_quality::item_quality; + df::enum_traits quality_traits; + for ( int i = 0; i < list_size; ++i ) { - debug() << " invalid quality token " << quality << endl; - continue; + const std::string quality = read_value ( i ); + df::enum_traits::base_type idx = linear_index ( debug(), quality_traits, quality ); + if ( idx < 0 ) + { + debug() << " invalid quality token " << quality << endl; + continue; + } + debug() << " quality: " << idx << " is " << quality << endl; + pile_list[idx] = true; } - debug() << " quality: " << idx << " is " << quality << endl; + } + else + { + quality_clear ( pile_list ); } } @@ -806,18 +877,33 @@ private: /** * @see serialize_list_organic_mat */ - void unserialize_list_other_mats ( const std::map other_mats, FuncReadImport read_value, int32_t list_size ) + void unserialize_list_other_mats ( const std::map other_mats, FuncReadImport read_value, int32_t list_size, std::vector *pile_list ) { - for ( int i = 0; i < list_size; ++i ) + if ( list_size > 0 ) { - const std::string token = read_value ( i ); - size_t idx = other_mats_token ( other_mats, token ); - if ( idx < 0 ) + pile_list->resize ( other_mats.size(), '\0' ); + for ( int i = 0; i < list_size; ++i ) { - debug() << "invalid other mat with token " << token; - continue; + const std::string token = read_value ( i ); + size_t idx = other_mats_token ( other_mats, token ); + if ( idx < 0 ) + { + debug() << "invalid other mat with token " << token; + continue; + } + debug() << " other_mats " << idx << " is " << token << endl; + if ( idx >= pile_list->size() ) + { + debug() << "error other_mats index too large! idx[" << idx << "] max_size[" << pile_list->size() << "]" << endl; + continue; + } + + pile_list->at ( idx ) = 1; } - debug() << " other_mats " << idx << " is " << token << endl; + } + else + { + pile_list->clear(); } } @@ -834,8 +920,7 @@ private: // skip procedurally generated items if ( a->base_flags.is_set ( 0 ) ) continue; ItemTypeInfo ii; - ii.decode ( type, i ); - if ( !ii.isValid() ) continue; + if ( !ii.decode ( type, i ) ) continue; add_value ( ii.getToken() ); debug() << " itemdef type" << i << " is " << ii.getToken() << endl; } @@ -845,14 +930,28 @@ private: /** * @see serialize_list_organic_mat */ - void unserialize_list_itemdef ( FuncReadImport read_value, int32_t list_size ) + void unserialize_list_itemdef ( FuncReadImport read_value, int32_t list_size, std::vector *pile_list, item_type::item_type type ) { - for ( int i = 0; i < list_size; ++i ) + if ( list_size > 0 ) { - std::string token = read_value ( i ); - ItemTypeInfo ii; - if ( !ii.find ( token ) ) continue; - debug() << " itemdef " << ii.subtype << " is " << token << endl; + pile_list->resize ( Items::getSubtypeCount ( type ), '\0' ); + for ( int i = 0; i < list_size; ++i ) + { + std::string token = read_value ( i ); + ItemTypeInfo ii; + if ( !ii.find ( token ) ) continue; + debug() << " itemdef " << ii.subtype << " is " << token << endl; + if ( ii.subtype >= pile_list->size() ) + { + debug() << "error itemdef index too large! idx[" << ii.subtype << "] max_size[" << pile_list->size() << "]" << endl; + continue; + } + pile_list->at ( ii.subtype ) = 1; + } + } + else + { + pile_list->clear(); } } @@ -891,17 +990,27 @@ private: mBuffer.set_unknown1 ( mPile->settings.unk1 ); mBuffer.set_allow_inorganic ( mPile->settings.allow_inorganic ); mBuffer.set_allow_organic ( mPile->settings.allow_organic ); + mBuffer.set_corpses ( mPile->settings.flags.bits.corpses ); } void read_general() { - const int bins = mBuffer.max_bins(); - const int wheelbarrows = mBuffer.max_wheelbarrows(); - const bool use_links_only = mBuffer.use_links_only(); - const bool unknown1 = mBuffer.unknown1(); - const bool allow_inorganic = mBuffer.allow_inorganic(); - const bool allow_organic = mBuffer.allow_organic(); - + if ( mBuffer.has_max_bins() ) + mPile->max_bins = mBuffer.max_bins(); + if ( mBuffer.has_max_wheelbarrows() ) + mPile->max_wheelbarrows = mBuffer.max_wheelbarrows(); + if ( mBuffer.has_max_barrels() ) + mPile->max_barrels = mBuffer.max_barrels(); + if ( mBuffer.has_use_links_only() ) + mPile->use_links_only = mBuffer.use_links_only(); + if ( mBuffer.has_unknown1() ) + mPile->settings.unk1 = mBuffer.unknown1(); + if ( mBuffer.has_allow_inorganic() ) + mPile->settings.allow_inorganic = mBuffer.allow_inorganic(); + if ( mBuffer.has_allow_organic() ) + mPile->settings.allow_organic = mBuffer.allow_organic(); + if ( mBuffer.has_corpses() ) + mPile->settings.flags.bits.corpses = mBuffer.corpses(); } void write_animals() @@ -924,19 +1033,37 @@ private: { if ( mBuffer.has_animals() ) { -// mPile->settings.flags.bits.animals = true; - debug() << "animals:" <settings.flags.bits.animals = 1; + debug() << "animals:" << endl; + mPile->settings.animals.empty_cages = mBuffer.animals().empty_cages(); + mPile->settings.animals.empty_traps = mBuffer.animals().empty_traps(); if ( mBuffer.animals().enabled_size() > 0 ) { - for ( auto i = 0; i < mBuffer.animals().enabled().size(); ++i ) + mPile->settings.animals.enabled.resize ( world->raws.creatures.all.size(), '\0' ); + debug() << " pile has " << mPile->settings.animals.enabled.size() << endl; + for ( auto i = 0; i < mBuffer.animals().enabled_size(); ++i ) { std::string id = mBuffer.animals().enabled ( i ); int idx = find_creature ( id ); debug() << id << " " << idx << endl; + if ( idx < 0 || idx >= mPile->settings.animals.enabled.size() ) + { + debug() << "WARNING: animal index invalid: " << idx << endl; + continue; + } + mPile->settings.animals.enabled.at ( idx ) = ( char ) 1; } } + else + { + mPile->settings.animals.enabled.clear(); + } + + } + else + { + mPile->settings.animals.enabled.clear(); + mPile->settings.flags.bits.animals = 0; } } @@ -953,7 +1080,7 @@ private: mBuffer.mutable_food()->add_meat ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().meat ( idx ); }; - return food_pair ( setter, mPile->settings.food.meat, getter, mBuffer.food().meat_size() ); + return food_pair ( setter, &mPile->settings.food.meat, getter, mBuffer.food().meat_size() ); } case organic_mat_category::Fish: { @@ -962,7 +1089,7 @@ private: mBuffer.mutable_food()->add_fish ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().fish ( idx ); }; - return food_pair ( setter, mPile->settings.food.fish, getter, mBuffer.food().fish_size() ); + return food_pair ( setter, &mPile->settings.food.fish, getter, mBuffer.food().fish_size() ); } case organic_mat_category::UnpreparedFish: { @@ -971,7 +1098,7 @@ private: mBuffer.mutable_food()->add_unprepared_fish ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().unprepared_fish ( idx ); }; - return food_pair ( setter, mPile->settings.food.unprepared_fish, getter, mBuffer.food().unprepared_fish_size() ); + return food_pair ( setter, &mPile->settings.food.unprepared_fish, getter, mBuffer.food().unprepared_fish_size() ); } case organic_mat_category::Eggs: { @@ -980,7 +1107,7 @@ private: mBuffer.mutable_food()->add_egg ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().egg ( idx ); }; - return food_pair ( setter, mPile->settings.food.egg, getter, mBuffer.food().egg_size() ); + return food_pair ( setter, &mPile->settings.food.egg, getter, mBuffer.food().egg_size() ); } case organic_mat_category::Plants: { @@ -989,7 +1116,7 @@ private: mBuffer.mutable_food()->add_plants ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().plants ( idx ); }; - return food_pair ( setter, mPile->settings.food.plants, getter, mBuffer.food().plants_size() ); + return food_pair ( setter, &mPile->settings.food.plants, getter, mBuffer.food().plants_size() ); } case organic_mat_category::PlantDrink: { @@ -998,7 +1125,7 @@ private: mBuffer.mutable_food()->add_drink_plant ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().drink_plant ( idx ); }; - return food_pair ( setter, mPile->settings.food.drink_plant, getter, mBuffer.food().drink_plant_size() ); + return food_pair ( setter, &mPile->settings.food.drink_plant, getter, mBuffer.food().drink_plant_size() ); } case organic_mat_category::CreatureDrink: { @@ -1007,7 +1134,7 @@ private: mBuffer.mutable_food()->add_drink_animal ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().drink_animal ( idx ); }; - return food_pair ( setter, mPile->settings.food.drink_animal, getter, mBuffer.food().drink_animal_size() ); + return food_pair ( setter, &mPile->settings.food.drink_animal, getter, mBuffer.food().drink_animal_size() ); } case organic_mat_category::PlantCheese: { @@ -1016,7 +1143,7 @@ private: mBuffer.mutable_food()->add_cheese_plant ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().cheese_plant ( idx ); }; - return food_pair ( setter, mPile->settings.food.cheese_plant, getter, mBuffer.food().cheese_plant_size() ); + return food_pair ( setter, &mPile->settings.food.cheese_plant, getter, mBuffer.food().cheese_plant_size() ); } case organic_mat_category::CreatureCheese: { @@ -1025,7 +1152,7 @@ private: mBuffer.mutable_food()->add_cheese_animal ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().cheese_animal ( idx ); }; - return food_pair ( setter, mPile->settings.food.cheese_animal, getter, mBuffer.food().cheese_animal_size() ); + return food_pair ( setter, &mPile->settings.food.cheese_animal, getter, mBuffer.food().cheese_animal_size() ); } case organic_mat_category::Seed: { @@ -1034,7 +1161,7 @@ private: mBuffer.mutable_food()->add_seeds ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().seeds ( idx ); }; - return food_pair ( setter, mPile->settings.food.seeds, getter, mBuffer.food().seeds_size() ); + return food_pair ( setter, &mPile->settings.food.seeds, getter, mBuffer.food().seeds_size() ); } case organic_mat_category::Leaf: { @@ -1043,7 +1170,7 @@ private: mBuffer.mutable_food()->add_leaves ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().leaves ( idx ); }; - return food_pair ( setter, mPile->settings.food.leaves, getter, mBuffer.food().leaves_size() ); + return food_pair ( setter, &mPile->settings.food.leaves, getter, mBuffer.food().leaves_size() ); } case organic_mat_category::PlantPowder: { @@ -1052,7 +1179,7 @@ private: mBuffer.mutable_food()->add_powder_plant ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().powder_plant ( idx ); }; - return food_pair ( setter, mPile->settings.food.powder_plant, getter, mBuffer.food().powder_plant_size() ); + return food_pair ( setter, &mPile->settings.food.powder_plant, getter, mBuffer.food().powder_plant_size() ); } case organic_mat_category::CreaturePowder: { @@ -1061,7 +1188,7 @@ private: mBuffer.mutable_food()->add_powder_creature ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().powder_creature ( idx ); }; - return food_pair ( setter, mPile->settings.food.powder_creature, getter, mBuffer.food().powder_creature_size() ); + return food_pair ( setter, &mPile->settings.food.powder_creature, getter, mBuffer.food().powder_creature_size() ); } case organic_mat_category::Glob: { @@ -1070,7 +1197,7 @@ private: mBuffer.mutable_food()->add_glob ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().glob ( idx ); }; - return food_pair ( setter, mPile->settings.food.glob, getter, mBuffer.food().glob_size() ); + return food_pair ( setter, &mPile->settings.food.glob, getter, mBuffer.food().glob_size() ); } case organic_mat_category::PlantLiquid: { @@ -1079,7 +1206,7 @@ private: mBuffer.mutable_food()->add_liquid_plant ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().liquid_plant ( idx ); }; - return food_pair ( setter, mPile->settings.food.liquid_plant, getter, mBuffer.food().liquid_plant_size() ); + return food_pair ( setter, &mPile->settings.food.liquid_plant, getter, mBuffer.food().liquid_plant_size() ); } case organic_mat_category::CreatureLiquid: { @@ -1088,7 +1215,7 @@ private: mBuffer.mutable_food()->add_liquid_animal ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().liquid_animal ( idx ); }; - return food_pair ( setter, mPile->settings.food.liquid_animal, getter, mBuffer.food().liquid_animal_size() ); + return food_pair ( setter, &mPile->settings.food.liquid_animal, getter, mBuffer.food().liquid_animal_size() ); } case organic_mat_category::MiscLiquid: { @@ -1097,7 +1224,7 @@ private: mBuffer.mutable_food()->add_liquid_misc ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().liquid_misc ( idx ); }; - return food_pair ( setter, mPile->settings.food.liquid_misc, getter, mBuffer.food().liquid_misc_size() ); + return food_pair ( setter, &mPile->settings.food.liquid_misc, getter, mBuffer.food().liquid_misc_size() ); } case organic_mat_category::Paste: @@ -1107,7 +1234,7 @@ private: mBuffer.mutable_food()->add_glob_paste ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().glob_paste ( idx ); }; - return food_pair ( setter, mPile->settings.food.glob_paste, getter, mBuffer.food().glob_paste_size() ); + return food_pair ( setter, &mPile->settings.food.glob_paste, getter, mBuffer.food().glob_paste_size() ); } case organic_mat_category::Pressed: { @@ -1116,7 +1243,7 @@ private: mBuffer.mutable_food()->add_glob_pressed ( id ); }; FuncReadImport getter = [=] ( size_t idx ) -> std::string { return mBuffer.food().glob_pressed ( idx ); }; - return food_pair ( setter, mPile->settings.food.glob_pressed, getter, mBuffer.food().glob_pressed_size() ); + return food_pair ( setter, &mPile->settings.food.glob_pressed, getter, mBuffer.food().glob_pressed_size() ); } case organic_mat_category::Leather: case organic_mat_category::Silk: @@ -1136,6 +1263,7 @@ private: case organic_mat_category::CookableLeaf: case organic_mat_category::Yarn: case organic_mat_category::MetalThread: + default: // not used in stockpile food menu break; } @@ -1146,6 +1274,7 @@ private: void write_food() { StockpileSettings::FoodSet *food = mBuffer.mutable_food(); + debug() << " food: " << endl; food->set_prepared_meals ( mPile->settings.food.prepared_meals ); using df::enums::organic_mat_category::organic_mat_category; @@ -1153,25 +1282,45 @@ private: for ( int32_t mat_category = traits.first_item_value; mat_category traits; if ( mBuffer.has_food() ) { + mPile->settings.flags.bits.food = 1; const StockpileSettings::FoodSet food = mBuffer.food(); debug() << "food:" < traits; + if ( food.has_prepared_meals() ) + mPile->settings.food.prepared_meals = food.prepared_meals(); + else + mPile->settings.food.prepared_meals = true; + + for ( int32_t mat_category = traits.first_item_value; mat_category clear(); } + mPile->settings.flags.bits.food = 0; } } @@ -1194,24 +1343,6 @@ private: mOtherMatsFurniture.insert ( std::make_pair ( 14,"YARN" ) ); } - std::string furn_other_mats_index ( int idx ) - { - auto it = mOtherMatsFurniture.find ( idx ); - if ( it == mOtherMatsFurniture.end() ) - return std::string(); - return it->second; - } - - int furn_other_mats ( const std::string & token ) - { - for ( auto it = mOtherMatsFurniture.begin(); it != mOtherMatsFurniture.end(); ++it ) - { - if ( it->second == token ) - return it->first; - } - return -1; - } - void write_furniture() { StockpileSettings::FurnitureSet *furniture= mBuffer.mutable_furniture(); @@ -1230,17 +1361,12 @@ private: } } // metal, stone/clay materials - MaterialInfo mi; - for ( size_t i = 0; i < mPile->settings.furniture.mats.size(); ++i ) + FuncMaterialAllowed filter = std::bind ( &StockpileSerializer::furniture_mat_is_allowed, this, _1 ); + serialize_list_material ( filter, [=] ( const std::string &token ) { - if ( mPile->settings.furniture.mats.at ( i ) ) - { - mi.decode ( 0, i ); - if ( !furniture_mat_is_allowed ( mi ) ) continue; - debug() << "furniture mat: " << mi.getToken() << endl; - furniture->add_mats ( mi.getToken() ); - } - } + furniture->add_mats ( token ); + }, mPile->settings.furniture.mats ); + // other mats serialize_list_other_mats ( mOtherMatsFurniture, [=] ( const std::string &token ) { @@ -1270,44 +1396,65 @@ private: { if ( mBuffer.has_furniture() ) { + mPile->settings.flags.bits.furniture = 1; const StockpileSettings::FurnitureSet furniture = mBuffer.furniture(); debug() << "furniture:" < type_traits; - for ( int i = 0; i < furniture.type_size(); ++i ) + if ( furniture.type_size() > 0 ) { - const std::string type = furniture.type ( i ); - df::enum_traits::base_type idx = linear_index ( debug(), type_traits, type ); - debug() << " type " << idx << " is " << type << endl; + using df::enums::furniture_type::furniture_type; + df::enum_traits type_traits; + mPile->settings.furniture.type.resize ( type_traits.last_item_value+1, '\0' ); + for ( int i = 0; i < furniture.type_size(); ++i ) + { + const std::string type = furniture.type ( i ); + df::enum_traits::base_type idx = linear_index ( debug(), type_traits, type ); + debug() << " type " << idx << " is " << type << endl; + if ( idx < 0 || idx >= mPile->settings.furniture.type.size() ) + { + debug() << "WARNING: furniture type index invalid " << type << ", idx=" << idx << endl; + continue; + } + mPile->settings.furniture.type.at ( idx ) = 1; + } } - // metal, stone/clay materials - for ( int i = 0; i < furniture.mats_size(); ++i ) + else + mPile->settings.furniture.type.clear(); + + FuncMaterialAllowed filter = std::bind ( &StockpileSerializer::furniture_mat_is_allowed, this, _1 ); + unserialize_list_material ( filter, [=] ( const size_t & idx ) -> const std::string& { - const std::string token = furniture.mats ( i ); - MaterialInfo mi; - mi.find ( token ); - if ( !furniture_mat_is_allowed ( mi ) ) continue; - debug() << " mats " << mi.index << " is " << token << endl; - } + return furniture.mats ( idx ); + }, furniture.mats_size(), &mPile->settings.furniture.mats ); + // other materials unserialize_list_other_mats ( mOtherMatsFurniture, [=] ( const size_t & idx ) -> const std::string& { return furniture.other_mats ( idx ); - }, furniture.other_mats_size() ); + }, furniture.other_mats_size(), &mPile->settings.furniture.other_mats ); // core quality unserialize_list_quality ( [=] ( const size_t & idx ) -> const std::string& { return furniture.quality_core ( idx ); - }, furniture.quality_core_size() ); + }, furniture.quality_core_size(), mPile->settings.furniture.quality_core ); // total quality unserialize_list_quality ( [=] ( const size_t & idx ) -> const std::string& { return furniture.quality_total ( idx ); - }, furniture.quality_total_size() ); + }, furniture.quality_total_size(), mPile->settings.furniture.quality_total ); + + } + else + { + mPile->settings.flags.bits.furniture = 0; + mPile->settings.furniture.type.clear(); + mPile->settings.furniture.other_mats.clear(); + mPile->settings.furniture.mats.clear(); + quality_clear ( mPile->settings.furniture.quality_core ); + quality_clear ( mPile->settings.furniture.quality_total ); } } @@ -1408,23 +1555,29 @@ private: }, mPile->settings.refuse.horns ); } - void refuse_read_helper ( std::function get_value, size_t list_size ) + void refuse_read_helper ( std::function get_value, size_t list_size, std::vector* pile_list ) { if ( list_size > 0 ) { + pile_list->resize ( world->raws.creatures.all.size(), '\0' ); for ( size_t i = 0; i < list_size; ++i ) { const std::string creature_id = get_value ( i ); const int idx = find_creature ( creature_id ); const df::creature_raw* creature = find_creature ( idx ); - if ( idx < 0 || !refuse_creature_is_allowed ( creature ) ) + if ( idx < 0 || !refuse_creature_is_allowed ( creature ) || idx >= pile_list->size() ) { - debug() << "invalid refuse creature: " << creature_id << endl; + debug() << "WARNING invalid refuse creature " << creature_id << ", idx=" << idx << endl; continue; } debug() << " creature " << idx << " is " << creature_id << endl; + pile_list->at ( idx ) = 1; } } + else + { + pile_list->clear(); + } } @@ -1433,66 +1586,84 @@ private: { if ( mBuffer.has_refuse() ) { + mPile->settings.flags.bits.refuse = 1; const StockpileSettings::RefuseSet refuse = mBuffer.refuse(); debug() << "refuse: " <settings.refuse.fresh_raw_hide = refuse.fresh_raw_hide(); + mPile->settings.refuse.rotten_raw_hide = refuse.rotten_raw_hide(); // type FuncItemAllowed filter = std::bind ( &StockpileSerializer::refuse_type_is_allowed, this, _1 ); unserialize_list_item_type ( filter, [=] ( const size_t & idx ) -> const std::string& { return refuse.type ( idx ); - }, refuse.type_size() ); + }, refuse.type_size(), &mPile->settings.refuse.type ); // corpses debug() << " corpses" << endl; refuse_read_helper ( [=] ( const size_t & idx ) -> const std::string& { return refuse.corpses ( idx ); - }, refuse.corpses_size() ); + }, refuse.corpses_size(), &mPile->settings.refuse.corpses ); // body_parts debug() << " body_parts" << endl; refuse_read_helper ( [=] ( const size_t & idx ) -> const std::string& { return refuse.body_parts ( idx ); - }, refuse.body_parts_size() ); + }, refuse.body_parts_size(), &mPile->settings.refuse.body_parts ); // skulls debug() << " skulls" << endl; refuse_read_helper ( [=] ( const size_t & idx ) -> const std::string& { return refuse.skulls ( idx ); - }, refuse.skulls_size() ); + }, refuse.skulls_size(), &mPile->settings.refuse.skulls ); // bones debug() << " bones" << endl; refuse_read_helper ( [=] ( const size_t & idx ) -> const std::string& { return refuse.bones ( idx ); - }, refuse.bones_size() ); + }, refuse.bones_size(), &mPile->settings.refuse.bones ); // hair debug() << " hair" << endl; refuse_read_helper ( [=] ( const size_t & idx ) -> const std::string& { return refuse.hair ( idx ); - }, refuse.hair_size() ); + }, refuse.hair_size(), &mPile->settings.refuse.hair ); // shells debug() << " shells" << endl; refuse_read_helper ( [=] ( const size_t & idx ) -> const std::string& { return refuse.shells ( idx ); - }, refuse.shells_size() ); + }, refuse.shells_size(), &mPile->settings.refuse.shells ); // teeth debug() << " teeth" << endl; refuse_read_helper ( [=] ( const size_t & idx ) -> const std::string& { return refuse.teeth ( idx ); - }, refuse.teeth_size() ); + }, refuse.teeth_size(), &mPile->settings.refuse.teeth ); // horns debug() << " horns" << endl; refuse_read_helper ( [=] ( const size_t & idx ) -> const std::string& { return refuse.horns ( idx ); - }, refuse.horns_size() ); + }, refuse.horns_size(), &mPile->settings.refuse.horns ); + } + else + { + mPile->settings.flags.bits.refuse = 0; + mPile->settings.refuse.type.clear(); + mPile->settings.refuse.corpses.clear(); + mPile->settings.refuse.body_parts.clear(); + mPile->settings.refuse.skulls.clear(); + mPile->settings.refuse.bones.clear(); + mPile->settings.refuse.hair.clear(); + mPile->settings.refuse.shells.clear(); + mPile->settings.refuse.teeth.clear(); + mPile->settings.refuse.horns.clear(); + mPile->settings.refuse.fresh_raw_hide = false; + mPile->settings.refuse.rotten_raw_hide = false; } } @@ -1507,33 +1678,32 @@ private: void write_stone() { StockpileSettings::StoneSet *stone= mBuffer.mutable_stone(); - MaterialInfo mi; - for ( size_t i = 0; i < mPile->settings.stone.mats.size(); ++i ) + + FuncMaterialAllowed filter = std::bind ( &StockpileSerializer::stone_is_allowed, this, _1 ); + serialize_list_material ( filter, [=] ( const std::string &token ) { - if ( mPile->settings.stone.mats.at ( i ) ) - { - mi.decode ( 0, i ); - if ( !stone_is_allowed ( mi ) ) continue; - debug() << "stone mat: " << i << " is " << mi.getToken() << endl; - stone->add_mats ( mi.getToken() ); - } - } + stone->add_mats ( token ); + }, mPile->settings.stone.mats ); } void read_stone() { if ( mBuffer.has_stone() ) { + mPile->settings.flags.bits.stone = 1; const StockpileSettings::StoneSet stone = mBuffer.stone(); debug() << "stone: " < const std::string& { - const std::string token = stone.mats ( i ); - MaterialInfo mi; - mi.find ( token ); - if ( !stone_is_allowed ( mi ) ) continue; - debug() << " mats " << mi.index << " is " << token << endl; - } + return stone.mats ( idx ); + }, stone.mats_size(), &mPile->settings.stone.mats ); + } + else + { + mPile->settings.flags.bits.stone = 0; + mPile->settings.stone.mats.clear(); } } @@ -1555,23 +1725,18 @@ private: item_type::AMMO ); // metal - MaterialInfo mi; - for ( size_t i = 0; i < mPile->settings.ammo.mats.size(); ++i ) + FuncMaterialAllowed filter = std::bind ( &StockpileSerializer::ammo_mat_is_allowed, this, _1 ); + serialize_list_material ( filter, [=] ( const std::string &token ) { - if ( mPile->settings.ammo.mats.at ( i ) ) - { - mi.decode ( 0, i ); - if ( !ammo_mat_is_allowed ( mi ) ) continue; - ammo->add_mats ( mi.getToken() ); - } - } - debug() << "after metal" << endl; - // other mats + ammo->add_mats ( token ); + }, mPile->settings.ammo.mats ); + + // other mats - only wood and bone if ( mPile->settings.ammo.other_mats.size() > 2 ) { debug() << "WARNING: ammo other materials > 2! " << mPile->settings.ammo.other_mats.size() << endl; } - debug() << "after other check" << endl; + for ( size_t i = 0; i < std::min ( size_t ( 2 ), mPile->settings.ammo.other_mats.size() ); ++i ) { if ( !mPile->settings.ammo.other_mats.at ( i ) ) @@ -1580,12 +1745,13 @@ private: ammo->add_other_mats ( token ); debug() << " other mats " << i << " is " << token << endl; } - debug() << "after other" << endl; + // quality core serialize_list_quality ( [=] ( const std::string &token ) { ammo->add_quality_core ( token ); }, mPile->settings.ammo.quality_core ); + // quality total serialize_list_quality ( [=] ( const std::string &token ) { @@ -1597,6 +1763,7 @@ private: { if ( mBuffer.has_ammo() ) { + mPile->settings.flags.bits.ammo = 1; const StockpileSettings::AmmoSet ammo = mBuffer.ammo(); debug() << "ammo: " < const std::string& { return ammo.type ( idx ); - }, ammo.type_size() ); + }, ammo.type_size(), &mPile->settings.ammo.type, item_type::AMMO ); - // metals - for ( int i = 0; i < ammo.mats_size(); ++i ) + // materials metals + FuncMaterialAllowed filter = std::bind ( &StockpileSerializer::ammo_mat_is_allowed, this, _1 ); + unserialize_list_material ( filter, [=] ( const size_t & idx ) -> const std::string& { - const std::string token = ammo.mats ( i ); - MaterialInfo mi; - mi.find ( token ); - if ( !ammo_mat_is_allowed ( mi ) ) continue; - debug() << " mats " << mi.index << " is " << token << endl; - } + return ammo.mats ( idx ); + }, ammo.mats_size(), &mPile->settings.ammo.mats ); // others - for ( int i = 0; i < ammo.other_mats_size(); ++i ) + if ( ammo.other_mats_size() > 0 ) { - const std::string token = ammo.other_mats ( i ); - const int32_t idx = token == "WOOD" ? 0 : token == "BONE" ? 1 : -1; - debug() << " other mats " << idx << " is " << token << endl; + // TODO remove hardcoded value + mPile->settings.ammo.other_mats.resize ( 2, '\0' ); + for ( int i = 0; i < ammo.other_mats_size(); ++i ) + { + const std::string token = ammo.other_mats ( i ); + const int32_t idx = token == "WOOD" ? 0 : token == "BONE" ? 1 : -1; + debug() << " other mats " << idx << " is " << token << endl; + if ( idx != -1 ) + mPile->settings.ammo.other_mats.at ( idx ) = 1; + } } + else + mPile->settings.ammo.other_mats.clear(); + // core quality unserialize_list_quality ( [=] ( const size_t & idx ) -> const std::string& { return ammo.quality_core ( idx ); - }, ammo.quality_core_size() ); + }, ammo.quality_core_size(), mPile->settings.ammo.quality_core ); + // total quality unserialize_list_quality ( [=] ( const size_t & idx ) -> const std::string& { return ammo.quality_total ( idx ); - }, ammo.quality_total_size() ); + }, ammo.quality_total_size(), mPile->settings.ammo.quality_total ); + } + else + { + mPile->settings.flags.bits.ammo = 0; + mPile->settings.ammo.type.clear(); + mPile->settings.ammo.mats.clear(); + mPile->settings.ammo.other_mats.clear(); + quality_clear ( mPile->settings.ammo.quality_core ); + quality_clear ( mPile->settings.ammo.quality_total ); } } @@ -1644,34 +1828,31 @@ private: void write_coins() { StockpileSettings::CoinSet *coins = mBuffer.mutable_coin(); - MaterialInfo mi; - for ( size_t i = 0; i < mPile->settings.coins.mats.size(); ++i ) + FuncMaterialAllowed filter = std::bind ( &StockpileSerializer::coins_mat_is_allowed, this, _1 ); + serialize_list_material ( filter, [=] ( const std::string &token ) { - if ( mPile->settings.coins.mats.at ( i ) ) - { - mi.decode ( 0, i ); - if ( !coins_mat_is_allowed ( mi ) ) continue; - debug() << " coin mat" << i << " is " << mi.getToken() << endl; - coins->add_mats ( mi.getToken() ); - } - } - + coins->add_mats ( token ); + }, mPile->settings.coins.mats ); } void read_coins() { if ( mBuffer.has_coin() ) { + mPile->settings.flags.bits.coins = 1; const StockpileSettings::CoinSet coins = mBuffer.coin(); debug() << "coins: " < const std::string& { - const std::string token = coins.mats ( i ); - MaterialInfo mi; - mi.find ( token ); - if ( !coins_mat_is_allowed ( mi ) ) continue; - debug() << " mats " << mi.index << " is " << token << endl; - } + return coins.mats ( idx ); + }, coins.mats_size(), &mPile->settings.coins.mats ); + } + else + { + mPile->settings.flags.bits.coins = 0; + mPile->settings.coins.mats.clear(); } } @@ -1734,6 +1915,7 @@ private: { if ( mBuffer.has_barsblocks() ) { + mPile->settings.flags.bits.bars_blocks = 1; const StockpileSettings::BarsBlocksSet bars_blocks = mBuffer.barsblocks(); debug() << "bars_blocks: " < const std::string& { return bars_blocks.bars_mats ( idx ); - }, bars_blocks.bars_mats_size() ); + }, bars_blocks.bars_mats_size(), &mPile->settings.bars_blocks.bars_mats ); // blocks filter = std::bind ( &StockpileSerializer::blocks_mat_is_allowed, this, _1 ); unserialize_list_material ( filter, [=] ( const size_t & idx ) -> const std::string& { return bars_blocks.blocks_mats ( idx ); - }, bars_blocks.blocks_mats_size() ); + }, bars_blocks.blocks_mats_size(), &mPile->settings.bars_blocks.blocks_mats ); // bars other mats unserialize_list_other_mats ( mOtherMatsBars, [=] ( const size_t & idx ) -> const std::string& { return bars_blocks.bars_other_mats ( idx ); - }, bars_blocks.bars_other_mats_size() ); + }, bars_blocks.bars_other_mats_size(), &mPile->settings.bars_blocks.bars_other_mats ); // blocks other mats unserialize_list_other_mats ( mOtherMatsBlocks, [=] ( const size_t & idx ) -> const std::string& { return bars_blocks.blocks_other_mats ( idx ); - }, bars_blocks.blocks_other_mats_size() ); + }, bars_blocks.blocks_other_mats_size(), &mPile->settings.bars_blocks.blocks_other_mats ); } + else + { + mPile->settings.flags.bits.bars_blocks = 0; + mPile->settings.bars_blocks.bars_other_mats.clear(); + mPile->settings.bars_blocks.bars_mats.clear(); + mPile->settings.bars_blocks.blocks_other_mats.clear(); + mPile->settings.bars_blocks.blocks_mats.clear(); + } } bool gem_mat_is_allowed ( const MaterialInfo &mi ) @@ -1814,10 +2004,12 @@ private: } } } + void read_gems() { if ( mBuffer.has_gems() ) { + mPile->settings.flags.bits.gems = 1; const StockpileSettings::GemsSet gems = mBuffer.gems(); debug() << "gems: " < const std::string& { return gems.rough_mats ( idx ); - }, gems.rough_mats_size() ); + }, gems.rough_mats_size(), &mPile->settings.gems.rough_mats ); // cut filter = std::bind ( &StockpileSerializer::gem_cut_mat_is_allowed, this, _1 ); unserialize_list_material ( filter, [=] ( const size_t & idx ) -> const std::string& { return gems.cut_mats ( idx ); - }, gems.cut_mats_size() ); + }, gems.cut_mats_size(), &mPile->settings.gems.rough_mats ); + const size_t builtin_size = std::extentraws.mat_table.builtin ) >::value; // rough other - for ( int i = 0; i < gems.rough_other_mats_size(); ++i ) + if ( gems.rough_other_mats_size() > 0 ) { - const std::string token = gems.rough_other_mats ( i ); - MaterialInfo mi; - mi.find ( token ); - if ( !mi.isValid() ) continue; - debug() << " rough_other mats " << mi.type << " is " << token << endl; + mPile->settings.gems.rough_other_mats.resize ( builtin_size, '\0' ); + for ( int i = 0; i < gems.rough_other_mats_size(); ++i ) + { + const std::string token = gems.rough_other_mats ( i ); + MaterialInfo mi; + mi.find ( token ); + if ( !mi.isValid() || mi.type >= builtin_size ) + { + debug() << "WARNING: invalid gem mat " << token << ". idx=" << mi.type << endl; + continue; + } + debug() << " rough_other mats " << mi.type << " is " << token << endl; + mPile->settings.gems.rough_other_mats.at ( mi.type ) = 1; + } } + else + mPile->settings.gems.rough_other_mats.clear(); + // cut other - for ( int i = 0; i < gems.cut_other_mats_size(); ++i ) + if ( gems.cut_other_mats_size() > 0 ) { - const std::string token = gems.cut_other_mats ( i ); - MaterialInfo mi; - mi.find ( token ); - if ( !mi.isValid() ) continue; - debug() << " cut_other mats " << mi.type << " is " << token << endl; + mPile->settings.gems.cut_other_mats.resize ( builtin_size, '\0' ); + for ( int i = 0; i < gems.cut_other_mats_size(); ++i ) + { + const std::string token = gems.cut_other_mats ( i ); + MaterialInfo mi; + mi.find ( token ); + if ( !mi.isValid() || mi.type >= builtin_size ) + { + debug() << "WARNING: invalid gem mat " << token << ". idx=" << mi.type << endl; + continue; + } + debug() << " cut_other mats " << mi.type << " is " << token << endl; + mPile->settings.gems.cut_other_mats.at ( mi.type ) = 1; + } } + else + mPile->settings.gems.cut_other_mats.clear(); + } + else + { + mPile->settings.flags.bits.gems = 0; + mPile->settings.gems.cut_other_mats.clear(); + mPile->settings.gems.cut_mats.clear(); + mPile->settings.gems.rough_other_mats.clear(); + mPile->settings.gems.rough_mats.clear(); } } @@ -1960,6 +2184,7 @@ private: { if ( mBuffer.has_finished_goods() ) { + mPile->settings.flags.bits.finished_goods = 1; const StockpileSettings::FinishedGoodsSet finished_goods = mBuffer.finished_goods(); debug() << "finished_goods: " < const std::string& { return finished_goods.type ( idx ); - }, finished_goods.type_size() ); + }, finished_goods.type_size(), &mPile->settings.finished_goods.type ); // materials FuncMaterialAllowed mat_filter = std::bind ( &StockpileSerializer::finished_goods_mat_is_allowed, this, _1 ); unserialize_list_material ( mat_filter, [=] ( const size_t & idx ) -> const std::string& { return finished_goods.mats ( idx ); - }, finished_goods.mats_size() ); + }, finished_goods.mats_size(), &mPile->settings.finished_goods.mats ); // other mats unserialize_list_other_mats ( mOtherMatsFinishedGoods, [=] ( const size_t & idx ) -> const std::string& { return finished_goods.other_mats ( idx ); - }, finished_goods.other_mats_size() ); + }, finished_goods.other_mats_size(), &mPile->settings.finished_goods.other_mats ); // core quality unserialize_list_quality ( [=] ( const size_t & idx ) -> const std::string& { return finished_goods.quality_core ( idx ); - }, finished_goods.quality_core_size() ); + }, finished_goods.quality_core_size(), mPile->settings.finished_goods.quality_total ); // total quality unserialize_list_quality ( [=] ( const size_t & idx ) -> const std::string& { return finished_goods.quality_total ( idx ); - }, finished_goods.quality_total_size() ); + }, finished_goods.quality_total_size(), mPile->settings.finished_goods.quality_total ); } + else + { + mPile->settings.flags.bits.finished_goods = 0; + mPile->settings.finished_goods.type.clear(); + mPile->settings.finished_goods.other_mats.clear(); + mPile->settings.finished_goods.mats.clear(); + quality_clear ( mPile->settings.finished_goods.quality_core ); + quality_clear ( mPile->settings.finished_goods.quality_total ); + } } void write_leather() @@ -2006,19 +2240,25 @@ private: { leather->add_mats ( id ); }; - serialize_list_organic_mat ( setter, mPile->settings.leather.mats, organic_mat_category::Leather ); + serialize_list_organic_mat ( setter, &mPile->settings.leather.mats, organic_mat_category::Leather ); } void read_leather() { if ( mBuffer.has_leather() ) { + mPile->settings.flags.bits.leather = 1; const StockpileSettings::LeatherSet leather = mBuffer.leather(); debug() << "leather: " < std::string + + unserialize_list_organic_mat ( [=] ( size_t idx ) -> std::string { return leather.mats ( idx ); - }; - unserialize_list_organic_mat ( getter, leather.mats_size(), organic_mat_category::Leather ); + }, leather.mats_size(), &mPile->settings.leather.mats, organic_mat_category::Leather ); + } + else + { + mPile->settings.flags.bits.leather = 0; + mPile->settings.leather.mats.clear(); } } @@ -2029,90 +2269,103 @@ private: serialize_list_organic_mat ( [=] ( const std::string &token ) { cloth->add_thread_silk ( token ); - }, mPile->settings.cloth.thread_silk, organic_mat_category::Silk ); + }, &mPile->settings.cloth.thread_silk, organic_mat_category::Silk ); serialize_list_organic_mat ( [=] ( const std::string &token ) { cloth->add_thread_plant ( token ); - }, mPile->settings.cloth.thread_plant, organic_mat_category::PlantFiber ); + }, &mPile->settings.cloth.thread_plant, organic_mat_category::PlantFiber ); serialize_list_organic_mat ( [=] ( const std::string &token ) { cloth->add_thread_yarn ( token ); - }, mPile->settings.cloth.thread_yarn, organic_mat_category::Yarn ); + }, &mPile->settings.cloth.thread_yarn, organic_mat_category::Yarn ); serialize_list_organic_mat ( [=] ( const std::string &token ) { cloth->add_thread_metal ( token ); - }, mPile->settings.cloth.thread_metal, organic_mat_category::MetalThread ); + }, &mPile->settings.cloth.thread_metal, organic_mat_category::MetalThread ); serialize_list_organic_mat ( [=] ( const std::string &token ) { cloth->add_cloth_silk ( token ); - }, mPile->settings.cloth.cloth_silk, organic_mat_category::Silk ); + }, &mPile->settings.cloth.cloth_silk, organic_mat_category::Silk ); serialize_list_organic_mat ( [=] ( const std::string &token ) { cloth->add_cloth_plant ( token ); - }, mPile->settings.cloth.cloth_plant, organic_mat_category::PlantFiber ); + }, &mPile->settings.cloth.cloth_plant, organic_mat_category::PlantFiber ); serialize_list_organic_mat ( [=] ( const std::string &token ) { cloth->add_cloth_yarn ( token ); - }, mPile->settings.cloth.cloth_yarn, organic_mat_category::Yarn ); + }, &mPile->settings.cloth.cloth_yarn, organic_mat_category::Yarn ); serialize_list_organic_mat ( [=] ( const std::string &token ) { cloth->add_cloth_metal ( token ); - }, mPile->settings.cloth.cloth_metal, organic_mat_category::MetalThread ); + }, &mPile->settings.cloth.cloth_metal, organic_mat_category::MetalThread ); } void read_cloth() { if ( mBuffer.has_cloth() ) { + mPile->settings.flags.bits.cloth = 1; const StockpileSettings::ClothSet cloth = mBuffer.cloth(); debug() << "cloth: " < std::string { return cloth.thread_silk ( idx ); - }, cloth.thread_silk_size(), organic_mat_category::Silk ); + }, cloth.thread_silk_size(), &mPile->settings.cloth.thread_silk, organic_mat_category::Silk ); unserialize_list_organic_mat ( [=] ( size_t idx ) -> std::string { return cloth.thread_plant ( idx ); - }, cloth.thread_plant_size(), organic_mat_category::PlantFiber ); + }, cloth.thread_plant_size(), &mPile->settings.cloth.thread_plant, organic_mat_category::PlantFiber ); unserialize_list_organic_mat ( [=] ( size_t idx ) -> std::string { return cloth.thread_yarn ( idx ); - }, cloth.thread_yarn_size(), organic_mat_category::Yarn ); + }, cloth.thread_yarn_size(), &mPile->settings.cloth.thread_yarn, organic_mat_category::Yarn ); unserialize_list_organic_mat ( [=] ( size_t idx ) -> std::string { return cloth.thread_metal ( idx ); - }, cloth.thread_metal_size(), organic_mat_category::MetalThread ); + }, cloth.thread_metal_size(), &mPile->settings.cloth.thread_metal, organic_mat_category::MetalThread ); unserialize_list_organic_mat ( [=] ( size_t idx ) -> std::string { return cloth.cloth_silk ( idx ); - }, cloth.cloth_silk_size(), organic_mat_category::Silk ); + }, cloth.cloth_silk_size(), &mPile->settings.cloth.cloth_silk, organic_mat_category::Silk ); unserialize_list_organic_mat ( [=] ( size_t idx ) -> std::string { return cloth.cloth_plant ( idx ); - }, cloth.cloth_plant_size(), organic_mat_category::PlantFiber ); + }, cloth.cloth_plant_size(), &mPile->settings.cloth.cloth_plant, organic_mat_category::PlantFiber ); unserialize_list_organic_mat ( [=] ( size_t idx ) -> std::string { return cloth.cloth_yarn ( idx ); - }, cloth.cloth_yarn_size(), organic_mat_category::Yarn ); + }, cloth.cloth_yarn_size(), &mPile->settings.cloth.cloth_yarn, organic_mat_category::Yarn ); unserialize_list_organic_mat ( [=] ( size_t idx ) -> std::string { return cloth.cloth_metal ( idx ); - }, cloth.cloth_metal_size(), organic_mat_category::MetalThread ); + }, cloth.cloth_metal_size(), &mPile->settings.cloth.cloth_metal, organic_mat_category::MetalThread ); + } + else + { + mPile->settings.cloth.thread_metal.clear(); + mPile->settings.cloth.thread_plant.clear(); + mPile->settings.cloth.thread_silk.clear(); + mPile->settings.cloth.thread_yarn.clear(); + mPile->settings.cloth.cloth_metal.clear(); + mPile->settings.cloth.cloth_plant.clear(); + mPile->settings.cloth.cloth_silk.clear(); + mPile->settings.cloth.cloth_yarn.clear(); + mPile->settings.flags.bits.cloth = 0; } } @@ -2139,16 +2392,33 @@ private: { if ( mBuffer.has_wood() ) { + mPile->settings.flags.bits.wood = 1; const StockpileSettings::WoodSet wood = mBuffer.wood(); debug() << "wood: " < 0 ) { - const std::string token = wood.mats ( i ); - const size_t idx = find_plant ( token ); - if ( idx < 0 ) continue; - debug() << " plant " << idx << " is " << token << endl; + mPile->settings.wood.mats.resize ( world->raws.plants.all.size(), '\0' ); + for ( int i = 0; i < wood.mats_size(); ++i ) + { + const std::string token = wood.mats ( i ); + const size_t idx = find_plant ( token ); + if ( idx < 0 || idx >= mPile->settings.wood.mats.size() ) + { + debug() << "WARNING wood mat index invalid " << token << ", idx=" << idx << endl; + continue; + } + debug() << " plant " << idx << " is " << token << endl; + mPile->settings.wood.mats.at ( idx ) = 1; + } } + else + mPile->settings.wood.mats.clear(); + } + else + { + mPile->settings.flags.bits.wood = 0; + mPile->settings.wood.mats.clear(); } } @@ -2213,6 +2483,7 @@ private: { if ( mBuffer.has_weapons() ) { + mPile->settings.flags.bits.weapons = 1; const StockpileSettings::WeaponsSet weapons = mBuffer.weapons(); debug() << "weapons: " < const std::string& { return weapons.weapon_type ( idx ); - }, weapons.weapon_type_size() ); + }, weapons.weapon_type_size(), &mPile->settings.weapons.weapon_type, item_type::WEAPON ); // trapcomp type unserialize_list_itemdef ( [=] ( const size_t & idx ) -> const std::string& { return weapons.trapcomp_type ( idx ); - }, weapons.trapcomp_type_size() ); + }, weapons.trapcomp_type_size(), &mPile->settings.weapons.trapcomp_type, item_type::TRAPCOMP ); // materials FuncMaterialAllowed mat_filter = std::bind ( &StockpileSerializer::weapons_mat_is_allowed, this, _1 ); unserialize_list_material ( mat_filter, [=] ( const size_t & idx ) -> const std::string& { return weapons.mats ( idx ); - }, weapons.mats_size() ); + }, weapons.mats_size(), &mPile->settings.weapons.mats ); // other mats unserialize_list_other_mats ( mOtherMatsWeaponsArmor, [=] ( const size_t & idx ) -> const std::string& { return weapons.other_mats ( idx ); - }, weapons.other_mats_size() ); + }, weapons.other_mats_size(), &mPile->settings.weapons.other_mats ); + // core quality unserialize_list_quality ( [=] ( const size_t & idx ) -> const std::string& { return weapons.quality_core ( idx ); - }, weapons.quality_core_size() ); + }, weapons.quality_core_size(), mPile->settings.weapons.quality_core ); // total quality unserialize_list_quality ( [=] ( const size_t & idx ) -> const std::string& { return weapons.quality_total ( idx ); - }, weapons.quality_total_size() ); + }, weapons.quality_total_size(), mPile->settings.weapons.quality_total ); + } + else + { + mPile->settings.flags.bits.weapons = 0; + mPile->settings.weapons.weapon_type.clear(); + mPile->settings.weapons.trapcomp_type.clear(); + mPile->settings.weapons.other_mats.clear(); + mPile->settings.weapons.mats.clear(); + quality_clear ( mPile->settings.weapons.quality_core ); + quality_clear ( mPile->settings.weapons.quality_total ); } } @@ -2364,6 +2646,7 @@ private: { if ( mBuffer.has_armor() ) { + mPile->settings.flags.bits.armor = 1; const StockpileSettings::ArmorSet armor = mBuffer.armor(); debug() << "armor: " < const std::string& { return armor.body ( idx ); - }, armor.body_size() ); + }, armor.body_size(), &mPile->settings.armor.body, item_type::ARMOR ); // head type unserialize_list_itemdef ( [=] ( const size_t & idx ) -> const std::string& { return armor.head ( idx ); - }, armor.head_size() ); + }, armor.head_size(), &mPile->settings.armor.head, item_type::HELM ); // feet type unserialize_list_itemdef ( [=] ( const size_t & idx ) -> const std::string& { return armor.feet ( idx ); - }, armor.feet_size() ); + }, armor.feet_size(), &mPile->settings.armor.feet, item_type::SHOES ); // hands type unserialize_list_itemdef ( [=] ( const size_t & idx ) -> const std::string& { return armor.hands ( idx ); - }, armor.hands_size() ); + }, armor.hands_size(), &mPile->settings.armor.hands, item_type::GLOVES ); // legs type unserialize_list_itemdef ( [=] ( const size_t & idx ) -> const std::string& { return armor.legs ( idx ); - }, armor.legs_size() ); + }, armor.legs_size(), &mPile->settings.armor.legs, item_type::PANTS ); // shield type unserialize_list_itemdef ( [=] ( const size_t & idx ) -> const std::string& { return armor.shield ( idx ); - }, armor.shield_size() ); + }, armor.shield_size(), &mPile->settings.armor.shield, item_type::SHIELD ); // materials FuncMaterialAllowed mat_filter = std::bind ( &StockpileSerializer::armor_mat_is_allowed, this, _1 ); unserialize_list_material ( mat_filter, [=] ( const size_t & idx ) -> const std::string& { return armor.mats ( idx ); - }, armor.mats_size() ); + }, armor.mats_size(), &mPile->settings.armor.mats ); // other mats unserialize_list_other_mats ( mOtherMatsWeaponsArmor, [=] ( const size_t & idx ) -> const std::string& { return armor.other_mats ( idx ); - }, armor.other_mats_size() ); + }, armor.other_mats_size(), &mPile->settings.armor.other_mats ); // core quality unserialize_list_quality ( [=] ( const size_t & idx ) -> const std::string& { return armor.quality_core ( idx ); - }, armor.quality_core_size() ); + }, armor.quality_core_size(), mPile->settings.armor.quality_core ); // total quality unserialize_list_quality ( [=] ( const size_t & idx ) -> const std::string& { return armor.quality_total ( idx ); - }, armor.quality_total_size() ); + }, armor.quality_total_size(), mPile->settings.armor.quality_total ); + } + else + { + mPile->settings.flags.bits.armor = 0; + mPile->settings.armor.body.clear(); + mPile->settings.armor.head.clear(); + mPile->settings.armor.feet.clear(); + mPile->settings.armor.hands.clear(); + mPile->settings.armor.legs.clear(); + mPile->settings.armor.shield.clear(); + mPile->settings.armor.other_mats.clear(); + mPile->settings.armor.mats.clear(); + quality_clear ( mPile->settings.armor.quality_core ); + quality_clear ( mPile->settings.armor.quality_total ); } } };