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()