Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Make generic focuses roles. #618

Merged
merged 1 commit into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions data/configurables/stories/generic.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
generic_army = {
category=generic

requirements={
always = yes
}

score=100004

shared_focus = army_effort
}

generic_aviation = {
category=generic

requirements={
always = yes
}

score=100003

shared_focus = aviation_effort
}

generic_naval = {
category=generic

requirements={
always = yes
}

score=100002

shared_focus = naval_effort
}

generic_industry = {
category=generic

requirements={
always = yes
}

score=100001

shared_focus = industrial_effort
}

generic_political = {
category=generic

requirements={
always = yes
}

score=100000

shared_focus = political_effort
}
4 changes: 4 additions & 0 deletions src/hoi4_world/roles/role.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ struct RoleOptions
std::string requirements;
float score;
std::vector<std::string> blockers;
std::vector<std::string> shared_focuses;
std::vector<std::string> focuses;
std::vector<std::string> repeat_focuses;
std::vector<std::string> removed_focuses;
Expand All @@ -35,6 +36,7 @@ class Role
requirements_(std::move(options.requirements)),
score_(options.score),
blockers_(std::move(options.blockers)),
shared_focuses_(std::move(options.shared_focuses)),
focuses_(std::move(options.focuses)),
repeat_focuses_(std::move(options.repeat_focuses)),
removed_focuses_(std::move(options.removed_focuses)),
Expand All @@ -48,6 +50,7 @@ class Role
[[nodiscard]] const std::string& GetRequirements() const { return requirements_; }
[[nodiscard]] float GetScore() const { return score_; }
[[nodiscard]] const std::vector<std::string>& GetBlockers() const { return blockers_; }
[[nodiscard]] const std::vector<std::string>& GetSharedFocuses() const { return shared_focuses_; }
[[nodiscard]] const std::vector<std::string>& GetFocuses() const { return focuses_; }
[[nodiscard]] const std::vector<std::string>& GetRepeatFocuses() const { return repeat_focuses_; }
[[nodiscard]] const std::vector<std::string>& GetRemovedFocuses() const { return removed_focuses_; }
Expand All @@ -62,6 +65,7 @@ class Role
std::string requirements_;
float score_;
std::vector<std::string> blockers_;
std::vector<std::string> shared_focuses_;
std::vector<std::string> focuses_;
std::vector<std::string> repeat_focuses_;
std::vector<std::string> removed_focuses_;
Expand Down
3 changes: 3 additions & 0 deletions src/hoi4_world/roles/role_importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ hoi4::RoleImporter::RoleImporter()
role_parser_.registerKeyword("block_category", [this](std::istream& input) {
role_options_.blockers.emplace_back(commonItems::getString(input));
});
role_parser_.registerKeyword("shared_focus", [this](std::istream& input) {
role_options_.shared_focuses.emplace_back(commonItems::getString(input));
});
role_parser_.registerKeyword("focus", [this](std::istream& input) {
role_options_.focuses.emplace_back(commonItems::stringOfItem(input).getString());
});
Expand Down
4 changes: 4 additions & 0 deletions src/hoi4_world/roles/role_importer_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ TEST(Hoi4worldRolesRoleimporterTests, DefaultsAreDefaulted)
EXPECT_TRUE(role.GetRequirements().empty());
EXPECT_EQ(role.GetScore(), 0.0F);
EXPECT_TRUE(role.GetBlockers().empty());
EXPECT_TRUE(role.GetSharedFocuses().empty());
EXPECT_TRUE(role.GetFocuses().empty());
EXPECT_TRUE(role.GetRepeatFocuses().empty());
EXPECT_TRUE(role.GetRemovedFocuses().empty());
Expand All @@ -43,6 +44,8 @@ TEST(Hoi4worldRolesRoleimporterTests, ItemsCanBeImported)
input << "\tblock_role=unification_role\n";
input << "\tblock_category=unification_category\n";
input << "\n";
input << "\tshared_focus=army_effort\n";
input << "\tshared_focus=aviation_effort\n";
input << "\tfocus={\n";
input << "\t\tid = $TAG$_italia_irredenta #start of tree for an italian unifier\n";
input << "\t}\n";
Expand Down Expand Up @@ -114,6 +117,7 @@ TEST(Hoi4worldRolesRoleimporterTests, ItemsCanBeImported)
"\t}");
EXPECT_FLOAT_EQ(role.GetScore(), 100.0F);
EXPECT_THAT(role.GetBlockers(), testing::ElementsAre("unification_role", "unification_category"));
EXPECT_THAT(role.GetSharedFocuses(), testing::ElementsAre("army_effort", "aviation_effort"));
EXPECT_THAT(role.GetFocuses(),
testing::ElementsAre("= {\n"
"\t\tid = $TAG$_italia_irredenta #start of tree for an italian unifier\n"
Expand Down
35 changes: 23 additions & 12 deletions src/hoi4_world/roles/stories_creator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,38 @@ using Tag = std::string;
using CombinationName = std::string;


bool IsRoleValidForCountry(const hoi4::Role& role, const std::string& country_tag)
{
// scan for 'always=yes' constructs
const std::regex always_match_regex(R"([\s\S]*always[\s\S]?=[\s\S]?yes[\s\S]*)");
std::smatch always_match;
if (std::regex_match(role.GetRequirements(), always_match, always_match_regex))
{
return true;
}

// scan for 'tag=TAG' constructs
const std::regex tag_match_regex(R"([\s\S]*tag[\s\S]?=[\s\S]?(\w{3})[\s\S]*)");
std::smatch tag_match;
if (std::regex_match(role.GetRequirements(), tag_match, tag_match_regex))
{
return country_tag == tag_match[1];
}

return false;
}


std::vector<std::pair<Tag, CombinationName>> MakeCombinations(const std::map<std::string, hoi4::Role>& roles,
const std::map<std::string, hoi4::Country>& countries)
{
std::vector<std::pair<Tag, CombinationName>> combinations;

for (const auto& [role_name, role]: roles)
{
// scan for 'tag=TAG' constructs
std::regex tag_match_regex(R"([\s\S]+tag=(.+)[\s\S]+)");
std::smatch match;
if (!std::regex_match(role.GetRequirements(), match, tag_match_regex))
{
continue;
}
std::string required_tag = match[1];

// even though a direct lookup would suffice for this simple condition, loop over all countries because we'll
// eventually have more complex conditions that aren't so easily checked
for (const std::string& country_tag: countries | std::views::keys)
{
if (required_tag == country_tag)
if (IsRoleValidForCountry(role, country_tag))
{
combinations.emplace_back(country_tag, role_name);
}
Expand Down