aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/economy
diff options
context:
space:
mode:
author Hop311 <Hop3114@gmail.com>2023-11-17 10:19:53 +0100
committer GitHub <noreply@github.com>2023-11-17 10:19:53 +0100
commite76336cd92639f4ec71088fc4c80aea4c25528cd (patch)
treeeeed419a7d97ecb58adf63a17eb9184db3e5ed7a /src/openvic-simulation/economy
parenta00b558a53edb40c9e6789790036f0b618e80ec1 (diff)
parent886b8b8f396438fc2b7da7d2508f2064d14150a8 (diff)
Merge pull request #75 from OpenVicProject/accumulated-changes
Accumulated changes
Diffstat (limited to 'src/openvic-simulation/economy')
-rw-r--r--src/openvic-simulation/economy/Building.cpp316
-rw-r--r--src/openvic-simulation/economy/Building.hpp171
-rw-r--r--src/openvic-simulation/economy/BuildingInstance.cpp52
-rw-r--r--src/openvic-simulation/economy/BuildingInstance.hpp33
-rw-r--r--src/openvic-simulation/economy/BuildingType.cpp114
-rw-r--r--src/openvic-simulation/economy/BuildingType.hpp89
-rw-r--r--src/openvic-simulation/economy/EconomyManager.hpp2
-rw-r--r--src/openvic-simulation/economy/Good.cpp14
-rw-r--r--src/openvic-simulation/economy/Good.hpp4
-rw-r--r--src/openvic-simulation/economy/ProductionType.cpp4
-rw-r--r--src/openvic-simulation/economy/ProductionType.hpp2
11 files changed, 298 insertions, 503 deletions
diff --git a/src/openvic-simulation/economy/Building.cpp b/src/openvic-simulation/economy/Building.cpp
deleted file mode 100644
index bade4a5..0000000
--- a/src/openvic-simulation/economy/Building.cpp
+++ /dev/null
@@ -1,316 +0,0 @@
-#include "Building.hpp"
-
-#include "openvic-simulation/map/Province.hpp" //imported here so the hpp doesn't get circular imports
-
-using namespace OpenVic;
-using namespace OpenVic::NodeTools;
-
-Building::Building(
- std::string_view identifier, BuildingType const& type, ARGS
-) : HasIdentifier { identifier }, type { type }, modifier { std::move(modifier) }, on_completion { on_completion },
- completion_size { completion_size }, max_level { max_level }, goods_cost { std::move(goods_cost) }, cost { cost },
- build_time { build_time }, visibility { visibility }, on_map { on_map }, default_enabled { default_enabled },
- production_type { production_type }, pop_build_factory { pop_build_factory }, strategic_factory { strategic_factory },
- advanced_factory { advanced_factory }, fort_level { fort_level }, naval_capacity { naval_capacity },
- colonial_points { std::move(colonial_points) }, in_province { in_province }, one_per_state { one_per_state },
- colonial_range { colonial_range }, infrastructure { infrastructure }, spawn_railway_track { spawn_railway_track },
- sail { sail }, steam { steam }, capital { capital }, port { port } {}
-
-BuildingType const& Building::get_type() const {
- return type;
-}
-
-ModifierValue const& Building::get_modifier() const {
- return modifier;
-}
-
-std::string_view Building::get_on_completion() const {
- return on_completion;
-}
-
-fixed_point_t Building::get_completion_size() const {
- return completion_size;
-}
-
-Building::level_t Building::get_max_level() const {
- return max_level;
-}
-
-Good::good_map_t const& Building::get_goods_cost() const {
- return goods_cost;
-}
-
-fixed_point_t Building::get_cost() const {
- return cost;
-}
-
-Timespan Building::get_build_time() const {
- return build_time;
-}
-
-bool Building::has_visibility() const {
- return visibility;
-}
-
-bool Building::is_on_map() const {
- return on_map;
-}
-
-bool Building::is_default_enabled() const {
- return default_enabled;
-}
-
-ProductionType const* Building::get_production_type() const {
- return production_type;
-}
-
-bool Building::is_pop_built_factory() const {
- return pop_build_factory;
-}
-
-bool Building::is_strategic_factory() const {
- return strategic_factory;
-}
-
-bool Building::is_advanced_factory() const {
- return advanced_factory;
-}
-
-Building::level_t Building::get_fort_level() const {
- return fort_level;
-}
-
-uint64_t Building::get_naval_capacity() const {
- return naval_capacity;
-}
-
-std::vector<fixed_point_t> const& Building::get_colonial_points() const {
- return colonial_points;
-}
-
-bool Building::is_in_province() const {
- return in_province;
-}
-
-bool Building::is_one_per_state() const {
- return one_per_state;
-}
-
-fixed_point_t Building::get_colonial_range() const {
- return colonial_range;
-}
-
-fixed_point_t Building::get_infrastructure() const {
- return infrastructure;
-}
-
-bool Building::spawned_railway_track() const {
- return spawn_railway_track;
-}
-
-BuildingType::BuildingType(std::string_view new_identifier) : HasIdentifier { new_identifier } {}
-
-BuildingInstance::BuildingInstance(Building const& building)
- : HasIdentifier { building.get_identifier() }, building { building } {}
-
-Building const& BuildingInstance::get_building() const {
- return building;
-}
-
-bool BuildingInstance::_can_expand() const {
- return level < building.get_max_level();
-}
-
-BuildingInstance::level_t BuildingInstance::get_current_level() const {
- return level;
-}
-
-void BuildingInstance::set_level(BuildingInstance::level_t new_level) {
- level = new_level;
-}
-
-ExpansionState BuildingInstance::get_expansion_state() const {
- return expansion_state;
-}
-
-Date BuildingInstance::get_start_date() const {
- return start;
-}
-
-Date BuildingInstance::get_end_date() const {
- return end;
-}
-
-float BuildingInstance::get_expansion_progress() const {
- return expansion_progress;
-}
-
-bool BuildingInstance::expand() {
- if (expansion_state == ExpansionState::CanExpand) {
- expansion_state = ExpansionState::Preparing;
- expansion_progress = 0.0f;
- return true;
- }
- return false;
-}
-
-/* REQUIREMENTS:
- * MAP-71, MAP-74, MAP-77
- */
-void BuildingInstance::update_state(Date today) {
- switch (expansion_state) {
- case ExpansionState::Preparing:
- start = today;
- end = start + building.get_build_time();
- break;
- case ExpansionState::Expanding:
- expansion_progress = static_cast<double>(today - start) / static_cast<double>(end - start);
- break;
- default: expansion_state = _can_expand() ? ExpansionState::CanExpand : ExpansionState::CannotExpand;
- }
-}
-
-void BuildingInstance::tick(Date today) {
- if (expansion_state == ExpansionState::Preparing) {
- expansion_state = ExpansionState::Expanding;
- }
- if (expansion_state == ExpansionState::Expanding) {
- if (end <= today) {
- level++;
- expansion_state = ExpansionState::CannotExpand;
- }
- }
-}
-
-BuildingManager::BuildingManager() : building_types { "building types" }, buildings { "buildings" } {}
-
-bool BuildingManager::add_building_type(std::string_view identifier) {
- if (identifier.empty()) {
- Logger::error("Invalid building type identifier - empty!");
- return false;
- }
- return building_types.add_item({ identifier }, duplicate_ignore_callback);
-}
-
-bool BuildingManager::add_building(std::string_view identifier, BuildingType const* type, ARGS) {
- if (identifier.empty()) {
- Logger::error("Invalid building identifier - empty!");
- return false;
- }
- if (type == nullptr) {
- Logger::error("Invalid building type for ", identifier, ": null");
- return false;
- }
-
- return buildings.add_item({
- identifier, *type, std::move(modifier), on_completion, completion_size, max_level, std::move(goods_cost),
- cost, build_time, visibility, on_map, default_enabled, production_type, pop_build_factory, strategic_factory,
- advanced_factory, fort_level, naval_capacity, std::move(colonial_points), in_province, one_per_state,
- colonial_range, infrastructure, spawn_railway_track, sail, steam, capital, port
- });
-}
-
-bool BuildingManager::load_buildings_file(
- GoodManager const& good_manager, ProductionTypeManager const& production_type_manager, ModifierManager& modifier_manager,
- ast::NodeCPtr root
-) {
- bool ret = expect_dictionary_reserve_length(buildings, [this](std::string_view, ast::NodeCPtr value) -> bool {
- return expect_key("type", expect_identifier(
- std::bind(&BuildingManager::add_building_type, this, std::placeholders::_1)
- ))(value);
- })(root);
- lock_building_types();
-
- ret &= expect_dictionary(
- [this, &good_manager, &production_type_manager, &modifier_manager](std::string_view key, ast::NodeCPtr value) -> bool {
- BuildingType const* type = nullptr;
- ProductionType const* production_type = nullptr;
- std::string_view on_completion;
- fixed_point_t completion_size = 0, cost = 0, infrastructure = 0, colonial_range = 0;
- Building::level_t max_level = 0, fort_level = 0;
- Good::good_map_t goods_cost;
- Timespan build_time;
- bool visibility = false, on_map = false, default_enabled = false, pop_build_factory = false;
- bool strategic_factory = false, advanced_factory = false;
- bool in_province = false, one_per_state = false, spawn_railway_track = false, sail = false, steam = false;
- bool capital = false, port = false;
- uint64_t naval_capacity = 0;
- std::vector<fixed_point_t> colonial_points;
- ModifierValue modifier;
-
- bool ret = modifier_manager.expect_modifier_value_and_keys(move_variable_callback(modifier),
- "type", ONE_EXACTLY, expect_building_type_identifier(assign_variable_callback_pointer(type)),
- "on_completion", ZERO_OR_ONE, expect_identifier(assign_variable_callback(on_completion)),
- "completion_size", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(completion_size)),
- "max_level", ONE_EXACTLY, expect_uint(assign_variable_callback(max_level)),
- "goods_cost", ONE_EXACTLY, good_manager.expect_good_decimal_map(move_variable_callback(goods_cost)),
- "cost", ZERO_OR_MORE, expect_fixed_point(assign_variable_callback(cost)),
- "time", ONE_EXACTLY, expect_days(assign_variable_callback(build_time)),
- "visibility", ONE_EXACTLY, expect_bool(assign_variable_callback(visibility)),
- "onmap", ONE_EXACTLY, expect_bool(assign_variable_callback(on_map)),
- "default_enabled", ZERO_OR_ONE, expect_bool(assign_variable_callback(default_enabled)),
- "production_type", ZERO_OR_ONE, production_type_manager.expect_production_type_identifier(
- assign_variable_callback_pointer(production_type)),
- "pop_build_factory", ZERO_OR_ONE, expect_bool(assign_variable_callback(pop_build_factory)),
- "strategic_factory", ZERO_OR_ONE, expect_bool(assign_variable_callback(strategic_factory)),
- "advanced_factory", ZERO_OR_ONE, expect_bool(assign_variable_callback(advanced_factory)),
- "fort_level", ZERO_OR_ONE, expect_uint(assign_variable_callback(fort_level)),
- "naval_capacity", ZERO_OR_ONE, expect_uint(assign_variable_callback(naval_capacity)),
- "colonial_points", ZERO_OR_ONE, expect_list(expect_fixed_point(
- [&colonial_points](fixed_point_t points) -> bool {
- colonial_points.push_back(points);
- return true;
- }
- )),
- "province", ZERO_OR_ONE, expect_bool(assign_variable_callback(in_province)),
- "one_per_state", ZERO_OR_ONE, expect_bool(assign_variable_callback(one_per_state)),
- "colonial_range", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(colonial_range)),
- "infrastructure", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(infrastructure)),
- "spawn_railway_track", ZERO_OR_ONE, expect_bool(assign_variable_callback(spawn_railway_track)),
- "sail", ZERO_OR_ONE, expect_bool(assign_variable_callback(sail)),
- "steam", ZERO_OR_ONE, expect_bool(assign_variable_callback(steam)),
- "capital", ZERO_OR_ONE, expect_bool(assign_variable_callback(capital)),
- "port", ZERO_OR_ONE, expect_bool(assign_variable_callback(port))
- )(value);
-
- ret &= add_building(
- key, type, std::move(modifier), on_completion, completion_size, max_level, std::move(goods_cost), cost,
- build_time, visibility, on_map, default_enabled, production_type, pop_build_factory, strategic_factory,
- advanced_factory, fort_level, naval_capacity, std::move(colonial_points), in_province, one_per_state,
- colonial_range, infrastructure, spawn_railway_track, sail, steam, capital, port
- );
-
- return ret;
- }
- )(root);
- lock_buildings();
-
- for (Building const& building : buildings.get_items()) {
- std::string max_modifier_prefix = "max_";
- std::string min_modifier_prefix = "min_build_";
- modifier_manager.add_modifier_effect(
- max_modifier_prefix.append(building.get_identifier()), true, ModifierEffect::format_t::INT
- );
- modifier_manager.add_modifier_effect(
- min_modifier_prefix.append(building.get_identifier()), false, ModifierEffect::format_t::INT
- );
- }
-
- return ret;
-}
-
-bool BuildingManager::generate_province_buildings(Province& province) const {
- province.reset_buildings();
- if (!building_types.is_locked()) {
- Logger::error("Cannot generate buildings until building types are locked!");
- return false;
- }
- bool ret = true;
- if (!province.get_water()) {
- for (Building const& building : buildings.get_items()) {
- ret &= province.add_building({ building });
- }
- }
- province.lock_buildings();
- return ret;
-}
diff --git a/src/openvic-simulation/economy/Building.hpp b/src/openvic-simulation/economy/Building.hpp
deleted file mode 100644
index c2eb1ef..0000000
--- a/src/openvic-simulation/economy/Building.hpp
+++ /dev/null
@@ -1,171 +0,0 @@
-#pragma once
-
-#include "openvic-simulation/Modifier.hpp"
-#include "openvic-simulation/economy/Good.hpp"
-#include "openvic-simulation/economy/ProductionType.hpp"
-#include "openvic-simulation/types/Date.hpp"
-#include "openvic-simulation/types/IdentifierRegistry.hpp"
-#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
-
-#define ARGS \
- ModifierValue&& modifier, std::string_view on_completion, fixed_point_t completion_size, level_t max_level, \
- Good::good_map_t&& goods_cost, fixed_point_t cost, Timespan build_time, bool visibility, bool on_map, \
- bool default_enabled, ProductionType const* production_type, bool pop_build_factory, bool strategic_factory, \
- bool advanced_factory, level_t fort_level, uint64_t naval_capacity, std::vector<fixed_point_t>&& colonial_points, \
- bool in_province, bool one_per_state, fixed_point_t colonial_range, fixed_point_t infrastructure, \
- bool spawn_railway_track, bool sail, bool steam, bool capital, bool port
-
-namespace OpenVic {
-
- struct BuildingManager;
- struct BuildingType;
-
- /* REQUIREMENTS:
- * MAP-11, MAP-72, MAP-73
- * MAP-12, MAP-75, MAP-76
- * MAP-13, MAP-78, MAP-79
- */
- struct Building : HasIdentifier {
- friend struct BuildingManager;
-
- using level_t = int16_t;
-
- private:
- BuildingType const& type;
- const ModifierValue modifier;
- const std::string on_completion; // probably sound played on completion
- const fixed_point_t completion_size;
- const level_t max_level;
- const Good::good_map_t goods_cost;
- const fixed_point_t cost;
- const Timespan build_time; // time
- const bool visibility;
- const bool on_map; // onmap
-
- const bool default_enabled;
- ProductionType const* production_type;
- const bool pop_build_factory;
- const bool strategic_factory;
- const bool advanced_factory;
-
- const level_t fort_level; // probably the step-per-level
-
- const uint64_t naval_capacity;
- const std::vector<fixed_point_t> colonial_points;
- const bool in_province; // province
- const bool one_per_state;
- const fixed_point_t colonial_range;
-
- const fixed_point_t infrastructure;
- const bool spawn_railway_track;
-
- const bool sail; // only in clipper shipyard
- const bool steam; // only in steamer shipyard
- const bool capital; // only in naval base
- const bool port; // only in naval base
-
- Building(std::string_view identifier, BuildingType const& type, ARGS);
-
- public:
- Building(Building&&) = default;
-
- BuildingType const& get_type() const;
- ModifierValue const& get_modifier() const;
- std::string_view get_on_completion() const;
- fixed_point_t get_completion_size() const;
- level_t get_max_level() const;
- Good::good_map_t const& get_goods_cost() const;
- fixed_point_t get_cost() const;
- Timespan get_build_time() const;
- bool has_visibility() const;
- bool is_on_map() const;
-
- bool is_default_enabled() const;
- ProductionType const* get_production_type() const;
- bool is_pop_built_factory() const;
- bool is_strategic_factory() const;
- bool is_advanced_factory() const;
-
- level_t get_fort_level() const;
-
- uint64_t get_naval_capacity() const;
- std::vector<fixed_point_t> const& get_colonial_points() const;
- bool is_in_province() const;
- bool is_one_per_state() const;
- fixed_point_t get_colonial_range() const;
-
- fixed_point_t get_infrastructure() const;
- bool spawned_railway_track() const;
- };
-
- struct BuildingType : HasIdentifier {
- friend struct BuildingManager;
-
- private:
- BuildingType(std::string_view new_identifier);
-
- public:
- BuildingType(BuildingType&&) = default;
- };
-
- enum class ExpansionState { CannotExpand, CanExpand, Preparing, Expanding };
-
- struct BuildingInstance : HasIdentifier { // used in the actual game
- friend struct BuildingManager;
- using level_t = Building::level_t;
-
- private:
- Building const& building;
-
- level_t level = 0;
- ExpansionState expansion_state = ExpansionState::CannotExpand;
- Date start, end;
- float expansion_progress;
-
- bool _can_expand() const;
-
- public:
- BuildingInstance(Building const& building);
- BuildingInstance(BuildingInstance&&) = default;
-
- Building const& get_building() const;
-
- level_t get_current_level() const;
- void set_level(level_t new_level);
-
- ExpansionState get_expansion_state() const;
- Date get_start_date() const;
- Date get_end_date() const;
- float get_expansion_progress() const;
-
- bool expand();
- void update_state(Date today);
- void tick(Date today);
- };
-
- struct Province;
-
- struct BuildingManager {
- using level_t = Building::level_t; // this is getting ridiculous
-
- private:
- IdentifierRegistry<BuildingType> building_types;
- IdentifierRegistry<Building> buildings;
-
- public:
- BuildingManager();
-
- bool add_building_type(std::string_view identifier);
- IDENTIFIER_REGISTRY_ACCESSORS(building_type)
-
- bool add_building(std::string_view identifier, BuildingType const* type, ARGS);
- IDENTIFIER_REGISTRY_ACCESSORS(building)
-
- bool load_buildings_file(
- GoodManager const& good_manager, ProductionTypeManager const& production_type_manager,
- ModifierManager& modifier_manager, ast::NodeCPtr root
- );
-
- bool generate_province_buildings(Province& province) const;
- };
-}
diff --git a/src/openvic-simulation/economy/BuildingInstance.cpp b/src/openvic-simulation/economy/BuildingInstance.cpp
new file mode 100644
index 0000000..417cdda
--- /dev/null
+++ b/src/openvic-simulation/economy/BuildingInstance.cpp
@@ -0,0 +1,52 @@
+#include "BuildingInstance.hpp"
+
+using namespace OpenVic;
+
+BuildingInstance::BuildingInstance(BuildingType const& new_building_type, level_t new_level)
+ : HasIdentifier { building_type.get_identifier() }, building_type { new_building_type }, level { new_level },
+ expansion_state { ExpansionState::CannotExpand } {}
+
+bool BuildingInstance::_can_expand() const {
+ return level < building_type.get_max_level();
+}
+
+void BuildingInstance::set_level(BuildingInstance::level_t new_level) {
+ level = new_level;
+}
+
+bool BuildingInstance::expand() {
+ if (expansion_state == ExpansionState::CanExpand) {
+ expansion_state = ExpansionState::Preparing;
+ expansion_progress = 0.0f;
+ return true;
+ }
+ return false;
+}
+
+/* REQUIREMENTS:
+ * MAP-71, MAP-74, MAP-77
+ */
+void BuildingInstance::update_state(Date today) {
+ switch (expansion_state) {
+ case ExpansionState::Preparing:
+ start_date = today;
+ end_date = start_date + building_type.get_build_time();
+ break;
+ case ExpansionState::Expanding:
+ expansion_progress = static_cast<double>(today - start_date) / static_cast<double>(end_date - start_date);
+ break;
+ default: expansion_state = _can_expand() ? ExpansionState::CanExpand : ExpansionState::CannotExpand;
+ }
+}
+
+void BuildingInstance::tick(Date today) {
+ if (expansion_state == ExpansionState::Preparing) {
+ expansion_state = ExpansionState::Expanding;
+ }
+ if (expansion_state == ExpansionState::Expanding) {
+ if (end_date <= today) {
+ level++;
+ expansion_state = ExpansionState::CannotExpand;
+ }
+ }
+}
diff --git a/src/openvic-simulation/economy/BuildingInstance.hpp b/src/openvic-simulation/economy/BuildingInstance.hpp
new file mode 100644
index 0000000..9fc9df1
--- /dev/null
+++ b/src/openvic-simulation/economy/BuildingInstance.hpp
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "openvic-simulation/economy/BuildingType.hpp"
+
+namespace OpenVic {
+
+ struct BuildingInstance : HasIdentifier { // used in the actual game
+ using level_t = BuildingType::level_t;
+
+ enum class ExpansionState { CannotExpand, CanExpand, Preparing, Expanding };
+
+ private:
+ BuildingType const& PROPERTY(building_type);
+
+ level_t PROPERTY(level);
+ ExpansionState PROPERTY(expansion_state);
+ Date PROPERTY(start_date)
+ Date PROPERTY(end_date);
+ float PROPERTY(expansion_progress);
+
+ bool _can_expand() const;
+
+ public:
+ BuildingInstance(BuildingType const& new_building_type, level_t new_level = 0);
+ BuildingInstance(BuildingInstance&&) = default;
+
+ void set_level(level_t new_level);
+
+ bool expand();
+ void update_state(Date today);
+ void tick(Date today);
+ };
+}
diff --git a/src/openvic-simulation/economy/BuildingType.cpp b/src/openvic-simulation/economy/BuildingType.cpp
new file mode 100644
index 0000000..b80999a
--- /dev/null
+++ b/src/openvic-simulation/economy/BuildingType.cpp
@@ -0,0 +1,114 @@
+#include "BuildingType.hpp"
+
+using namespace OpenVic;
+using namespace OpenVic::NodeTools;
+
+BuildingType::BuildingType(
+ std::string_view identifier, ARGS
+) : HasIdentifier { identifier }, type { type }, modifier { std::move(modifier) }, on_completion { on_completion },
+ completion_size { completion_size }, max_level { max_level }, goods_cost { std::move(goods_cost) }, cost { cost },
+ build_time { build_time }, visibility { visibility }, on_map { on_map }, default_enabled { default_enabled },
+ production_type { production_type }, pop_build_factory { pop_build_factory }, strategic_factory { strategic_factory },
+ advanced_factory { advanced_factory }, fort_level { fort_level }, naval_capacity { naval_capacity },
+ colonial_points { std::move(colonial_points) }, in_province { in_province }, one_per_state { one_per_state },
+ colonial_range { colonial_range }, infrastructure { infrastructure }, spawn_railway_track { spawn_railway_track },
+ sail { sail }, steam { steam }, capital { capital }, port { port } {}
+
+BuildingManager::BuildingManager() : building_types { "building types" } {}
+
+bool BuildingManager::add_building_type(std::string_view identifier, ARGS) {
+ if (identifier.empty()) {
+ Logger::error("Invalid building identifier - empty!");
+ return false;
+ }
+
+ return building_types.add_item({
+ identifier, type, std::move(modifier), on_completion, completion_size, max_level, std::move(goods_cost),
+ cost, build_time, visibility, on_map, default_enabled, production_type, pop_build_factory, strategic_factory,
+ advanced_factory, fort_level, naval_capacity, std::move(colonial_points), in_province, one_per_state,
+ colonial_range, infrastructure, spawn_railway_track, sail, steam, capital, port
+ });
+}
+
+bool BuildingManager::load_buildings_file(
+ GoodManager const& good_manager, ProductionTypeManager const& production_type_manager, ModifierManager& modifier_manager,
+ ast::NodeCPtr root
+) {
+ const bool ret = expect_dictionary_reserve_length(
+ building_types,
+ [this, &good_manager, &production_type_manager, &modifier_manager](std::string_view key, ast::NodeCPtr value) -> bool {
+ std::string_view type;
+ ProductionType const* production_type = nullptr;
+ std::string_view on_completion;
+ fixed_point_t completion_size = 0, cost = 0, infrastructure = 0, colonial_range = 0;
+ BuildingType::level_t max_level = 0, fort_level = 0;
+ Good::good_map_t goods_cost;
+ Timespan build_time;
+ bool visibility = false, on_map = false, default_enabled = false, pop_build_factory = false;
+ bool strategic_factory = false, advanced_factory = false;
+ bool in_province = false, one_per_state = false, spawn_railway_track = false, sail = false, steam = false;
+ bool capital = false, port = false;
+ uint64_t naval_capacity = 0;
+ std::vector<fixed_point_t> colonial_points;
+ ModifierValue modifier;
+
+ bool ret = modifier_manager.expect_modifier_value_and_keys(move_variable_callback(modifier),
+ "type", ONE_EXACTLY, expect_identifier(assign_variable_callback(type)),
+ "on_completion", ZERO_OR_ONE, expect_identifier(assign_variable_callback(on_completion)),
+ "completion_size", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(completion_size)),
+ "max_level", ONE_EXACTLY, expect_uint(assign_variable_callback(max_level)),
+ "goods_cost", ONE_EXACTLY, good_manager.expect_good_decimal_map(move_variable_callback(goods_cost)),
+ "cost", ZERO_OR_MORE, expect_fixed_point(assign_variable_callback(cost)),
+ "time", ONE_EXACTLY, expect_days(assign_variable_callback(build_time)),
+ "visibility", ONE_EXACTLY, expect_bool(assign_variable_callback(visibility)),
+ "onmap", ONE_EXACTLY, expect_bool(assign_variable_callback(on_map)),
+ "default_enabled", ZERO_OR_ONE, expect_bool(assign_variable_callback(default_enabled)),
+ "production_type", ZERO_OR_ONE, production_type_manager.expect_production_type_identifier(
+ assign_variable_callback_pointer(production_type)),
+ "pop_build_factory", ZERO_OR_ONE, expect_bool(assign_variable_callback(pop_build_factory)),
+ "strategic_factory", ZERO_OR_ONE, expect_bool(assign_variable_callback(strategic_factory)),
+ "advanced_factory", ZERO_OR_ONE, expect_bool(assign_variable_callback(advanced_factory)),
+ "fort_level", ZERO_OR_ONE, expect_uint(assign_variable_callback(fort_level)),
+ "naval_capacity", ZERO_OR_ONE, expect_uint(assign_variable_callback(naval_capacity)),
+ "colonial_points", ZERO_OR_ONE, expect_list(expect_fixed_point(
+ [&colonial_points](fixed_point_t points) -> bool {
+ colonial_points.push_back(points);
+ return true;
+ }
+ )),
+ "province", ZERO_OR_ONE, expect_bool(assign_variable_callback(in_province)),
+ "one_per_state", ZERO_OR_ONE, expect_bool(assign_variable_callback(one_per_state)),
+ "colonial_range", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(colonial_range)),
+ "infrastructure", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(infrastructure)),
+ "spawn_railway_track", ZERO_OR_ONE, expect_bool(assign_variable_callback(spawn_railway_track)),
+ "sail", ZERO_OR_ONE, expect_bool(assign_variable_callback(sail)),
+ "steam", ZERO_OR_ONE, expect_bool(assign_variable_callback(steam)),
+ "capital", ZERO_OR_ONE, expect_bool(assign_variable_callback(capital)),
+ "port", ZERO_OR_ONE, expect_bool(assign_variable_callback(port))
+ )(value);
+
+ ret &= add_building_type(
+ key, type, std::move(modifier), on_completion, completion_size, max_level, std::move(goods_cost), cost,
+ build_time, visibility, on_map, default_enabled, production_type, pop_build_factory, strategic_factory,
+ advanced_factory, fort_level, naval_capacity, std::move(colonial_points), in_province, one_per_state,
+ colonial_range, infrastructure, spawn_railway_track, sail, steam, capital, port
+ );
+
+ return ret;
+ }
+ )(root);
+ lock_building_types();
+
+ for (BuildingType const& building_type : building_types.get_items()) {
+ std::string max_modifier_prefix = "max_";
+ std::string min_modifier_prefix = "min_build_";
+ modifier_manager.add_modifier_effect(
+ max_modifier_prefix.append(building_type.get_identifier()), true, ModifierEffect::format_t::INT
+ );
+ modifier_manager.add_modifier_effect(
+ min_modifier_prefix.append(building_type.get_identifier()), false, ModifierEffect::format_t::INT
+ );
+ }
+
+ return ret;
+}
diff --git a/src/openvic-simulation/economy/BuildingType.hpp b/src/openvic-simulation/economy/BuildingType.hpp
new file mode 100644
index 0000000..a49c461
--- /dev/null
+++ b/src/openvic-simulation/economy/BuildingType.hpp
@@ -0,0 +1,89 @@
+#pragma once
+
+#include "openvic-simulation/misc/Modifier.hpp"
+#include "openvic-simulation/economy/Good.hpp"
+#include "openvic-simulation/economy/ProductionType.hpp"
+#include "openvic-simulation/types/Date.hpp"
+#include "openvic-simulation/types/IdentifierRegistry.hpp"
+#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
+
+#define ARGS \
+ std::string_view type, ModifierValue&& modifier, std::string_view on_completion, fixed_point_t completion_size, \
+ level_t max_level, Good::good_map_t&& goods_cost, fixed_point_t cost, Timespan build_time, bool visibility, bool on_map, \
+ bool default_enabled, ProductionType const* production_type, bool pop_build_factory, bool strategic_factory, \
+ bool advanced_factory, level_t fort_level, uint64_t naval_capacity, std::vector<fixed_point_t>&& colonial_points, \
+ bool in_province, bool one_per_state, fixed_point_t colonial_range, fixed_point_t infrastructure, \
+ bool spawn_railway_track, bool sail, bool steam, bool capital, bool port
+
+namespace OpenVic {
+
+ struct BuildingManager;
+
+ /* REQUIREMENTS:
+ * MAP-11, MAP-72, MAP-73
+ * MAP-12, MAP-75, MAP-76
+ * MAP-13, MAP-78, MAP-79
+ */
+ struct BuildingType : HasIdentifier {
+ friend struct BuildingManager;
+
+ using level_t = int16_t;
+
+ private:
+ std::string PROPERTY(type);
+ ModifierValue PROPERTY(modifier);
+ std::string PROPERTY(on_completion); // probably sound played on completion
+ fixed_point_t PROPERTY(completion_size);
+ level_t PROPERTY(max_level);
+ Good::good_map_t PROPERTY(goods_cost);
+ fixed_point_t PROPERTY(cost);
+ Timespan PROPERTY(build_time); // time
+ bool PROPERTY(visibility);
+ bool PROPERTY(on_map); // onmap
+
+ bool PROPERTY(default_enabled);
+ ProductionType const* PROPERTY(production_type);
+ bool PROPERTY(pop_build_factory);
+ bool PROPERTY(strategic_factory);
+ bool PROPERTY(advanced_factory);
+
+ level_t PROPERTY(fort_level); // probably the step-per-level
+
+ uint64_t PROPERTY(naval_capacity);
+ std::vector<fixed_point_t> PROPERTY(colonial_points);
+ bool PROPERTY(in_province); // province
+ bool PROPERTY(one_per_state);
+ fixed_point_t PROPERTY(colonial_range);
+
+ fixed_point_t PROPERTY(infrastructure);
+ bool PROPERTY(spawn_railway_track);
+
+ bool PROPERTY(sail); // only in clipper shipyard
+ bool PROPERTY(steam); // only in steamer shipyard
+ bool PROPERTY(capital); // only in naval base
+ bool PROPERTY(port); // only in naval base
+
+ BuildingType(std::string_view identifier, ARGS);
+
+ public:
+ BuildingType(BuildingType&&) = default;
+ };
+
+ struct BuildingManager {
+ using level_t = BuildingType::level_t; // this is getting ridiculous
+
+ private:
+ IdentifierRegistry<BuildingType> building_types;
+
+ public:
+ BuildingManager();
+
+ bool add_building_type(std::string_view identifier, ARGS);
+ IDENTIFIER_REGISTRY_ACCESSORS(building_type)
+
+ bool load_buildings_file(
+ GoodManager const& good_manager, ProductionTypeManager const& production_type_manager,
+ ModifierManager& modifier_manager, ast::NodeCPtr root
+ );
+ };
+}
diff --git a/src/openvic-simulation/economy/EconomyManager.hpp b/src/openvic-simulation/economy/EconomyManager.hpp
index 7445614..d53aa7e 100644
--- a/src/openvic-simulation/economy/EconomyManager.hpp
+++ b/src/openvic-simulation/economy/EconomyManager.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "openvic-simulation/economy/Building.hpp"
+#include "openvic-simulation/economy/BuildingType.hpp"
#include "openvic-simulation/economy/Good.hpp"
#include "openvic-simulation/economy/ProductionType.hpp"
diff --git a/src/openvic-simulation/economy/Good.cpp b/src/openvic-simulation/economy/Good.cpp
index 2b1d694..4c1f7ba 100644
--- a/src/openvic-simulation/economy/Good.cpp
+++ b/src/openvic-simulation/economy/Good.cpp
@@ -64,7 +64,7 @@ bool GoodManager::add_good_category(std::string_view identifier) {
}
bool GoodManager::add_good(
- std::string_view identifier, colour_t colour, GoodCategory const* category, Good::price_t base_price,
+ std::string_view identifier, colour_t colour, GoodCategory const& category, Good::price_t base_price,
bool available_from_start, bool tradeable, bool money, bool overseas_penalty
) {
if (identifier.empty()) {
@@ -75,16 +75,12 @@ bool GoodManager::add_good(
Logger::error("Invalid good colour for ", identifier, ": ", colour_to_hex_string(colour));
return false;
}
- if (category == nullptr) {
- Logger::error("Invalid good category for ", identifier, ": null");
- return false;
- }
if (base_price <= Good::NULL_PRICE) {
Logger::error("Invalid base price for ", identifier, ": ", base_price);
return false;
}
return goods.add_item({
- identifier, colour, *category, base_price, available_from_start,
+ identifier, colour, category, base_price, available_from_start,
tradeable, money, overseas_penalty
});
}
@@ -107,10 +103,8 @@ bool GoodManager::load_goods_file(ast::NodeCPtr root) {
)(root);
lock_good_categories();
goods.reserve(goods.size() + total_expected_goods);
- ret &= expect_dictionary([this](std::string_view good_category_key, ast::NodeCPtr good_category_value) -> bool {
- GoodCategory const* good_category = get_good_category_by_identifier(good_category_key);
-
- return expect_dictionary([this, good_category](std::string_view key, ast::NodeCPtr value) -> bool {
+ ret &= expect_good_category_dictionary([this](GoodCategory const& good_category, ast::NodeCPtr good_category_value) -> bool {
+ return expect_dictionary([this, &good_category](std::string_view key, ast::NodeCPtr value) -> bool {
colour_t colour = NULL_COLOUR;
Good::price_t base_price;
bool available_from_start = true, tradeable = true;
diff --git a/src/openvic-simulation/economy/Good.hpp b/src/openvic-simulation/economy/Good.hpp
index ae2d6a9..805e6a5 100644
--- a/src/openvic-simulation/economy/Good.hpp
+++ b/src/openvic-simulation/economy/Good.hpp
@@ -33,7 +33,7 @@ namespace OpenVic {
using price_t = fixed_point_t;
static constexpr price_t NULL_PRICE = fixed_point_t::_0();
- using good_map_t = decimal_map_t<Good const*>;
+ using good_map_t = fixed_point_map_t<Good const*>;
private:
GoodCategory const& category;
@@ -73,7 +73,7 @@ namespace OpenVic {
IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_PLURAL(good_category, good_categories)
bool add_good(
- std::string_view identifier, colour_t colour, GoodCategory const* category, Good::price_t base_price,
+ std::string_view identifier, colour_t colour, GoodCategory const& category, Good::price_t base_price,
bool available_from_start, bool tradeable, bool money, bool overseas_penalty
);
IDENTIFIER_REGISTRY_ACCESSORS(good)
diff --git a/src/openvic-simulation/economy/ProductionType.cpp b/src/openvic-simulation/economy/ProductionType.cpp
index 1c65c4d..6eb7ff9 100644
--- a/src/openvic-simulation/economy/ProductionType.cpp
+++ b/src/openvic-simulation/economy/ProductionType.cpp
@@ -145,7 +145,7 @@ node_callback_t ProductionTypeManager::_expect_employed_pop_list(
return false; \
}
-bool ProductionTypeManager::add_production_type(PRODUCTION_TYPE_ARGS, GoodManager const& good_manager) {
+bool ProductionTypeManager::add_production_type(PRODUCTION_TYPE_ARGS) {
if (identifier.empty()) {
Logger::error("Invalid production type identifier - empty!");
return false;
@@ -274,7 +274,7 @@ bool ProductionTypeManager::load_production_types_file(
ret &= add_production_type(
key, owner, employees, type, workforce, std::move(input_goods), output_goods, value, std::move(bonuses),
- std::move(efficiency), coastal, farm, mine, good_manager
+ std::move(efficiency), coastal, farm, mine
);
return ret;
}
diff --git a/src/openvic-simulation/economy/ProductionType.hpp b/src/openvic-simulation/economy/ProductionType.hpp
index 802580b..13862a7 100644
--- a/src/openvic-simulation/economy/ProductionType.hpp
+++ b/src/openvic-simulation/economy/ProductionType.hpp
@@ -101,7 +101,7 @@ namespace OpenVic {
public:
ProductionTypeManager();
- bool add_production_type(PRODUCTION_TYPE_ARGS, GoodManager const& good_manager);
+ bool add_production_type(PRODUCTION_TYPE_ARGS);
IDENTIFIER_REGISTRY_ACCESSORS(production_type)
bool load_production_types_file(GoodManager const& good_manager, PopManager const& pop_manager, ast::NodeCPtr root);