Skip to content
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
30 changes: 19 additions & 11 deletions src/openvic-simulation/dataloader/Dataloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -531,23 +531,31 @@ bool Dataloader::_load_technologies(DefinitionManager& definition_manager) {
bool Dataloader::_load_inventions(DefinitionManager& definition_manager) {
static constexpr std::string_view inventions_directory = "inventions";

InventionManager& invention_manager = definition_manager.get_research_manager().get_invention_manager();
ResearchManager& research_manager = definition_manager.get_research_manager();
InventionManager& invention_manager = research_manager.get_invention_manager();
TechnologyManager& technology_manager = research_manager.get_technology_manager();

bool ret = apply_to_files(
lookup_files_in_dir(inventions_directory, ".txt"),
[this, &definition_manager, &invention_manager](fs::path const& file) -> bool {
return invention_manager.load_inventions_file(
definition_manager.get_modifier_manager(),
definition_manager.get_military_manager().get_unit_type_manager(),
definition_manager.get_economy_manager().get_building_type_manager(),
definition_manager.get_crime_manager(),
parse_defines_cached(file).get_file_node()
);
}
lookup_files_in_dir(inventions_directory, ".txt"),
[this, &definition_manager, &invention_manager, &technology_manager](fs::path const& file) -> bool {
return invention_manager.load_inventions_file(
technology_manager,
definition_manager.get_modifier_manager(),
definition_manager.get_military_manager().get_unit_type_manager(),
definition_manager.get_economy_manager().get_building_type_manager(),
definition_manager.get_crime_manager(),
parse_defines_cached(file).get_file_node()
);
}
);

invention_manager.lock_inventions();

if (!invention_manager.generate_invention_links(technology_manager)) {
spdlog::critical_s("Failed to generate invention links!");
ret = false;
}

return ret;
}

Expand Down
112 changes: 78 additions & 34 deletions src/openvic-simulation/research/Invention.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "openvic-simulation/map/Crime.hpp"
#include "openvic-simulation/military/UnitType.hpp"
#include "openvic-simulation/modifier/ModifierManager.hpp"
#include "openvic-simulation/research/Technology.hpp"

using namespace OpenVic;
using namespace OpenVic::NodeTools;
Expand All @@ -19,7 +20,8 @@ Invention::Invention(
bool new_unlock_gas_attack,
bool new_unlock_gas_defence,
ConditionScript&& new_limit,
ConditionalWeightBase&& new_chance
ConditionalWeightBase&& new_chance,
memory::vector<memory::string>&& new_raw_associated_tech_identifiers
) : HasIndex { new_index },
Modifier { new_identifier, std::move(new_values), modifier_type_t::INVENTION },
news { new_news },
Expand All @@ -29,7 +31,8 @@ Invention::Invention(
unlock_gas_attack { new_unlock_gas_attack },
unlock_gas_defence { new_unlock_gas_defence },
limit { std::move(new_limit) },
chance { std::move(new_chance) } {}
chance { std::move(new_chance) },
raw_associated_tech_identifiers { std::move(new_raw_associated_tech_identifiers) } {}

bool Invention::parse_scripts(DefinitionManager const& definition_manager) {
bool ret = true;
Expand All @@ -42,51 +45,69 @@ bool Invention::parse_scripts(DefinitionManager const& definition_manager) {

bool InventionManager::add_invention(
std::string_view identifier, ModifierValue&& values, bool news, Invention::unit_set_t&& activated_units,
Invention::building_set_t&& activated_buildings, Invention::crime_set_t&& enabled_crimes,
bool unlock_gas_attack, bool unlock_gas_defence, ConditionScript&& limit, ConditionalWeightBase&& chance
Invention::building_set_t&& activated_buildings, Invention::crime_set_t&& enabled_crimes, bool unlock_gas_attack,
bool unlock_gas_defence, ConditionScript&& limit, ConditionalWeightBase&& chance,
memory::vector<memory::string>&& raw_associated_tech_identifiers
) {
if (identifier.empty()) {
spdlog::error_s("Invalid invention identifier - empty!");
return false;
}

return inventions.emplace_item(
identifier,
Invention::index_t { get_invention_count() }, identifier,
std::move(values), news, std::move(activated_units), std::move(activated_buildings),
std::move(enabled_crimes), unlock_gas_attack, unlock_gas_defence, std::move(limit), std::move(chance)
identifier, Invention::index_t { get_invention_count() }, identifier, std::move(values), news,
std::move(activated_units), std::move(activated_buildings), std::move(enabled_crimes), unlock_gas_attack,
unlock_gas_defence, std::move(limit), std::move(chance),
std::move(raw_associated_tech_identifiers)
);
}

bool InventionManager::load_inventions_file(
ModifierManager const& modifier_manager, UnitTypeManager const& unit_type_manager,
TechnologyManager const& tech_manager, ModifierManager const& modifier_manager, UnitTypeManager const& unit_type_manager,
BuildingTypeManager const& building_type_manager, CrimeManager const& crime_manager, ast::NodeCPtr root
) {
return expect_dictionary_reserve_length(
inventions, [this, &modifier_manager, &unit_type_manager, &building_type_manager, &crime_manager](
std::string_view identifier, ast::NodeCPtr value
) -> bool {
using enum scope_type_t;
return expect_dictionary_reserve_length(inventions, [&](std::string_view identifier, ast::NodeCPtr value) -> bool {
using enum scope_type_t;

// TODO - use the same variable for all modifiers rather than combining them at the end?
ModifierValue loose_modifiers;
ModifierValue modifiers;
// TODO - use the same variable for all modifiers rather than combining them at the end?
ModifierValue loose_modifiers;
ModifierValue modifiers;

Invention::unit_set_t activated_units;
Invention::building_set_t activated_buildings;
Invention::crime_set_t enabled_crimes;
Invention::unit_set_t activated_units;
Invention::building_set_t activated_buildings;
Invention::crime_set_t enabled_crimes;

bool unlock_gas_attack = false;
bool unlock_gas_defence = false;
bool news = true; //defaults to true!
bool unlock_gas_attack = false;
bool unlock_gas_defence = false;
bool news = true; // defaults to true!

ConditionScript limit { COUNTRY, COUNTRY, NO_SCOPE };
ConditionalWeightBase chance { COUNTRY, COUNTRY, NO_SCOPE };
ConditionScript limit { COUNTRY, COUNTRY, NO_SCOPE };
ConditionalWeightBase chance { COUNTRY, COUNTRY, NO_SCOPE };

bool ret = NodeTools::expect_dictionary_keys_and_default(
memory::vector<memory::string> found_tech_ids;

auto parse_limit_and_find_techs = [&](ast::NodeCPtr node) -> bool {

if (!limit.expect_script()(node)) {
return false;
}

expect_dictionary(
[&](std::string_view key, ast::NodeCPtr /*value*/) -> bool {
if (tech_manager.get_technology_by_identifier(key) != nullptr) {
found_tech_ids.push_back(memory::string(key));
}
return true;
}
)(node);

return true;
};

bool ret = NodeTools::expect_dictionary_keys_and_default(
modifier_manager.expect_base_country_modifier(loose_modifiers),
"news", ZERO_OR_ONE, expect_bool(assign_variable_callback(news)),
"limit", ONE_EXACTLY, limit.expect_script(),
"limit", ONE_EXACTLY, parse_limit_and_find_techs,
"chance", ONE_EXACTLY, chance.expect_conditional_weight(),
"effect", ZERO_OR_ONE, NodeTools::expect_dictionary_keys_and_default(
modifier_manager.expect_technology_modifier(modifiers),
Expand All @@ -103,16 +124,39 @@ bool InventionManager::load_inventions_file(
)
)(value);

modifiers += loose_modifiers;
modifiers += loose_modifiers;

ret &= add_invention(
identifier, std::move(modifiers), news, std::move(activated_units), std::move(activated_buildings),
std::move(enabled_crimes), unlock_gas_attack, unlock_gas_defence, std::move(limit), std::move(chance)
);
ret &= add_invention(
identifier, std::move(modifiers), news, std::move(activated_units), std::move(activated_buildings),
std::move(enabled_crimes), unlock_gas_attack, unlock_gas_defence, std::move(limit), std::move(chance),
std::move(found_tech_ids)
);

return ret;
return ret;
})(root);
}

bool InventionManager::generate_invention_links(TechnologyManager& tech_manager) {
if (!inventions.is_locked()) {
spdlog::error_s("Cannot generate invention links until inventions are locked!");
return false;
}

bool ret = true;

for (Invention& invention : inventions.get_items()) {
for (const memory::string& tech_id : invention.raw_associated_tech_identifiers) {
Technology const* tech = tech_manager.get_technology_by_identifier(tech_id);
if (tech) {
auto* mutable_tech = const_cast<Technology*>(tech);
mutable_tech->add_invention(&invention);
}
}
)(root);

invention.raw_associated_tech_identifiers.clear();
}

return ret;
}

bool InventionManager::parse_scripts(DefinitionManager const& definition_manager) {
Expand Down
14 changes: 12 additions & 2 deletions src/openvic-simulation/research/Invention.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ namespace OpenVic {
struct UnitType;
struct UnitTypeManager;

struct Technology;
struct TechnologyManager;

struct Invention : HasIndex<Invention, invention_index_t>, Modifier {
friend struct InventionManager;

Expand All @@ -34,6 +37,8 @@ namespace OpenVic {
const bool PROPERTY_CUSTOM_PREFIX(unlock_gas_defence, will);
ConditionScript PROPERTY(limit);
ConditionalWeightBase PROPERTY(chance);

memory::vector<memory::string> raw_associated_tech_identifiers;

bool parse_scripts(DefinitionManager const& definition_manager);

Expand All @@ -49,7 +54,8 @@ namespace OpenVic {
bool new_unlock_gas_attack,
bool new_unlock_gas_defence,
ConditionScript&& new_limit,
ConditionalWeightBase&& new_chance
ConditionalWeightBase&& new_chance,
memory::vector<memory::string>&& new_raw_associated_tech_identifiers
);
Invention(Invention&&) = default;
};
Expand All @@ -61,14 +67,18 @@ namespace OpenVic {
bool add_invention(
std::string_view identifier, ModifierValue&& values, bool news, Invention::unit_set_t&& activated_units,
Invention::building_set_t&& activated_buildings, Invention::crime_set_t&& enabled_crimes, bool unlock_gas_attack,
bool unlock_gas_defence, ConditionScript&& limit, ConditionalWeightBase&& chance
bool unlock_gas_defence, ConditionScript&& limit, ConditionalWeightBase&& chance,
memory::vector<memory::string>&& raw_associated_tech_identifiers
);

bool load_inventions_file(
TechnologyManager const& tech_manager,
ModifierManager const& modifier_manager, UnitTypeManager const& unit_type_manager,
BuildingTypeManager const& building_type_manager, CrimeManager const& crime_manager, ast::NodeCPtr root
); // inventions/*.txt

bool generate_invention_links(TechnologyManager& tech_manager);

bool parse_scripts(DefinitionManager const& definition_manager);
};
}
6 changes: 6 additions & 0 deletions src/openvic-simulation/research/Technology.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace OpenVic {
struct TechnologyArea;
struct TechnologyManager;
struct UnitTypeManager;
struct Invention;

struct TechnologyFolder : HasIdentifier, HasIndex<TechnologyFolder, technology_folder_index_t> {
friend struct TechnologyManager;
Expand Down Expand Up @@ -58,6 +59,7 @@ namespace OpenVic {
unit_set_t PROPERTY(activated_units);
building_set_t PROPERTY(activated_buildings);
ConditionalWeightFactorMul PROPERTY(ai_chance);
memory::vector<Invention const*> PROPERTY(inventions);

bool parse_scripts(DefinitionManager const& definition_manager);

Expand All @@ -82,6 +84,10 @@ namespace OpenVic {
ConditionalWeightFactorMul&& new_ai_chance
);
Technology(Technology&&) = default;

void add_invention(Invention const* invention) {
inventions.push_back(invention);
}
};

struct TechnologySchool : Modifier {
Expand Down