diff options
author | Hop311 <Hop3114@gmail.com> | 2024-05-09 23:32:18 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-09 23:32:18 +0200 |
commit | b0a533f945bbc6201fd7df4bc60746cb98efaba4 (patch) | |
tree | 56c84e804b11a271e15f38e64d5b3727c636b474 | |
parent | f57bbe6604a237c9fea52aec43641585d0b24568 (diff) | |
parent | a3ef8c1ad72f7e839e073679f374195681208837 (diff) |
Merge pull request #228 from OpenVicProject/menu-tweaks
Topbar display data + Population menu rebel icons
8 files changed, 529 insertions, 65 deletions
diff --git a/extension/src/openvic-extension/classes/GUINode.cpp b/extension/src/openvic-extension/classes/GUINode.cpp index c9af7e2..452efc8 100644 --- a/extension/src/openvic-extension/classes/GUINode.cpp +++ b/extension/src/openvic-extension/classes/GUINode.cpp @@ -84,8 +84,9 @@ void GUINode::_bind_methods() { OV_BIND_METHOD(GUINode::hide_node, { "path" }); OV_BIND_METHOD(GUINode::hide_nodes, { "paths" }); - OV_BIND_SMETHOD(int_to_formatted_string, { "val" }); - OV_BIND_SMETHOD(float_to_formatted_string, { "val", "decimal_places" }); + OV_BIND_SMETHOD(int_to_string_suffixed, { "val" }); + OV_BIND_SMETHOD(float_to_string_suffixed, { "val" }); + OV_BIND_SMETHOD(float_to_string_dp, { "val", "decimal_places" }); OV_BIND_SMETHOD(format_province_name, { "province_identifier" }); } @@ -221,17 +222,26 @@ Error GUINode::hide_nodes(TypedArray<NodePath> const& paths) const { return ret; } -String GUINode::int_to_formatted_string(int64_t val) { - return Utilities::int_to_formatted_string(val); +String GUINode::int_to_string_suffixed(int64_t val) { + return Utilities::int_to_string_suffixed(val); } -String GUINode::float_to_formatted_string(float val, int32_t decimal_places) { - return Utilities::float_to_formatted_string(val, decimal_places); +String GUINode::float_to_string_suffixed(float val) { + return Utilities::float_to_string_suffixed(val); +} + +String GUINode::float_to_string_dp(float val, int32_t decimal_places) { + return Utilities::float_to_string_dp(val, decimal_places); } String GUINode::format_province_name(String const& province_identifier) { - static const String province_prefix = "PROV"; - return province_prefix + province_identifier; + if (!province_identifier.is_empty()) { + static const String province_prefix = "PROV"; + return province_prefix + province_identifier; + } else { + static const String no_province = "NO PROVINCE"; + return no_province; + } } Ref<BitMap> GUINode::get_click_mask() const { diff --git a/extension/src/openvic-extension/classes/GUINode.hpp b/extension/src/openvic-extension/classes/GUINode.hpp index 8d926cc..60c0050 100644 --- a/extension/src/openvic-extension/classes/GUINode.hpp +++ b/extension/src/openvic-extension/classes/GUINode.hpp @@ -85,8 +85,9 @@ namespace OpenVic { godot::Error hide_node(godot::NodePath const& path) const; godot::Error hide_nodes(godot::TypedArray<godot::NodePath> const& paths) const; - static godot::String int_to_formatted_string(int64_t val); - static godot::String float_to_formatted_string(float val, int32_t decimal_places); + static godot::String int_to_string_suffixed(int64_t val); + static godot::String float_to_string_suffixed(float val); + static godot::String float_to_string_dp(float val, int32_t decimal_places); static godot::String format_province_name(godot::String const& province_identifier); godot::Ref<godot::BitMap> get_click_mask() const; diff --git a/extension/src/openvic-extension/singletons/PopulationMenu.cpp b/extension/src/openvic-extension/singletons/PopulationMenu.cpp index a598ceb..609142a 100644 --- a/extension/src/openvic-extension/singletons/PopulationMenu.cpp +++ b/extension/src/openvic-extension/singletons/PopulationMenu.cpp @@ -400,6 +400,18 @@ void MenuSingleton::_population_menu_update_filtered_pops() { _population_menu_sort_pops(); } +template<std::derived_from<HasIdentifier> T> +static bool compare_translated_identifiers(Object const& object, T const& lhs, T const& rhs) { + return object.tr(std_view_to_godot_string(lhs.get_identifier())) + < object.tr(std_view_to_godot_string(rhs.get_identifier())); +} + +template<std::derived_from<HasIdentifier> T> +static bool compare_translated_identifiers(Object const& object, T const* lhs, T const* rhs) { + return (lhs != nullptr ? object.tr(std_view_to_godot_string(lhs->get_identifier())) : godot::String {}) + < (rhs != nullptr ? object.tr(std_view_to_godot_string(rhs->get_identifier())) : godot::String {}); +} + MenuSingleton::sort_func_t MenuSingleton::_get_population_menu_sort_func(population_menu_t::PopSortKey sort_key) const { using enum population_menu_t::PopSortKey; switch (sort_key) { @@ -409,23 +421,19 @@ MenuSingleton::sort_func_t MenuSingleton::_get_population_menu_sort_func(populat }; case SORT_TYPE: return [this](Pop const* a, Pop const* b) -> bool { - return tr(std_view_to_godot_string(a->get_type().get_identifier())) - < tr(std_view_to_godot_string(b->get_type().get_identifier())); + return compare_translated_identifiers(*this, a->get_type(), b->get_type()); }; case SORT_CULTURE: return [this](Pop const* a, Pop const* b) -> bool { - return tr(std_view_to_godot_string(a->get_culture().get_identifier())) - < tr(std_view_to_godot_string(b->get_culture().get_identifier())); + return compare_translated_identifiers(*this, a->get_culture(), b->get_culture()); }; case SORT_RELIGION: return [this](Pop const* a, Pop const* b) -> bool { - return tr(std_view_to_godot_string(a->get_religion().get_identifier())) - < tr(std_view_to_godot_string(b->get_religion().get_identifier())); + return compare_translated_identifiers(*this, a->get_religion(), b->get_religion()); }; case SORT_LOCATION: return [this](Pop const* a, Pop const* b) -> bool { - return tr(a->get_location() != nullptr ? std_view_to_godot_string(a->get_location()->get_identifier()) : String {}) - < tr(b->get_location() != nullptr ? std_view_to_godot_string(b->get_location()->get_identifier()) : String {}); + return compare_translated_identifiers(*this, a->get_location(), b->get_location()); }; case SORT_MILITANCY: return [](Pop const* a, Pop const* b) -> bool { @@ -464,7 +472,11 @@ MenuSingleton::sort_func_t MenuSingleton::_get_population_menu_sort_func(populat return a->get_luxury_needs_fulfilled() < b->get_luxury_needs_fulfilled(); }; case SORT_REBEL_FACTION: - return [](Pop const* a, Pop const* b) -> bool { return false; }; // TODO - implement + return [this](Pop const* a, Pop const* b) -> bool { + // TODO - include country adjective for [pan-]nationalist rebels + // TODO - handle social/political reform movements + return compare_translated_identifiers(*this, a->get_rebel_type(), b->get_rebel_type()); + }; case SORT_SIZE_CHANGE: return [](Pop const* a, Pop const* b) -> bool { return a->get_total_change() < b->get_total_change(); @@ -566,7 +578,10 @@ TypedArray<Dictionary> MenuSingleton::get_population_menu_pop_rows(int32_t start static const StringName pop_luxury_needs_key = "luxury_needs"; // TODO - goods not available on market or goods not affordale + price (for all 3 needs types) - // TODO - rebel faction icon and name/description + static const StringName pop_rebel_icon_key = "rebel_icon"; + // TODO - rebel faction name/description + // TODO - icons for social/political reform movements + // TODO - flags for country-related rebels static const StringName pop_size_change_key = "size_change"; // TODO - size change breakdown @@ -585,8 +600,9 @@ TypedArray<Dictionary> MenuSingleton::get_population_menu_pop_rows(int32_t start pop_dict[pop_type_icon_key] = pop->get_type().get_sprite(); pop_dict[pop_culture_key] = std_view_to_godot_string(pop->get_culture().get_identifier()); pop_dict[pop_religion_icon_key] = pop->get_religion().get_icon(); - pop_dict[pop_location_key] = - pop->get_location() != nullptr ? std_view_to_godot_string(pop->get_location()->get_identifier()) : String {}; + if (pop->get_location() != nullptr) { + pop_dict[pop_location_key] = std_view_to_godot_string(pop->get_location()->get_identifier()); + } pop_dict[pop_militancy_key] = pop->get_militancy().to_float(); pop_dict[pop_consciousness_key] = pop->get_consciousness().to_float(); pop_dict[pop_ideology_key] = GFXPieChartTexture::distribution_to_slices_array(pop->get_ideologies()); @@ -596,6 +612,9 @@ TypedArray<Dictionary> MenuSingleton::get_population_menu_pop_rows(int32_t start pop_dict[pop_life_needs_key] = pop->get_life_needs_fulfilled().to_float(); pop_dict[pop_everyday_needs_key] = pop->get_everyday_needs_fulfilled().to_float(); pop_dict[pop_luxury_needs_key] = pop->get_luxury_needs_fulfilled().to_float(); + if (pop->get_rebel_type() != nullptr) { + pop_dict[pop_rebel_icon_key] = pop->get_rebel_type()->get_icon(); + } pop_dict[pop_size_change_key] = pop->get_total_change(); pop_dict[pop_literacy_key] = pop->get_literacy().to_float(); diff --git a/extension/src/openvic-extension/utility/Utilities.cpp b/extension/src/openvic-extension/utility/Utilities.cpp index 4389e95..694b658 100644 --- a/extension/src/openvic-extension/utility/Utilities.cpp +++ b/extension/src/openvic-extension/utility/Utilities.cpp @@ -13,7 +13,7 @@ using namespace OpenVic; /* Int to 2 decimal place string in terms of the largest suffix less than or equal to it, * or normal integer string if less than the smallest suffix. */ -String Utilities::int_to_formatted_string(int64_t val) { +String Utilities::int_to_string_suffixed(int64_t val) { static const std::vector<std::pair<int64_t, String>> suffixes { { 1'000'000'000'000, "T" }, { 1'000'000'000, "B" }, @@ -36,8 +36,30 @@ String Utilities::int_to_formatted_string(int64_t val) { return (negative ? "-" : "") + String::num_int64(val); } +String Utilities::float_to_string_suffixed(float val) { + const float abs_val = std::abs(val); + + if (abs_val < 10'000.0f) { + return float_to_string_dp(val, 1); + } + + if (abs_val < 1'000'000.0f) { + return float_to_string_dp(val / 1'000.0f, 2) + "k"; + } + + if (abs_val < 1'000'000'000.0f) { + return float_to_string_dp(val / 1'000'000.0f, 2) + "M"; + } + + if (abs_val < 1'000'000'000'000.0f) { + return float_to_string_dp(val / 1'000'000'000.0f, 2) + "B"; + } + + return float_to_string_dp(val / 1'000'000'000'000.0f, 2) + "T"; +} + /* Float to string formatted with the specified number of decimal places. */ -String Utilities::float_to_formatted_string(float val, int32_t decimal_places) { +String Utilities::float_to_string_dp(float val, int32_t decimal_places) { return String::num(val, decimal_places).pad_decimals(decimal_places); } diff --git a/extension/src/openvic-extension/utility/Utilities.hpp b/extension/src/openvic-extension/utility/Utilities.hpp index 15ff6b6..0cd9edc 100644 --- a/extension/src/openvic-extension/utility/Utilities.hpp +++ b/extension/src/openvic-extension/utility/Utilities.hpp @@ -33,9 +33,11 @@ namespace OpenVic::Utilities { return std_to_godot_string_name(static_cast<std::string>(str)); } - godot::String int_to_formatted_string(int64_t val); + godot::String int_to_string_suffixed(int64_t val); - godot::String float_to_formatted_string(float val, int32_t decimal_places); + godot::String float_to_string_suffixed(float val); + + godot::String float_to_string_dp(float val, int32_t decimal_places); constexpr real_t to_real_t(std::floating_point auto val) { return static_cast<real_t>(val); @@ -83,4 +85,4 @@ namespace OpenVic::Utilities { namespace literals { constexpr real_t operator""_real(long double val) { return to_real_t(val); } } -}
\ No newline at end of file +} diff --git a/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd b/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd index 5de2d25..15f8dca 100644 --- a/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd +++ b/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd @@ -49,9 +49,13 @@ var _pop_list_cash_labels : Array[Label] var _pop_list_life_needs_progressbars : Array[TextureProgressBar] var _pop_list_everyday_needs_progressbars : Array[TextureProgressBar] var _pop_list_luxury_needs_progressbars : Array[TextureProgressBar] +var _pop_list_rebel_texture_rects : Array[TextureRect] var _pop_list_rebel_icons : Array[GFXSpriteTexture] +var _pop_list_social_movement_texture_rects : Array[TextureRect] var _pop_list_social_movement_icons : Array[GFXSpriteTexture] +var _pop_list_political_movement_texture_rects : Array[TextureRect] var _pop_list_political_movement_icons : Array[GFXSpriteTexture] +var _pop_list_national_movement_texture_rects : Array[TextureRect] var _pop_list_national_movement_flags : Array[GFXMaskedFlagTexture] var _pop_list_size_change_icons : Array[GFXSpriteTexture] var _pop_list_literacy_labels : Array[Label] @@ -357,13 +361,33 @@ func _setup_pop_list() -> void: _pop_list_luxury_needs_progressbars.push_back(GUINode.get_progress_bar_from_node(pop_row_panel.get_node(^"./luxneed_progress"))) - _pop_list_rebel_icons.push_back(GUINode.get_gfx_sprite_texture_from_node(pop_row_panel.get_node(^"./pop_revolt"))) + var pop_list_rebel_texture_rect : TextureRect = GUINode.get_texture_rect_from_node(pop_row_panel.get_node(^"./pop_revolt")) + _pop_list_rebel_texture_rects.push_back(pop_list_rebel_texture_rect) + if pop_list_rebel_texture_rect: + _pop_list_rebel_icons.push_back(GUINode.get_gfx_sprite_texture_from_node(pop_list_rebel_texture_rect)) + else: + _pop_list_rebel_icons.push_back(null) - _pop_list_social_movement_icons.push_back(GUINode.get_gfx_sprite_texture_from_node(pop_row_panel.get_node(^"./pop_movement_social"))) + var pop_list_social_movement_texture_rect : TextureRect = GUINode.get_texture_rect_from_node(pop_row_panel.get_node(^"./pop_movement_social")) + _pop_list_social_movement_texture_rects.push_back(pop_list_social_movement_texture_rect) + if pop_list_social_movement_texture_rect: + _pop_list_social_movement_icons.push_back(GUINode.get_gfx_sprite_texture_from_node(pop_list_social_movement_texture_rect)) + else: + _pop_list_social_movement_icons.push_back(null) - _pop_list_political_movement_icons.push_back(GUINode.get_gfx_sprite_texture_from_node(pop_row_panel.get_node(^"./pop_movement_political"))) + var pop_list_political_movement_texture_rect : TextureRect = GUINode.get_texture_rect_from_node(pop_row_panel.get_node(^"./pop_movement_political")) + _pop_list_political_movement_texture_rects.push_back(pop_list_political_movement_texture_rect) + if pop_list_political_movement_texture_rect: + _pop_list_political_movement_icons.push_back(GUINode.get_gfx_sprite_texture_from_node(pop_list_political_movement_texture_rect)) + else: + _pop_list_political_movement_icons.push_back(null) - _pop_list_national_movement_flags.push_back(GUINode.get_gfx_masked_flag_texture_from_node(pop_row_panel.get_node(^"./pop_movement_flag"))) + var pop_list_national_movement_texture_rect : TextureRect = GUINode.get_texture_rect_from_node(pop_row_panel.get_node(^"./pop_movement_flag")) + _pop_list_national_movement_texture_rects.push_back(pop_list_national_movement_texture_rect) + if pop_list_national_movement_texture_rect: + _pop_list_national_movement_flags.push_back(GUINode.get_gfx_masked_flag_texture_from_node(pop_list_national_movement_texture_rect)) + else: + _pop_list_national_movement_flags.push_back(null) _pop_list_size_change_icons.push_back(GUINode.get_gfx_sprite_texture_from_node(pop_row_panel.get_node(^"./growth_indicator"))) @@ -436,7 +460,7 @@ func _update_province_list(scroll_index : int = -1) -> void: ) if _province_list_size_labels[index]: - _province_list_size_labels[index].set_text(GUINode.int_to_formatted_string(province_list_info[size_key])) + _province_list_size_labels[index].set_text(GUINode.int_to_string_suffixed(province_list_info[size_key])) if _province_list_growth_icons[index]: _province_list_growth_icons[index].set_icon_index(get_growth_icon_index(province_list_info[change_key])) @@ -529,7 +553,7 @@ func _update_distributions(): var weight_label : Label = GUINode.get_label_from_node(child.get_node(^"./legend_value")) if weight_label: - weight_label.set_text("%s%%" % GUINode.float_to_formatted_string(distribution_row[slice_weight_key] * 100.0, 1)) + weight_label.set_text("%s%%" % GUINode.float_to_string_dp(distribution_row[slice_weight_key] * 100.0, 1)) func _update_pop_list() -> void: if _pop_list_scrollbar: @@ -561,13 +585,14 @@ func _update_pop_list() -> void: const pop_life_needs_key : StringName = &"life_needs" const pop_everyday_needs_key : StringName = &"everyday_needs" const pop_luxury_needs_key : StringName = &"luxury_needs" + const pop_rebel_icon_key : StringName = &"rebel_icon" const pop_size_change_key : StringName = &"size_change" const pop_literacy_key : StringName = &"literacy" var pop_row : Dictionary = pop_rows[index] if _pop_list_size_labels[index]: - _pop_list_size_labels[index].set_text(GUINode.int_to_formatted_string(pop_row[pop_size_key])) + _pop_list_size_labels[index].set_text(GUINode.int_to_string_suffixed(pop_row[pop_size_key])) if _pop_list_type_icons[index]: _pop_list_type_icons[index].set_icon_index(pop_row[pop_type_icon_key]) if _pop_list_culture_labels[index]: @@ -575,11 +600,11 @@ func _update_pop_list() -> void: if _pop_list_religion_icons[index]: _pop_list_religion_icons[index].set_icon_index(pop_row[pop_religion_icon_key]) if _pop_list_location_labels[index]: - _pop_list_location_labels[index].set_text(GUINode.format_province_name(pop_row[pop_location_key])) + _pop_list_location_labels[index].set_text(GUINode.format_province_name(pop_row.get(pop_location_key, ""))) if _pop_list_militancy_labels[index]: - _pop_list_militancy_labels[index].set_text(GUINode.float_to_formatted_string(pop_row[pop_militancy_key], 2)) + _pop_list_militancy_labels[index].set_text(GUINode.float_to_string_dp(pop_row[pop_militancy_key], 2)) if _pop_list_consciousness_labels[index]: - _pop_list_consciousness_labels[index].set_text(GUINode.float_to_formatted_string(pop_row[pop_consciousness_key], 2)) + _pop_list_consciousness_labels[index].set_text(GUINode.float_to_string_dp(pop_row[pop_consciousness_key], 2)) if _pop_list_ideology_charts[index]: _pop_list_ideology_charts[index].set_slices_array(pop_row[pop_ideology_key]) if _pop_list_issues_charts[index]: @@ -587,17 +612,34 @@ func _update_pop_list() -> void: if _pop_list_unemployment_progressbars[index]: _pop_list_unemployment_progressbars[index].set_value_no_signal(pop_row[pop_unemployment_key]) if _pop_list_cash_labels[index]: - _pop_list_cash_labels[index].set_text(GUINode.float_to_formatted_string(pop_row[pop_cash_key], 2)) + _pop_list_cash_labels[index].set_text(GUINode.float_to_string_dp(pop_row[pop_cash_key], 2)) if _pop_list_life_needs_progressbars[index]: _pop_list_life_needs_progressbars[index].set_value_no_signal(pop_row[pop_life_needs_key]) if _pop_list_everyday_needs_progressbars[index]: _pop_list_everyday_needs_progressbars[index].set_value_no_signal(pop_row[pop_everyday_needs_key]) if _pop_list_luxury_needs_progressbars[index]: _pop_list_luxury_needs_progressbars[index].set_value_no_signal(pop_row[pop_luxury_needs_key]) + if _pop_list_rebel_texture_rects[index]: + var rebel_icon : int = pop_row.get(pop_rebel_icon_key, 0) + if rebel_icon > 0: + if _pop_list_rebel_icons[index]: + _pop_list_rebel_icons[index].set_icon_index(rebel_icon) + _pop_list_rebel_texture_rects[index].show() + else: + _pop_list_rebel_texture_rects[index].hide() + + # TODO - handle social/political reform and country rebels + if _pop_list_social_movement_texture_rects[index]: + _pop_list_social_movement_texture_rects[index].hide() + if _pop_list_political_movement_texture_rects[index]: + _pop_list_political_movement_texture_rects[index].hide() + if _pop_list_national_movement_texture_rects[index]: + _pop_list_national_movement_texture_rects[index].hide() + if _pop_list_size_change_icons[index]: _pop_list_size_change_icons[index].set_icon_index(get_growth_icon_index(pop_row[pop_size_change_key])) if _pop_list_literacy_labels[index]: - _pop_list_literacy_labels[index].set_text("%s%%" % GUINode.float_to_formatted_string(pop_row[pop_literacy_key], 2)) + _pop_list_literacy_labels[index].set_text("%s%%" % GUINode.float_to_string_dp(pop_row[pop_literacy_key], 2)) _pop_list_rows[index].show() else: diff --git a/game/src/Game/GameSession/ProvinceOverviewPanel.gd b/game/src/Game/GameSession/ProvinceOverviewPanel.gd index 42f6765..fd089e7 100644 --- a/game/src/Game/GameSession/ProvinceOverviewPanel.gd +++ b/game/src/Game/GameSession/ProvinceOverviewPanel.gd @@ -176,7 +176,6 @@ func _ready() -> void: if population_menu_button: population_menu_button.pressed.connect( func() -> void: - pass MenuSingleton.population_menu_select_province(_selected_index) _on_close_button_pressed() Events.NationManagementScreens.open_nation_management_screen(NationManagement.Screen.POPULATION) @@ -323,14 +322,14 @@ func _update_info() -> void: if _rgo_income_label: # TODO - add £ sign and replace placeholder with actual value - _rgo_income_label.text = GUINode.float_to_formatted_string(12.34567, 3) + _rgo_income_label.text = "%s £" % GUINode.float_to_string_dp(12.34567, 3) if _rgo_employment_percentage_texture: pass if _rgo_employment_population_label: # TODO - replace placeholder with actual value - _rgo_employment_population_label.text = GUINode.int_to_formatted_string(_province_info.get(_province_info_total_population_key, 0) / 10) + _rgo_employment_population_label.text = GUINode.int_to_string_suffixed(_province_info.get(_province_info_total_population_key, 0) / 10) if _rgo_employment_percentage_label: pass @@ -345,7 +344,7 @@ func _update_info() -> void: pass if _total_population_label: - _total_population_label.text = GUINode.int_to_formatted_string(_province_info.get(_province_info_total_population_key, 0)) + _total_population_label.text = GUINode.int_to_string_suffixed(_province_info.get(_province_info_total_population_key, 0)) if _migration_label: pass diff --git a/game/src/Game/GameSession/Topbar.gd b/game/src/Game/GameSession/Topbar.gd index 8da15e0..c1fde1c 100644 --- a/game/src/Game/GameSession/Topbar.gd +++ b/game/src/Game/GameSession/Topbar.gd @@ -1,19 +1,85 @@ extends GUINode -@export var _outliner_guinode : GUINode +# Country info +var _country_flag_texture : GFXMaskedFlagTexture +var _country_flag_overlay_texture : GFXSpriteTexture +var _country_name_label : Label +var _country_rank_label : Label +var _country_prestige_label : Label +var _country_prestige_rank_label : Label +var _country_industrial_power_label : Label +var _country_industrial_power_rank_label : Label +var _country_military_power_label : Label +var _country_military_power_rank_label : Label +var _country_colonial_power_label : Label +# Time controls var _speed_up_button : Button var _speed_down_button : Button -var _speed_indicator_button : Button var _speed_indicator_texture : GFXSpriteTexture var _date_label : Label -var _country_name_label : Label # NationManagement.Screen-Button var _nation_management_buttons : Dictionary # NationManagement.Screen-GFXSpriteTexture var _nation_management_button_textures : Dictionary +# Production +var _production_top_goods_textures : Array[GFXSpriteTexture] +var _production_alert_building_texture : GFXSpriteTexture +var _production_alert_closed_texture : GFXSpriteTexture +var _production_alert_unemployment_texture : GFXSpriteTexture + +# Budget +# TODO - line chart +var _budget_funds_label : Label + +# Technology +var _technology_progress_bar : TextureProgressBar +var _technology_current_research_label : Label +var _technology_literacy_label : Label +var _technology_research_points_label : Label + +# Politics +var _politics_party_icon : TextureRect +var _politics_party_label : Label +var _politics_suppression_points_label : Label +var _politics_infamy_label : Label +var _politics_reforms_texture : GFXSpriteTexture +var _politics_decisions_texture : GFXSpriteTexture +var _politics_election_texture : GFXSpriteTexture +var _politics_rebels_texture : GFXSpriteTexture + +# Population +var _population_total_size_label : Label +var _population_national_foci_label : Label +var _population_militancy_label : Label +var _population_consciousness_label : Label + +# Trade +var _trade_imported_textures : Array[GFXSpriteTexture] +var _trade_exported_textures : Array[GFXSpriteTexture] + +# Diplomacy +var _diplomacy_peace_label : Label +var _diplomacy_war_enemies_overlapping_elements_box : GUIOverlappingElementsBox +var _diplomacy_diplomatic_points_label : Label +var _diplomacy_alert_colony_texture : GFXSpriteTexture +var _diplomacy_alert_crisis_texture : GFXSpriteTexture +var _diplomacy_alert_sphere_texture : GFXSpriteTexture +var _diplomacy_alert_great_power_texture : GFXSpriteTexture + +# Military +var _military_army_size_label : Label +var _military_navy_size_label : Label +var _military_mobilisation_size_label : Label +var _military_leadership_points_label : Label + +# TODO - use GFX file font colour codes +const FONT_GREEN : Color = Color("009F03") +const FONT_RED : Color = Color("FF3232") +const FONT_YELLOW : Color = Color("FFBD00") + func _ready() -> void: GameSingleton.gamestate_updated.connect(_update_info) GameSingleton.clock_state_changed.connect(_update_speed_controls) @@ -25,43 +91,48 @@ func _ready() -> void: ^"./topbar/topbar_outlinerbutton" ]) - const player_country : String = "SLV" - # Disables all consuming invisible panel var topbar := get_panel_from_nodepath(^"./topbar") if topbar: topbar.mouse_filter = Control.MOUSE_FILTER_IGNORE set_click_mask_from_nodepaths([^"./topbar/topbar_bg", ^"./topbar/topbar_paper"]) - # Player country info - var player_flag_texture : GFXMaskedFlagTexture = get_gfx_masked_flag_texture_from_nodepath(^"./topbar/player_flag") - if player_flag_texture: - player_flag_texture.set_flag_country_name(player_country) + # Country info + var country_flag_button = get_button_from_nodepath(^"./topbar/player_flag") + if country_flag_button: + country_flag_button.pressed.connect( + func() -> void: + # TODO - open the diplomacy menu on the Wars tab + Events.NationManagementScreens.open_nation_management_screen(NationManagement.Screen.DIPLOMACY) + ) + _country_flag_texture = GUINode.get_gfx_masked_flag_texture_from_node(country_flag_button) + _country_flag_overlay_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/topbar_flag_overlay") + _country_name_label = get_label_from_nodepath(^"./topbar/CountryName") + _country_rank_label = get_label_from_nodepath(^"./topbar/nation_totalrank") + _country_prestige_label = get_label_from_nodepath(^"./topbar/country_prestige") + _country_prestige_rank_label = get_label_from_nodepath(^"./topbar/selected_prestige_rank") + _country_industrial_power_label = get_label_from_nodepath(^"./topbar/country_economic") + _country_industrial_power_rank_label = get_label_from_nodepath(^"./topbar/selected_industry_rank") + _country_military_power_label = get_label_from_nodepath(^"./topbar/country_military") + _country_military_power_rank_label = get_label_from_nodepath(^"./topbar/selected_military_rank") + _country_colonial_power_label = get_label_from_nodepath(^"./topbar/country_colonial_power") # Time controls _speed_up_button = get_button_from_nodepath(^"./topbar/button_speedup") if _speed_up_button: _speed_up_button.pressed.connect(_on_increase_speed_button_pressed) - _speed_down_button = get_button_from_nodepath(^"./topbar/button_speeddown") if _speed_down_button: _speed_down_button.pressed.connect(_on_decrease_speed_button_pressed) - var pause_bg_button : Button = get_button_from_nodepath(^"./topbar/pause_bg") if pause_bg_button: pause_bg_button.pressed.connect(_on_play_pause_button_pressed) - + var speed_indicator_button = get_button_from_nodepath(^"./topbar/speed_indicator") + if speed_indicator_button: + speed_indicator_button.pressed.connect(_on_play_pause_button_pressed) + _speed_indicator_texture = GUINode.get_gfx_sprite_texture_from_node(speed_indicator_button) _date_label = get_label_from_nodepath(^"./topbar/DateText") - _country_name_label = get_label_from_nodepath(^"./topbar/CountryName") - if _country_name_label: - _country_name_label.text = player_country - - _speed_indicator_button = get_button_from_nodepath(^"./topbar/speed_indicator") - if _speed_indicator_button: - _speed_indicator_button.pressed.connect(_on_play_pause_button_pressed) - _speed_indicator_texture = GUINode.get_gfx_sprite_texture_from_node(_speed_indicator_button) - # Nation management screens const screen_nodepaths : Dictionary = { NationManagement.Screen.PRODUCTION : ^"./topbar/topbarbutton_production", @@ -87,6 +158,117 @@ func _ready() -> void: _on_update_active_nation_management_screen ) + # Production + const PRODUCED_GOOD_COUNT : int = 5 + for idx in PRODUCED_GOOD_COUNT: + _production_top_goods_textures.push_back(get_gfx_sprite_texture_from_nodepath("./topbar/topbar_produced%d" % idx)) + _production_alert_building_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/alert_building_factories") + _production_alert_closed_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/alert_closed_factories") + _production_alert_unemployment_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/alert_unemployed_workers") + + # Budget + _budget_funds_label = get_label_from_nodepath(^"./topbar/budget_funds") + + # Technology + _technology_progress_bar = get_progress_bar_from_nodepath(^"./topbar/topbar_tech_progress") + _technology_current_research_label = get_label_from_nodepath(^"./topbar/tech_current_research") + _technology_literacy_label = get_label_from_nodepath(^"./topbar/tech_literacy_value") + if _technology_literacy_label: + _technology_literacy_label.add_theme_color_override(&"font_color", FONT_YELLOW) + _technology_research_points_label = get_label_from_nodepath(^"./topbar/topbar_researchpoints_value") + if _technology_research_points_label: + _technology_research_points_label.add_theme_color_override(&"font_color", FONT_YELLOW) + + # Politics + _politics_party_icon = get_texture_rect_from_nodepath(^"./topbar/politics_party_icon") + _politics_party_label = get_label_from_nodepath(^"./topbar/politics_ruling_party") + var politics_suppression_button : Button = get_button_from_nodepath(^"./topbar/topbar_supression_icon") + if politics_suppression_button: + politics_suppression_button.pressed.connect( + func() -> void: + # TODO - open the politics menu on the Movements tab + Events.NationManagementScreens.toggle_nation_management_screen(NationManagement.Screen.POLITICS) + ) + _politics_suppression_points_label = get_label_from_nodepath(^"./topbar/politics_supressionpoints_value") + if _politics_suppression_points_label: + _politics_suppression_points_label.add_theme_color_override(&"font_color", FONT_YELLOW) + _politics_infamy_label = get_label_from_nodepath(^"./topbar/politics_infamy_value") + if _politics_infamy_label: + _politics_infamy_label.add_theme_color_override(&"font_color", FONT_YELLOW) + var politics_reforms_button : Button = get_button_from_nodepath(^"./topbar/alert_can_do_reforms") + if politics_reforms_button: + politics_reforms_button.pressed.connect( + func() -> void: + # TODO - open the politics menu on the Reforms tab + Events.NationManagementScreens.toggle_nation_management_screen(NationManagement.Screen.POLITICS) + ) + _politics_reforms_texture = GUINode.get_gfx_sprite_texture_from_node(politics_reforms_button) + var politics_decisions_button : Button = get_button_from_nodepath(^"./topbar/alert_can_do_decisions") + if politics_decisions_button: + politics_decisions_button.pressed.connect( + func() -> void: + # TODO - open the politics menu on the Decisions tab + Events.NationManagementScreens.toggle_nation_management_screen(NationManagement.Screen.POLITICS) + ) + _politics_decisions_texture = GUINode.get_gfx_sprite_texture_from_node(politics_decisions_button) + _politics_election_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/alert_is_in_election") + var politics_rebels_button : Button = get_button_from_nodepath(^"./topbar/alert_have_rebels") + if politics_rebels_button: + politics_rebels_button.pressed.connect( + func() -> void: + # TODO - open the politics menu on the Movements tab + Events.NationManagementScreens.toggle_nation_management_screen(NationManagement.Screen.POLITICS) + ) + _politics_rebels_texture = GUINode.get_gfx_sprite_texture_from_node(politics_rebels_button) + + # Population + _population_total_size_label = get_label_from_nodepath(^"./topbar/population_total_value") + _population_national_foci_label = get_label_from_nodepath(^"./topbar/topbar_focus_value") + _population_militancy_label = get_label_from_nodepath(^"./topbar/population_avg_mil_value") + if _population_militancy_label: + _population_militancy_label.add_theme_color_override(&"font_color", FONT_YELLOW) + _population_consciousness_label = get_label_from_nodepath(^"./topbar/population_avg_con_value") + if _population_consciousness_label: + _population_consciousness_label.add_theme_color_override(&"font_color", FONT_YELLOW) + + # Trade + const TRADE_GOOD_COUNT : int = 3 + for idx in TRADE_GOOD_COUNT: + _trade_imported_textures.push_back(get_gfx_sprite_texture_from_nodepath("./topbar/topbar_import%d" % idx)) + _trade_exported_textures.push_back(get_gfx_sprite_texture_from_nodepath("./topbar/topbar_export%d" % idx)) + + # Diplomacy + _diplomacy_peace_label = get_label_from_nodepath(^"./topbar/diplomacy_status") + _diplomacy_war_enemies_overlapping_elements_box = get_gui_overlapping_elements_box_from_nodepath(^"./topbar/diplomacy_at_war") + _diplomacy_diplomatic_points_label = get_label_from_nodepath(^"./topbar/diplomacy_diplopoints_value") + if _diplomacy_diplomatic_points_label: + _diplomacy_diplomatic_points_label.add_theme_color_override(&"font_color", FONT_YELLOW) + var diplomacy_alert_colony_button : Button = get_button_from_nodepath(^"./topbar/alert_colony") + if diplomacy_alert_colony_button: + diplomacy_alert_colony_button.pressed.connect( + func() -> void: + # TODO - move to and select province in upgradable colony if any exist + Events.NationManagementScreens.open_nation_management_screen(NationManagement.Screen.DIPLOMACY) + ) + _diplomacy_alert_colony_texture = GUINode.get_gfx_sprite_texture_from_node(diplomacy_alert_colony_button) + _diplomacy_alert_crisis_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/alert_crisis") + _diplomacy_alert_sphere_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/alert_can_increase_opinion") + _diplomacy_alert_great_power_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/alert_loosing_gp") + + # Military + _military_army_size_label = get_label_from_nodepath(^"./topbar/military_army_value") + if _military_army_size_label: + _military_army_size_label.add_theme_color_override(&"font_color", FONT_YELLOW) + _military_navy_size_label = get_label_from_nodepath(^"./topbar/military_navy_value") + if _military_navy_size_label: + _military_navy_size_label.add_theme_color_override(&"font_color", FONT_YELLOW) + _military_mobilisation_size_label = get_label_from_nodepath(^"./topbar/military_manpower_value") + if _military_mobilisation_size_label: + _military_mobilisation_size_label.add_theme_color_override(&"font_color", FONT_YELLOW) + _military_leadership_points_label = get_label_from_nodepath(^"./topbar/military_leadership_value") + if _military_leadership_points_label: + _military_leadership_points_label.add_theme_color_override(&"font_color", FONT_YELLOW) + _update_info() _update_speed_controls() @@ -96,9 +278,196 @@ func _notification(what : int) -> void: _update_info() func _update_info() -> void: + # Placeholder data + const player_country : String = "ENG" + + ## Country info + if _country_flag_texture: + _country_flag_texture.set_flag_country_name(player_country) + + if _country_flag_overlay_texture: + # 1 - Great Power + # 2 - Secondary Power + # 3 - Civilised + # 4 - Uncivilised + _country_flag_overlay_texture.set_icon_index(1) + + if _country_name_label: + _country_name_label.set_text(player_country) + + if _country_rank_label: + # TODO - fix label alignment + _country_rank_label.set_text(" %d" % 1) + + if _country_prestige_label: + _country_prestige_label.set_text(str(11)) + + if _country_prestige_rank_label: + _country_prestige_rank_label.set_text(str(1)) + + if _country_industrial_power_label: + _country_industrial_power_label.set_text(str(22)) + + if _country_industrial_power_rank_label: + _country_industrial_power_rank_label.set_text(str(2)) + + if _country_military_power_label: + _country_military_power_label.set_text(str(33)) + + if _country_military_power_rank_label: + _country_military_power_rank_label.set_text(str(3)) + + if _country_colonial_power_label: + # TODO - colour (first number is red if non-positive) + _country_colonial_power_label.set_text("%s/%s" % [123, 456]) + + ## Time control if _date_label: _date_label.text = MenuSingleton.get_longform_date() + ## Production + for idx : int in _production_top_goods_textures.size(): + if _production_top_goods_textures[idx]: + _production_top_goods_textures[idx].set_icon_index(idx + 2) + + if _production_alert_building_texture: + _production_alert_building_texture.set_icon_index(2) + + if _production_alert_closed_texture: + _production_alert_closed_texture.set_icon_index(2) + + if _production_alert_unemployment_texture: + _production_alert_unemployment_texture.set_icon_index(2) + + ## Budget + if _budget_funds_label: + var cash : float = 0.0 + var earnings : float = 0.0 + _budget_funds_label.set_text("%s £ (%s%s £ )" % [ + GUINode.float_to_string_suffixed(cash), + "+" if earnings >= 0.0 else "", + GUINode.float_to_string_suffixed(earnings) + ]) + # TODO - set colours: cash yellow, earnings red (-), yellow (0) or green (+) + _budget_funds_label.add_theme_color_override(&"font_color", FONT_YELLOW) + + ## Technology + if _technology_progress_bar: + pass # TODO - set tech progress + + if _technology_current_research_label: + # TODO - set current research or "unciv_nation" (in red) if uncivilised + # TODO - process colour markers in localisation for "TB_TECH_NO_CURRENT" + + # Remove § symbols + colour codes from string + var no_research : String = tr("TB_TECH_NO_CURRENT") + while true: + const COLOUR_CHAR : String = "\u00A7" + var pos : int = no_research.find(COLOUR_CHAR) + if pos >= 0: + no_research = no_research.erase(pos, 2) + else: + break + + _technology_current_research_label.set_text(no_research) + _technology_current_research_label.add_theme_color_override(&"font_color", FONT_RED) + + if _technology_literacy_label: + _technology_literacy_label.set_text("%s%%" % GUINode.float_to_string_dp(80.0, 1)) + + if _technology_research_points_label: + _technology_research_points_label.set_text(GUINode.float_to_string_dp(10.0, 2)) + + ## Politics + if _politics_party_icon: + _politics_party_icon.set_modulate(Color(1.0, 1.0, 0.0)) + + if _politics_party_label: + _politics_party_label.set_text("ENG_liberal") + + if _politics_suppression_points_label: + _politics_suppression_points_label.set_text(GUINode.float_to_string_dp(2.5, 1)) + + if _politics_infamy_label: + _politics_infamy_label.set_text(GUINode.float_to_string_dp(0.0, 2)) + + if _politics_reforms_texture: + _politics_reforms_texture.set_icon_index(2) + + if _politics_decisions_texture: + _politics_decisions_texture.set_icon_index(2) + + if _politics_election_texture: + _politics_election_texture.set_icon_index(2) + + if _politics_rebels_texture: + _politics_rebels_texture.set_icon_index(2) + + ## Population + if _population_total_size_label: + _population_total_size_label.set_text("%s(%s)" % [ + GUINode.int_to_string_suffixed(16000000), + GUINode.int_to_string_suffixed(1500), + ]) + + # TODO - set colours: yellow total population number, green or red change number (both numbers with a white suffix!) + _population_total_size_label.add_theme_color_override(&"font_color", FONT_YELLOW) + + if _population_national_foci_label: + var foci_used : int = 1 + var max_foci : int = 1 + _population_national_foci_label.set_text("%d/%d" % [foci_used, max_foci]) + _population_national_foci_label.add_theme_color_override(&"font_color", FONT_RED if foci_used < max_foci else FONT_GREEN) + + if _population_militancy_label: + _population_militancy_label.set_text(GUINode.float_to_string_dp(1.5, 2)) + + if _population_consciousness_label: + _population_consciousness_label.set_text(GUINode.float_to_string_dp(0.05, 2)) + + ## Trade + for idx : int in _trade_imported_textures.size(): + if _trade_imported_textures[idx]: + _trade_imported_textures[idx].set_icon_index(idx + 2 + _production_top_goods_textures.size()) + + for idx : int in _trade_exported_textures.size(): + if _trade_exported_textures[idx]: + _trade_exported_textures[idx].set_icon_index(idx + 2 + _production_top_goods_textures.size() + _trade_imported_textures.size()) + + ## Diplomacy + if _diplomacy_peace_label: + _diplomacy_peace_label.set_text("TOPBAR_AT_PEACE") + + # TODO - add war enemy flags to _diplomacy_war_enemies_overlapping_elements_box + + if _diplomacy_diplomatic_points_label: + _diplomacy_diplomatic_points_label.set_text(GUINode.float_to_string_dp(7.4, 0)) + + if _diplomacy_alert_colony_texture: + _diplomacy_alert_colony_texture.set_icon_index(3) + + if _diplomacy_alert_crisis_texture: + _diplomacy_alert_crisis_texture.set_icon_index(3) + + if _diplomacy_alert_sphere_texture: + _diplomacy_alert_sphere_texture.set_icon_index(2) + + if _diplomacy_alert_great_power_texture: + _diplomacy_alert_great_power_texture.set_icon_index(2) + + ## Military + if _military_army_size_label: + _military_army_size_label.set_text("%d/%d" % [57, 120]) + + if _military_navy_size_label: + _military_navy_size_label.set_text("%d/%d" % [123, 267]) + + if _military_mobilisation_size_label: + _military_mobilisation_size_label.set_text(str(38)) + + if _military_leadership_points_label: + _military_leadership_points_label.set_text(str(15)) + func _update_speed_controls() -> void: # TODO - decide whether to disable these or not # (they don't appear to get disabled in the base game) @@ -108,7 +477,7 @@ func _update_speed_controls() -> void: #if _speed_down_button: # _speed_down_button.disabled = not MenuSingleton.can_decrease_speed() - if _speed_indicator_button and _speed_indicator_texture: + if _speed_indicator_texture: var index : int = 1 if not MenuSingleton.is_paused(): index += MenuSingleton.get_speed() + 1 |