diff options
author | Hop311 <hop3114@gmail.com> | 2023-04-18 19:49:37 +0200 |
---|---|---|
committer | Hop311 <hop3114@gmail.com> | 2023-04-18 19:49:37 +0200 |
commit | 1fdd198f943a41468b03b2cdc62c24147f707239 (patch) | |
tree | f53bdaad16e077957c7410a54f8638868d3f2351 | |
parent | f168c91ff266beda8066014257a30d93704882ee (diff) |
Better province image + terrain + some buttons
38 files changed, 1146 insertions, 335 deletions
diff --git a/extension/src/MapSingleton.cpp b/extension/src/MapSingleton.cpp index 73cf522..6f90dee 100644 --- a/extension/src/MapSingleton.cpp +++ b/extension/src/MapSingleton.cpp @@ -11,11 +11,13 @@ MapSingleton* MapSingleton::singleton = nullptr; void MapSingleton::_bind_methods() { ClassDB::bind_method(D_METHOD("load_province_identifier_file", "file_path"), &MapSingleton::load_province_identifier_file); + ClassDB::bind_method(D_METHOD("load_water_province_file", "file_path"), &MapSingleton::load_water_province_file); ClassDB::bind_method(D_METHOD("load_region_file", "file_path"), &MapSingleton::load_region_file); ClassDB::bind_method(D_METHOD("load_province_shape_file", "file_path"), &MapSingleton::load_province_shape_file); ClassDB::bind_method(D_METHOD("get_province_index_from_uv_coords", "coords"), &MapSingleton::get_province_index_from_uv_coords); ClassDB::bind_method(D_METHOD("get_province_identifier_from_uv_coords", "coords"), &MapSingleton::get_province_identifier_from_uv_coords); + ClassDB::bind_method(D_METHOD("get_region_identifier_from_province_identifier", "identifier"), &MapSingleton::get_region_identifier_from_province_identifier); ClassDB::bind_method(D_METHOD("get_width"), &MapSingleton::get_width); ClassDB::bind_method(D_METHOD("get_height"), &MapSingleton::get_height); ClassDB::bind_method(D_METHOD("get_province_index_image"), &MapSingleton::get_province_index_image); @@ -43,16 +45,19 @@ MapSingleton::MapSingleton() { { "mapmode_province", [](Map const&, Province const& province) -> Province::colour_t { return province.get_colour(); } }, { "mapmode_region", [](Map const&, Province const& province) -> Province::colour_t { Region const* region = province.get_region(); - if (region != nullptr) return region->get_provinces().front()->get_colour(); + if (region != nullptr) return region->get_colour(); return province.get_colour(); } }, + { "mapmode_terrain", [](Map const&, Province const& province) -> Province::colour_t { + return province.is_water() ? 0x4287F5 : 0x0D7017; + } }, { "mapmode_index", [](Map const& map, Province const& province) -> Province::colour_t { const uint8_t f = float(province.get_index()) / float(map.get_province_count()) * 255.0f; return (f << 16) | (f << 8) | f; } } }; - std::string error_message = ""; - for (mapmode_t mapmode : mapmodes) + std::string error_message; + for (mapmode_t const& mapmode : mapmodes) if (map.add_mapmode(mapmode.first, mapmode.second, error_message) != SUCCESS) UtilityFunctions::push_error(error_message.c_str()); } @@ -62,34 +67,43 @@ MapSingleton::~MapSingleton() { singleton = nullptr; } -Error MapSingleton::parse_json_dictionary_file(String const& file_description, String const& file_path, - String const& identifier_prefix, parse_json_entry_func_t parse_entry) const { +static Error load_json_file(String const& file_description, String const& file_path, Variant& result) { + result.clear(); UtilityFunctions::print("Loading ", file_description, " file: ", file_path); - Ref<FileAccess> file = FileAccess::open(file_path, FileAccess::ModeFlags::READ); + const Ref<FileAccess> file = FileAccess::open(file_path, FileAccess::ModeFlags::READ); Error err = FileAccess::get_open_error(); if (err != OK || file.is_null()) { UtilityFunctions::push_error("Failed to load ", file_description, " file: ", file_path); return err == OK ? FAILED : err; } const String json_string = file->get_as_text(); - Ref<JSON> json; - json.instantiate(); - err = json->parse(json_string); + JSON json; + err = json.parse(json_string); if (err != OK) { UtilityFunctions::push_error("Failed to parse ", file_description, " file as JSON: ", file_path, - "\nError at line ", json->get_error_line(), ": ", json->get_error_message()); + "\nError at line ", json.get_error_line(), ": ", json.get_error_message()); return err; } - const Variant json_var = json->get_data(); + result = json.get_data(); + return err; +} + +using parse_json_entry_func_t = std::function<godot::Error (godot::String const&, godot::Variant const&)>; + +static Error parse_json_dictionary_file(String const& file_description, String const& file_path, + String const& identifier_prefix, parse_json_entry_func_t parse_entry) { + Variant json_var; + Error err = load_json_file(file_description, file_path, json_var); + if (err != OK) return err; const Variant::Type type = json_var.get_type(); if (type != Variant::DICTIONARY) { UtilityFunctions::push_error("Invalid ", file_description, " JSON: root has type ", Variant::get_type_name(type), " (expected Dictionary)"); return FAILED; } - const Dictionary dict = json_var; + Dictionary const& dict = json_var; const Array identifiers = dict.keys(); - for (int idx = 0; idx < identifiers.size(); ++idx) { + for (int64_t idx = 0; idx < identifiers.size(); ++idx) { String const& identifier = identifiers[idx]; Variant const& entry = dict[identifier]; if (identifier.is_empty()) { @@ -108,20 +122,20 @@ Error MapSingleton::_parse_province_identifier_entry(String const& identifier, V const Variant::Type type = entry.get_type(); Province::colour_t colour = Province::NULL_COLOUR; if (type == Variant::ARRAY) { - const Array colour_array = entry; + Array const& colour_array = entry; if (colour_array.size() == 3) { for (int jdx = 0; jdx < 3; ++jdx) { - const Variant var = colour_array[jdx]; + Variant const& var = colour_array[jdx]; if (var.get_type() != Variant::FLOAT) { colour = Province::NULL_COLOUR; break; } - double colour_double = var; + const double colour_double = var; if (std::trunc(colour_double) != colour_double) { colour = Province::NULL_COLOUR; break; } - int64_t colour_int = static_cast<int64_t>(colour_double); + const int64_t colour_int = static_cast<int64_t>(colour_double); if (colour_int < 0 || colour_int > 255) { colour = Province::NULL_COLOUR; break; @@ -130,17 +144,18 @@ Error MapSingleton::_parse_province_identifier_entry(String const& identifier, V } } } else if (type == Variant::STRING) { - String colour_string = entry; + String const& colour_string = entry; if (colour_string.is_valid_hex_number()) { - int64_t colour_int = colour_string.hex_to_int(); + const int64_t colour_int = colour_string.hex_to_int(); if (0 <= colour_int && colour_int <= 0xFFFFFF) colour = colour_int; } - } else { + } + if (colour == Province::NULL_COLOUR) { UtilityFunctions::push_error("Invalid colour for province identifier \"", identifier, "\": ", entry); return FAILED; } - std::string error_message = ""; + std::string error_message; if (map.add_province(identifier.utf8().get_data(), colour, error_message) != SUCCESS) { UtilityFunctions::push_error(error_message.c_str()); return FAILED; @@ -162,12 +177,12 @@ Error MapSingleton::_parse_region_entry(String const& identifier, Variant const& Variant::Type type = entry.get_type(); std::vector<std::string> province_identifiers; if (type == Variant::ARRAY) { - const Array province_array = entry; + Array const& province_array = entry; for (int64_t idx = 0; idx < province_array.size(); ++idx) { - const Variant province_var = province_array[idx]; + Variant const& province_var = province_array[idx]; type = province_var.get_type(); if (type == Variant::STRING) { - String province_string = province_var; + String const& province_string = province_var; province_identifiers.push_back(province_string.utf8().get_data()); } else { UtilityFunctions::push_error("Invalid province identifier for region \"", identifier, "\": ", entry); @@ -175,7 +190,11 @@ Error MapSingleton::_parse_region_entry(String const& identifier, Variant const& } } } - std::string error_message = ""; + if (province_identifiers.empty()) { + UtilityFunctions::push_error("Invalid province list for region \"", identifier, "\": ", entry); + return FAILED; + } + std::string error_message; if (map.add_region(identifier.utf8().get_data(), province_identifiers, error_message) != SUCCESS) { UtilityFunctions::push_error(error_message.c_str()); return FAILED; @@ -218,7 +237,7 @@ Error MapSingleton::load_province_shape_file(String const& file_path) { } if (err != OK) return err; - std::string error_message = ""; + std::string error_message; if (map.generate_province_index_image(width, height, province_shape_image->get_data().ptr(), error_message) != SUCCESS) { UtilityFunctions::push_error(error_message.c_str()); err = FAILED; @@ -239,6 +258,37 @@ Error MapSingleton::load_province_shape_file(String const& file_path) { return err; } +Error MapSingleton::load_water_province_file(String const& file_path) { + Variant json_var; + Error err = load_json_file("water province", file_path, json_var); + if (err != OK) return err; + Variant::Type type = json_var.get_type(); + if (type != Variant::ARRAY) { + UtilityFunctions::push_error("Invalid water province JSON: root has type ", + Variant::get_type_name(type), " (expected Array)"); + err = FAILED; + } else { + Array const& array = json_var; + std::string error_message; + for (int64_t idx = 0; idx < array.size(); ++idx) { + Variant const& entry = array[idx]; + type = entry.get_type(); + if (type != Variant::STRING) { + UtilityFunctions::push_error("Invalid water province identifier: ", entry); + err = FAILED; + continue; + } + String const& identifier = entry; + if (map.set_water_province(identifier.utf8().get_data(), error_message) != SUCCESS) { + UtilityFunctions::push_error(error_message.c_str()); + err = FAILED; + } + } + } + map.lock_water_provinces(); + return err; +} + Province* MapSingleton::get_province_from_uv_coords(godot::Vector2 const& coords) { if (province_index_image.is_valid()) { const PackedByteArray index_data_array = province_index_image->get_data(); @@ -273,6 +323,15 @@ String MapSingleton::get_province_identifier_from_uv_coords(Vector2 const& coord return String{}; } +String MapSingleton::get_region_identifier_from_province_identifier(String const& identifier) const { + Province const* province = map.get_province_by_identifier(identifier.utf8().get_data()); + if (province != nullptr) { + Region const* region = province->get_region(); + if (region != nullptr) return region->get_identifier().c_str(); + } + return String{}; +} + int32_t MapSingleton::get_width() const { return map.get_width(); } @@ -291,11 +350,11 @@ Ref<Image> MapSingleton::get_province_colour_image() const { Error MapSingleton::update_colour_image() { static PackedByteArray colour_data_array; - static const int64_t colour_data_array_size = (Province::MAX_INDEX + 1) * 3; + static const int64_t colour_data_array_size = (Province::MAX_INDEX + 1) * 4; colour_data_array.resize(colour_data_array_size); Error err = OK; - std::string error_message = ""; + std::string error_message; if (map.generate_mapmode_colours(mapmode_index, colour_data_array.ptrw(), error_message) != SUCCESS) { UtilityFunctions::push_error(error_message.c_str()); err = FAILED; @@ -305,7 +364,7 @@ Error MapSingleton::update_colour_image() { if (province_colour_image.is_null()) province_colour_image.instantiate(); province_colour_image->set_data(PROVINCE_INDEX_SQRT, PROVINCE_INDEX_SQRT, - false, Image::FORMAT_RGB8, colour_data_array); + false, Image::FORMAT_RGBA8, colour_data_array); if (province_colour_image.is_null()) { UtilityFunctions::push_error("Failed to update province colour image"); return FAILED; diff --git a/extension/src/MapSingleton.hpp b/extension/src/MapSingleton.hpp index 9205e92..6ec2ea4 100644 --- a/extension/src/MapSingleton.hpp +++ b/extension/src/MapSingleton.hpp @@ -8,8 +8,6 @@ namespace OpenVic2 { class MapSingleton : public godot::Object { - using parse_json_entry_func_t = std::function<godot::Error (godot::String const&, godot::Variant const&)>; - GDCLASS(MapSingleton, godot::Object) static MapSingleton* singleton; @@ -18,8 +16,6 @@ namespace OpenVic2 { Map map; Mapmode::index_t mapmode_index = 0; - godot::Error parse_json_dictionary_file(godot::String const& file_description, godot::String const& file_path, - godot::String const& identifier_prefix, parse_json_entry_func_t parse_entry) const; godot::Error _parse_province_identifier_entry(godot::String const& identifier, godot::Variant const& entry); godot::Error _parse_region_entry(godot::String const& identifier, godot::Variant const& entry); protected: @@ -32,6 +28,7 @@ namespace OpenVic2 { ~MapSingleton(); godot::Error load_province_identifier_file(godot::String const& file_path); + godot::Error load_water_province_file(godot::String const& file_path); godot::Error load_region_file(godot::String const& file_path); godot::Error load_province_shape_file(godot::String const& file_path); @@ -39,6 +36,7 @@ namespace OpenVic2 { Province const* get_province_from_uv_coords(godot::Vector2 const& coords) const; int32_t get_province_index_from_uv_coords(godot::Vector2 const& coords) const; godot::String get_province_identifier_from_uv_coords(godot::Vector2 const& coords) const; + godot::String get_region_identifier_from_province_identifier(godot::String const& identifier) const; int32_t get_width() const; int32_t get_height() const; godot::Ref<godot::Image> get_province_index_image() const; diff --git a/extension/src/openvic2/Date.cpp b/extension/src/openvic2/Date.cpp index 3c5b8d8..e1cef72 100644 --- a/extension/src/openvic2/Date.cpp +++ b/extension/src/openvic2/Date.cpp @@ -1,108 +1,115 @@ #include <sstream> #include "Date.hpp" -namespace OpenVic2 { - bool Timespan::operator< (Timespan const& other) const { return days < other.days; } - bool Timespan::operator> (Timespan const& other) const { return days > other.days; } - bool Timespan::operator<= (Timespan const& other) const { return days <= other.days; } - bool Timespan::operator>= (Timespan const& other) const { return days >= other.days; } - bool Timespan::operator== (Timespan const& other) const { return days == other.days; } - bool Timespan::operator!= (Timespan const& other) const { return days != other.days; } - - Timespan Timespan::operator+ (Timespan const& other) const { return Timespan(days + other.days); } - Timespan Timespan::operator- (Timespan const& other) const { return Timespan(days - other.days); } - Timespan Timespan::operator* (int64_t const& factor) const { return Timespan(days * factor); } - Timespan Timespan::operator/ (int64_t const& factor) const { return Timespan(days / factor); } - - Timespan& Timespan::operator+= (Timespan const& other) { - days += other.days; - return *this; - } - Timespan& Timespan::operator-= (Timespan const& other) { - days -= other.days; - return *this; - } +using namespace OpenVic2; + +bool Timespan::operator< (Timespan const& other) const { return days < other.days; } +bool Timespan::operator> (Timespan const& other) const { return days > other.days; } +bool Timespan::operator<= (Timespan const& other) const { return days <= other.days; } +bool Timespan::operator>= (Timespan const& other) const { return days >= other.days; } +bool Timespan::operator== (Timespan const& other) const { return days == other.days; } +bool Timespan::operator!= (Timespan const& other) const { return days != other.days; } + +Timespan Timespan::operator+ (Timespan const& other) const { return Timespan(days + other.days); } +Timespan Timespan::operator- (Timespan const& other) const { return Timespan(days - other.days); } +Timespan Timespan::operator* (int64_t const& factor) const { return Timespan(days * factor); } +Timespan Timespan::operator/ (int64_t const& factor) const { return Timespan(days / factor); } + +Timespan& Timespan::operator+= (Timespan const& other) { + days += other.days; + return *this; +} +Timespan& Timespan::operator-= (Timespan const& other) { + days -= other.days; + return *this; +} - Timespan fromYearZero(year_t year, month_t month, date_t day) { - int64_t daysElapsed = year * DAYS_IN_YEAR; - size_t daysSinceMonthStart = (day == 0) ? 0 : day - 1; //Underflow protection - for (size_t x = 0; x < month && x < MONTHS_IN_YEAR; x++) { - daysElapsed += DAYS_IN_MONTH[x]; - } - daysElapsed += daysSinceMonthStart; - return Timespan(daysElapsed); - } +Timespan::operator std::string() const { + return std::to_string(days); +} +std::ostream &operator<<(std::ostream &out, Timespan const& timespan) { + return out << static_cast<std::string>(timespan); +} - //This function is not set up to handle dates before Year 0 - YearMonthDayBundle toGregorianDate(Timespan const& timespan) { - year_t year = 0; - month_t month = 0; - date_t day = 0; +Timespan fromYearZero(year_t year, month_t month, date_t day) { + int64_t daysElapsed = year * DAYS_IN_YEAR; + size_t daysSinceMonthStart = (day == 0) ? 0 : day - 1; //Underflow protection + for (size_t x = 0; x < month && x < MONTHS_IN_YEAR; x++) { + daysElapsed += DAYS_IN_MONTH[x]; + } + daysElapsed += daysSinceMonthStart; + return Timespan(daysElapsed); +} - if (timespan >= 0) { - year = timespan.days / DAYS_IN_YEAR; - int64_t remainingDays = timespan.days % DAYS_IN_YEAR; +//This function is not set up to handle dates before Year 0 +YearMonthDayBundle toGregorianDate(Timespan const& timespan) { + year_t year = 0; + month_t month = 0; + date_t day = 0; - for (size_t x = 0; x < MONTHS_IN_YEAR && remainingDays >= DAYS_IN_MONTH[x]; x++) { - remainingDays -= DAYS_IN_MONTH[x]; - month++; - } + if (timespan >= 0) { + year = timespan.days / DAYS_IN_YEAR; + int64_t remainingDays = timespan.days % DAYS_IN_YEAR; - //Corrects month and day to be 1-indexed + for (size_t x = 0; x < MONTHS_IN_YEAR && remainingDays >= DAYS_IN_MONTH[x]; x++) { + remainingDays -= DAYS_IN_MONTH[x]; month++; - day++; } - return std::make_tuple(year, month, day); + + //Corrects month and day to be 1-indexed + month++; + day++; } + return std::make_tuple(year, month, day); +} - Date::Date(Timespan const& timespan) : ts(timespan) { updateDate(ts); } +Date::Date(Timespan const& timespan) : ts(timespan) { updateDate(ts); } - Date::Date(year_t year, month_t month, date_t day) { - ts = fromYearZero(year, month, day); - updateDate(ts); - } +Date::Date(year_t year, month_t month, date_t day) { + ts = fromYearZero(year, month, day); + updateDate(ts); +} - void Date::updateDate(Timespan const& timespan) { - gregorianDate = toGregorianDate(timespan); - } +void Date::updateDate(Timespan const& timespan) { + gregorianDate = toGregorianDate(timespan); +} - size_t Date::getDay() const { return std::get<2>(gregorianDate); } - size_t Date::getMonth() const { return std::get<1>(gregorianDate); } - size_t Date::getYear() const { return std::get<0>(gregorianDate); } +size_t Date::getDay() const { return std::get<2>(gregorianDate); } +size_t Date::getMonth() const { return std::get<1>(gregorianDate); } +size_t Date::getYear() const { return std::get<0>(gregorianDate); } - bool Date::operator< (Date const& other) const { return ts < other.ts; } - bool Date::operator> (Date const& other) const { return ts > other.ts; } - bool Date::operator<= (Date const& other) const { return ts <= other.ts; } - bool Date::operator>= (Date const& other) const { return ts >= other.ts; } - bool Date::operator== (Date const& other) const { return ts == other.ts; } - bool Date::operator!= (Date const& other) const { return ts != other.ts; } +bool Date::operator< (Date const& other) const { return ts < other.ts; } +bool Date::operator> (Date const& other) const { return ts > other.ts; } +bool Date::operator<= (Date const& other) const { return ts <= other.ts; } +bool Date::operator>= (Date const& other) const { return ts >= other.ts; } +bool Date::operator== (Date const& other) const { return ts == other.ts; } +bool Date::operator!= (Date const& other) const { return ts != other.ts; } - Date Date::operator+ (Timespan timespan) const { return Date(ts + timespan); } - Timespan Date::operator- (Date const& other) const { return ts - other.ts; } +Date Date::operator+ (Timespan timespan) const { return Date(ts + timespan); } +Timespan Date::operator- (Date const& other) const { return ts - other.ts; } - Date& Date::operator+= (Timespan const& timespan) { - ts += timespan; - updateDate(ts); - return *this; - } - Date& Date::operator-= (Timespan const& timespan) { - ts -= timespan; - updateDate(ts); - return *this; - } - Date Date::operator++ (int) { - Date oldCopy = *this; - (*this) += 1; - return oldCopy; - } +Date& Date::operator+= (Timespan const& timespan) { + ts += timespan; + updateDate(ts); + return *this; +} +Date& Date::operator-= (Timespan const& timespan) { + ts -= timespan; + updateDate(ts); + return *this; +} +Date Date::operator++ (int) { + Date oldCopy = *this; + (*this) += 1; + return oldCopy; +} - Date::operator std::string() const { - std::stringstream ss; - ss << getYear() << '.' << getMonth() << '.' << getDay(); - return ss.str(); - } - std::ostream &operator<<(std::ostream &out, Date const& date) { - return out << static_cast<std::string>(date); - } +Date::operator std::string() const { + std::stringstream ss; + ss << getYear() << '.' << getMonth() << '.' << getDay(); + return ss.str(); +} +std::ostream &operator<<(std::ostream &out, Date const& date) { + return out << static_cast<std::string>(date); } diff --git a/extension/src/openvic2/Date.hpp b/extension/src/openvic2/Date.hpp index 841b118..9ed5963 100644 --- a/extension/src/openvic2/Date.hpp +++ b/extension/src/openvic2/Date.hpp @@ -28,6 +28,9 @@ namespace OpenVic2 { Timespan& operator+= (Timespan const& other); Timespan& operator-= (Timespan const& other); + + explicit operator std::string() const; + friend std::ostream& operator<< (std::ostream& out, Timespan const& timespan); }; static constexpr size_t MONTHS_IN_YEAR = 12; diff --git a/extension/src/openvic2/Map.cpp b/extension/src/openvic2/Map.cpp index 1654189..0ac8091 100644 --- a/extension/src/openvic2/Map.cpp +++ b/extension/src/openvic2/Map.cpp @@ -1,14 +1,14 @@ #include "Map.hpp" #include <cassert> +#include <unordered_set> using namespace OpenVic2; static const std::string SEPARATOR = "\n - "; Mapmode::Mapmode(index_t new_index, std::string const& new_identifier, colour_func_t new_colour_func) - : index(new_index), identifier(new_identifier), colour_func(new_colour_func) { - assert(!identifier.empty()); + : HasIdentifier(new_identifier), index(new_index), colour_func(new_colour_func) { assert(colour_func != nullptr); } @@ -16,10 +16,6 @@ Mapmode::index_t Mapmode::get_index() const { return index; } -std::string const& Mapmode::get_identifier() const { - return identifier; -} - Mapmode::colour_func_t Mapmode::get_colour_func() const { return colour_func; } @@ -42,15 +38,15 @@ return_t Map::add_province(std::string const& identifier, Province::colour_t col return FAILURE; } Province new_province{ static_cast<Province::index_t>(provinces.size() + 1), identifier, colour }; - for (Province const& province : provinces) { - if (province.get_identifier() == identifier) { - error_message = "Duplicate province identifiers: " + province.to_string() + " and " + new_province.to_string(); - return FAILURE; - } - if (province.get_colour() == colour) { - error_message = "Duplicate province colours: " + province.to_string() + " and " + new_province.to_string(); - return FAILURE; - } + Province const* old_province = get_province_by_identifier(identifier); + if (old_province != nullptr) { + error_message = "Duplicate province identifiers: " + old_province->to_string() + " and " + new_province.to_string(); + return FAILURE; + } + old_province = get_province_by_colour(colour); + if (old_province != nullptr) { + error_message = "Duplicate province colours: " + old_province->to_string() + " and " + new_province.to_string(); + return FAILURE; } provinces.push_back(new_province); error_message = "Added province: " + new_province.to_string(); @@ -61,6 +57,29 @@ void Map::lock_provinces() { provinces_locked = true; } +return_t Map::set_water_province(std::string const& identifier, std::string& error_message) { + if (water_provinces_locked) { + error_message = "The map's water provinces have already been locked!"; + return FAILURE; + } + Province* province = get_province_by_identifier(identifier); + if (province == nullptr) { + error_message = "Unrecognised water province identifier: " + identifier; + return FAILURE; + } + if (province->is_water()) { + error_message = "Province " + identifier + " is already a water province!"; + return FAILURE; + } + province->water = true; + error_message = "Set province " + identifier + " as a water province"; + return SUCCESS; +} + +void Map::lock_water_provinces() { + water_provinces_locked = true; +} + return_t Map::add_region(std::string const& identifier, std::vector<std::string> const& province_identifiers, std::string& error_message) { if (regions_locked) { error_message = "The map's region list has already been locked!"; @@ -75,7 +94,7 @@ return_t Map::add_region(std::string const& identifier, std::vector<std::string> return FAILURE; } Region new_region{ identifier }; - error_message = "Error message for region: " + identifier; + error_message.clear(); for (std::string const& province_identifier : province_identifiers) { Province* province = get_province_by_identifier(province_identifier); if (province != nullptr) { @@ -90,28 +109,36 @@ return_t Map::add_region(std::string const& identifier, std::vector<std::string> error_message += regions[other_region_index].get_identifier(); else error_message += "an unknown region with index " + std::to_string(other_region_index); - } else new_region.provinces.push_back(province); + } else new_region.provinces.insert(province); } } else error_message += SEPARATOR + "Invalid province identifier " + province_identifier; } + return_t ret = SUCCESS; if (!new_region.get_province_count()) { error_message += SEPARATOR + "No valid provinces in region's list"; - return FAILURE; + ret = FAILURE; } - for (Region const& region : regions) { - if (region.get_identifier() == identifier) { - error_message += SEPARATOR + "Duplicate region identifiers: " + region.get_identifier() + " and " + identifier; - return FAILURE; + Region const* old_region = get_region_by_identifier(identifier); + if (old_region != nullptr) { + error_message += SEPARATOR + "Duplicate region identifiers: " + old_region->get_identifier() + " and " + identifier; + ret = FAILURE; + } + + if (ret == SUCCESS) { + regions.push_back(new_region); + // Used to detect provinces listed in multiple regions, will + // be corrected once regions is stable (i.e. lock_regions). + Region* tmp_region_index = reinterpret_cast<Region*>(regions.size()); + for (Province* province : new_region.get_provinces()) + province->region = tmp_region_index; + if (!error_message.empty()) { + error_message += SEPARATOR; + ret = FAILURE; } + error_message += "Added region: " + identifier; } - regions.push_back(new_region); - error_message += SEPARATOR + "Added region: " + identifier; - // Used to detect provinces listed in multiple regions, will - // be corrected once regions is stable (i.e. lock_regions). - Region* tmp_region_index = reinterpret_cast<Region*>(regions.size()); - for (Province* province : new_region.get_provinces()) - province->region = tmp_region_index; - return SUCCESS; + if (ret != SUCCESS) error_message = "Error message for region: " + identifier + error_message; + return ret; } void Map::lock_regions() { @@ -161,6 +188,20 @@ Province const* Map::get_province_by_colour(Province::colour_t colour) const { return nullptr; } +Region* Map::get_region_by_identifier(std::string const& identifier) { + if (!identifier.empty()) + for (Region& region : regions) + if (region.get_identifier() == identifier) return ®ion; + return nullptr; +} + +Region const* Map::get_region_by_identifier(std::string const& identifier) const { + if (!identifier.empty()) + for (Region const& region : regions) + if (region.get_identifier() == identifier) return ®ion; + return nullptr; +} + static Province::colour_t colour_at(uint8_t const* colour_data, int32_t idx) { return (colour_data[idx * 3] << 16) | (colour_data[idx * 3 + 1] << 8) | colour_data[idx * 3 + 2]; } @@ -188,17 +229,13 @@ return_t Map::generate_province_index_image(size_t new_width, size_t new_height, std::vector<bool> province_checklist(provinces.size()); return_t ret = SUCCESS; - - error_message = "Error message for province index image generation:"; + std::unordered_set<Province::colour_t> unrecognised_colours; + error_message.clear(); for (int32_t y = 0; y < height; ++y) { for (int32_t x = 0; x < width; ++x) { const int32_t idx = x + y * width; const Province::colour_t colour = colour_at(colour_data, idx); - if (colour == Province::NULL_COLOUR) { - province_index_image[idx] = Province::NULL_INDEX; - continue; - } if (x > 0) { const int32_t jdx = idx - 1; if (colour_at(colour_data, jdx) == colour) { @@ -220,8 +257,11 @@ return_t Map::generate_province_index_image(size_t new_width, size_t new_height, province_checklist[index - 1] = true; continue; } - error_message += SEPARATOR + "Unrecognised province colour " + Province::colour_to_hex_string(colour) + " at (" + std::to_string(x) + ", " + std::to_string(x) + ")"; - ret = FAILURE; + if (unrecognised_colours.find(colour) == unrecognised_colours.end()) { + unrecognised_colours.insert(colour); + error_message += SEPARATOR + "Unrecognised province colour " + Province::colour_to_hex_string(colour) + " at (" + std::to_string(x) + ", " + std::to_string(y) + ")"; + ret = FAILURE; + } province_index_image[idx] = Province::NULL_INDEX; } } @@ -233,7 +273,8 @@ return_t Map::generate_province_index_image(size_t new_width, size_t new_height, } } - error_message += SEPARATOR + "Generated province index image"; + if (!error_message.empty()) error_message = "Error message for province index image generation:" + error_message + SEPARATOR; + error_message += "Generated province index image"; return ret; } @@ -259,11 +300,10 @@ return_t Map::add_mapmode(std::string const& identifier, Mapmode::colour_func_t return FAILURE; } Mapmode new_mapmode{ mapmodes.size(), identifier, colour_func }; - for (Mapmode const& mapmode : mapmodes) { - if (mapmode.get_identifier() == identifier) { - error_message = "Duplicate mapmode identifiers: " + mapmode.get_identifier() + " and " + identifier; - return FAILURE; - } + Mapmode const* old_mapmode = get_mapmode_by_identifier(identifier); + if (old_mapmode != nullptr) { + error_message = "Duplicate mapmode identifiers: " + old_mapmode->get_identifier() + " and " + identifier; + return FAILURE; } mapmodes.push_back(new_mapmode); error_message = "Added mapmode: " + identifier; @@ -295,12 +335,14 @@ return_t Map::generate_mapmode_colours(Mapmode::index_t index, uint8_t* target, return FAILURE; } Mapmode const& mapmode = mapmodes[index]; - target += 3; // Skip past Province::NULL_INDEX + target += 4; // Skip past Province::NULL_INDEX for (Province const& province : provinces) { const Province::colour_t colour = mapmode.get_colour_func()(*this, province); *target++ = (colour >> 16) & 0xFF; *target++ = (colour >> 8) & 0xFF; *target++ = colour & 0xFF; + *target++ = province.is_water() ? 0 : 255; } + error_message = "Generated province colours for mapmode " + mapmode.get_identifier(); return SUCCESS; } diff --git a/extension/src/openvic2/Map.hpp b/extension/src/openvic2/Map.hpp index 42963c9..73ab8fd 100644 --- a/extension/src/openvic2/Map.hpp +++ b/extension/src/openvic2/Map.hpp @@ -1,75 +1,24 @@ #pragma once -#include <string> -#include <cstdint> #include <vector> #include <functional> -#include "Types.hpp" +#include "Region.hpp" namespace OpenVic2 { - struct Region; - struct Map; - /* REQUIREMENTS: - * MAP-43, MAP-47 - */ - struct Province { - friend struct Map; - - using colour_t = uint32_t; - using index_t = uint16_t; - - static const colour_t NULL_COLOUR = 0, MAX_COLOUR = 0xFFFFFF; - static const index_t NULL_INDEX = 0, MAX_INDEX = 0xFFFF; - private: - index_t index; - std::string identifier; - colour_t colour; - Region* region = nullptr; - - Province(index_t new_index, std::string const& new_identifier, colour_t new_colour); - public: - static std::string colour_to_hex_string(colour_t colour); - - index_t get_index() const; - std::string const& get_identifier() const; - colour_t get_colour() const; - Region* get_region() const; - std::string to_string() const; - }; - - /* REQUIREMENTS: - * MAP-6, MAP-44, MAP-48 - */ - struct Region { - friend struct Map; - private: - std::string identifier; - std::vector<Province*> provinces; - - Region(std::string const& new_identifier); - public: - std::string const& get_identifier() const; - size_t get_province_count() const; - bool contains_province(Province const* province) const; - std::vector<Province*> const& get_provinces() const; - }; - - struct Mapmode { + struct Mapmode : HasIdentifier { friend struct Map; using colour_func_t = std::function<Province::colour_t (Map const&, Province const&)>; using index_t = size_t; private: index_t index; - std::string identifier; colour_func_t colour_func; Mapmode(index_t new_index, std::string const& new_identifier, colour_func_t new_colour_func); public: index_t get_index() const; - std::string const& get_identifier() const; colour_func_t get_colour_func() const; }; @@ -80,7 +29,7 @@ namespace OpenVic2 { private: std::vector<Province> provinces; std::vector<Region> regions; - bool provinces_locked = false, regions_locked = false; + bool provinces_locked = false, water_provinces_locked = false, regions_locked = false; size_t width = 0, height = 0; std::vector<Province::index_t> province_index_image; @@ -88,10 +37,12 @@ namespace OpenVic2 { public: return_t add_province(std::string const& identifier, Province::colour_t colour, std::string& error_message); void lock_provinces(); + return_t set_water_province(std::string const& identifier, std::string& error_message); + void lock_water_provinces(); return_t add_region(std::string const& identifier, std::vector<std::string> const& province_identifiers, std::string& error_message); void lock_regions(); - size_t get_province_count() const; + size_t get_province_count() const; Province* get_province_by_index(Province::index_t index); Province const* get_province_by_index(Province::index_t index) const; Province* get_province_by_identifier(std::string const& identifier); @@ -99,6 +50,9 @@ namespace OpenVic2 { Province* get_province_by_colour(Province::colour_t colour); Province const* get_province_by_colour(Province::colour_t colour) const; + Region* get_region_by_identifier(std::string const& identifier); + Region const* get_region_by_identifier(std::string const& identifier) const; + return_t generate_province_index_image(size_t new_width, size_t new_height, uint8_t const* colour_data, std::string& error_message); size_t get_width() const; size_t get_height() const; diff --git a/extension/src/openvic2/Province.cpp b/extension/src/openvic2/Province.cpp index 49f1b0e..7d55708 100644 --- a/extension/src/openvic2/Province.cpp +++ b/extension/src/openvic2/Province.cpp @@ -1,4 +1,4 @@ -#include "Map.hpp" +#include "Province.hpp" #include <cassert> #include <sstream> @@ -7,9 +7,8 @@ using namespace OpenVic2; Province::Province(index_t new_index, std::string const& new_identifier, colour_t new_colour) : - index(new_index), identifier(new_identifier), colour(new_colour) { + HasIdentifier(new_identifier), index(new_index), colour(new_colour) { assert(index != NULL_INDEX); - assert(!identifier.empty()); assert(colour != NULL_COLOUR); } @@ -23,10 +22,6 @@ Province::index_t Province::get_index() const { return index; } -std::string const& Province::get_identifier() const { - return identifier; -} - Province::colour_t Province::get_colour() const { return colour; } @@ -35,6 +30,14 @@ Region* Province::get_region() const { return region; } +bool Province::is_water() const { + return water; +} + +Province::life_rating_t Province::get_life_rating() const { + return life_rating; +} + std::string Province::to_string() const { - return "(#" + std::to_string(index) + ", " + identifier + ", 0x" + colour_to_hex_string(colour) + ")"; + return "(#" + std::to_string(index) + ", " + get_identifier() + ", 0x" + colour_to_hex_string(colour) + ")"; } diff --git a/extension/src/openvic2/Province.hpp b/extension/src/openvic2/Province.hpp new file mode 100644 index 0000000..deebd8c --- /dev/null +++ b/extension/src/openvic2/Province.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include "Types.hpp" + +namespace OpenVic2 { + struct Region; + struct Map; + + /* REQUIREMENTS: + * MAP-5, MAP-8, MAP-43, MAP-47 + */ + struct Province : HasIdentifier { + friend struct Map; + + using colour_t = uint32_t; + using index_t = uint16_t; + using life_rating_t = int8_t; + + static const colour_t NULL_COLOUR = 0, MAX_COLOUR = 0xFFFFFF; + static const index_t NULL_INDEX = 0, MAX_INDEX = 0xFFFF; + private: + index_t index; + colour_t colour; + Region* region = nullptr; + bool water = false; + life_rating_t life_rating = 0; + + Province(index_t new_index, std::string const& new_identifier, colour_t new_colour); + public: + static std::string colour_to_hex_string(colour_t colour); + + index_t get_index() const; + colour_t get_colour() const; + Region* get_region() const; + bool is_water() const; + life_rating_t get_life_rating() const; + std::string to_string() const; + }; +} diff --git a/extension/src/openvic2/Region.cpp b/extension/src/openvic2/Region.cpp index 6ee05f5..67a75a9 100644 --- a/extension/src/openvic2/Region.cpp +++ b/extension/src/openvic2/Region.cpp @@ -1,26 +1,26 @@ -#include "Map.hpp" +#include "Region.hpp" #include <cassert> #include <algorithm> using namespace OpenVic2; -Region::Region(std::string const& new_identifier) : identifier(new_identifier) { - assert(!identifier.empty()); -} - -std::string const& Region::get_identifier() const { - return identifier; -} - -size_t Region::get_province_count() const { +size_t ProvinceSet::get_province_count() const { return provinces.size(); } -bool Region::contains_province(Province const* province) const { +bool ProvinceSet::contains_province(Province const* province) const { return province && std::find(provinces.begin(), provinces.end(), province) != provinces.end(); } -std::vector<Province*> const& Region::get_provinces() const { +std::set<Province*> const& ProvinceSet::get_provinces() const { return provinces; } + +Region::Region(std::string const& new_identifier) : HasIdentifier(new_identifier) {} + +Province::colour_t Region::get_colour() const { + if (provinces.empty()) return 0xFF0000; + Province const* province = *provinces.cbegin(); + return province->get_colour(); +} diff --git a/extension/src/openvic2/Region.hpp b/extension/src/openvic2/Region.hpp new file mode 100644 index 0000000..4ebabd1 --- /dev/null +++ b/extension/src/openvic2/Region.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include <set> + +#include "Province.hpp" + +namespace OpenVic2 { + struct Map; + + struct ProvinceSet { + protected: + std::set<Province*> provinces; + public: + size_t get_province_count() const; + bool contains_province(Province const* province) const; + std::set<Province*> const& get_provinces() const; + }; + + /* REQUIREMENTS: + * MAP-6, MAP-44, MAP-48 + */ + struct Region : HasIdentifier, ProvinceSet { + friend struct Map; + private: + Region(std::string const& new_identifier); + public: + Province::colour_t get_colour() const; + }; +} diff --git a/extension/src/openvic2/Types.cpp b/extension/src/openvic2/Types.cpp new file mode 100644 index 0000000..67c7a21 --- /dev/null +++ b/extension/src/openvic2/Types.cpp @@ -0,0 +1,13 @@ +#include "Types.hpp" + +#include <cassert> + +using namespace OpenVic2; + +HasIdentifier::HasIdentifier(std::string const& new_identifier) : identifier(new_identifier) { + assert(!identifier.empty()); +} + +std::string const& HasIdentifier::get_identifier() const { + return identifier; +} diff --git a/extension/src/openvic2/Types.hpp b/extension/src/openvic2/Types.hpp index 0fb1c8b..bf5ee27 100644 --- a/extension/src/openvic2/Types.hpp +++ b/extension/src/openvic2/Types.hpp @@ -1,7 +1,18 @@ #pragma once +#include <string> + namespace OpenVic2 { using return_t = bool; // This mirrors godot::Error, where `OK = 0` and `FAILED = 1`. static const return_t SUCCESS = false, FAILURE = true; + + struct HasIdentifier { + private: + std::string identifier; + protected: + HasIdentifier(std::string const& new_identifier); + public: + std::string const& get_identifier() const; + }; } diff --git a/game/art/terrain/farmlands.png b/game/art/terrain/farmlands.png Binary files differnew file mode 100644 index 0000000..3702ad0 --- /dev/null +++ b/game/art/terrain/farmlands.png diff --git a/game/art/terrain/terrain.png.import b/game/art/terrain/farmlands.png.import index d7a078f..4a06b1f 100644 --- a/game/art/terrain/terrain.png.import +++ b/game/art/terrain/farmlands.png.import @@ -2,16 +2,16 @@ importer="texture" type="CompressedTexture2D" -uid="uid://cmw0pvjthnn8c" -path="res://.godot/imported/terrain.png-06c63c2b87b3131a2067f668f87a9d67.ctex" +uid="uid://ckf222w5usrsu" +path="res://.godot/imported/farmlands.png-821213ab9dba19cea6f6c966b3a3760b.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://art/terrain/terrain.png" -dest_files=["res://.godot/imported/terrain.png-06c63c2b87b3131a2067f668f87a9d67.ctex"] +source_file="res://art/terrain/farmlands.png" +dest_files=["res://.godot/imported/farmlands.png-821213ab9dba19cea6f6c966b3a3760b.ctex"] [params] @@ -21,7 +21,7 @@ compress/lossy_quality=0.7 compress/hdr_compression=1 compress/normal_map=2 compress/channel_pack=0 -mipmaps/generate=true +mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" diff --git a/game/art/terrain/terrain.png b/game/art/terrain/terrain.png Binary files differdeleted file mode 100644 index 6d36dee..0000000 --- a/game/art/terrain/terrain.png +++ /dev/null diff --git a/game/common/map/provinces.json b/game/common/map/provinces.json index 66de29b..71be5cb 100644 --- a/game/common/map/provinces.json +++ b/game/common/map/provinces.json @@ -2,8 +2,222 @@ "prov_britain": [150, 0, 0], "prov_ireland": [23, 147, 31], "prov_iceland": "343D91", + "prov_corsica": "FFD800", + "prov_sardinia": "00FFFF", + "prov_sicily": "FFA13D", + "prov_malta": "96E6FF", + "prov_cyprus": "FFE682", + "prov_greenland": "7A66FF", + "prov_baleares": "FF9E21", + "prov_gotland": "8300FF", + "prov_crete": "FF3523", + "prov_jan_mayen": "003FFF", + "prov_faroes": "964B00", + "prov_mann": "935575", + "prov_shetlands": "916F7D", + "prov_orkney": "8E1C70", + "prov_channel_islands": "8C6267", + "prov_madiera": "87580C", + "prov_canarias": "843740", + "prov_sjaeland": "820B02", + "prov_bornholm": "7F512F", + "prov_bear_island": "AE2AD6", + "prov_pantelleria": "FFA575", + "prov_iberia": "FF425D", + "prov_scandinavia": "005F32", + "prov_jutland": "B7004B", + "prov_fyn": "B55C63", + "prov_hiiumaa": "52FFB2", + "prov_saaremaa": "B5E31D", + "prov_italy": "47872C", + "prov_elba": "333333", + "prov_france": "0B0BC6", + "prov_netherlands": "FF472C", + "prov_belgium": "8C6A16", + "prov_luxembourg": "8FB7C6", + "prov_switzerland": "A50000", + "prov_balkans": "00FF5D", + "prov_crimea": "752179", + "prov_germany": "303030", + "prov_poland": "C90043", + "prov_baltics": "6327C4", + "prov_finland": "E8E8E8", + "prov_aland": "8769B3", + "prov_ukraine": "C1CB00", + "prov_russia": "006311", + + "prov_north_america": "A114FF", "prov_cuba": "1E29FF", + "prov_nova_scotia": "1115FF", + "prov_bermuda": "FF2370", + "prov_jamaica": "329600", + "prov_hispaniola": "742B7C", + "prov_aleutians": "FF07AC", + "prov_bahamas": "824261", + "prov_turks_and_caicos": "7F4424", + "prov_puerto_rico": "0D7C57", + "prov_barbados": "747A48", + "prov_grenada": "32774B", + "prov_st_vincent": "535C75", + "prov_st_lucia": "E15CEE", + "prov_martinique": "EDB274", + "prov_dominica": "EAE77E", + "prov_guadeloupe": "E8279E", + "prov_montserrat": "80AAE5", + "prov_antigua": "E2AEB9", + "prov_barbuda": "E0966D", + "prov_st_kitts": "DD85DA", + "prov_west_virgin_islands": "304716", + "prov_east_virgin_islands": "44321E", + "prov_cayman_islands": "FF7900", + "prov_angulia": "FF3D57", + "prov_central_america": "005B5E", + "prov_mexico": "3BA533", + + "prov_south_america": "2F7A22", + "prov_galapagos": "638293", + "prov_falklands": "91451F", + "prov_south_georgia": "8E8B8E", + + "prov_africa": "7F3300", "prov_madagascar": "790091", + "prov_socotra": "89801A", + "prov_mauritius": "1C8400", + "prov_reunion": "7D821F", + "prov_comoros": "7F5731", + "prov_sao_tome": "FFAFE8", + "prov_fernando_po": "FF665B", + "prov_cape_verde": "00FF48", + "prov_ascension": "7C3B3E", + "prov_st_helena": "7A6C48", + "prov_tristan_da_cunha": "77680E", + "prov_seychelles": "EF68FF", + "prov_prince_edward_islands": "826F68", + "prov_kerguelen_islands": "671F7F", + "prov_heard_island": "7C4244", + "prov_egypt": "A5815B", + "prov_morocco": "D44509", + + "prov_middle_east": "615EA8", "prov_ceylon": "FF6A00", - "prov_formosa": "82B1FF" + "prov_formosa": "82B1FF", + "prov_sakhalin": "006421", + "prov_maldives": "DC0000", + "prov_hainan": "688785", + "prov_hokkaido": "BA0DB5", + "prov_diego_garcia": "752268", + "prov_philippines": "FFA5AD", + "prov_india": "720041", + "prov_andamans": "706054", + "prov_nicobar_islands": "30006B", + "prov_indochina": "007272", + "prov_korea": "1E2570", + "prov_okinawa": "216D38", + "prov_yaeyama": "6B120A", + "prov_kyushu": "9E2521", + "prov_shikoku": "6F9B61", + "prov_japan": "99581B", + "prov_kurils": "992B15", + "prov_manchuria": "B79900", + "prov_china": "B57A53", + "prov_central_asia": "00B2B2", + "prov_siberia": "000EAF", + "prov_iran": "703E1D", + "prov_anatolia": "A81000", + + "prov_oceania": "FF4C00", + "prov_indonesia": "A56A9E", + "prov_north_island": "DB41AF", + "prov_south_island": "D86E47", + "prov_tasmania": "D6BF2C", + "prov_australia": "5BB1D3", + "prov_hawaii": "008C5D", + + "prov_aral_sea": "AA61C6", + "prov_caspian_sea": "00C413", + "prov_lake_ladoga": "462A64", + "prov_lake_ontario": "46CD64", + "prov_lake_erie": "9F2663", + "prov_lake_huron": "9FC6EA", + "prov_lake_michigan": "9FC62A", + "prov_lake_superior": "9F352A", + "prov_lake_baikal": "B51453", + "prov_lake_woods": "9F892A", + "prov_lake_manitoba": "FF0071", + "prov_reindeer_lake": "FF7DFF", + "prov_lake_ronge": "D9FF51", + "prov_lake_athabasca": "FF7D3D", + "prov_great_slave_lake": "49FF6B", + "prov_great_bear_lake": "FFC6C9", + + "prov_azov_sea": "3E33FF", + "prov_black_sea": "3EE1FF", + "prov_marmara_sea": "00009D", + "prov_agean_sea": "0019FF", + "prov_ionian_sea": "003A9D", + "prov_adriatic_sea": "00E3FF", + "prov_tyrrhenian_sea": "0935FF", + "prov_east_mediterranean": "00BBFF", + "prov_central_mediterranean": "3A5FDC", + "prov_west_mediterranean": "93C5FF", + "prov_ligurian_sea": "0000B0", + "prov_balearic_sea": "001BFF", + "prov_alboran_sea": "3E98FF", + "prov_gulf_bothnia": "52E39D", + "prov_gulf_finland": "0935C2", + "prov_gulf_riga": "004987", + "prov_baltic_sea": "5BC5CB", + "prov_danish_straits": "004DB0", + "prov_english_channel": "0079FF", + "prov_irish_sea": "544DFF", + "prov_biscay_bay": "93EEFF", + "prov_north_sea": "31BBFF", + "prov_red_sea": "0952FF", + "prov_arabian_sea": "00007E", + "prov_persian_gulf": "3EA3FF", + "prov_andaman_sea": "0092FF", + "prov_bay_bengal": "4075FF", + "prov_okhotsk_sea": "66C5FF", + "prov_japan_sea": "3A92DC", + "prov_east_china_sea": "0066CB", + "prov_south_china_sea": "3EEEFF", + "prov_philippine_sea": "210066", + "prov_celebes_sea": "0066BB", + "prov_java_sea": "3E33C9", + "prov_banda_sea": "73A3FF", + "prov_arafura_sea": "0000D4", + "prov_gulf_mexico": "00639D", + "prov_caribbean_sea": "00C2DA", + "prov_mozambique_channel": "098FFF", + "prov_zanj_sea": "93B5FF", + "prov_kara_sea": "49FFFF", + "prov_barents_sea": "3A40DC", + "prov_norwegian_sea": "000087", + "prov_greenland_sea": "33EEFF", + "prov_labrador_sea": "003787", + "prov_hudson_bay": "93F7FF", + "prov_gulf_st_lawrence": "4DF7FF", + "prov_gulf_alaska": "2C2F87", + "prov_gulf_california": "2C2FCF", + "prov_east_siberian_sea": "52E3FF", + "prov_sargasso_sea": "0019DA", + "prov_gulf_guinea": "008BDA", + "prov_celtic_sea": "0050B0", + "prov_argentine_sea": "0082B0", + "prov_chilean_sea": "47FFFF", + "prov_north_atlantic": "00B3FF", + "prov_central_atlantic": "68C5FF", + "prov_south_atlantic": "004DDA", + "prov_indian_ocean": "000066", + "prov_great_australian_bight": "3A75FF", + "prov_tasman_sea": "002CD4", + "prov_coral_sea": "8919FF", + "prov_melanesia": "3AA8FF", + "prov_micronesia": "0098CB", + "prov_polynesia": "003EDA", + "prov_north_pacific": "00EECF", + "prov_south_pacific": "03B3FF", + "prov_bering_sea": "0049DA", + "prov_chukchi_sea": "0087A5", + "prov_beaufort_sea": "93BEFF" } diff --git a/game/common/map/provinces.png b/game/common/map/provinces.png Binary files differindex 68bf528..73cc33c 100644 --- a/game/common/map/provinces.png +++ b/game/common/map/provinces.png diff --git a/game/common/map/regions.json b/game/common/map/regions.json index bbeeb56..1684fb5 100644 --- a/game/common/map/regions.json +++ b/game/common/map/regions.json @@ -1,6 +1,13 @@ { - "region_europe": ["prov_britain", "prov_ireland", "prov_iceland"], - "region_america": ["prov_cuba"], - "region_africa": ["prov_madagascar"], - "region_asia": ["prov_ceylon", "prov_formosa"] + "region_europe": ["prov_britain", "prov_ireland", "prov_iceland", "prov_corsica", "prov_sardinia", "prov_sicily", "prov_malta", "prov_cyprus", "prov_greenland", "prov_baleares", "prov_gotland", "prov_crete", "prov_jan_mayen", "prov_faroes", "prov_mann", "prov_shetlands", "prov_orkney", "prov_channel_islands", "prov_madiera", "prov_canarias", "prov_sjaeland", "prov_bornholm", "prov_bear_island", "prov_pantelleria", "prov_iberia", "prov_scandinavia", "prov_jutland", "prov_fyn", "prov_hiiumaa", "prov_saaremaa", "prov_italy", "prov_elba", "prov_france", "prov_netherlands", "prov_belgium", "prov_luxembourg", "prov_switzerland", "prov_balkans", "prov_crimea", "prov_germany", "prov_poland", "prov_baltics", "prov_finland", "prov_aland", "prov_ukraine", "prov_russia"], + + "region_north_america": ["prov_north_america", "prov_cuba", "prov_nova_scotia", "prov_bermuda", "prov_jamaica", "prov_hispaniola", "prov_aleutians", "prov_bahamas", "prov_turks_and_caicos", "prov_puerto_rico", "prov_barbados", "prov_grenada", "prov_st_vincent", "prov_st_lucia", "prov_martinique", "prov_dominica", "prov_guadeloupe", "prov_montserrat", "prov_antigua", "prov_barbuda", "prov_st_kitts", "prov_west_virgin_islands", "prov_east_virgin_islands", "prov_cayman_islands", "prov_angulia", "prov_central_america", "prov_mexico"], + + "region_south_america": ["prov_south_america", "prov_galapagos", "prov_falklands", "prov_south_georgia"], + + "region_africa": ["prov_africa", "prov_madagascar", "prov_socotra", "prov_mauritius", "prov_reunion", "prov_comoros", "prov_sao_tome", "prov_fernando_po", "prov_cape_verde", "prov_ascension", "prov_st_helena", "prov_tristan_da_cunha", "prov_seychelles", "prov_prince_edward_islands", "prov_kerguelen_islands", "prov_heard_island", "prov_egypt", "prov_morocco"], + + "region_asia": ["prov_middle_east", "prov_ceylon", "prov_formosa", "prov_sakhalin", "prov_maldives", "prov_hainan", "prov_hokkaido", "prov_diego_garcia", "prov_philippines", "prov_india", "prov_andamans", "prov_nicobar_islands", "prov_indochina", "prov_korea", "prov_okinawa", "prov_yaeyama", "prov_kyushu", "prov_shikoku", "prov_japan", "prov_kurils", "prov_manchuria", "prov_china", "prov_central_asia", "prov_siberia", "prov_iran", "prov_anatolia"], + + "region_oceania": ["prov_indonesia", "prov_north_island", "prov_south_island", "prov_tasmania", "prov_australia", "prov_hawaii", "prov_oceania"] } diff --git a/game/common/map/water.json b/game/common/map/water.json new file mode 100644 index 0000000..fda53a9 --- /dev/null +++ b/game/common/map/water.json @@ -0,0 +1,6 @@ + +[ + "prov_aral_sea", "prov_caspian_sea", "prov_lake_ladoga", "prov_lake_ontario", "prov_lake_erie", "prov_lake_huron", "prov_lake_michigan", "prov_lake_superior", "prov_lake_baikal", "prov_lake_woods", "prov_lake_manitoba", "prov_reindeer_lake", "prov_lake_ronge", "prov_lake_athabasca", "prov_great_slave_lake", "prov_great_bear_lake", + + "prov_azov_sea", "prov_black_sea", "prov_marmara_sea", "prov_agean_sea", "prov_ionian_sea", "prov_adriatic_sea", "prov_tyrrhenian_sea", "prov_east_mediterranean", "prov_central_mediterranean", "prov_west_mediterranean", "prov_ligurian_sea", "prov_balearic_sea", "prov_alboran_sea", "prov_gulf_bothnia", "prov_gulf_finland", "prov_gulf_riga", "prov_baltic_sea", "prov_danish_straits", "prov_english_channel", "prov_irish_sea", "prov_biscay_bay", "prov_north_sea", "prov_red_sea", "prov_arabian_sea", "prov_persian_gulf", "prov_andaman_sea", "prov_bay_bengal", "prov_okhotsk_sea", "prov_japan_sea", "prov_east_china_sea", "prov_south_china_sea", "prov_philippine_sea", "prov_celebes_sea", "prov_java_sea", "prov_banda_sea", "prov_arafura_sea", "prov_gulf_mexico", "prov_caribbean_sea", "prov_mozambique_channel", "prov_zanj_sea", "prov_kara_sea", "prov_barents_sea", "prov_norwegian_sea", "prov_greenland_sea", "prov_labrador_sea", "prov_hudson_bay", "prov_gulf_st_lawrence", "prov_gulf_alaska", "prov_gulf_california", "prov_east_siberian_sea", "prov_sargasso_sea", "prov_gulf_guinea", "prov_celtic_sea", "prov_argentine_sea", "prov_chilean_sea", "prov_north_atlantic", "prov_central_atlantic", "prov_south_atlantic", "prov_indian_ocean", "prov_great_australian_bight", "prov_tasman_sea", "prov_coral_sea", "prov_melanesia", "prov_micronesia", "prov_polynesia", "prov_north_pacific", "prov_south_pacific", "prov_bering_sea", "prov_chukchi_sea", "prov_beaufort_sea" +] diff --git a/game/localisation/en_GB/mapmodes.csv b/game/localisation/en_GB/mapmodes.csv index c5b1bb0..440175f 100644 --- a/game/localisation/en_GB/mapmodes.csv +++ b/game/localisation/en_GB/mapmodes.csv @@ -2,4 +2,5 @@ ,, Test Mapmodes mapmode_province,Province Mapmode mapmode_region,Region Mapmode +mapmode_terrain,Terrain Mapmode mapmode_index,Index Mapmode diff --git a/game/localisation/en_GB/menus.csv b/game/localisation/en_GB/menus.csv index b483662..33e5c42 100644 --- a/game/localisation/en_GB/menus.csv +++ b/game/localisation/en_GB/menus.csv @@ -49,5 +49,17 @@ GAMELOBBY_START,Start Game GAMELOBBY_BACK,Back ,, Game Session Menu -GAMESESSIONMENU_RESIGN,Resign +GAMESESSIONMENU_SAVE,Save Game +GAMESESSIONMENU_LOAD,Load Game +GAMESESSIONMENU_OPTIONS,Options +GAMESESSIONMENU_MAINMENU,Resign +GAMESESSIONMENU_QUIT,Quit GAMESESSIONMENU_CLOSE,Close + +GAMESESSIONMENU_MAINMENU_DIALOG_TITLE,Resign Game +GAMESESSIONMENU_MAINMENU_DIALOG_TEXT,Are you sure you want to resign and return to the main menu? +GAMESESSIONMENU_QUIT_DIALOG_TITLE,Quit Game +GAMESESSIONMENU_QUIT_DIALOG_TEXT,Are you sure you want to quit and return to desktop? + +DIALOG_OK,OK +DIALOG_CANCEL,Cancel diff --git a/game/localisation/en_GB/provinces.csv b/game/localisation/en_GB/provinces.csv index 3b47955..24248a0 100644 --- a/game/localisation/en_GB/provinces.csv +++ b/game/localisation/en_GB/provinces.csv @@ -1,9 +1,230 @@ -,, Test Provinces +,, Europe prov_britain_NAME,Britain prov_ireland_NAME,Ireland prov_iceland_NAME,Iceland +prov_corsica_NAME,Corsica +prov_sardinia_NAME,Sardinia +prov_sicily_NAME,Sicily +prov_malta_NAME,Malta +prov_cyprus_NAME,Cyprus +prov_greenland_NAME,Greenland +prov_baleares_NAME,Balearic Islands +prov_gotland_NAME,Gotland +prov_crete_NAME,Crete +prov_jan_mayen_NAME,Jan Mayen +prov_faroes_NAME,Faroe Islands +prov_mann_NAME,Isle of Mann +prov_shetlands_NAME,Shetlands +prov_orkney_NAME,Orkney +prov_channel_islands_NAME,Channel Islands +prov_madiera_NAME,Madiera +prov_canarias_NAME,Canarias +prov_sjaeland_NAME,Sjaeland +prov_bornholm_NAME,Bornholm +prov_bear_island_NAME,Bear Island +prov_pantelleria_NAME,Pantelleria +prov_iberia_NAME,Iberia +prov_scandinavia_NAME,Scandinavia +prov_jutland_NAME,Jutland +prov_fyn_NAME,Fyn +prov_hiiumaa_NAME,Hiiumaa +prov_saaremaa_NAME,Saaremaa +prov_italy_NAME,Italy +prov_elba_NAME,Elba +prov_france_NAME,France +prov_netherlands_NAME,Netherlands +prov_belgium_NAME,Belgium +prov_luxembourg_NAME,Luxembourg +prov_switzerland_NAME,Switzerland +prov_balkans_NAME,Balkans +prov_crimea_NAME,Crimea +prov_germany_NAME,Germany +prov_poland_NAME,Poland +prov_baltics_NAME,Baltics +prov_finland_NAME,Finland +prov_aland_NAME,Åland +prov_ukraine_NAME,Ukraine +prov_russia_NAME,Russia + +,, North America +prov_north_america_NAME,North America prov_cuba_NAME,Cuba +prov_nova_scotia_NAME,Nova Scotia +prov_bermuda_NAME,Bermuda +prov_jamaica_NAME,Jamaica +prov_hispaniola_NAME,Hispaniola +prov_aleutians_name,Aleutian Islands +prov_bahamas_NAME,Bahamas +prov_turks_and_caicos_NAME,Turks and Caicos +prov_puerto_rico_NAME,Puerto Rico +prov_barbados_NAME,Barbados +prov_grenada_NAME,Grenada +prov_st_vincent_NAME,St Vincent +prov_st_lucia_NAME,St Lucia +prov_martinique_NAME,Martinique +prov_dominica_NAME,Dominica +prov_guadeloupe_NAME,Guadeloupe +prov_montserrat_NAME,Montserrat +prov_antigua_NAME,Antigua +prov_barbuda_NAME,Barbuda +prov_st_kitts_NAME,St Kitts +prov_west_virgin_islands_NAME,West Virgin Islands +prov_east_virgin_islands_NAME,East Virgin Islands +prov_cayman_islands_NAME,Cayman Islands +prov_angulia_NAME,Angulia +prov_central_america_NAME,Central America +prov_mexico_NAME,Mexico + +,, South America +prov_south_america_NAME,South America +prov_galapagos_NAME,Galapagos +prov_falklands_NAME,Falklands +prov_south_georgia_NAME,South Georgia + +,, Africa +prov_africa_NAME,Africa prov_madagascar_NAME,Madagascar +prov_socotra_NAME,Socotra +prov_mauritius_NAME,Mauritius +prov_reunion_NAME,Réunion +prov_comoros_NAME,Comoros +prov_sao_tome_NAME,Sao Tome +prov_fernando_po_NAME,Fernando Po +prov_cape_verde_NAME,Cape Verde +prov_ascension_NAME,Ascension +prov_st_helena_NAME,St Helena +prov_tristan_da_cunha_NAME,Tristan da Cunha +prov_seychelles_NAME,Seychelles +prov_prince_edward_islands_NAME,Prince Edward Islands +prov_kerguelen_islands_NAME,Kerguelen Islands +prov_heard_island_NAME,Heard Island +prov_egypt_NAME,Egypt +prov_morocco_NAME,Morocco + +,, Asia +prov_middle_east_NAME,Middle East prov_ceylon_NAME,Ceylon prov_formosa_NAME,Formosa +prov_sakhalin_NAME,Sakhalin +prov_maldives_NAME,Maldives +prov_hainan_NAME,Hainan +prov_hokkaido_NAME,Hokkaido +prov_diego_garcia_NAME,Diego Garcia +prov_philippines_NAME,Philippines +prov_india_NAME,India +prov_andamans_NAME,Andaman Islands +prov_nicobar_islands_NAME,Nicobar Islands +prov_indochina_NAME,Indochina +prov_korea_NAME,Korea +prov_okinawa_NAME,Okinawa +prov_yaeyama_NAME,Yaeyama +prov_kyushu_NAME,Kyushu +prov_shikoku_NAME,Shikoku +prov_japan_NAME,Japan +prov_kurils_NAME,Kuril Islands +prov_manchuria_NAME,Manchuria +prov_china_NAME,China +prov_central_asia_NAME,Central Asia +prov_siberia_NAME,Siberia +prov_iran_NAME,Iran +prov_anatolia_NAME,Anatolia + +,, Oceania +prov_oceania_NAME,Oceania +prov_indonesia_NAME,Indonesia +prov_north_island_NAME,North Island +prov_south_island_NAME,South Island +prov_tasmania_NAME,Tasmania +prov_australia_NAME,Australia +prov_hawaii_NAME,Hawaii + +,, Lakes +prov_aral_sea_NAME,Aral Sea +prov_caspian_sea_NAME,Caspian Sea +prov_lake_ladoga_NAME,Lake Ladoga +prov_lake_ontario_NAME,Lake Ontario +prov_lake_erie_NAME,Lake Erie +prov_lake_huron_NAME,Lake Huron +prov_lake_michigan_NAME,Lake Michigan +prov_lake_superior_NAME,Lake Superior +prov_lake_baikal_NAME,Lake Baikal +prov_lake_woods_NAME,Lake of the Woods +prov_lake_manitoba_NAME,Lake Manitoba +prov_reindeer_lake_NAME,Reindeer Lake +prov_lake_ronge_NAME,Lac la Ronge +prov_lake_athabasca_NAME,Lake Athabasca +prov_great_slave_lake_NAME,Great Slave Lake +prov_great_bear_lake_NAME,Great Bear Lake + +,, Seas and Oceans +prov_azov_sea_NAME,Sea of Azov +prov_black_sea_NAME,Black Sea +prov_marmara_sea_NAME,Sea of Marmara +prov_agean_sea_NAME,Agean Sea +prov_ionian_sea_NAME,Ionian Sea +prov_adriatic_sea_NAME,Adriatic Sea +prov_tyrrhenian_sea_NAME,Tyrrhenian Sea +prov_east_mediterranean_NAME,East Mediterranean Sea +prov_central_mediterranean_NAME,Central Mediterranean Sea +prov_west_mediterranean_NAME,West Mediterranean Sea +prov_ligurian_sea_NAME,Ligurian Sea +prov_balearic_sea_NAME,Balearic Sea +prov_alboran_sea_NAME,Alboran Sea +prov_gulf_bothnia_NAME,Gulf of Bothnia +prov_gulf_finland_NAME,Gulf of Finland +prov_gulf_riga_NAME,Gulf of Riga +prov_baltic_sea_NAME,Baltic Sea +prov_danish_straits_NAME,Danish Straits +prov_english_channel_NAME,English Channel +prov_irish_sea_NAME,Irish Sea +prov_biscay_bay_NAME,Bay of Biscay +prov_north_sea_NAME,North Sea +prov_red_sea_NAME,Red Sea +prov_arabian_sea_NAME,Arabian Sea +prov_persian_gulf_NAME,Persian Gulf +prov_andaman_sea_NAME,Andaman Sea +prov_bay_bengal_NAME,Bay of Bengal +prov_okhotsk_sea_NAME,Sea of Okhotsk +prov_japan_sea_NAME,Sea of Japan +prov_east_china_sea_NAME,East China Sea +prov_south_china_sea_NAME,South China Sea +prov_philippine_sea_NAME,Philippine Sea +prov_celebes_sea_NAME,Celebes Sea +prov_java_sea_NAME,Java Sea +prov_banda_sea_NAME,Banda Sea +prov_arafura_sea_NAME,Arafura Sea +prov_gulf_mexico_NAME,Gulf of Mexico +prov_caribbean_sea_NAME,Caribbean Sea +prov_mozambique_channel_NAME,Mozambique Channel +prov_zanj_sea_NAME,Sea of Zanj +prov_kara_sea_NAME,Kara Sea +prov_barents_sea_NAME,Barents Sea +prov_norwegian_sea_NAME,Norwegian Sea +prov_greenland_sea_NAME,Greenland Sea +prov_labrador_sea_NAME,Labrador Sea +prov_hudson_bay_NAME,Hudson Bay +prov_gulf_st_lawrence_NAME,Gulf of St Lawrence +prov_gulf_alaska_NAME,Gulf of Alaska +prov_gulf_california_NAME,Gulf of California +prov_east_siberian_sea_NAME,East Siberian Sea +prov_sargasso_sea_NAME,Sargasso Sea +prov_gulf_guinea_NAME,Gulf of Guinea +prov_celtic_sea_NAME,Celtic Sea +prov_argentine_sea_NAME,Argentine Sea +prov_chilean_sea_NAME,Chilean Sea +prov_north_atlantic_NAME,North Atlantic Ocean +prov_central_atlantic_NAME,Central Atlantic Ocean +prov_south_atlantic_NAME,South Atlantic Ocean +prov_indian_ocean_NAME,Indian Ocean +prov_great_australian_bight_NAME,Great Australian Bight +prov_tasman_sea_NAME,Tasman Sea +prov_coral_sea_NAME,Coral Sea +prov_melanesia_NAME,Melanesia +prov_micronesia_NAME,Micronesia +prov_polynesia_NAME,Polynesia +prov_north_pacific_NAME,North Pacific Ocean +prov_south_pacific_NAME,South Pacific Ocean +prov_bering_sea_NAME,Bering Sea +prov_chukchi_sea_NAME,Chukchi Sea +prov_beaufort_sea_NAME,Beaufort Sea diff --git a/game/localisation/en_GB/regions.csv b/game/localisation/en_GB/regions.csv new file mode 100644 index 0000000..8fe8943 --- /dev/null +++ b/game/localisation/en_GB/regions.csv @@ -0,0 +1,8 @@ + +,, Regions +region_europe_NAME,Europe +region_north_america_NAME,North America +region_south_america_NAME,South America +region_africa_NAME,Africa +region_asia_NAME,Asia +region_oceania_NAME,Oceania diff --git a/game/localisation/en_GB/regions.csv.import b/game/localisation/en_GB/regions.csv.import new file mode 100644 index 0000000..8dd0c09 --- /dev/null +++ b/game/localisation/en_GB/regions.csv.import @@ -0,0 +1,3 @@ +[remap] + +importer="keep" diff --git a/game/localisation/en_US/menus.csv b/game/localisation/en_US/menus.csv index 27a0858..807d1cb 100644 --- a/game/localisation/en_US/menus.csv +++ b/game/localisation/en_US/menus.csv @@ -1,3 +1,4 @@ + ,, Main Menu MAINMENU_TITLE,OpenVic2 MAINMENU_NEW_GAME,New Game @@ -48,5 +49,9 @@ GAMELOBBY_START,Start Game GAMELOBBY_BACK,Back ,, Game Session Menu -GAMESESSIONMENU_RESIGN,Resign +GAMESESSIONMENU_SAVE,Save Game +GAMESESSIONMENU_LOAD,Load Game +GAMESESSIONMENU_OPTIONS,Options +GAMESESSIONMENU_MAINMENU,Resign +GAMESESSIONMENU_QUIT,Quit GAMESESSIONMENU_CLOSE,Close diff --git a/game/localisation/fr_FR/menus.csv b/game/localisation/fr_FR/menus.csv index 8e8a7ad..0d84b64 100644 --- a/game/localisation/fr_FR/menus.csv +++ b/game/localisation/fr_FR/menus.csv @@ -1,3 +1,4 @@ + ,, Main Menu MAINMENU_TITLE,OpenVic2 MAINMENU_NEW_GAME,Nouveau Jeu @@ -48,5 +49,9 @@ GAMELOBBY_START,Démarrer Jeu GAMELOBBY_BACK,Retourner ,, Game Session Menu -GAMESESSIONMENU_RESIGN,Démissionner +GAMESESSIONMENU_SAVE,Sauvegarder la Partie +GAMESESSIONMENU_LOAD,Charger la Partie +GAMESESSIONMENU_OPTIONS,Options +GAMESESSIONMENU_MAINMENU,Démissionner +GAMESESSIONMENU_QUIT,Quitter GAMESESSIONMENU_CLOSE,Fermer diff --git a/game/src/Autoload/Events.gd b/game/src/Autoload/Events.gd index f4aac70..dbd3f9f 100644 --- a/game/src/Autoload/Events.gd +++ b/game/src/Autoload/Events.gd @@ -4,14 +4,17 @@ var Options = preload("Events/Options.gd").new() var Localisation = preload("Events/Localisation.gd").new() const _province_identifier_file : String = "res://common/map/provinces.json" +const _water_province_file : String = "res://common/map/water.json" const _region_file : String = "res://common/map/regions.json" const _province_shape_file : String = "res://common/map/provinces.png" # REQUIREMENTS -# * FS-333, FS-335, FS-341 +# * FS-333, FS-334, FS-335, FS-341 func _ready(): if MapSingleton.load_province_identifier_file(_province_identifier_file) != OK: push_error("Failed to load province identifiers") + if MapSingleton.load_water_province_file(_water_province_file) != OK: + push_error("Failed to load water provinces") if MapSingleton.load_region_file(_region_file) != OK: push_error("Failed to load regions") if MapSingleton.load_province_shape_file(_province_shape_file) != OK: diff --git a/game/src/GameSession/GameSession.gd b/game/src/GameSession/GameSession.gd index 38eaba1..fe83a8a 100644 --- a/game/src/GameSession/GameSession.gd +++ b/game/src/GameSession/GameSession.gd @@ -1,16 +1,11 @@ -extends Node +extends Control @export var _game_session_menu : Control func _ready(): - print("GameSession ready") + Events.Options.load_settings_from_file() # REQUIREMENTS: # * SS-42 func _on_game_session_menu_button_pressed(): _game_session_menu.visible = !_game_session_menu.visible - -# REQUIREMENTS: -# * SS-64 -func _on_game_session_menu_close_button_pressed(): - _game_session_menu.hide() diff --git a/game/src/GameSession/GameSession.tscn b/game/src/GameSession/GameSession.tscn index e270f8a..d23cb6c 100644 --- a/game/src/GameSession/GameSession.tscn +++ b/game/src/GameSession/GameSession.tscn @@ -1,13 +1,21 @@ -[gd_scene load_steps=6 format=3 uid="uid://bgnupcshe1m7r"] +[gd_scene load_steps=7 format=3 uid="uid://bgnupcshe1m7r"] [ext_resource type="Script" path="res://src/GameSession/GameSession.gd" id="1_eklvp"] [ext_resource type="PackedScene" uid="uid://g524p8lr574w" path="res://src/GameSession/MapControlPanel.tscn" id="3_afh6d"] [ext_resource type="PackedScene" uid="uid://dvdynl6eir40o" path="res://src/GameSession/GameSessionMenu.tscn" id="3_bvmqh"] [ext_resource type="PackedScene" uid="uid://dkehmdnuxih2r" path="res://src/GameSession/MapView.tscn" id="4_xkg5j"] [ext_resource type="PackedScene" uid="uid://byq323jbel48u" path="res://src/GameSession/ProvinceOverviewPanel.tscn" id="5_osjnn"] +[ext_resource type="PackedScene" uid="uid://cnbfxjy1m6wja" path="res://src/OptionMenu/OptionsMenu.tscn" id="6_p5mnx"] -[node name="GameSession" type="Node" node_paths=PackedStringArray("_game_session_menu")] +[node name="GameSession" type="Control" node_paths=PackedStringArray("_game_session_menu")] editor_description = "SS-102, UI-546" +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 script = ExtResource("1_eklvp") _game_session_menu = NodePath("GameSessionMenu") @@ -15,6 +23,7 @@ _game_session_menu = NodePath("GameSessionMenu") [node name="GameSessionMenu" parent="." instance=ExtResource("3_bvmqh")] visible = false +layout_mode = 1 anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 @@ -24,28 +33,31 @@ grow_horizontal = 2 grow_vertical = 2 [node name="MapControlPanel" parent="." instance=ExtResource("3_afh6d")] +layout_mode = 1 anchors_preset = 3 anchor_left = 1.0 anchor_top = 1.0 anchor_right = 1.0 anchor_bottom = 1.0 -offset_left = -350.0 -offset_top = -210.0 grow_horizontal = 0 grow_vertical = 0 [node name="ProvinceOverviewPanel" parent="." instance=ExtResource("5_osjnn")] -anchors_preset = -1 -anchor_top = 0.583333 -anchor_right = 0.15625 -offset_top = 0.0 -offset_right = 0.0 +layout_mode = 1 + +[node name="OptionsMenu" parent="." instance=ExtResource("6_p5mnx")] +visible = false +layout_mode = 1 [connection signal="map_view_camera_changed" from="MapView" to="MapControlPanel" method="_on_map_view_camera_changed"] [connection signal="province_selected" from="MapView" to="ProvinceOverviewPanel" method="_on_province_selected"] -[connection signal="close_button_pressed" from="GameSessionMenu" to="." method="_on_game_session_menu_close_button_pressed"] +[connection signal="options_button_pressed" from="GameSessionMenu" to="OptionsMenu" method="show"] [connection signal="game_session_menu_button_pressed" from="MapControlPanel" to="." method="_on_game_session_menu_button_pressed"] [connection signal="mapmode_changed" from="MapControlPanel" to="MapView" method="_update_colour_texture"] [connection signal="minimap_clicked" from="MapControlPanel" to="MapView" method="_on_minimap_clicked"] [connection signal="mouse_entered" from="MapControlPanel" to="MapView" method="_on_mouse_exited_viewport"] [connection signal="mouse_exited" from="MapControlPanel" to="MapView" method="_on_mouse_entered_viewport"] +[connection signal="zoom_in_button_pressed" from="MapControlPanel" to="MapView" method="zoom_in"] +[connection signal="zoom_out_button_pressed" from="MapControlPanel" to="MapView" method="zoom_out"] +[connection signal="back_button_pressed" from="OptionsMenu" to="MapView" method="enable_processing"] +[connection signal="back_button_pressed" from="OptionsMenu" to="OptionsMenu" method="hide"] diff --git a/game/src/GameSession/GameSessionMenu.gd b/game/src/GameSession/GameSessionMenu.gd index 3722b52..8a76c0f 100644 --- a/game/src/GameSession/GameSessionMenu.gd +++ b/game/src/GameSession/GameSessionMenu.gd @@ -1,19 +1,24 @@ extends PanelContainer -signal close_button_pressed - @export var _main_menu_scene : PackedScene -func _ready(): - print("GameSessionMenu ready") +signal options_button_pressed # REQUIREMENTS: # * SS-47 # * UIFUN-69 -func _on_to_main_menu_pressed(): +func _on_main_menu_confirmed() -> void: get_tree().change_scene_to_packed(_main_menu_scene) # REQUIREMENTS: -# * UIFUN-69 -func _on_close_button_pressed(): - close_button_pressed.emit() +# * SS-48 +# * UIFUN-70 +func _on_quit_confirmed() -> void: + get_tree().quit() + +# REQUIREMENTS: +# * SS-7, SS-46 +# * UIFUN-11 +func _on_options_button_pressed() -> void: + hide() + options_button_pressed.emit() diff --git a/game/src/GameSession/GameSessionMenu.tscn b/game/src/GameSession/GameSessionMenu.tscn index 45fff4b..a753184 100644 --- a/game/src/GameSession/GameSessionMenu.tscn +++ b/game/src/GameSession/GameSessionMenu.tscn @@ -8,21 +8,64 @@ editor_description = "UI-68" script = ExtResource("1_usq6o") _main_menu_scene = ExtResource("2_xi6a4") -[node name="VBoxContainer" type="VBoxContainer" parent="."] +[node name="MarginContainer" type="MarginContainer" parent="."] layout_mode = 2 +theme_override_constants/margin_left = 10 +theme_override_constants/margin_top = 10 +theme_override_constants/margin_right = 10 +theme_override_constants/margin_bottom = 10 -[node name="MainMenuButton" type="Button" parent="VBoxContainer"] +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"] +layout_mode = 2 + +[node name="SaveButton" type="Button" parent="MarginContainer/VBoxContainer"] +editor_description = "UI-69" +layout_mode = 2 +text = "GAMESESSIONMENU_SAVE" + +[node name="LoadButton" type="Button" parent="MarginContainer/VBoxContainer"] +editor_description = "UI-70" +layout_mode = 2 +text = "GAMESESSIONMENU_LOAD" + +[node name="OptionsButton" type="Button" parent="MarginContainer/VBoxContainer"] +editor_description = "UI-10" +layout_mode = 2 +text = "GAMESESSIONMENU_OPTIONS" + +[node name="MainMenuButton" type="Button" parent="MarginContainer/VBoxContainer"] editor_description = "UI-71" layout_mode = 2 -text = "GAMESESSIONMENU_RESIGN" +text = "GAMESESSIONMENU_MAINMENU" + +[node name="QuitButton" type="Button" parent="MarginContainer/VBoxContainer"] +editor_description = "UI-72" +layout_mode = 2 +text = "GAMESESSIONMENU_QUIT" -[node name="HSeparator" type="HSeparator" parent="VBoxContainer"] +[node name="HSeparator" type="HSeparator" parent="MarginContainer/VBoxContainer"] layout_mode = 2 -[node name="CloseButton" type="Button" parent="VBoxContainer"] -editor_description = "UI-80" +[node name="CloseButton" type="Button" parent="MarginContainer/VBoxContainer"] +editor_description = "SS-64, UI-80, UIFUN-79" layout_mode = 2 text = "GAMESESSIONMENU_CLOSE" -[connection signal="pressed" from="VBoxContainer/MainMenuButton" to="." method="_on_to_main_menu_pressed"] -[connection signal="pressed" from="VBoxContainer/CloseButton" to="." method="_on_close_button_pressed"] +[node name="MainMenuDialog" type="ConfirmationDialog" parent="."] +title = "GAMESESSIONMENU_MAINMENU_DIALOG_TITLE" +ok_button_text = "DIALOG_OK" +dialog_text = "GAMESESSIONMENU_MAINMENU_DIALOG_TEXT" +cancel_button_text = "DIALOG_CANCEL" + +[node name="QuitDialog" type="ConfirmationDialog" parent="."] +title = "GAMESESSIONMENU_QUIT_DIALOG_TITLE" +ok_button_text = "DIALOG_OK" +dialog_text = "GAMESESSIONMENU_QUIT_DIALOG_TEXT" +cancel_button_text = "DIALOG_CANCEL" + +[connection signal="pressed" from="MarginContainer/VBoxContainer/OptionsButton" to="." method="_on_options_button_pressed"] +[connection signal="pressed" from="MarginContainer/VBoxContainer/MainMenuButton" to="MainMenuDialog" method="popup_centered"] +[connection signal="pressed" from="MarginContainer/VBoxContainer/QuitButton" to="QuitDialog" method="popup_centered"] +[connection signal="pressed" from="MarginContainer/VBoxContainer/CloseButton" to="." method="hide"] +[connection signal="confirmed" from="MainMenuDialog" to="." method="_on_main_menu_confirmed"] +[connection signal="confirmed" from="QuitDialog" to="." method="_on_quit_confirmed"] diff --git a/game/src/GameSession/MapControlPanel.gd b/game/src/GameSession/MapControlPanel.gd index 693890f..d5810c5 100644 --- a/game/src/GameSession/MapControlPanel.gd +++ b/game/src/GameSession/MapControlPanel.gd @@ -4,6 +4,8 @@ signal game_session_menu_button_pressed signal mapmode_changed signal map_view_camera_changed(near_left : Vector2, far_left : Vector2, far_right : Vector2, near_right : Vector2) signal minimap_clicked(pos_clicked : Vector2) +signal zoom_in_button_pressed +signal zoom_out_button_pressed @export var _mapmodes_grid : GridContainer @@ -17,6 +19,7 @@ func _add_mapmode_button(identifier : String) -> void: button.tooltip_text = identifier button.toggle_mode = true button.button_group = _mapmode_button_group + button.mouse_filter = MOUSE_FILTER_PASS _mapmodes_grid.add_child(button) if _mapmode_button_group.get_pressed_button() == null: button.button_pressed = true @@ -44,3 +47,13 @@ func _on_map_view_camera_changed(near_left : Vector2, far_left : Vector2, far_ri func _on_minimap_clicked(pos_clicked : Vector2) -> void: minimap_clicked.emit(pos_clicked) + +# REQUIREMENTS: +# * UIFUN-269 +func _on_zoom_in_button_pressed() -> void: + zoom_in_button_pressed.emit() + +# REQUIREMENTS: +# * UIFUN-270 +func _on_zoom_out_button_pressed() -> void: + zoom_out_button_pressed.emit() diff --git a/game/src/GameSession/MapControlPanel.tscn b/game/src/GameSession/MapControlPanel.tscn index 70d7eab..27205e3 100644 --- a/game/src/GameSession/MapControlPanel.tscn +++ b/game/src/GameSession/MapControlPanel.tscn @@ -15,49 +15,89 @@ events = [SubResource("InputEventAction_5nck3")] editor_description = "SS-103" mouse_filter = 1 script = ExtResource("1_ign64") -_mapmodes_grid = NodePath("HBoxContainer/VBoxContainer/MapmodesGrid") +_mapmodes_grid = NodePath("MarginContainer/HBoxContainer/VBoxContainer/MapmodesGrid") -[node name="HBoxContainer" type="HBoxContainer" parent="."] +[node name="MarginContainer" type="MarginContainer" parent="."] layout_mode = 2 -alignment = 2 +theme_override_constants/margin_left = 5 +theme_override_constants/margin_top = 5 +theme_override_constants/margin_right = 5 +theme_override_constants/margin_bottom = 5 -[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer"] +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"] layout_mode = 2 +theme_override_constants/separation = 6 +alignment = 1 -[node name="MapmodesGrid" type="GridContainer" parent="HBoxContainer/VBoxContainer"] +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/HBoxContainer"] +layout_mode = 2 +alignment = 1 + +[node name="MapmodesGrid" type="GridContainer" parent="MarginContainer/HBoxContainer/VBoxContainer"] editor_description = "UI-750" layout_mode = 2 columns = 11 -[node name="Minimap" type="PanelContainer" parent="HBoxContainer/VBoxContainer"] +[node name="Minimap" type="PanelContainer" parent="MarginContainer/HBoxContainer/VBoxContainer"] editor_description = "UI-549" layout_mode = 2 mouse_filter = 1 -[node name="TextureRect" type="TextureRect" parent="HBoxContainer/VBoxContainer/Minimap"] +[node name="TextureRect" type="TextureRect" parent="MarginContainer/HBoxContainer/VBoxContainer/Minimap"] editor_description = "UI-751, FS-338" layout_mode = 2 texture = ExtResource("2_r613r") -[node name="ViewportQuad" type="Control" parent="HBoxContainer/VBoxContainer/Minimap"] +[node name="ViewportQuad" type="Control" parent="MarginContainer/HBoxContainer/VBoxContainer/Minimap"] layout_mode = 2 mouse_filter = 2 script = ExtResource("3_s4dml") -[node name="Frame" type="NinePatchRect" parent="HBoxContainer/VBoxContainer/Minimap"] +[node name="Frame" type="NinePatchRect" parent="MarginContainer/HBoxContainer/VBoxContainer/Minimap"] layout_mode = 2 texture = ExtResource("4_f1exl") -[node name="AuxiliaryPanel" type="VBoxContainer" parent="HBoxContainer"] +[node name="AuxiliaryPanel" type="VBoxContainer" parent="MarginContainer/HBoxContainer"] editor_description = "UI-761" layout_mode = 2 -[node name="GameSessionMenuButton" type="Button" parent="HBoxContainer/AuxiliaryPanel"] +[node name="GameSessionMenuButton" type="Button" parent="MarginContainer/HBoxContainer/AuxiliaryPanel"] editor_description = "UI-9" layout_mode = 2 +mouse_filter = 1 shortcut = SubResource("Shortcut_fc1tk") text = "ESC" -[connection signal="map_view_camera_changed" from="." to="HBoxContainer/VBoxContainer/Minimap/ViewportQuad" method="_on_map_view_camera_changed"] -[connection signal="minimap_clicked" from="HBoxContainer/VBoxContainer/Minimap/ViewportQuad" to="." method="_on_minimap_clicked"] -[connection signal="pressed" from="HBoxContainer/AuxiliaryPanel/GameSessionMenuButton" to="." method="_on_game_session_menu_button_pressed"] +[node name="LedgerButton" type="Button" parent="MarginContainer/HBoxContainer/AuxiliaryPanel"] +editor_description = "UI-860" +layout_mode = 2 +mouse_filter = 1 +text = "L" + +[node name="FindButton" type="Button" parent="MarginContainer/HBoxContainer/AuxiliaryPanel"] +editor_description = "UI-861" +layout_mode = 2 +mouse_filter = 1 +text = "F" + +[node name="ZoomButtonsContainer" type="HBoxContainer" parent="MarginContainer/HBoxContainer/AuxiliaryPanel"] +layout_mode = 2 +alignment = 1 + +[node name="ZoomInButton" type="Button" parent="MarginContainer/HBoxContainer/AuxiliaryPanel/ZoomButtonsContainer"] +editor_description = "UI-862" +layout_mode = 2 +mouse_filter = 1 +text = "+" + +[node name="ZoomOutButton" type="Button" parent="MarginContainer/HBoxContainer/AuxiliaryPanel/ZoomButtonsContainer"] +editor_description = "UI-863" +layout_mode = 2 +mouse_filter = 1 +text = "-" + +[connection signal="map_view_camera_changed" from="." to="MarginContainer/HBoxContainer/VBoxContainer/Minimap/ViewportQuad" method="_on_map_view_camera_changed"] +[connection signal="minimap_clicked" from="MarginContainer/HBoxContainer/VBoxContainer/Minimap/ViewportQuad" to="." method="_on_minimap_clicked"] +[connection signal="pressed" from="MarginContainer/HBoxContainer/AuxiliaryPanel/GameSessionMenuButton" to="." method="_on_game_session_menu_button_pressed"] +[connection signal="pressed" from="MarginContainer/HBoxContainer/AuxiliaryPanel/ZoomButtonsContainer/ZoomInButton" to="." method="_on_zoom_in_button_pressed"] +[connection signal="pressed" from="MarginContainer/HBoxContainer/AuxiliaryPanel/ZoomButtonsContainer/ZoomOutButton" to="." method="_on_zoom_out_button_pressed"] diff --git a/game/src/GameSession/MapView.gd b/game/src/GameSession/MapView.gd index 54d8df8..ae49e82 100644 --- a/game/src/GameSession/MapView.gd +++ b/game/src/GameSession/MapView.gd @@ -16,6 +16,7 @@ const _shader_param_province_index : StringName = &"province_index_tex" const _shader_param_province_colour : StringName = &"province_colour_tex" const _shader_param_hover_index : StringName = &"hover_index" const _shader_param_selected_index : StringName = &"selected_index" +const _shader_param_terrain_tile_factor : StringName = &"terrain_tile_factor" @export var _camera : Camera3D @@ -25,9 +26,9 @@ const _shader_param_selected_index : StringName = &"selected_index" var _drag_anchor : Vector2 var _drag_active : bool = false -var _mouse_over_viewport : bool = false +var _mouse_over_viewport : bool = true -@export var _zoom_target_min : float = 0.2 +@export var _zoom_target_min : float = 0.05 @export var _zoom_target_max : float = 5.0 @export var _zoom_target_step : float = 0.1 @export var _zoom_epsilon : float = _zoom_target_step * 0.1 @@ -100,6 +101,7 @@ func _ready(): # Set map mesh size and get bounds _map_image_size = Vector2(Vector2i(MapSingleton.get_width(), MapSingleton.get_height())) _map_mesh.aspect_ratio = _map_image_size.x / _map_image_size.y + _map_shader_material.set_shader_parameter(_shader_param_terrain_tile_factor, _map_image_size.y / 64.0) var map_mesh_aabb := _map_mesh.get_core_aabb() * _map_mesh_instance.transform _map_mesh_corner = Vector2( min(map_mesh_aabb.position.x, map_mesh_aabb.end.x), @@ -137,10 +139,16 @@ func _viewport_to_map_coords(pos_viewport : Vector2) -> Vector2: push_error("Invalid intersection: ", intersection) return Vector2(0.5, 0.5) +func zoom_in() -> void: + _zoom_target -= _zoom_target_step + +func zoom_out() -> void: + _zoom_target += _zoom_target_step + # REQUIREMENTS # * SS-31 func _unhandled_input(event : InputEvent): - if event.is_action_pressed(_action_click): + if _mouse_over_viewport and event.is_action_pressed(_action_click): # Check if the mouse is outside of bounds if _map_mesh.is_valid_uv_coord(_mouse_pos_map): var selected_index := MapSingleton.get_province_index_from_uv_coords(_mouse_pos_map) @@ -159,9 +167,9 @@ func _unhandled_input(event : InputEvent): push_warning("Drag being deactivated while already not active!") _drag_active = false elif event.is_action_pressed(_action_zoomin, true): - _zoom_target -= _zoom_target_step + zoom_in() elif event.is_action_pressed(_action_zoomout, true): - _zoom_target += _zoom_target_step + zoom_out() func _physics_process(delta : float): _mouse_pos_viewport = get_viewport().get_mouse_position() @@ -228,7 +236,7 @@ func _zoom_process(delta : float) -> void: _camera.position.y = height func _update_orientation() -> void: - var dir := Vector3(0, -1, -exp(-_camera.position.y * 2.0 + 0.5)) + var dir := Vector3(0, -1, -exp(-_camera.position.y - 1)) _camera.look_at(_camera.position + dir) func _update_minimap_viewport() -> void: @@ -254,4 +262,12 @@ func _on_minimap_clicked(pos_clicked : Vector2): pos_clicked *= _map_mesh_dims _camera.position.x = pos_clicked.x _camera.position.z = pos_clicked.y - _clamp_over_map()
\ No newline at end of file + _clamp_over_map() + +func enable_processing() -> void: + set_process_unhandled_input(true) + set_physics_process(true) + +func disable_processing() -> void: + set_process_unhandled_input(false) + set_physics_process(false) diff --git a/game/src/GameSession/MapView.tscn b/game/src/GameSession/MapView.tscn index 93fc162..c8934c5 100644 --- a/game/src/GameSession/MapView.tscn +++ b/game/src/GameSession/MapView.tscn @@ -2,14 +2,15 @@ [ext_resource type="Script" path="res://src/GameSession/MapView.gd" id="1_exccw"] [ext_resource type="Shader" path="res://src/GameSession/TerrainMap.gdshader" id="1_upocn"] -[ext_resource type="Texture2D" uid="uid://cmw0pvjthnn8c" path="res://art/terrain/terrain.png" id="3_l8pnf"] +[ext_resource type="Texture2D" uid="uid://ckf222w5usrsu" path="res://art/terrain/farmlands.png" id="3_47mq1"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_tayeg"] render_priority = 0 shader = ExtResource("1_upocn") shader_parameter/hover_index = null shader_parameter/selected_index = null -shader_parameter/terrain_tex = ExtResource("3_l8pnf") +shader_parameter/terrain_tile_factor = null +shader_parameter/farmlands_tex = ExtResource("3_47mq1") [sub_resource type="MapMesh" id="MapMesh_3gtsd"] @@ -21,6 +22,7 @@ _map_mesh_instance = NodePath("MapMeshInstance") [node name="MapCamera" type="Camera3D" parent="."] transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0.25, 1.5, -2.75) +near = 0.01 [node name="MapMeshInstance" type="MeshInstance3D" parent="."] editor_description = "FS-343" diff --git a/game/src/GameSession/ProvinceOverviewPanel.gd b/game/src/GameSession/ProvinceOverviewPanel.gd index 434f6b1..4615df9 100644 --- a/game/src/GameSession/ProvinceOverviewPanel.gd +++ b/game/src/GameSession/ProvinceOverviewPanel.gd @@ -1,22 +1,33 @@ extends Panel @export var _province_name_label : Label +@export var _region_name_label : Label -@export var province_identifier: String = "": - get: return province_identifier +var _province_identifier: String = "": + get: return _province_identifier set(v): - province_identifier = v + _province_identifier = v update_info() +const _name_suffix : String = "_NAME" + func _ready(): update_info() func update_info() -> void: - _province_name_label.text = province_identifier + "_NAME" - visible = not province_identifier.is_empty() + if _province_identifier: + _province_name_label.text = _province_identifier + _name_suffix + var region_identifier := MapSingleton.get_region_identifier_from_province_identifier(_province_identifier) + if region_identifier: + _region_name_label.text = region_identifier + _name_suffix + else: + _region_name_label.text = "NO REGION" + show() + else: + hide() func _on_province_selected(identifier : String) -> void: - province_identifier = identifier + _province_identifier = identifier -func _on_button_pressed() -> void: - province_identifier = "" +func _on_close_button_pressed() -> void: + _province_identifier = "" diff --git a/game/src/GameSession/ProvinceOverviewPanel.tscn b/game/src/GameSession/ProvinceOverviewPanel.tscn index 2df95fb..7d21edc 100644 --- a/game/src/GameSession/ProvinceOverviewPanel.tscn +++ b/game/src/GameSession/ProvinceOverviewPanel.tscn @@ -2,7 +2,7 @@ [ext_resource type="Script" path="res://src/GameSession/ProvinceOverviewPanel.gd" id="1_3n8k5"] -[node name="ProvinceOverviewPanel" type="Panel" node_paths=PackedStringArray("_province_name_label")] +[node name="ProvinceOverviewPanel" type="Panel" node_paths=PackedStringArray("_province_name_label", "_region_name_label")] editor_description = "UI-56" anchors_preset = 2 anchor_top = 1.0 @@ -12,6 +12,7 @@ offset_right = 200.0 grow_vertical = 0 script = ExtResource("1_3n8k5") _province_name_label = NodePath("VBoxContainer/ProvinceName") +_region_name_label = NodePath("VBoxContainer/RegionName") [node name="VBoxContainer" type="VBoxContainer" parent="."] layout_mode = 1 @@ -29,7 +30,13 @@ layout_mode = 2 text = "PROVINCE_NAME" vertical_alignment = 1 -[node name="Button" type="Button" parent="."] +[node name="RegionName" type="Label" parent="VBoxContainer"] +editor_description = "UI-58" +layout_mode = 2 +text = "REGION_NAME" +vertical_alignment = 1 + +[node name="CloseButton" type="Button" parent="."] custom_minimum_size = Vector2(30, 30) layout_mode = 1 anchors_preset = -1 @@ -39,4 +46,4 @@ anchor_bottom = 0.103333 grow_horizontal = 0 text = "X" -[connection signal="pressed" from="Button" to="." method="_on_button_pressed"] +[connection signal="pressed" from="CloseButton" to="." method="_on_close_button_pressed"] diff --git a/game/src/GameSession/TerrainMap.gdshader b/game/src/GameSession/TerrainMap.gdshader index 7aca0f9..9ce1a24 100644 --- a/game/src/GameSession/TerrainMap.gdshader +++ b/game/src/GameSession/TerrainMap.gdshader @@ -2,16 +2,18 @@ shader_type spatial; render_mode unshaded; -// Cosmetic terrain texture -uniform sampler2D terrain_tex: source_color, repeat_enable, filter_linear; +// Cosmetic farmlands terrain texture +uniform sampler2D farmlands_tex: source_color, repeat_enable, filter_linear; // Province index texture -uniform sampler2D province_index_tex : repeat_enable, filter_nearest; +uniform sampler2D province_index_tex : source_color, repeat_enable, filter_nearest; // Province colour texture uniform sampler2D province_colour_tex: source_color, repeat_enable, filter_nearest; // Index of the mouse over the map mesh uniform uint hover_index; // Index of the currently selected province uniform uint selected_index; +// The number of times the terrain textures should tile vertically +uniform float terrain_tile_factor; uvec2 vec2_to_uvec2(vec2 v) { return uvec2(v * 255.0); @@ -29,17 +31,39 @@ uint read_uint16(sampler2D tex, vec2 uv) { return uvec2_to_uint(read_uvec2(tex, uv)); } -void fragment() { - uvec2 prov_idx_split = read_uvec2(province_index_tex, UV); - uint prov_index = uvec2_to_uint(prov_idx_split); +const vec3 water_colour = vec3(0, 0, 1); + +vec3 get_terrain_colour(vec2 uv, vec2 corner, vec2 half_pixel_size, vec2 terrain_uv) { + uvec2 index_split = read_uvec2(province_index_tex, fma(corner, half_pixel_size, uv)); + uint index = uvec2_to_uint(index_split); + vec4 province_data = texelFetch(province_colour_tex, ivec2(index_split), 0); + vec3 province_colour = province_data.rgb; + float is_land = province_data.a; + vec3 farmlands_colour = texture(farmlands_tex, terrain_uv).rgb; + vec3 terrain_colour = mix(water_colour, farmlands_colour, is_land); + float mix_val = 0.4 + float(index == hover_index) * 0.2 + float(index == selected_index) * 0.2; + vec3 mixed_colour = mix(terrain_colour, province_colour, mix_val); + return mixed_colour; +} - // Boost prov_colour's contribution if it matches hover_colour or selected_colour - float mix_val = 0.3 + float(prov_index == hover_index) * 0.3 + float(prov_index == selected_index) * 0.3; - // Don't mix if the province index is 0 - mix_val *= float(prov_index != 0u); +vec3 mix_terrain_colour(vec2 uv) { + vec2 map_size = vec2(textureSize(province_index_tex, 0)); + vec2 pixel_offset = mod(fma(uv, map_size, vec2(0.5)), 1.0); + vec2 half_pixel_size = 0.49 / map_size; - vec3 terrain_colour = texture(terrain_tex, UV).rgb; - vec3 province_colour = texelFetch(province_colour_tex, ivec2(prov_idx_split), 0).rgb; + vec2 terrain_uv = uv; + terrain_uv.x *= map_size.x / map_size.y; + terrain_uv *= terrain_tile_factor; - ALBEDO = mix(terrain_colour, province_colour, mix_val); + return mix( + mix(get_terrain_colour(uv, vec2(-1, -1), half_pixel_size, terrain_uv), + get_terrain_colour(uv, vec2(+1, -1), half_pixel_size, terrain_uv), pixel_offset.x), + mix(get_terrain_colour(uv, vec2(-1, +1), half_pixel_size, terrain_uv), + get_terrain_colour(uv, vec2(+1, +1), half_pixel_size, terrain_uv), pixel_offset.x), + pixel_offset.y); +} + +void fragment() { + vec3 terrain_colour = mix_terrain_colour(UV); + ALBEDO = terrain_colour; } |