diff --git a/CMakeLists.txt b/CMakeLists.txt index e417575c4..b6c6f427c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,7 @@ set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/hoi4_world/characters/hoi4_chara set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/hoi4_world/countries/hoi4_countries_converter.cpp") set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/hoi4_world/countries/hoi4_country.cpp") set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/hoi4_world/countries/hoi4_country_converter.cpp") +set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/hoi4_world/decisions/decisions_category_importer.cpp") set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/hoi4_world/diplomacy/hoi4_war_converter.cpp") set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/hoi4_world/focus_trees/focus.cpp") set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/hoi4_world/focus_trees/focus_importer.cpp") @@ -127,6 +128,8 @@ set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/out_hoi4/characters/out_characte set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/out_hoi4/countries/out_countries.cpp") set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/out_hoi4/countries/out_country.cpp") set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/out_hoi4/decisions/out_decisions.cpp") +set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/out_hoi4/decisions/out_decisions_categories.cpp") +set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/out_hoi4/decisions/out_decisions_category.cpp") set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/out_hoi4/diplomacy/out_war.cpp") set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/out_hoi4/focus_trees/out_focus.cpp") set(CONVERTER_SOURCES ${CONVERTER_SOURCES} "src/out_hoi4/focus_trees/out_focus_tree.cpp") @@ -389,6 +392,7 @@ set(TEST_SOURCES ${TEST_SOURCES} "src/hoi4_world/characters/hoi4_character_tests set(TEST_SOURCES ${TEST_SOURCES} "src/hoi4_world/countries/hoi4_countries_converter_tests.cpp") set(TEST_SOURCES ${TEST_SOURCES} "src/hoi4_world/countries/hoi4_country_converter_tests.cpp") set(TEST_SOURCES ${TEST_SOURCES} "src/hoi4_world/countries/hoi4_country_converter_tests_tech.cpp") +set(TEST_SOURCES ${TEST_SOURCES} "src/hoi4_world/decisions/decisions_category_importer_tests.cpp") set(TEST_SOURCES ${TEST_SOURCES} "src/hoi4_world/diplomacy/hoi4_war_converter_tests.cpp") set(TEST_SOURCES ${TEST_SOURCES} "src/hoi4_world/focus_trees/focus_tests.cpp") set(TEST_SOURCES ${TEST_SOURCES} "src/hoi4_world/focus_trees/focus_importer_tests.cpp") @@ -455,6 +459,8 @@ set(TEST_SOURCES ${TEST_SOURCES} "src/out_hoi4/characters/out_character_tests.cp set(TEST_SOURCES ${TEST_SOURCES} "src/out_hoi4/countries/out_countries_tests.cpp") set(TEST_SOURCES ${TEST_SOURCES} "src/out_hoi4/countries/out_country_tests.cpp") set(TEST_SOURCES ${TEST_SOURCES} "src/out_hoi4/decisions/out_decisions_tests.cpp") +set(TEST_SOURCES ${TEST_SOURCES} "src/out_hoi4/decisions/out_decisions_categories_tests.cpp") +set(TEST_SOURCES ${TEST_SOURCES} "src/out_hoi4/decisions/out_decisions_category_tests.cpp") set(TEST_SOURCES ${TEST_SOURCES} "src/out_hoi4/diplomacy/out_war_tests.cpp") set(TEST_SOURCES ${TEST_SOURCES} "src/out_hoi4/flags/out_flags_tests.cpp") set(TEST_SOURCES ${TEST_SOURCES} "src/out_hoi4/focus_trees/out_focus_tests.cpp") diff --git a/data/configurables/stories/italy_unification.txt b/data/configurables/stories/italy_unification.txt index 782879b6f..626a936c3 100644 --- a/data/configurables/stories/italy_unification.txt +++ b/data/configurables/stories/italy_unification.txt @@ -108,6 +108,13 @@ unification_italy = { } } + decisions_categories={ + sample_decision_category={ + icon=generic_form_nation + visible={ + } + } + } } @@ -234,6 +241,14 @@ unification_italy_2 = { set_cosmetic_tag = ITA_UNIFIED } } + + decisions_categories={ + sample_decision_category={ + icon=generic_form_nation + visible={ + } + } + } } @@ -360,4 +375,12 @@ unification_italy_3 = { set_cosmetic_tag = ITA_UNIFIED } } + + decisions_categories={ + sample_decision_category={ + icon=generic_form_nation + visible={ + } + } + } } \ No newline at end of file diff --git a/src/hoi4_world/decisions/decisions_category.h b/src/hoi4_world/decisions/decisions_category.h new file mode 100644 index 000000000..044e3404c --- /dev/null +++ b/src/hoi4_world/decisions/decisions_category.h @@ -0,0 +1,33 @@ +#ifndef SRC_HOI4WORLD_DECISIONS_DECISIONSCATEGORY_H +#define SRC_HOI4WORLD_DECISIONS_DECISIONSCATEGORY_H + + + +#include +#include +#include + + + +namespace hoi4 +{ + +struct DecisionsCategory +{ + std::string name; + std::string icon; + std::string picture; + std::optional priority; + std::string allowed; + std::string visible; + std::string visibility_type; + std::vector> extra_items; + + std::strong_ordering operator<=>(const DecisionsCategory& rhs) const = default; +}; + +} // namespace hoi4 + + + +#endif // SRC_HOI4WORLD_DECISIONS_DECISIONSCATEGORY_H \ No newline at end of file diff --git a/src/hoi4_world/decisions/decisions_category_importer.cpp b/src/hoi4_world/decisions/decisions_category_importer.cpp new file mode 100644 index 000000000..b32f0d7e9 --- /dev/null +++ b/src/hoi4_world/decisions/decisions_category_importer.cpp @@ -0,0 +1,53 @@ +#include "src/hoi4_world/decisions/decisions_category_importer.h" + +#include "external/commonItems/CommonRegexes.h" +#include "external/commonItems/ParserHelpers.h" + + + +hoi4::DecisionsCategoryImporter::DecisionsCategoryImporter() +{ + parser.registerKeyword("name", [this](std::istream& the_stream) { + name_ = commonItems::getString(the_stream); + }); + parser.registerKeyword("icon", [this](std::istream& the_stream) { + icon_ = commonItems::getString(the_stream); + }); + parser.registerKeyword("picture", [this](std::istream& the_stream) { + picture_ = commonItems::getString(the_stream); + }); + parser.registerKeyword("priority", [this](std::istream& the_stream) { + priority_ = commonItems::getInt(the_stream); + }); + parser.registerKeyword("allowed", [this](std::istream& the_stream) { + allowed_ = commonItems::stringOfItem(the_stream).getString(); + }); + parser.registerKeyword("visible", [this](std::istream& the_stream) { + visible_ = commonItems::stringOfItem(the_stream).getString(); + }); + parser.registerKeyword("visibility_type", [this](std::istream& the_stream) { + visibility_type_ = commonItems::stringOfItem(the_stream).getString(); + }); + parser.registerRegex(commonItems::catchallRegex, [this](const std::string& itemName, std::istream& the_stream) { + extra_items_.push_back(std::make_pair(itemName, commonItems::stringOfItem(the_stream).getString())); + }); +} + + + +hoi4::DecisionsCategory hoi4::DecisionsCategoryImporter::GetDecisionsCategory(std::string_view name, + std::istream& the_stream) +{ + name_ = name; + icon_.clear(); + picture_.clear(); + priority_.reset(); + allowed_.clear(); + visible_.clear(); + visibility_type_.clear(); + extra_items_.clear(); + + parser.parseStream(the_stream); + + return {name_, icon_, picture_, priority_, allowed_, visible_, visibility_type_, extra_items_}; +} \ No newline at end of file diff --git a/src/hoi4_world/decisions/decisions_category_importer.h b/src/hoi4_world/decisions/decisions_category_importer.h new file mode 100644 index 000000000..36ea716a0 --- /dev/null +++ b/src/hoi4_world/decisions/decisions_category_importer.h @@ -0,0 +1,41 @@ +#ifndef SRC_HOI4WORLD_DECISIONS_DECISIONSCATEGORYIMPORTER_H +#define SRC_HOI4WORLD_DECISIONS_DECISIONSCATEGORYIMPORTER_H + + + +#include + +#include "decisions_category.h" +#include "external/commonItems/Parser.h" +#include "src/hoi4_world/decisions/decisions_category.h" + + + +namespace hoi4 +{ + +class DecisionsCategoryImporter +{ + public: + DecisionsCategoryImporter(); + + [[nodiscard]] DecisionsCategory GetDecisionsCategory(std::string_view name, std::istream& the_stream); + + private: + commonItems::parser parser; + + std::string name_; + std::string icon_; + std::string picture_; + std::optional priority_; + std::string allowed_; + std::string visible_; + std::string visibility_type_; + std::vector> extra_items_; +}; + +} // namespace hoi4 + + + +#endif // SRC_HOI4WORLD_DECISIONS_DECISIONSCATEGORYIMPORTER_H \ No newline at end of file diff --git a/src/hoi4_world/decisions/decisions_category_importer_tests.cpp b/src/hoi4_world/decisions/decisions_category_importer_tests.cpp new file mode 100644 index 000000000..37ca5b3ba --- /dev/null +++ b/src/hoi4_world/decisions/decisions_category_importer_tests.cpp @@ -0,0 +1,77 @@ +#include + +#include "external/commonItems/external/googletest/googlemock/include/gmock/gmock-matchers.h" +#include "external/commonItems/external/googletest/googletest/include/gtest/gtest.h" +#include "src/hoi4_world/decisions/decisions_category.h" +#include "src/hoi4_world/decisions/decisions_category_importer.h" + + +namespace hoi4 +{ + +TEST(Hoi4worldDecisionsDecisionscategoryimporterTests, DefaultsAreDefaulted) +{ + std::stringstream input; + input << "= {\n"; + input << "}"; + const DecisionsCategory decisions_category = + hoi4::DecisionsCategoryImporter{}.GetDecisionsCategory("test_name", input); + + EXPECT_EQ(decisions_category.name, "test_name"); + EXPECT_TRUE(decisions_category.icon.empty()); + EXPECT_TRUE(decisions_category.picture.empty()); + EXPECT_FALSE(decisions_category.priority.has_value()); + EXPECT_TRUE(decisions_category.allowed.empty()); + EXPECT_TRUE(decisions_category.visible.empty()); + EXPECT_TRUE(decisions_category.visibility_type.empty()); + EXPECT_TRUE(decisions_category.extra_items.empty()); +} + + +TEST(HoI4World_Decisions_DecisionsCategoryTests, ItemsCanBeSet) +{ + std::stringstream input; + input << "= {\n"; + input << "\ticon = generic_research\n"; + input << "\tpicture = GFX_decision_cat_picture_naval_treaties\n"; + input << "\tpriority = 100\n"; + input << "\tallowed = {\n"; + input << "\t\thas_dlc = \"Man the Guns\"\n"; + input << "\t}\n"; + input << "\tvisible = {\n"; + input << "\t\tis_debug = yes\n"; + input << "\t}\n"; + input << "\tvisibility_type = map_and_decisions_view\n"; + input << "\textra_item_one = {\n"; + input << "\t}\n"; + input << "\textra_item_two = {\n"; + input << "\t\tcan_it_have_stuff_inside = yes\n"; + input << "\t}\n"; + input << "}"; + const DecisionsCategory decisions_category = + hoi4::DecisionsCategoryImporter{}.GetDecisionsCategory("category_name", input); + + EXPECT_EQ(decisions_category.name, "category_name"); + EXPECT_EQ(decisions_category.icon, "generic_research"); + EXPECT_EQ(decisions_category.picture, "GFX_decision_cat_picture_naval_treaties"); + EXPECT_EQ(decisions_category.priority.value_or(0), 100); + EXPECT_EQ(decisions_category.allowed, + "= {\n" + "\t\thas_dlc = \"Man the Guns\"\n" + "\t}"); + EXPECT_EQ(decisions_category.visible, + "= {\n" + "\t\tis_debug = yes\n" + "\t}"); + EXPECT_EQ(decisions_category.visibility_type, "= map_and_decisions_view"); + EXPECT_THAT(decisions_category.extra_items, + testing::ElementsAre(std::pair{"extra_item_one", + "= {\n" + "\t}"}, + std::pair{"extra_item_two", + "= {\n" + "\t\tcan_it_have_stuff_inside = yes\n" + "\t}"})); +} + +} // namespace hoi4 \ No newline at end of file diff --git a/src/hoi4_world/roles/role.h b/src/hoi4_world/roles/role.h index e43176f8b..b5a93be44 100644 --- a/src/hoi4_world/roles/role.h +++ b/src/hoi4_world/roles/role.h @@ -6,6 +6,7 @@ #include #include +#include "src/hoi4_world/decisions/decisions_category.h" #include "src/hoi4_world/focus_trees/focus.h" #include "src/hoi4_world/roles/repeat_focus.h" @@ -25,6 +26,7 @@ struct RoleOptions std::vector focuses; std::vector repeat_focuses; std::vector removed_focuses; + std::vector decisions_categories; std::vector decisions; std::vector events; }; @@ -43,6 +45,7 @@ class Role focuses_(std::move(options.focuses)), repeat_focuses_(std::move(options.repeat_focuses)), removed_focuses_(std::move(options.removed_focuses)), + decisions_categories_(std::move(options.decisions_categories)), decisions_(std::move(options.decisions)), events_(std::move(options.events)) { @@ -57,6 +60,7 @@ class Role [[nodiscard]] const std::vector& GetFocuses() const { return focuses_; } [[nodiscard]] const std::vector& GetRepeatFocuses() const { return repeat_focuses_; } [[nodiscard]] const std::vector& GetRemovedFocuses() const { return removed_focuses_; } + [[nodiscard]] const std::vector& GetDecisionsCategories() const { return decisions_categories_; } [[nodiscard]] const std::vector& GetDecisions() const { return decisions_; } [[nodiscard]] const std::vector& GetEvents() const { return events_; } @@ -72,6 +76,7 @@ class Role std::vector focuses_; std::vector repeat_focuses_; std::vector removed_focuses_; + std::vector decisions_categories_; std::vector decisions_; std::vector events_; }; diff --git a/src/hoi4_world/roles/role_importer.cpp b/src/hoi4_world/roles/role_importer.cpp index 2caa7e471..a8310a6a8 100644 --- a/src/hoi4_world/roles/role_importer.cpp +++ b/src/hoi4_world/roles/role_importer.cpp @@ -1,11 +1,18 @@ #include "src/hoi4_world/roles/role_importer.h" +#include "external/commonItems/CommonRegexes.h" #include "external/commonItems/ParserHelpers.h" hoi4::RoleImporter::RoleImporter() { + decisions_categories_parser_.registerRegex(commonItems::catchallRegex, + [this](std::string name, std::istream& input) { + role_options_.decisions_categories.emplace_back( + decisions_category_importer_.GetDecisionsCategory(name, input)); + }); + role_parser_.registerKeyword("category", [this](std::istream& input) { role_options_.category = commonItems::getString(input); }); @@ -33,6 +40,9 @@ hoi4::RoleImporter::RoleImporter() role_parser_.registerKeyword("removed_focus", [this](std::istream& input) { role_options_.removed_focuses.emplace_back(commonItems::stringOfItem(input).getString()); }); + role_parser_.registerKeyword("decisions_categories", [this](std::istream& input) { + decisions_categories_parser_.parseStream(input); + }); role_parser_.registerKeyword("decision", [this](std::istream& input) { role_options_.decisions.emplace_back(commonItems::stringOfItem(input).getString()); }); diff --git a/src/hoi4_world/roles/role_importer.h b/src/hoi4_world/roles/role_importer.h index 5691499f2..a27396956 100644 --- a/src/hoi4_world/roles/role_importer.h +++ b/src/hoi4_world/roles/role_importer.h @@ -4,6 +4,7 @@ #include "external/commonItems/Parser.h" +#include "src/hoi4_world/decisions/decisions_category_importer.h" #include "src/hoi4_world/focus_trees/focus_importer.h" #include "src/hoi4_world/roles/repeat_focus_importer.h" #include "src/hoi4_world/roles/role.h" @@ -27,6 +28,8 @@ class RoleImporter commonItems::parser role_parser_; FocusImporter focus_importer_; RepeatFocusImporter repeat_focus_importer_; + DecisionsCategoryImporter decisions_category_importer_; + commonItems::parser decisions_categories_parser_; }; }; // namespace hoi4 diff --git a/src/hoi4_world/roles/role_importer_tests.cpp b/src/hoi4_world/roles/role_importer_tests.cpp index 5dca42a40..8b2274b49 100644 --- a/src/hoi4_world/roles/role_importer_tests.cpp +++ b/src/hoi4_world/roles/role_importer_tests.cpp @@ -26,6 +26,7 @@ TEST(Hoi4worldRolesRoleimporterTests, DefaultsAreDefaulted) EXPECT_TRUE(role.GetFocuses().empty()); EXPECT_TRUE(role.GetRepeatFocuses().empty()); EXPECT_TRUE(role.GetRemovedFocuses().empty()); + EXPECT_TRUE(role.GetDecisionsCategories().empty()); EXPECT_TRUE(role.GetDecisions().empty()); EXPECT_TRUE(role.GetEvents().empty()); } @@ -92,6 +93,12 @@ TEST(Hoi4worldRolesRoleimporterTests, ItemsCanBeImported) input << "\tremoved_focus={\n"; input << "\t\tid = $TAG$_remove_me_2\n"; input << "\t}\n"; + input << "\tdecisions_categories={\n"; + input << "\t\t$TAG$_a_decisions_category={\n"; + input << "\t\t}\n"; + input << "\t\t$TAG$_another_decisions_category={\n"; + input << "\t\t}\n"; + input << "\t}\n"; input << "\tdecision={\n"; input << "\t\tid = $TAG$_a_decision\n"; input << "\t}\n"; @@ -133,6 +140,9 @@ TEST(Hoi4worldRolesRoleimporterTests, ItemsCanBeImported) "= {\n" "\t\tid = $TAG$_remove_me_2\n" "\t}")); + EXPECT_THAT(role.GetDecisionsCategories(), + testing::ElementsAre(DecisionsCategory{.name = "$TAG$_a_decisions_category"}, + DecisionsCategory{.name = "$TAG$_another_decisions_category"})); EXPECT_THAT(role.GetDecisions(), testing::ElementsAre("= {\n" "\t\tid = $TAG$_a_decision\n" diff --git a/src/hoi4_world/world/hoi4_world.h b/src/hoi4_world/world/hoi4_world.h index aa3b2feae..158b53417 100644 --- a/src/hoi4_world/world/hoi4_world.h +++ b/src/hoi4_world/world/hoi4_world.h @@ -10,6 +10,7 @@ #include "external/commonItems/Localization/LocalizationDatabase.h" #include "src/hoi4_world/characters/hoi4_character.h" #include "src/hoi4_world/countries/hoi4_country.h" +#include "src/hoi4_world/decisions/decisions_category.h" #include "src/hoi4_world/localizations/localizations.h" #include "src/hoi4_world/map/buildings.h" #include "src/hoi4_world/map/railways.h" @@ -60,9 +61,15 @@ class World [[nodiscard]] const Railways& GetRailways() const { return railways_; } [[nodiscard]] const Localizations& GetLocalizations() const { return localizations_; } [[nodiscard]] const std::map& GetCharacters() const { return characters_; } + [[nodiscard]] const std::set& GetDecisionsCategories() const { return decisions_categories_; } [[nodiscard]] std::map& GetModifiableCountries() { return countries_; } + void SetDecisionsCategories(std::set decisions_categories) + { + decisions_categories_ = std::move(decisions_categories); + } + private: std::map countries_; std::set great_powers_; @@ -73,6 +80,8 @@ class World Railways railways_; Localizations localizations_; std::map characters_; + + std::set decisions_categories_; }; } // namespace hoi4 diff --git a/src/hoi4_world/world/hoi4_world_converter.cpp b/src/hoi4_world/world/hoi4_world_converter.cpp index bde1b3eb6..5ea81774d 100644 --- a/src/hoi4_world/world/hoi4_world_converter.cpp +++ b/src/hoi4_world/world/hoi4_world_converter.cpp @@ -232,8 +232,6 @@ hoi4::World hoi4::ConvertWorld(const commonItems::ModFilesystem& hoi4_mod_filesy std::future world_framework_future, const configuration::Configuration& config) { - std::map countries; - Log(LogLevel::Info) << "Creating Hoi4 world"; @@ -278,7 +276,7 @@ hoi4::World hoi4::ConvertWorld(const commonItems::ModFilesystem& hoi4_mod_filesy std::map characters; std::map culture_queues; - countries = ConvertCountries(source_world, + std::map countries = ConvertCountries(source_world, world_mapper, source_world.GetLocalizations(), states, @@ -332,6 +330,8 @@ hoi4::World hoi4::ConvertWorld(const commonItems::ModFilesystem& hoi4_mod_filesy .localizations = localizations, .characters = characters}); + std::set decisions_categories; + const std::map roles = ImportRoles(); std::map& modifiable_countries = world.GetModifiableCountries(); for (const auto& [tag, country_roles]: CreateStories(roles, modifiable_countries)) @@ -343,9 +343,19 @@ hoi4::World hoi4::ConvertWorld(const commonItems::ModFilesystem& hoi4_mod_filesy continue; } + for (const Role& country_role: country_roles) + { + for (const DecisionsCategory& role_category: country_role.GetDecisionsCategories()) + { + decisions_categories.insert(role_category); + } + } + const FocusTree tree = AssembleTree(country_roles, tag, world); country_itr->second.SetFocusTree(tree); } + world.SetDecisionsCategories(decisions_categories); + return world; } diff --git a/src/out_hoi4/decisions/out_decisions_categories.cpp b/src/out_hoi4/decisions/out_decisions_categories.cpp new file mode 100644 index 000000000..b1ed7b66c --- /dev/null +++ b/src/out_hoi4/decisions/out_decisions_categories.cpp @@ -0,0 +1,32 @@ +#include "src/out_hoi4/decisions/out_decisions_categories.h" + +#include + +#include "external/fmt/include/fmt/format.h" +#include "src/out_hoi4/decisions/out_decisions_category.h" + + + +namespace out +{ + +void OutputDecisionsCategories(std::string_view output_name, + const std::set& decisions_categories) +{ + std::string categories_file_name = + fmt::format("output/{}/common/decisions/categories/converter_decision_categories.txt", output_name); + std::ofstream categories_file(categories_file_name); + if (!categories_file.is_open()) + { + throw std::runtime_error(fmt::format("Could not create {}", categories_file_name)); + } + + for (const hoi4::DecisionsCategory& decisions_category: decisions_categories) + { + categories_file << decisions_category; + } + + categories_file.close(); +} + +} // namespace out \ No newline at end of file diff --git a/src/out_hoi4/decisions/out_decisions_categories.h b/src/out_hoi4/decisions/out_decisions_categories.h new file mode 100644 index 000000000..e5a9456a9 --- /dev/null +++ b/src/out_hoi4/decisions/out_decisions_categories.h @@ -0,0 +1,22 @@ +#ifndef OUT_DECISIONS_CATEGORIES_H +#define OUT_DECISIONS_CATEGORIES_H + + + +#include + +#include "src/hoi4_world/decisions/decisions_category.h" + + + +namespace out +{ + +void OutputDecisionsCategories(std::string_view output_name, + const std::set& decisions_categories); + +} // namespace out + + + +#endif // OUT_DECISIONS_CATEGORIES_H \ No newline at end of file diff --git a/src/out_hoi4/decisions/out_decisions_categories_tests.cpp b/src/out_hoi4/decisions/out_decisions_categories_tests.cpp new file mode 100644 index 000000000..418380d9a --- /dev/null +++ b/src/out_hoi4/decisions/out_decisions_categories_tests.cpp @@ -0,0 +1,63 @@ +#include +#include +#include + +#include "external/commonItems/OSCompatibilityLayer.h" +#include "external/commonItems/external/googletest/googlemock/include/gmock/gmock-matchers.h" +#include "external/commonItems/external/googletest/googletest/include/gtest/gtest.h" +#include "external/fmt/include/fmt/format.h" +#include "src/hoi4_world/decisions/decisions_category.h" +#include "src/out_hoi4/decisions/out_decisions_categories.h" + + + +namespace +{ + +void CreateFolders(std::string_view test_name) +{ + commonItems::TryCreateFolder("output"); + commonItems::TryCreateFolder(fmt::format("output/{}", test_name)); + commonItems::TryCreateFolder(fmt::format("output/{}/common", test_name)); + commonItems::TryCreateFolder(fmt::format("output/{}/common/decisions", test_name)); + commonItems::TryCreateFolder(fmt::format("output/{}/common/decisions/categories", test_name)); +} + +} // namespace + + + +namespace out +{ + +TEST(Outhoi4DecisionsOutdecisionscategoriesTests, CategoriesFileIsCreated) +{ + CreateFolders("CategoriesFileIsCreated"); + + OutputDecisionsCategories("CategoriesFileIsCreated", + { + {.name = "category_one"}, + {.name = "category_two"}, + }); + + EXPECT_TRUE(commonItems::DoesFileExist( + "output/CategoriesFileIsCreated/common/decisions/categories/converter_decision_categories.txt")); + std::ifstream categories_file( + "output/CategoriesFileIsCreated/common/decisions/categories/converter_decision_categories.txt"); + ASSERT_TRUE(categories_file.is_open()); + std::stringstream categories_file_stream; + std::copy(std::istreambuf_iterator(categories_file), + std::istreambuf_iterator(), + std::ostreambuf_iterator(categories_file_stream)); + categories_file.close(); + + EXPECT_EQ(categories_file_stream.str(), + "category_one = {\n" + "}\n" + "\n" + "category_two = {\n" + "}\n" + "\n"); +} + +} // namespace out \ No newline at end of file diff --git a/src/out_hoi4/decisions/out_decisions_category.cpp b/src/out_hoi4/decisions/out_decisions_category.cpp new file mode 100644 index 000000000..5b2460409 --- /dev/null +++ b/src/out_hoi4/decisions/out_decisions_category.cpp @@ -0,0 +1,45 @@ +#include "src/out_hoi4/decisions/out_decisions_category.h" + + + +namespace out +{ + +std::ostream& operator<<(std::ostream& out, const hoi4::DecisionsCategory& decisions_category) +{ + out << decisions_category.name << " = {\n"; + if (!decisions_category.icon.empty()) + { + out << "\ticon = " << decisions_category.icon << "\n"; + } + if (!decisions_category.picture.empty()) + { + out << "\tpicture = " << decisions_category.picture << "\n"; + } + if (decisions_category.priority) + { + out << "\tpriority = " << *decisions_category.priority << "\n"; + } + if (!decisions_category.allowed.empty()) + { + out << "\tallowed " << decisions_category.allowed << "\n"; + } + if (!decisions_category.visible.empty()) + { + out << "\tvisible " << decisions_category.visible << "\n"; + } + if (!decisions_category.visibility_type.empty()) + { + out << "\tvisibility_type " << decisions_category.visibility_type << "\n"; + } + for (const auto& extraItem: decisions_category.extra_items) + { + out << "\t" << extraItem.first << " " << extraItem.second << "\n"; + } + out << "}\n"; + out << "\n"; + + return out; +} + +} // namespace out \ No newline at end of file diff --git a/src/out_hoi4/decisions/out_decisions_category.h b/src/out_hoi4/decisions/out_decisions_category.h new file mode 100644 index 000000000..6a058c73f --- /dev/null +++ b/src/out_hoi4/decisions/out_decisions_category.h @@ -0,0 +1,21 @@ +#ifndef OUT_DECISIONS_CATEGORY_H +#define OUT_DECISIONS_CATEGORY_H + + + +#include + +#include "src/hoi4_world/decisions/decisions_category.h" + + + +namespace out +{ + +std::ostream& operator<<(std::ostream& out, const hoi4::DecisionsCategory& decisions_category); + +} // namespace out + + + +#endif // OUT_DECISIONS_CATEGORY_H \ No newline at end of file diff --git a/src/out_hoi4/decisions/out_decisions_category_tests.cpp b/src/out_hoi4/decisions/out_decisions_category_tests.cpp new file mode 100644 index 000000000..5babf344f --- /dev/null +++ b/src/out_hoi4/decisions/out_decisions_category_tests.cpp @@ -0,0 +1,65 @@ +#include +#include + +#include "external/commonItems/external/googletest/googlemock/include/gmock/gmock-matchers.h" +#include "external/commonItems/external/googletest/googletest/include/gtest/gtest.h" +#include "src/out_hoi4/decisions/out_decisions_category.h" + + + +namespace out +{ + +TEST(Outhoi4DecisionsOutdecisionscategoryTests, BasicsAreOutput) +{ + const hoi4::DecisionsCategory category({.name = "test_name"}); + + std::ostringstream output; + output << category; + + std::ostringstream expected; + expected << "test_name = {\n"; + expected << "}\n"; + expected << "\n"; + EXPECT_EQ(output.str(), expected.str()); +} + + +TEST(Outhoi4DecisionsOutdecisionscategoryTests, SetItemsAreOutput) +{ + const hoi4::DecisionsCategory category({ + .name = "test_name", + .icon = "test_icon", + .picture = "test_picture", + .priority = 42, + .allowed = "= { test_allowed }", + .visible = "= { test_visible }", + .visibility_type = "= { test_visibility_type }", + .extra_items = + { + {"extra_one", "= { value_one }"}, + {"extra_two", "= { value_two }"}, + {"extra_two", "= { value_three }"}, + }, + }); + + std::ostringstream output; + output << category; + + std::ostringstream expected; + expected << "test_name = {\n"; + expected << "\ticon = test_icon\n"; + expected << "\tpicture = test_picture\n"; + expected << "\tpriority = 42\n"; + expected << "\tallowed = { test_allowed }\n"; + expected << "\tvisible = { test_visible }\n"; + expected << "\tvisibility_type = { test_visibility_type }\n"; + expected << "\textra_one = { value_one }\n"; + expected << "\textra_two = { value_two }\n"; + expected << "\textra_two = { value_three }\n"; + expected << "}\n"; + expected << "\n"; + EXPECT_EQ(output.str(), expected.str()); +} + +} // namespace out diff --git a/src/out_hoi4/world/out_world.cpp b/src/out_hoi4/world/out_world.cpp index e0cb84ed6..ca1d95b53 100644 --- a/src/out_hoi4/world/out_world.cpp +++ b/src/out_hoi4/world/out_world.cpp @@ -6,6 +6,7 @@ #include "external/fmt/include/fmt/format.h" #include "src/out_hoi4/countries/out_countries.h" #include "src/out_hoi4/decisions/out_decisions.h" +#include "src/out_hoi4/decisions/out_decisions_categories.h" #include "src/out_hoi4/ideas/out_ideas.h" #include "src/out_hoi4/localizations/out_localizations.h" #include "src/out_hoi4/map/out_buildings.h" @@ -91,6 +92,7 @@ void out::OutputWorld(std::string_view output_name, const hoi4::World& world, co OutputLocalizations(output_name, world.GetLocalizations()); OutputNames(output_name, world.GetCountries()); OutputPortraits(output_name, world.GetCountries()); + OutputDecisionsCategories(output_name, world.GetDecisionsCategories()); OutputBookmark(output_name, "grand_campaign", date("1936.1.1"), diff --git a/src/out_hoi4/world/out_world_tests.cpp b/src/out_hoi4/world/out_world_tests.cpp index 74fa36669..baf7647bd 100644 --- a/src/out_hoi4/world/out_world_tests.cpp +++ b/src/out_hoi4/world/out_world_tests.cpp @@ -23,6 +23,8 @@ void CreateTestFolders(std::string_view test_name) commonItems::TryCreateFolder(fmt::format("output/{}/common/characters", test_name)); commonItems::TryCreateFolder(fmt::format("output/{}/common/countries", test_name)); commonItems::TryCreateFolder(fmt::format("output/{}/common/country_tags", test_name)); + commonItems::TryCreateFolder(fmt::format("output/{}/common/decisions", test_name)); + commonItems::TryCreateFolder(fmt::format("output/{}/common/decisions/categories", test_name)); commonItems::TryCreateFolder(fmt::format("output/{}/common/ideas", test_name)); commonItems::TryCreateFolder(fmt::format("output/{}/common/names", test_name)); commonItems::TryCreateFolder(fmt::format("output/{}/common/national_focus", test_name));