From 3550c455526eb6f8935f488810e73fe01a1177a9 Mon Sep 17 00:00:00 2001 From: Hop311 Date: Mon, 8 May 2023 22:01:13 +0100 Subject: Added GoodManager --- src/openvic2/GameManager.cpp | 4 ++- src/openvic2/GameManager.hpp | 4 ++- src/openvic2/Good.cpp | 3 -- src/openvic2/Good.hpp | 21 ------------ src/openvic2/Types.cpp | 4 +-- src/openvic2/Types.hpp | 15 +++++--- src/openvic2/economy/Good.cpp | 79 +++++++++++++++++++++++++++++++++++++++++++ src/openvic2/economy/Good.hpp | 55 ++++++++++++++++++++++++++++++ src/openvic2/map/Building.cpp | 9 +++-- src/openvic2/map/Map.cpp | 32 +++++++++++++----- src/openvic2/map/Map.hpp | 8 ++++- src/openvic2/map/Province.cpp | 9 ++++- src/openvic2/map/Province.hpp | 7 +++- src/openvic2/map/Region.cpp | 6 ++-- src/openvic2/map/Region.hpp | 6 ++-- 15 files changed, 210 insertions(+), 52 deletions(-) delete mode 100644 src/openvic2/Good.cpp delete mode 100644 src/openvic2/Good.hpp create mode 100644 src/openvic2/economy/Good.cpp create mode 100644 src/openvic2/economy/Good.hpp diff --git a/src/openvic2/GameManager.cpp b/src/openvic2/GameManager.cpp index da775ba..349c276 100644 --- a/src/openvic2/GameManager.cpp +++ b/src/openvic2/GameManager.cpp @@ -31,8 +31,10 @@ return_t GameManager::setup() { session_start = time(nullptr); clock.reset(); today = { 1836 }; + good_manager.reset_to_defaults(); + return_t ret = map.setup(good_manager, building_manager); set_needs_update(); - return map.generate_province_buildings(building_manager); + return ret; } Date const& GameManager::get_today() const { diff --git a/src/openvic2/GameManager.hpp b/src/openvic2/GameManager.hpp index fc5d344..5e46e58 100644 --- a/src/openvic2/GameManager.hpp +++ b/src/openvic2/GameManager.hpp @@ -2,6 +2,7 @@ #include "GameAdvancementHook.hpp" #include "map/Map.hpp" +#include "economy/Good.hpp" namespace OpenVic2 { struct GameManager { @@ -9,9 +10,10 @@ namespace OpenVic2 { Map map; BuildingManager building_manager; + GoodManager good_manager; GameAdvancementHook clock; - time_t session_start; /* SS-54, as well as allowing time-tracking */ private: + time_t session_start; /* SS-54, as well as allowing time-tracking */ Date today; state_updated_func_t state_updated; bool needs_update; diff --git a/src/openvic2/Good.cpp b/src/openvic2/Good.cpp deleted file mode 100644 index e3389de..0000000 --- a/src/openvic2/Good.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "Good.hpp" - -using namespace OpenVic2; diff --git a/src/openvic2/Good.hpp b/src/openvic2/Good.hpp deleted file mode 100644 index 378bbc4..0000000 --- a/src/openvic2/Good.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "Types.hpp" - -namespace OpenVic2 { - class Good : HasIdentifier { - public: - std::string category; - price_t cost; - std::string colour; - bool isAvailable; - bool isTradable; - bool isMoney; - bool hasOverseasPenalty; - - Good(Good&&) = default; - Good(std::string const& identifier,std::string const& category, price_t cost, std::string const& colour, - bool isAvailable, bool isTradable, bool isMoney, bool hasOverseasPenalty) : HasIdentifier(identifier), - category(category), cost(cost), colour(colour), isAvailable(isAvailable), isMoney(isMoney), hasOverseasPenalty(hasOverseasPenalty) {}; - }; -} diff --git a/src/openvic2/Types.cpp b/src/openvic2/Types.cpp index f51ad7c..719f5b1 100644 --- a/src/openvic2/Types.cpp +++ b/src/openvic2/Types.cpp @@ -14,8 +14,8 @@ std::string const& HasIdentifier::get_identifier() const { return identifier; } -HasColour::HasColour(colour_t const new_colour) : colour(new_colour) { - assert(colour != NULL_COLOUR && colour <= MAX_COLOUR_RGB); +HasColour::HasColour(colour_t const new_colour, bool can_be_null) : colour(new_colour) { + assert((can_be_null || colour != NULL_COLOUR) && colour <= MAX_COLOUR_RGB); } colour_t HasColour::get_colour() const { return colour; } diff --git a/src/openvic2/Types.hpp b/src/openvic2/Types.hpp index e4a0e2d..a16f3bd 100644 --- a/src/openvic2/Types.hpp +++ b/src/openvic2/Types.hpp @@ -15,9 +15,15 @@ namespace OpenVic2 { * When colour_t is used in a purely graphical context, NULL_COLOUR * should be allowed. */ - static constexpr colour_t NULL_COLOUR = 0, MAX_COLOUR_RGB = 0xFFFFFF; - constexpr colour_t to_alpha_value(float a) { - return static_cast(std::clamp(a, 0.0f, 1.0f) * 255.0f) << 24; + static constexpr colour_t NULL_COLOUR = 0, FULL_COLOUR = 0xFF, MAX_COLOUR_RGB = 0xFFFFFF; + constexpr colour_t float_to_colour_byte(float f, float min = 0.0f, float max = 1.0f) { + return static_cast(std::clamp(min + f * (max - min), min, max) * 255.0f); + } + constexpr colour_t fraction_to_colour_byte(int n, int d, float min = 0.0f, float max = 1.0f) { + return float_to_colour_byte(static_cast(n) / static_cast(d), min, max); + } + constexpr colour_t float_to_alpha_value(float a) { + return float_to_colour_byte(a) << 24; } using index_t = uint16_t; @@ -25,6 +31,7 @@ namespace OpenVic2 { // TODO: price_t must be changed to a fixed-point numeric type before multiplayer using price_t = double; + static constexpr price_t NULL_PRICE = 0.0; using return_t = bool; // This mirrors godot::Error, where `OK = 0` and `FAILED = 1`. @@ -54,7 +61,7 @@ namespace OpenVic2 { class HasColour { const colour_t colour; protected: - HasColour(colour_t const new_colour); + HasColour(colour_t const new_colour, bool can_be_null = false); public: HasColour(HasColour const&) = delete; HasColour(HasColour&&) = default; diff --git a/src/openvic2/economy/Good.cpp b/src/openvic2/economy/Good.cpp new file mode 100644 index 0000000..94cb9e3 --- /dev/null +++ b/src/openvic2/economy/Good.cpp @@ -0,0 +1,79 @@ +#include "Good.hpp" + +#include + +using namespace OpenVic2; + +Good::Good(std::string const& new_identifier, std::string const& new_category, colour_t new_colour, price_t new_base_price, + bool new_default_available, bool new_tradeable, bool new_currency, bool new_overseas_maintenance) + : HasIdentifier{ new_identifier }, HasColour{ new_colour, true }, category{ new_category }, base_price{ new_base_price }, + default_available{ new_default_available }, tradeable{ new_tradeable }, currency{ new_currency }, + overseas_maintenance{ new_overseas_maintenance } { + assert(base_price > NULL_PRICE); +} + +std::string const& Good::get_category() const { + return category; +} + +price_t Good::get_base_price() const { + return base_price; +} + +price_t Good::get_price() const { + return price; +} + +bool Good::is_default_available() const { + return default_available; +} + +bool Good::is_available() const { + return available; +} + +void Good::reset_to_defaults() { + available = default_available; + price = base_price; +} + +GoodManager::GoodManager() : goods{ "goods" } {} + +return_t GoodManager::add_good(std::string const& identifier, std::string const& category, colour_t colour, + price_t base_price, bool default_available, bool tradeable, bool currency, bool overseas_maintenance) { + if (identifier.empty()) { + Logger::error("Invalid good identifier - empty!"); + return FAILURE; + } + if (category.empty()) { + Logger::error("Invalid good category - empty!"); + return FAILURE; + } + if (base_price <= NULL_PRICE) { + Logger::error("Invalid base price for ", identifier, ": ", base_price); + return FAILURE; + } + return goods.add_item({ identifier, category, colour, base_price, default_available, tradeable, currency, overseas_maintenance }); +} + +void GoodManager::lock_goods() { + goods.lock(); +} + +void GoodManager::reset_to_defaults() { + for (Good& good : goods.get_items()) + good.reset_to_defaults(); +} + +Good const* GoodManager::get_good_by_index(size_t index) const { + return goods.get_item_by_index(index); +} + +size_t GoodManager::get_good_count() const { + return goods.get_item_count(); +} + +std::vector const& GoodManager::get_goods() const { + return goods.get_items(); +} + diff --git a/src/openvic2/economy/Good.hpp b/src/openvic2/economy/Good.hpp new file mode 100644 index 0000000..a34ffa8 --- /dev/null +++ b/src/openvic2/economy/Good.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include "../Types.hpp" + +namespace OpenVic2 { + struct GoodManager; + + /* ECON-3 , ECON-4 , ECON-5 , ECON-6 , ECON-7 , ECON-8 , ECON-9 , ECON-10, ECON-11, ECON-12, ECON-13, ECON-14, + * ECON-15, ECON-16, ECON-17, ECON-18, ECON-19, ECON-20, ECON-21, ECON-22, ECON-23, ECON-24, ECON-25, ECON-26, + * ECON-27, ECON-28, ECON-29, ECON-30, ECON-31, ECON-32, ECON-33, ECON-34, ECON-35, ECON-36, ECON-37, ECON-38, + * ECON-39, ECON-40, ECON-41, ECON-42, ECON-43, ECON-44, ECON-45, ECON-46, ECON-47, ECON-48, ECON-49, ECON-50 + * + * ECON-123, ECON-124, ECON-125, ECON-126, ECON-127, ECON-128, ECON-129, ECON-130, ECON-131, ECON-132, ECON-133, ECON-134, + * ECON-135, ECON-136, ECON-137, ECON-138, ECON-139, ECON-140, ECON-141, ECON-142, ECON-234, ECON-235, ECON-236, ECON-237, + * ECON-238, ECON-239, ECON-240, ECON-241, ECON-242, ECON-243, ECON-244, ECON-245, ECON-246, ECON-247, ECON-248, ECON-249, + * ECON-250, ECON-251, ECON-252, ECON-253, ECON-254, ECON-255, ECON-256, ECON-257, ECON-258, ECON-259, ECON-260, ECON-261 + */ + struct Good : HasIdentifier, HasColour { + friend struct GoodManager; + private: + const std::string category; + const price_t base_price; + price_t price; + const bool default_available, tradeable, currency, overseas_maintenance; + bool available; + + Good(std::string const& new_identifier, std::string const& new_category, colour_t new_colour, price_t new_base_price, + bool new_default_available, bool new_tradeable, bool new_currency, bool new_overseas_maintenance); + public: + Good(Good&&) = default; + + std::string const& get_category() const; + price_t get_base_price() const; + price_t get_price() const; + bool is_default_available() const; + bool is_available() const; + void reset_to_defaults(); + }; + + struct GoodManager { + private: + IdentifierRegistry goods; + public: + GoodManager(); + + return_t add_good(std::string const& identifier, std::string const& category, colour_t colour, price_t base_price, + bool default_available, bool tradeable, bool currency, bool overseas_maintenance); + void lock_goods(); + void reset_to_defaults(); + + Good const* get_good_by_index(size_t index) const; + size_t get_good_count() const; + std::vector const& get_goods() const; + }; +} diff --git a/src/openvic2/map/Building.cpp b/src/openvic2/map/Building.cpp index 1e26873..4e0b14a 100644 --- a/src/openvic2/map/Building.cpp +++ b/src/openvic2/map/Building.cpp @@ -76,7 +76,7 @@ void Building::tick(Date const& today) { BuildingType::BuildingType(std::string const& new_identifier, Building::level_t new_max_level, Timespan new_build_time) : HasIdentifier{ new_identifier }, max_level{ new_max_level }, build_time{ new_build_time } { - assert(new_max_level >= 0); + assert(max_level >= 0); assert(build_time >= 0); } @@ -115,8 +115,13 @@ BuildingType const* BuildingManager::get_building_type_by_identifier(std::string } return_t BuildingManager::generate_province_buildings(Province& province) const { - return_t ret = SUCCESS; province.reset_buildings(); + if (!building_types.is_locked()) { + Logger::error("Cannot generate buildings until building types are locked!"); + return FAILURE; + } + if (province.is_water()) return SUCCESS; + return_t ret = SUCCESS; for (BuildingType const& type : building_types.get_items()) if (province.add_building(type) != SUCCESS) ret = FAILURE; province.lock_buildings(); diff --git a/src/openvic2/map/Map.cpp b/src/openvic2/map/Map.cpp index 1f44c43..d456a1f 100644 --- a/src/openvic2/map/Map.cpp +++ b/src/openvic2/map/Map.cpp @@ -4,6 +4,7 @@ #include #include "../Logger.hpp" +#include "../economy/Good.hpp" using namespace OpenVic2; @@ -95,7 +96,7 @@ return_t Map::add_region(std::string const& identifier, std::vector else Logger::error("Province ", province_identifier, " is already part of an unknown region with index ", other_region_index); ret = FAILURE; - } else new_region.provinces.insert(province); + } else new_region.provinces.push_back(province); } } else { Logger::error("Invalid province identifier ", province_identifier); @@ -154,6 +155,18 @@ index_t Map::get_province_index_at(size_t x, size_t y) const { return NULL_INDEX; } +void Map::set_selected_province(index_t index) { + selected_province = index <= get_province_count() ? index : NULL_INDEX; +} + +index_t Map::get_selected_province_index() const { + return selected_province; +} + +Province const* Map::get_selected_province() const { + return get_province_by_index(get_selected_province_index()); +} + Region* Map::get_region_by_identifier(std::string const& identifier) { return regions.get_item_by_identifier(identifier); } @@ -306,18 +319,21 @@ return_t Map::generate_mapmode_colours(Mapmode::index_t index, uint8_t* target) *target++ = 0; for (Province const& province : provinces.get_items()) { const colour_t colour = mapmode->get_colour(*this, province); - *target++ = (colour >> 16) & 0xFF; - *target++ = (colour >> 8) & 0xFF; - *target++ = colour & 0xFF; - *target++ = (colour >> 24) & 0xFF; + *target++ = (colour >> 16) & FULL_COLOUR; + *target++ = (colour >> 8) & FULL_COLOUR; + *target++ = colour & FULL_COLOUR; + *target++ = (colour >> 24) & FULL_COLOUR; } return SUCCESS; } -return_t Map::generate_province_buildings(BuildingManager const& manager) { +return_t Map::setup(GoodManager const& good_manager, BuildingManager const& building_manager) { return_t ret = SUCCESS; - for (Province& province : provinces.get_items()) - if (manager.generate_province_buildings(province) != SUCCESS) ret = FAILURE; + for (Province& province : provinces.get_items()) { + if (!province.is_water()) // Set all land provinces to have an RGO based on their index to test them + province.rgo = good_manager.get_good_by_index(province.get_index() % good_manager.get_good_count()); + if (building_manager.generate_province_buildings(province) != SUCCESS) ret = FAILURE; + } return ret; } diff --git a/src/openvic2/map/Map.hpp b/src/openvic2/map/Map.hpp index cb8dcb1..dd42076 100644 --- a/src/openvic2/map/Map.hpp +++ b/src/openvic2/map/Map.hpp @@ -21,6 +21,8 @@ namespace OpenVic2 { colour_t get_colour(Map const& map, Province const& province) const; }; + struct GoodManager; + /* REQUIREMENTS: * MAP-4 */ @@ -46,6 +48,7 @@ namespace OpenVic2 { size_t width = 0, height = 0; std::vector province_shape_image; colour_index_map_t colour_index_map; + index_t selected_province = NULL_INDEX; index_t get_index_from_colour(colour_t colour) const; public: @@ -64,6 +67,9 @@ namespace OpenVic2 { Province* get_province_by_identifier(std::string const& identifier); Province const* get_province_by_identifier(std::string const& identifier) const; index_t get_province_index_at(size_t x, size_t y) const; + void set_selected_province(index_t index); + index_t get_selected_province_index() const; + Province const* get_selected_province() const; Region* get_region_by_identifier(std::string const& identifier); Region const* get_region_by_identifier(std::string const& identifier) const; @@ -82,7 +88,7 @@ namespace OpenVic2 { static constexpr size_t MAPMODE_COLOUR_SIZE = 4; return_t generate_mapmode_colours(Mapmode::index_t index, uint8_t* target) const; - return_t generate_province_buildings(BuildingManager const& manager); + return_t setup(GoodManager const& good_manager, BuildingManager const& building_manager); void update_state(Date const& today); void tick(Date const& today); diff --git a/src/openvic2/map/Province.cpp b/src/openvic2/map/Province.cpp index b3d455b..6c80317 100644 --- a/src/openvic2/map/Province.cpp +++ b/src/openvic2/map/Province.cpp @@ -9,7 +9,6 @@ using namespace OpenVic2; Province::Province(index_t new_index, std::string const& new_identifier, colour_t new_colour) : HasIdentifier{ new_identifier }, HasColour{ new_colour }, index{ new_index }, buildings{ "buildings" } { assert(index != NULL_INDEX); - assert(new_colour != NULL_COLOUR); } index_t Province::get_index() const { @@ -40,6 +39,10 @@ void Province::reset_buildings() { buildings.reset(); } +Building const* Province::get_building_by_identifier(std::string const& identifier) const { + return buildings.get_item_by_identifier(identifier); +} + std::vector const& Province::get_buildings() const { return buildings.get_items(); } @@ -50,6 +53,10 @@ return_t Province::expand_building(std::string const& building_type_identifier) return building->expand(); } +Good const* Province::get_rgo() const { + return rgo; +} + std::string Province::to_string() const { std::stringstream stream; stream << "(#" << std::to_string(index) << ", " << get_identifier() << ", 0x" << colour_to_hex_string() << ")"; diff --git a/src/openvic2/map/Province.hpp b/src/openvic2/map/Province.hpp index 9b07fc1..44d0dee 100644 --- a/src/openvic2/map/Province.hpp +++ b/src/openvic2/map/Province.hpp @@ -5,9 +5,10 @@ namespace OpenVic2 { struct Map; struct Region; + struct Good; /* REQUIREMENTS: - * MAP-5, MAP-8, MAP-43, MAP-47 + * MAP-5, MAP-7, MAP-8, MAP-43, MAP-47 */ struct Province : HasIdentifier, HasColour { friend struct Map; @@ -20,6 +21,8 @@ namespace OpenVic2 { bool water = false; life_rating_t life_rating = 0; IdentifierRegistry buildings; + // TODO - change this into a factory-like structure + Good const* rgo = nullptr; Province(index_t new_index, std::string const& new_identifier, colour_t new_colour); public: @@ -32,8 +35,10 @@ namespace OpenVic2 { return_t add_building(BuildingType const& type); void lock_buildings(); void reset_buildings(); + Building const* get_building_by_identifier(std::string const& identifier) const; std::vector const& get_buildings() const; return_t expand_building(std::string const& building_type_identifier); + Good const* get_rgo() const; std::string to_string() const; void update_state(Date const& today); diff --git a/src/openvic2/map/Region.cpp b/src/openvic2/map/Region.cpp index da0dfdd..d6d8dcc 100644 --- a/src/openvic2/map/Region.cpp +++ b/src/openvic2/map/Region.cpp @@ -12,13 +12,13 @@ bool ProvinceSet::contains_province(Province const* province) const { return province && std::find(provinces.begin(), provinces.end(), province) != provinces.end(); } -std::set const& ProvinceSet::get_provinces() const { +std::vector const& ProvinceSet::get_provinces() const { return provinces; } Region::Region(std::string const& new_identifier) : HasIdentifier{ new_identifier } {} colour_t Region::get_colour() const { - if (provinces.empty()) return 0xFF0000; - return (*provinces.cbegin())->get_colour(); + if (provinces.empty()) return FULL_COLOUR << 16; + return provinces.front()->get_colour(); } diff --git a/src/openvic2/map/Region.hpp b/src/openvic2/map/Region.hpp index 3920dfc..f688254 100644 --- a/src/openvic2/map/Region.hpp +++ b/src/openvic2/map/Region.hpp @@ -1,18 +1,16 @@ #pragma once -#include - #include "Province.hpp" namespace OpenVic2 { struct ProvinceSet { protected: - std::set provinces; + std::vector provinces; public: size_t get_province_count() const; bool contains_province(Province const* province) const; - std::set const& get_provinces() const; + std::vector const& get_provinces() const; }; /* REQUIREMENTS: -- cgit v1.2.3-56-ga3b1