diff --git a/extension/doc_classes/MenuSingleton.xml b/extension/doc_classes/MenuSingleton.xml index c4e85637..83c862e6 100644 --- a/extension/doc_classes/MenuSingleton.xml +++ b/extension/doc_classes/MenuSingleton.xml @@ -155,14 +155,46 @@ + + + + + Returns the effects, point cost, unlock year, and prerequisite tech of the given technology, in a [Dictionary]. + + + + + + Returns a [Dictionary] with static defines for the technology menu. + + + + + + Returns a [Dictionary] with the dynamic state of the technology menu. + + + + + + Returns the coloured symbol used by met tooltip conditions "(*)" + + + + + + Returns the coloured symbol used by unmet tooltip conditions "(X)" + + + Returns the symbol used to separate normal and extended tooltips. @@ -254,6 +286,12 @@ + + + + + + diff --git a/extension/src/openvic-extension/singletons/GameSingleton.cpp b/extension/src/openvic-extension/singletons/GameSingleton.cpp index 37418c3a..ec4cc038 100644 --- a/extension/src/openvic-extension/singletons/GameSingleton.cpp +++ b/extension/src/openvic-extension/singletons/GameSingleton.cpp @@ -12,6 +12,7 @@ #include "openvic-extension/singletons/MenuSingleton.hpp" #include "openvic-extension/utility/ClassBindings.hpp" #include "openvic-extension/utility/Utilities.hpp" +#include "openvic-simulation/country/CountryInstance.hpp" using namespace godot; using namespace OpenVic; @@ -179,17 +180,6 @@ Error GameSingleton::setup_game(int32_t bookmark_index) { set_viewed_country(starting_country); ERR_FAIL_NULL_V(viewed_country, FAILED); - // TODO - remove this test starting research - for ( - Technology const& technology : - get_definition_manager().get_research_manager().get_technology_manager().get_technologies() - ) { - if (starting_country->can_research_tech(technology, instance_manager->get_today())) { - starting_country->start_research(technology, *instance_manager); - break; - } - } - return ERR(ret); } @@ -425,7 +415,7 @@ void GameSingleton::unset_selected_province() { set_selected_province(ProvinceDefinition::NULL_INDEX); } -void GameSingleton::set_viewed_country(CountryInstance const* new_viewed_country) { +void GameSingleton::set_viewed_country(CountryInstance* new_viewed_country) { if (viewed_country != new_viewed_country) { viewed_country = new_viewed_country; @@ -439,7 +429,7 @@ void GameSingleton::set_viewed_country_by_province_index(int32_t province_index) InstanceManager* instance_manager = get_instance_manager(); ERR_FAIL_NULL(instance_manager); - ProvinceInstance const* province_instance = + ProvinceInstance* province_instance = instance_manager->get_map_instance().get_province_instance_by_index(province_index); ERR_FAIL_NULL(province_instance); diff --git a/extension/src/openvic-extension/singletons/GameSingleton.hpp b/extension/src/openvic-extension/singletons/GameSingleton.hpp index 653d712b..c08c3459 100644 --- a/extension/src/openvic-extension/singletons/GameSingleton.hpp +++ b/extension/src/openvic-extension/singletons/GameSingleton.hpp @@ -15,7 +15,7 @@ namespace OpenVic { GameManager game_manager; - CountryInstance const* PROPERTY(viewed_country, nullptr); + CountryInstance* PROPERTY_PTR(viewed_country, nullptr); godot::Vector2i image_subdivisions; godot::Ref province_shape_texture; @@ -133,7 +133,7 @@ namespace OpenVic { void set_selected_province(int32_t index); void unset_selected_province(); - void set_viewed_country(CountryInstance const* new_viewed_country); + void set_viewed_country(CountryInstance* new_viewed_country); void set_viewed_country_by_province_index(int32_t province_index); godot::Vector2 get_viewed_country_capital_position() const; diff --git a/extension/src/openvic-extension/singletons/MenuSingleton.cpp b/extension/src/openvic-extension/singletons/MenuSingleton.cpp index 1d70b9ab..475c1154 100644 --- a/extension/src/openvic-extension/singletons/MenuSingleton.cpp +++ b/extension/src/openvic-extension/singletons/MenuSingleton.cpp @@ -1,16 +1,27 @@ #include "MenuSingleton.hpp" +#include +#include +#include +#include + #include +#include +#include -#include #include #include +#include +#include +#include +#include +#include "openvic-extension/classes/GUILabel.hpp" +#include "openvic-extension/utility/Utilities.hpp" #include "openvic-extension/classes/GFXPieChartTexture.hpp" #include "openvic-extension/classes/GUINode.hpp" #include "openvic-extension/singletons/GameSingleton.hpp" #include "openvic-extension/utility/ClassBindings.hpp" -#include "openvic-extension/utility/Utilities.hpp" using namespace godot; using namespace OpenVic; @@ -167,13 +178,17 @@ String MenuSingleton::_make_modifier_effect_value_coloured( return result; } -String MenuSingleton::_make_modifier_effects_tooltip(ModifierValue const& modifier) const { +String MenuSingleton::_make_modifier_effect_tooltip(ModifierEffect const& effect, const fixed_point_t value) const { + return tr(Utilities::std_to_godot_string(effect.get_localisation_key())) + ": " + + _make_modifier_effect_value_coloured(effect, value, true); +} + +String MenuSingleton::_make_modifier_effects_tooltip(ModifierValue const& modifiers) const { String result; - for (auto const& [effect, value] : modifier.get_values()) { + for (auto const& [effect, value] : modifiers.get_values()) { if (value != fixed_point_t::_0()) { - result += "\n" + tr(Utilities::std_to_godot_string(effect->get_localisation_key())) + ": " + - _make_modifier_effect_value_coloured(*effect, value, true); + result += "\n" + _make_modifier_effect_tooltip(*effect, value); } } @@ -315,6 +330,9 @@ String MenuSingleton::_make_mobilisation_impact_tooltip() const { void MenuSingleton::_bind_methods() { OV_BIND_SMETHOD(get_tooltip_separator); + OV_BIND_SMETHOD(get_tooltip_condition_met); + OV_BIND_SMETHOD(get_tooltip_condition_unmet); + OV_BIND_METHOD(MenuSingleton::get_country_name_from_identifier, { "country_identifier" }); OV_BIND_METHOD(MenuSingleton::get_country_adjective_from_identifier, { "country_identifier" }); @@ -431,6 +449,12 @@ void MenuSingleton::_bind_methods() { OV_BIND_METHOD(MenuSingleton::get_search_result_position, { "result_index" }); ADD_SIGNAL(MethodInfo(_signal_search_cache_changed())); + + /* TECHNOLOGY MENU */ + OV_BIND_METHOD(MenuSingleton::get_technology_menu_defines); + OV_BIND_METHOD(MenuSingleton::get_technology_menu_info); + OV_BIND_METHOD(MenuSingleton::get_specific_technology_info, { "technology_id" }); + OV_BIND_METHOD(MenuSingleton::start_research, { "technology_id" }); } MenuSingleton* MenuSingleton::get_singleton() { @@ -455,6 +479,16 @@ String MenuSingleton::get_tooltip_separator() { return tooltip_separator; } +String MenuSingleton::get_tooltip_condition_met() { + static const String condition_met = String { "(" } + GUILabel::get_colour_marker() + String { "G*" } + GUILabel::get_colour_marker() + "W)"; + return condition_met; +} + +String MenuSingleton::get_tooltip_condition_unmet() { + static const String condition_unmet = String { "(" } + GUILabel::get_colour_marker() + String { "RX" } + GUILabel::get_colour_marker() + "W)"; + return condition_unmet; +} + String MenuSingleton::get_country_name_from_identifier(String const& country_identifier) const { if (country_identifier.is_empty()) { return {}; diff --git a/extension/src/openvic-extension/singletons/MenuSingleton.hpp b/extension/src/openvic-extension/singletons/MenuSingleton.hpp index fb5b1d4d..7b656cf1 100644 --- a/extension/src/openvic-extension/singletons/MenuSingleton.hpp +++ b/extension/src/openvic-extension/singletons/MenuSingleton.hpp @@ -1,14 +1,16 @@ #pragma once -#include - #include #include +#include #include #include #include #include +#include +#include +#include namespace OpenVic { struct CountryInstance; @@ -144,6 +146,7 @@ namespace OpenVic { ModifierEffect const& format_effect, fixed_point_t value, bool plus_for_non_negative ); + godot::String _make_modifier_effect_tooltip(ModifierEffect const& effect, const fixed_point_t value) const; godot::String _make_modifier_effects_tooltip(ModifierValue const& modifier) const; template @@ -168,6 +171,9 @@ namespace OpenVic { ~MenuSingleton(); static godot::String get_tooltip_separator(); + static godot::String get_tooltip_condition_met(); + static godot::String get_tooltip_condition_unmet(); + godot::String get_country_name_from_identifier(godot::String const& country_identifier) const; godot::String get_country_adjective_from_identifier(godot::String const& country_identifier) const; @@ -233,6 +239,12 @@ namespace OpenVic { /* Array of GFXPieChartTexture::godot_pie_chart_data_t. */ godot::TypedArray get_population_menu_distribution_info() const; + /* TECHNOLOGY MENU */ + godot::Dictionary get_technology_menu_defines() const; + godot::Dictionary get_technology_menu_info() const; + godot::Dictionary get_specific_technology_info(godot::String technology_id) const; + void start_research(godot::String technology_id); // TODO: move to PlayerSingleton + /* MILITARY MENU */ godot::Dictionary make_leader_dict(LeaderBase const& leader); template diff --git a/extension/src/openvic-extension/singletons/TechnologyMenu.cpp b/extension/src/openvic-extension/singletons/TechnologyMenu.cpp new file mode 100644 index 00000000..eb58e061 --- /dev/null +++ b/extension/src/openvic-extension/singletons/TechnologyMenu.cpp @@ -0,0 +1,192 @@ +#include "MenuSingleton.hpp" +#include "openvic-simulation/research/Technology.hpp" + +#include +#include +#include + +#include + +#include "openvic-extension/singletons/GameSingleton.hpp" +#include "openvic-extension/utility/Utilities.hpp" + +using namespace OpenVic; +using namespace godot; + +/* TECHNOLOGY MENU */ +Dictionary MenuSingleton::get_technology_menu_defines() const { + GameSingleton const* game_singleton = GameSingleton::get_singleton(); + ERR_FAIL_NULL_V(game_singleton, {}); + + static const StringName tech_folders_key = "tech_folders"; + static const StringName tech_areas_key = "tech_areas"; + static const StringName technologies_key = "technologies"; + static const StringName folder_tech_count_key = "folder_tech_count"; + + Dictionary ret; + + std::vector const& tech_folders = game_singleton->get_definition_manager().get_research_manager().get_technology_manager().get_technology_folders(); + + PackedStringArray tech_folder_identifiers {}; + Array tech_area_identifiers {}; + Array tech_identifiers {}; + PackedInt32Array folder_tech_count {}; + for (TechnologyFolder const& folder : tech_folders) { + tech_folder_identifiers.push_back(Utilities::std_to_godot_string(folder.get_identifier())); + int32_t num_in_folder = 0; + + PackedStringArray folder_areas {}; + Array tech_folder_nested_array {}; // tech_identifiers has three levels of nested arrays :P + for (TechnologyArea const* area : folder.get_technology_areas()) { + folder_areas.push_back(Utilities::std_to_godot_string(area->get_identifier())); + + PackedStringArray area_technologies {}; + for (Technology const* tech : area->get_technologies()) { + area_technologies.push_back(Utilities::std_to_godot_string(tech->get_identifier())); + num_in_folder++; + } + tech_folder_nested_array.push_back(std::move(area_technologies)); + } + tech_area_identifiers.push_back(std::move(folder_areas)); + tech_identifiers.push_back(std::move(tech_folder_nested_array)); + folder_tech_count.push_back(num_in_folder); + } + ret[tech_folders_key] = std::move(tech_folder_identifiers); + ret[tech_areas_key] = std::move(tech_area_identifiers); + ret[technologies_key] = std::move(tech_identifiers); + ret[folder_tech_count_key] = std::move(folder_tech_count); + + return ret; +} + +Dictionary MenuSingleton::get_technology_menu_info() const { + GameSingleton const* game_singleton = GameSingleton::get_singleton(); + ERR_FAIL_NULL_V(game_singleton, {}); + TechnologyManager const& tech_manager = game_singleton->get_definition_manager().get_research_manager().get_technology_manager(); + + static const StringName tech_school_key = "tech_school"; + static const StringName tech_school_mod_values = "tech_school_mod_values"; + static const StringName tech_school_mod_icons = "tech_school_mod_icons"; + static const StringName tech_school_mod_tt = "tech_school_mod_tt"; + + static const StringName researched_technologies_key = "researched_technologies"; + static const StringName researchable_technologies_key = "researchable_technologies"; + + static const StringName current_research_tech = "current_research_tech"; + static const StringName current_research_cat = "current_research_cat"; + static const StringName current_research_finish_date = "current_research_finish_date"; + static const StringName current_research_invested = "current_research_invested"; + static const StringName current_research_cost = "current_research_cost"; + static const StringName current_research_effect_tt = "current_research_effect_tt"; + static const StringName current_research_progress = "current_research_progress"; + + Dictionary ret; + + const CountryInstance* country = game_singleton->get_viewed_country(); + if (country == nullptr) { return ret; } + + std::vector tech_folder_identifiers = tech_manager.get_technology_folder_identifiers(); + + ret[tech_school_key] = Utilities::std_to_godot_string(country->get_tech_school() == nullptr ? tech_manager.get_technology_school_by_index(0)->get_identifier() : country->get_tech_school()->get_identifier()); + + static const auto bonus_suffix = "_research_bonus"; + auto compareFolders = [&tech_folder_identifiers](std::pair a, std::pair b) -> bool { + std::string tempA{a.first.substr(0, a.first.find(bonus_suffix))}; + std::string tempB{b.first.substr(0, b.first.find(bonus_suffix))}; + return std::find(tech_folder_identifiers.begin(), tech_folder_identifiers.end(), tempA) < std::find(tech_folder_identifiers.begin(), tech_folder_identifiers.end(), tempB); + }; + + std::vector> school_modifiers {}; + if (country->get_tech_school() != nullptr) { + for (auto effect : country->get_tech_school()->get_values()) { + if (!effect.first->get_identifier().starts_with("unciv")) { + if (effect.second != 0) { + school_modifiers.push_back({effect.first->get_localisation_key(), effect.second}); + } + } + } + if (country->get_tech_school()->get_effect_count() > 0) { + std::sort(school_modifiers.begin(), school_modifiers.end(), compareFolders); + } + } + + PackedFloat32Array school_modifier_values {}; + PackedInt32Array school_modifier_icons {}; + PackedStringArray school_modifier_tt {}; + + for (auto modifier : school_modifiers) { + int32_t folder_id = std::find(tech_folder_identifiers.begin(), tech_folder_identifiers.end(), modifier.first.substr(0, modifier.first.find(bonus_suffix))) - tech_folder_identifiers.begin(); + + school_modifier_values.push_back(modifier.second.to_float()); + school_modifier_icons.push_back(1 + folder_id); + school_modifier_tt.push_back(_make_modifier_effect_tooltip(**game_singleton->get_definition_manager().get_modifier_manager().get_modifier_effect_cache().get_research_bonus_effects().get_item_by_key(*tech_manager.get_technology_folder_by_index(folder_id)), modifier.second)); + } + + ret[tech_school_mod_values] = std::move(school_modifier_values); + ret[tech_school_mod_icons] = std::move(school_modifier_icons); + ret[tech_school_mod_tt] = std::move(school_modifier_tt); + + PackedStringArray researched_technologies {}; + PackedStringArray researchable_technologies {}; + for (Technology const& tech : tech_manager.get_technologies()) { + if (country->is_technology_unlocked(tech)) { + researched_technologies.push_back(Utilities::std_to_godot_string(tech.get_identifier())); + } + if (country->can_research_tech(tech, game_singleton->get_instance_manager()->get_today())) { + researchable_technologies.push_back(Utilities::std_to_godot_string(tech.get_identifier())); + } + } + ret[researched_technologies_key] = std::move(researched_technologies); + ret[researchable_technologies_key] = std::move(researchable_technologies); + + Technology const* current_research = country->get_current_research(); + if (current_research != nullptr) { + ret[current_research_tech] = Utilities::std_to_godot_string(current_research->get_identifier()); + ret[current_research_cat] = tr(Utilities::std_to_godot_string(current_research->get_area().get_folder().get_identifier())) + ", " + tr(Utilities::std_to_godot_string(current_research->get_area().get_identifier())); + ret[current_research_finish_date] = Utilities::date_to_string(country->get_expected_research_completion_date()); + ret[current_research_invested] = country->get_invested_research_points().to_int32_t(); + ret[current_research_cost] = country->get_current_research_cost().to_int32_t(); + ret[current_research_effect_tt] = _make_modifier_effects_tooltip(*current_research).trim_prefix("\n"); + ret[current_research_progress] = country->get_research_progress().to_float(); + } + + return ret; +} + +Dictionary MenuSingleton::get_specific_technology_info(String technology_id) const { + GameSingleton const* game_singleton = GameSingleton::get_singleton(); + ERR_FAIL_NULL_V(game_singleton, {}); + + static const StringName effect_tooltip_key = "effects"; + static const StringName research_points_key = "research_points"; + static const StringName start_year_key = "start_year"; + static const StringName prerequisite_key = "prerequisite"; + + Dictionary ret; + + Technology const* technology = game_singleton->get_definition_manager().get_research_manager().get_technology_manager().get_technology_by_identifier(Utilities::godot_to_std_string(technology_id)); + CountryInstance const* viewed_country = game_singleton->get_viewed_country(); + if (technology == nullptr || viewed_country == nullptr) { + return ret; + } + + ret[effect_tooltip_key] = _make_modifier_effects_tooltip(*technology).trim_prefix("\n"); + ret[research_points_key] = viewed_country->calculate_research_cost(*technology, game_singleton->get_definition_manager().get_modifier_manager().get_modifier_effect_cache()).to_int32_t(); + ret[start_year_key] = technology->get_year(); + if (technology->get_index_in_area() > 0) { + ret[prerequisite_key] = Utilities::std_to_godot_string(technology->get_area().get_technologies()[technology->get_index_in_area() - 1]->get_identifier()); + } + + return ret; +} + +void MenuSingleton::start_research(String technology_id) { + GameSingleton* game_singleton = GameSingleton::get_singleton(); + ERR_FAIL_NULL(game_singleton); + + CountryInstance* viewed_country = game_singleton->get_viewed_country(); + Technology const* technology = game_singleton->get_definition_manager().get_research_manager().get_technology_manager().get_technology_by_identifier(Utilities::godot_to_std_string(technology_id)); + if (technology == nullptr || viewed_country == nullptr) { return; } + + viewed_country->start_research(*technology, *game_singleton->get_instance_manager()); +} \ No newline at end of file diff --git a/game/src/Game/GameSession/NationManagementScreen/TechnologyMenu.gd b/game/src/Game/GameSession/NationManagementScreen/TechnologyMenu.gd index 8386fef3..55739ae2 100644 --- a/game/src/Game/GameSession/NationManagementScreen/TechnologyMenu.gd +++ b/game/src/Game/GameSession/NationManagementScreen/TechnologyMenu.gd @@ -4,6 +4,35 @@ var _active : bool = false const _screen : NationManagement.Screen = NationManagement.Screen.TECHNOLOGY +var _tech_defines : Dictionary = MenuSingleton.get_technology_menu_defines() + +var _tech_folders : PackedStringArray +var _tech_areas : Array +var _technologies : Array +var _folder_tech_counts : PackedInt32Array + +var _tech_folder_buttons : Array +var _tech_folder_progressbars : Array +var _tech_folder_number_discovered_labels : Array + +var _tech_school : GUILabel +var _tech_school_modifiers : GUIOverlappingElementsBox +var _current_research_label : GUILabel +var _current_research_cat_label : GUILabel +var _current_research_progressbar : GUIProgressBar + +var _selected_tech_picture : GUIIcon +var _selected_tech_label : GUILabel +var _selected_tech_effects : GUILabel +var _selected_tech_research_points : GUILabel +var _selected_tech_unlock_year : GUILabel + +var _start_research_button : GUIIconButton + +var _selected_folder = 0 +var _selected_technology : String +var _selected_technology_info : Dictionary + func _ready() -> void: GameSingleton.gamestate_updated.connect(_update_info) @@ -13,12 +42,145 @@ func _ready() -> void: set_click_mask_from_nodepaths([^"./country_technology/main_bg"]) + # TECHNOLOGY SCHOOLS + _tech_school = get_gui_label_from_nodepath(^"./country_technology/administration_type") + _tech_school_modifiers = get_gui_overlapping_elements_box_from_nodepath(^"./country_technology/school_bonus_icons") + if _tech_school_modifiers: + _tech_school_modifiers.set_gui_child_element_name("country_technology", "school_icon_window") + + # CURRENT RESEARCH PROGRESSBAR + _current_research_label = get_gui_label_from_nodepath(^"./country_technology/research_progress_name") + _current_research_cat_label = get_gui_label_from_nodepath(^"./country_technology/research_progress_category") + _current_research_progressbar = get_gui_progress_bar_from_nodepath(^"./country_technology/research_progress") + + # FOLDERS, AREAS, TECHNOLOGIES + _tech_folders = _tech_defines.get("tech_folders", []) + _tech_areas = _tech_defines.get("tech_areas", []) + _technologies = _tech_defines.get("technologies", []) + if _technologies[0][0][0]: + _selected_technology = _technologies[0][0][0] + _selected_technology_info = MenuSingleton.get_specific_technology_info(_selected_technology) + _folder_tech_counts = _tech_defines.get("folder_tech_count", 0) + for i in range(_tech_folders.size()): + add_gui_element("country_technology", "folder_window") + + var folder_node = get_node(^"./folder_window") + var root_node = get_node(^"./country_technology") + + folder_node.reparent(root_node) + folder_node.name = _tech_folders[i] + "_folder" + + var pos = GUINode.get_gui_position("country_technology", "folder_offset") + pos.x += folder_node.get_size().x * i + folder_node.set_position(pos) + + var icon = GUINode.get_gui_icon_from_node(folder_node.get_node(^"./folder_icon")) + if icon: + icon.set_icon_index(i+1) + + var title = GUINode.get_gui_label_from_node(folder_node.get_node(^"./folder_category")) + if title: + title.set_text(_tech_folders[i]) + + var button = GUINode.get_gui_icon_button_from_node(folder_node.get_node(^"./folder_button")) + var button_tooltip : String = tr("TECHNOLOGYVIEW_SHOW_FOLDER_TOOLTIP") + var button_dict : Dictionary = { "FOLDER" : _tech_folders[i] } + if button: + if i == 0: + button.set_icon_index(2) + button.pressed.connect( # change selected technology area + func() -> void: + _tech_folder_buttons[_selected_folder].set_icon_index(1) + for x in range(_tech_areas[_selected_folder].size()): + root_node.get_node("./" + _tech_areas[_selected_folder][x]).visible = false + _selected_folder = i + button.set_icon_index(2) + for x in range(_tech_areas[_selected_folder].size()): + root_node.get_node("./" + _tech_areas[_selected_folder][x]).visible = true + ) + button.set_tooltip_string_and_substitution_dict(button_tooltip, button_dict) + _tech_folder_buttons.push_back(button) + + var progressbar = GUINode.get_gui_progress_bar_from_node(folder_node.get_node(^"./folder_progress")) + if progressbar: + progressbar.mouse_filter = Control.MOUSE_FILTER_IGNORE + _tech_folder_progressbars.push_back(progressbar) + + var discovered = GUINode.get_gui_label_from_node(folder_node.get_node(^"folder_number_discovered")) + if discovered: + _tech_folder_number_discovered_labels.push_back(discovered) + + # areas + var folder_areas : PackedStringArray = _tech_areas[i] + for area_index in range(folder_areas.size()): + add_gui_element("country_technology", "tech_group") + + var area_node = get_node(^"./tech_group") + + area_node.reparent(root_node) + area_node.name = folder_areas[area_index] + if i != 0: + area_node.set_visible(false) + + pos = GUINode.get_gui_position("country_technology", "tech_group_offset") + pos.x += area_node.get_size().x * area_index + area_node.set_position(pos) + + var area_title = GUINode.get_gui_label_from_node(area_node.get_node(^"./group_name")) + if area_title: + area_title.set_text(folder_areas[area_index]) + + # technologies + var area_technologies : PackedStringArray = _technologies[i][area_index] + for tech_index in range(area_technologies.size()): + add_gui_element("country_technology", "tech_window") + + var tech_node = get_node(^"./tech_window") + + tech_node.reparent(area_node) + tech_node.name = area_technologies[tech_index] + + pos = GUINode.get_gui_position("country_technology", "tech_offset") + pos.y += tech_node.get_size().y * tech_index + tech_node.set_position(pos) + + var tech_name = GUINode.get_gui_label_from_node(tech_node.get_node(^"./tech_name")) + if tech_name: + tech_name.set_text(area_technologies[tech_index]) + + var tech_button = GUINode.get_gui_icon_button_from_node(tech_node.get_node(^"./start_research")) + if tech_button: + tech_button.pressed.connect(_on_tech_selected.bind(area_technologies[tech_index])) + + # SELECTED TECH WINDOW + _selected_tech_picture = GUINode.get_gui_icon_from_node(get_node(^"./country_technology/selected_tech_window/picture")) + _selected_tech_label = GUINode.get_gui_label_from_node(get_node(^"./country_technology/selected_tech_window/title")) + _selected_tech_effects = GUINode.get_gui_label_from_node(get_node(^"./country_technology/selected_tech_window/effect")) + _selected_tech_research_points = GUINode.get_gui_label_from_node(get_node(^"./country_technology/selected_tech_window/diff")) + _selected_tech_unlock_year = GUINode.get_gui_label_from_node(get_node(^"./country_technology/selected_tech_window/year")) + _start_research_button = GUINode.get_gui_icon_button_from_node(get_node(^"./country_technology/selected_tech_window/start")) + if _start_research_button: + _start_research_button.pressed.connect( + func() -> void: + MenuSingleton.start_research(_selected_technology) + print("Started Research of " + _selected_technology) + _update_info() + get_parent()._update_info() + ) + + # CLOSE BUTTON var close_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_technology/close_button") if close_button: close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen)) _update_info() +func _on_tech_selected(technology_id : String) -> void: + if _selected_technology != technology_id: + _selected_technology = technology_id + _selected_technology_info = MenuSingleton.get_specific_technology_info(_selected_technology) + _update_info() + func _notification(what : int) -> void: match what: NOTIFICATION_TRANSLATION_CHANGED: @@ -30,7 +192,115 @@ func _on_update_active_nation_management_screen(active_screen : NationManagement func _update_info() -> void: if _active: - # TODO - update UI state + var info : Dictionary = MenuSingleton.get_technology_menu_info() + + if _tech_school: + _tech_school.set_text(info.get("tech_school", "")) + + if _tech_school_modifiers: + var mod_values : PackedFloat32Array = info.get("tech_school_mod_values", PackedFloat32Array()) + var mod_icons : PackedInt32Array = info.get("tech_school_mod_icons", PackedInt32Array()) + var mod_tooltips : PackedStringArray = info.get("tech_school_mod_tt", PackedStringArray()) + var mod_count = mod_values.size() + _tech_school_modifiers.set_child_count(mod_count) + for i in range(mod_count): + var main_icon = get_gui_icon_from_nodepath("./country_technology/school_bonus_icons/school_icon_window_{x}/main_icon".format({"x": i})) + main_icon.set_icon_index(mod_icons[i]) + main_icon.mouse_filter = Control.MOUSE_FILTER_PASS + main_icon.set_tooltip_string(mod_tooltips[i]) + var plusminus_icon = get_gui_icon_from_nodepath("./country_technology/school_bonus_icons/school_icon_window_{x}/plusminus_icon".format({"x": i})) + plusminus_icon.set_icon_index(2 if mod_values[i] > 0 else 1) + plusminus_icon.mouse_filter = Control.MOUSE_FILTER_PASS + plusminus_icon.set_tooltip_string(mod_tooltips[i]) + + var current_research : String = info.get("current_research_tech", "") + if _current_research_label and _current_research_label.text != current_research: + _current_research_label.set_text(current_research if current_research else "TECHNOLOGYVIEW_NO_RESEARCH") + + if _current_research_cat_label: + _current_research_cat_label.set_text(info.get("current_research_cat", "")) + + if _current_research_progressbar: + if current_research != "": + _current_research_progressbar.value = info.get("current_research_progress", 0) + _current_research_progressbar.set_tooltip_string_and_substitution_dict( + tr("TECHNOLOGYVIEW_RESEARCH_TOOLTIP") + "\n" + + tr("TECHNOLOGYVIEW_RESEARCH_INVESTED_TOOLTIP") + + MenuSingleton.get_tooltip_separator() + + info.get("current_research_effect_tt", ""), + { + "TECH": tr(current_research), + "DATE": info.get("current_research_finish_date", "1836.1.1"), + "INVESTED": info.get("current_research_invested", 0), + "COST": info.get("current_research_cost", 0) + } + ) + else: + _current_research_progressbar.set_tooltip_string(tr("TECHNOLOGYVIEW_NO_RESEARCH_TOOLTIP")) + + var researched_techs : PackedStringArray = info.get("researched_technologies", PackedStringArray()) + var avail_techs : PackedStringArray = info.get("researchable_technologies", PackedStringArray()) + + for ix in range(_technologies.size()): + var folder_number_discovered = 0 + for iy in range(_technologies[ix].size()): + for iz in range(_technologies[ix][iy].size()): + var tech_identifier = _technologies[ix][iy][iz] + var tech_info : Dictionary = MenuSingleton.get_specific_technology_info(tech_identifier) + var tech = get_gui_icon_button_from_nodepath("./country_technology/{y}/{z}/start_research".format({"y":_tech_areas[ix][iy], "z":tech_identifier})) + if tech: + if researched_techs.has(tech_identifier): + tech.set_icon_index(2) + folder_number_discovered += 1 + elif current_research == tech_identifier: + tech.set_icon_index(1) + elif avail_techs.has(tech_identifier): + tech.set_icon_index(3) + else: + tech.set_icon_index(4) + tech.set_tooltip_string("§Y{tech}§W\n".format({ "tech": tr(tech_identifier) }) + tech_info.get("effects", "") + MenuSingleton.get_tooltip_separator() + tr("TECH_INVENTIONS_TOOLTIP") + "\nTODO: Inventions") + var label: GUILabel = _tech_folder_number_discovered_labels[ix] + if label: + label.set_text("{r}/{a}".format({"r":folder_number_discovered,"a":_folder_tech_counts[ix]})) + var progbar: GUIProgressBar = _tech_folder_progressbars[ix] + if progbar: + progbar.value = float(folder_number_discovered) / float(_folder_tech_counts[ix]) + + # SELECTED TECHNOLOGY PANEL + if _selected_tech_label: + _selected_tech_label.set_text(_selected_technology) + if _selected_tech_picture and _selected_technology: + _selected_tech_picture.set_texture(AssetManager.get_texture("gfx/pictures/tech/{a}.tga".format({ "a": _selected_technology }))) + if _selected_tech_effects: + _selected_tech_effects.set_text(_selected_technology_info.get("effects", "")) + if _selected_tech_research_points: + _selected_tech_research_points.set_text(str(_selected_technology_info.get("research_points", 0))) + if _selected_tech_unlock_year: + _selected_tech_unlock_year.set_text(str(_selected_technology_info.get("start_year", 1836))) + if _start_research_button: + if current_research == _selected_technology: + _start_research_button.disabled = true + _start_research_button.set_tooltip_string_and_substitution_dict(tr("TECHNOLOGYVIEW_UNDER_RESEARCH_TOOLTIP"), { "TECH": tr(_selected_technology) }) + elif researched_techs.has(_selected_technology): + _start_research_button.disabled = true + _start_research_button.set_tooltip_string_and_substitution_dict(tr("TECHNOLOGYVIEW_ALREADY_RESEARCHED_TOOLTIP"), { "TECH": tr(_selected_technology) }) + elif avail_techs.has(_selected_technology): + _start_research_button.disabled = false + _start_research_button.set_tooltip_string_and_substitution_dict(tr("TECHNOLOGYVIEW_START_RESEARCH_TOOLTIP"), { "TECH": tr(_selected_technology) }) + else: + _start_research_button.disabled = true + _start_research_button.set_tooltip_string_and_substitution_dict( + tr("TECHNOLOGYVIEW_CANNOT_RESEARCH_TOOLTIP") + "\n" + + tr("TECHNOLOGYVIEW_HAVE_NOT_YEAR") + "\n" + + (MenuSingleton.get_tooltip_condition_met() if researched_techs.has(_selected_technology_info.get("prerequisite", "")) else MenuSingleton.get_tooltip_condition_unmet()) + + " " + tr("TECHNOLOGYVIEW_HAVE_DISCOVERED_PREREQ_TOOLTIP").replace("$TECH$", "$PREREQ$"), + { + "TECH": tr(_selected_technology), + "YEAR": str(_selected_technology_info.get("start_year", 1836)), + "PREREQ": _selected_technology_info.get("prerequisite", "") + } + ) + show() else: hide()