diff --git a/docs/changelog.txt b/docs/changelog.txt index 14a9ba0ca3..fcd16dc002 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -61,6 +61,7 @@ Template for new versions: ## Fixes ## Misc Improvements +- `stockpiles`: add support for managing the dyed, undyed, and color filter settings. ## Documentation diff --git a/plugins/stockpiles/StockpileSerializer.cpp b/plugins/stockpiles/StockpileSerializer.cpp index efac3e8bad..ad76977f1a 100644 --- a/plugins/stockpiles/StockpileSerializer.cpp +++ b/plugins/stockpiles/StockpileSerializer.cpp @@ -12,6 +12,7 @@ #include "df/building_stockpilest.h" #include "df/creature_raw.h" #include "df/caste_raw.h" +#include "df/descriptor_color.h" #include "df/inorganic_raw.h" #include "df/item_quality.h" #include @@ -497,6 +498,57 @@ static void unserialize_list_organic_mat(color_ostream& out, const char* subcat, } } +static bool serialize_list_color(color_ostream& out, FuncWriteExport add_value, const vector* colors) { + bool all = world->raws.descriptors.colors.size() == colors->size(); + if (!colors) { + DEBUG(log, out).print("serialize_list_color: list null\n"); + return all; + } + for (size_t i = 0; i < colors->size(); ++i) { + if (!colors->at(i)) { + all = false; + continue; + } + add_value(world->raws.descriptors.colors[i]->id); + } + return all; +} + +// Find the index of a named color, returning SIZE_MAX on unknown. +static size_t find_color_by_token(const string& token) { + auto& colors = world->raws.descriptors.colors; + size_t num_colors = colors.size(); + for (size_t idx = 0; idx < num_colors; ++ idx) { + if (colors[idx]->id == token) { + return idx; + } + } + return SIZE_MAX; +} + +static void unserialize_list_color(color_ostream& out, const char* subcat, bool all, char val, const vector& filters, + FuncReadImport read_value, int32_t list_size, vector& pile_list) { + size_t num_elems = world->raws.descriptors.colors.size(); + pile_list.resize(num_elems, '\0'); + if (all) { + for (size_t idx = 0; idx < num_elems; ++idx) { + set_filter_elem(out, subcat, filters, val, world->raws.descriptors.colors[idx]->id, idx, pile_list[idx]); + } + return; + } + + for (int32_t idx = 0; idx < list_size; ++idx) { + const string& value = read_value(idx); + + size_t color = find_color_by_token(value); + if (color == SIZE_MAX) { + WARN(log, out).print("unknown color %s", value.c_str()); + continue; + } + set_filter_elem(out, subcat, filters, val, value, color, pile_list[color]); + } +} + static bool serialize_list_item_type(color_ostream& out, FuncItemAllowed is_allowed, FuncWriteExport add_value, const vector& list) { using df::enums::item_type::item_type; @@ -1059,10 +1111,12 @@ static bool armor_mat_is_allowed(const MaterialInfo& mi) { bool StockpileSettingsSerializer::write_armor(color_ostream& out, StockpileSettings::ArmorSet* armor) { auto & parmor = mSettings->armor; - bool all = parmor.unusable && parmor.usable; + bool all = parmor.unusable && parmor.usable && parmor.dyed && parmor.undyed; armor->set_unusable(parmor.unusable); armor->set_usable(parmor.usable); + armor->set_dyed(parmor.dyed); + armor->set_undyed(parmor.undyed); // armor type all = serialize_list_itemdef(out, @@ -1125,6 +1179,9 @@ bool StockpileSettingsSerializer::write_armor(color_ostream& out, StockpileSetti all = serialize_list_quality(out, [&](const string& token) { armor->add_quality_total(token); }, parmor.quality_total) && all; + all = serialize_list_color(out, [&](const string& token) { armor->add_color(token); }, + &parmor.color) && all; + return all; } @@ -1148,6 +1205,9 @@ void StockpileSettingsSerializer::read_armor(color_ostream& out, DeserializeMode parmor.mats.clear(); quality_clear(parmor.quality_core); quality_clear(parmor.quality_total); + parmor.dyed = false; + parmor.undyed = false; + parmor.color.clear(); }, [&](bool all, char val) { auto & barmor = mBuffer.armor(); @@ -1195,6 +1255,13 @@ void StockpileSettingsSerializer::read_armor(color_ostream& out, DeserializeMode unserialize_list_quality(out, "total", all, val, filters, [&](const size_t& idx) -> const string& { return barmor.quality_total(idx); }, barmor.quality_total_size(), parmor.quality_total); + + unserialize_list_color(out, "color", all, val, filters, + [&](const size_t& idx) -> const string& { return barmor.color(idx); }, + barmor.color_size(), parmor.color); + + set_flag(out, "dyed", filters, all, val, barmor.dyed(), parmor.dyed); + set_flag(out, "undyed", filters, all, val, barmor.undyed(), parmor.undyed); }); } @@ -1266,7 +1333,9 @@ void StockpileSettingsSerializer::read_bars_blocks(color_ostream& out, Deseriali } bool StockpileSettingsSerializer::write_cloth(color_ostream& out, StockpileSettings::ClothSet* cloth) { - bool all = true; + bool all = mSettings->cloth.dyed && mSettings->cloth.undyed; + cloth->set_dyed(mSettings->cloth.dyed); + cloth->set_undyed(mSettings->cloth.undyed); all = serialize_list_organic_mat(out, [&](const string& token) { cloth->add_thread_silk(token); }, @@ -1300,6 +1369,10 @@ bool StockpileSettingsSerializer::write_cloth(color_ostream& out, StockpileSetti [&](const string& token) { cloth->add_cloth_metal(token); }, &mSettings->cloth.cloth_metal, organic_mat_category::MetalThread) && all; + all = serialize_list_color(out, + [&](const string& token) { cloth->add_color(token); }, + &mSettings->cloth.color) && all; + return all; } @@ -1319,6 +1392,9 @@ void StockpileSettingsSerializer::read_cloth(color_ostream& out, DeserializeMode pcloth.cloth_plant.clear(); pcloth.cloth_yarn.clear(); pcloth.cloth_metal.clear(); + pcloth.dyed = false; + pcloth.undyed = false; + pcloth.color.clear(); }, [&](bool all, char val) { auto & bcloth = mBuffer.cloth(); @@ -1354,6 +1430,13 @@ void StockpileSettingsSerializer::read_cloth(color_ostream& out, DeserializeMode unserialize_list_organic_mat(out, "cloth/metal", all, val, filters, [&](size_t idx) -> string { return bcloth.cloth_metal(idx); }, bcloth.cloth_metal_size(), pcloth.cloth_metal, organic_mat_category::MetalThread); + + unserialize_list_color(out, "cloth/color", all, val, filters, + [&](size_t idx) -> string { return bcloth.color(idx); }, + bcloth.color_size(), pcloth.color); + + set_flag(out, "dyed", filters, all, val, bcloth.dyed(), pcloth.dyed); + set_flag(out, "undyed", filters, all, val, bcloth.undyed(), pcloth.undyed); }); } @@ -1425,10 +1508,14 @@ static bool finished_goods_mat_is_allowed(const MaterialInfo& mi) { } bool StockpileSettingsSerializer::write_finished_goods(color_ostream& out, StockpileSettings::FinishedGoodsSet* finished_goods) { - bool all = serialize_list_item_type(out, + bool all = mSettings->finished_goods.dyed && mSettings->finished_goods.undyed; + finished_goods->set_dyed(mSettings->finished_goods.dyed); + finished_goods->set_undyed(mSettings->finished_goods.undyed); + + all = serialize_list_item_type(out, finished_goods_type_is_allowed, [&](const string& token) { finished_goods->add_type(token); }, - mSettings->finished_goods.type); + mSettings->finished_goods.type) && all; all = serialize_list_material(out, finished_goods_mat_is_allowed, @@ -1447,6 +1534,10 @@ bool StockpileSettingsSerializer::write_finished_goods(color_ostream& out, Stock [&](const string& token) { finished_goods->add_quality_total(token); }, mSettings->finished_goods.quality_total) && all; + all = serialize_list_color(out, + [&](const string& token) { finished_goods->add_color(token); }, + &mSettings->finished_goods.color) && all; + return all; } @@ -1463,6 +1554,9 @@ void StockpileSettingsSerializer::read_finished_goods(color_ostream& out, Deseri pfinished_goods.mats.clear(); quality_clear(pfinished_goods.quality_core); quality_clear(pfinished_goods.quality_total); + pfinished_goods.dyed = false; + pfinished_goods.undyed = false; + pfinished_goods.color.clear(); }, [&](bool all, char val) { auto & bfinished_goods = mBuffer.finished_goods(); @@ -1486,6 +1580,13 @@ void StockpileSettingsSerializer::read_finished_goods(color_ostream& out, Deseri unserialize_list_quality(out, "total", all, val, filters, [&](const size_t& idx) -> const string& { return bfinished_goods.quality_total(idx); }, bfinished_goods.quality_total_size(), pfinished_goods.quality_total); + + unserialize_list_color(out, "color", all, val, filters, + [&](const size_t& idx) -> const string& { return bfinished_goods.color(idx); }, + bfinished_goods.color_size(), pfinished_goods.color); + + set_flag(out, "dyed", filters, all, val, bfinished_goods.dyed(), pfinished_goods.dyed); + set_flag(out, "undyed", filters, all, val, bfinished_goods.undyed(), pfinished_goods.undyed); }); } @@ -1934,9 +2035,17 @@ void StockpileSettingsSerializer::read_gems(color_ostream& out, DeserializeMode } bool StockpileSettingsSerializer::write_leather(color_ostream& out, StockpileSettings::LeatherSet* leather) { - return serialize_list_organic_mat(out, + bool all = mSettings->leather.dyed && mSettings->leather.undyed; + leather->set_dyed(mSettings->leather.dyed); + leather->set_undyed(mSettings->leather.undyed); + + all = serialize_list_organic_mat(out, [&](const string& id) { leather->add_mats(id); }, - &mSettings->leather.mats, organic_mat_category::Leather); + &mSettings->leather.mats, organic_mat_category::Leather) && all; + all = serialize_list_color(out, + [&](const string& id) { leather->add_color(id); }, + &mSettings->leather.color) && all; + return all; } void StockpileSettingsSerializer::read_leather(color_ostream& out, DeserializeMode mode, const vector& filters) { @@ -1948,6 +2057,9 @@ void StockpileSettingsSerializer::read_leather(color_ostream& out, DeserializeMo mSettings->flags.mask_leather, [&]() { pleather.mats.clear(); + pleather.color.clear(); + pleather.dyed = false; + pleather.undyed = false; }, [&](bool all, char val) { auto & bleather = mBuffer.leather(); @@ -1955,6 +2067,12 @@ void StockpileSettingsSerializer::read_leather(color_ostream& out, DeserializeMo unserialize_list_organic_mat(out, "", all, val, filters, [&](size_t idx) -> string { return bleather.mats(idx); }, bleather.mats_size(), pleather.mats, organic_mat_category::Leather); + unserialize_list_color(out, "", all, val, filters, + [&](size_t idx) -> string { return bleather.color(idx); }, + bleather.color_size(), pleather.color); + + set_flag(out, "dyed", filters, all, val, bleather.dyed(), pleather.dyed); + set_flag(out, "undyed", filters, all, val, bleather.undyed(), pleather.undyed); }); } diff --git a/plugins/stockpiles/proto/stockpiles.proto b/plugins/stockpiles/proto/stockpiles.proto index 681e7d9279..49a6d1c42e 100644 --- a/plugins/stockpiles/proto/stockpiles.proto +++ b/plugins/stockpiles/proto/stockpiles.proto @@ -100,10 +100,16 @@ message StockpileSettings { repeated string mats = 3; repeated string quality_core = 4; repeated string quality_total = 5; + optional bool dyed = 7; + optional bool undyed = 8; + repeated string color = 9; } message LeatherSet { optional bool all = 2; repeated string mats = 1; + optional bool dyed = 3; + optional bool undyed = 4; + repeated string color = 5; } message ClothSet { optional bool all = 9; @@ -115,6 +121,9 @@ message StockpileSettings { repeated string cloth_plant = 6; repeated string cloth_yarn = 7; repeated string cloth_metal = 8; + optional bool dyed = 10; + optional bool undyed = 11; + repeated string color = 12; } message WoodSet { optional bool all = 2; @@ -145,6 +154,9 @@ message StockpileSettings { repeated string quality_total = 10; optional bool usable = 11; optional bool unusable = 12; + optional bool dyed = 14; + optional bool undyed = 15; + repeated string color = 16; } message CorpsesSet { optional bool all = 1;