aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hop311 <Hop3114@gmail.com>2024-02-19 21:35:07 +0100
committer GitHub <noreply@github.com>2024-02-19 21:35:07 +0100
commit275cfbb62fe69828aeb9968110ad822447322a4e (patch)
tree15fe433ba9259623e2cb90a0ea7ae6a5c2f364b8
parente4de451ce753dd8786546b9e2c94c579c8dab52e (diff)
parent1455861632cd50f48f6e8ef8c50004087eff36f1 (diff)
Merge pull request #202 from OpenVicProject/nation-management-screens
Basic Nation Management Screen framework
m---------extension/deps/openvic-simulation0
-rw-r--r--extension/src/openvic-extension/classes/GFXIconTexture.cpp2
-rw-r--r--extension/src/openvic-extension/classes/GFXPieChartTexture.cpp6
-rw-r--r--extension/src/openvic-extension/classes/GUINode.cpp26
-rw-r--r--extension/src/openvic-extension/classes/GUINode.hpp6
-rw-r--r--extension/src/openvic-extension/utility/UITools.cpp135
-rw-r--r--extension/src/openvic-extension/utility/UITools.hpp5
-rw-r--r--extension/src/openvic-extension/utility/Utilities.cpp2
-rw-r--r--extension/src/openvic-extension/utility/Utilities.hpp16
-rw-r--r--game/src/Game/Autoload/Events.gd6
-rw-r--r--game/src/Game/Autoload/Events/NationManagementScreens.gd25
-rw-r--r--game/src/Game/GameSession/GameSession.tscn50
-rw-r--r--game/src/Game/GameSession/NationManagementScreen/BudgetMenu.gd34
-rw-r--r--game/src/Game/GameSession/NationManagementScreen/DiplomacyMenu.gd34
-rw-r--r--game/src/Game/GameSession/NationManagementScreen/MilitaryMenu.gd34
-rw-r--r--game/src/Game/GameSession/NationManagementScreen/PoliticsMenu.gd34
-rw-r--r--game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd34
-rw-r--r--game/src/Game/GameSession/NationManagementScreen/ProductionMenu.gd34
-rw-r--r--game/src/Game/GameSession/NationManagementScreen/TechnologyMenu.gd34
-rw-r--r--game/src/Game/GameSession/NationManagementScreen/TradeMenu.gd34
-rw-r--r--game/src/Game/GameSession/ProvinceOverviewPanel.gd8
-rw-r--r--game/src/Game/GameSession/Topbar.gd41
-rw-r--r--game/src/Game/GameStart.gd2
-rw-r--r--game/src/Game/GlobalClass/NationManagement.gd13
24 files changed, 538 insertions, 77 deletions
diff --git a/extension/deps/openvic-simulation b/extension/deps/openvic-simulation
-Subproject 068c13ede817d17df599ca3481261bf17ed9560
+Subproject 5216e893ebc5253b123bbf15b7509745d38f5a8
diff --git a/extension/src/openvic-extension/classes/GFXIconTexture.cpp b/extension/src/openvic-extension/classes/GFXIconTexture.cpp
index 5d29c07..99df7e4 100644
--- a/extension/src/openvic-extension/classes/GFXIconTexture.cpp
+++ b/extension/src/openvic-extension/classes/GFXIconTexture.cpp
@@ -3,7 +3,6 @@
#include <godot_cpp/variant/utility_functions.hpp>
#include "openvic-extension/singletons/AssetManager.hpp"
-#include "openvic-extension/singletons/GameSingleton.hpp"
#include "openvic-extension/utility/ClassBindings.hpp"
#include "openvic-extension/utility/UITools.hpp"
#include "openvic-extension/utility/Utilities.hpp"
@@ -11,7 +10,6 @@
using namespace godot;
using namespace OpenVic;
-using OpenVic::Utilities::godot_to_std_string;
using OpenVic::Utilities::std_view_to_godot_string;
using OpenVic::Utilities::std_view_to_godot_string_name;
diff --git a/extension/src/openvic-extension/classes/GFXPieChartTexture.cpp b/extension/src/openvic-extension/classes/GFXPieChartTexture.cpp
index c9a2a72..f4c7851 100644
--- a/extension/src/openvic-extension/classes/GFXPieChartTexture.cpp
+++ b/extension/src/openvic-extension/classes/GFXPieChartTexture.cpp
@@ -1,16 +1,14 @@
#include "GFXPieChartTexture.hpp"
-#include "openvic-extension/singletons/AssetManager.hpp"
-#include "openvic-extension/singletons/GameSingleton.hpp"
+#include <numbers>
+
#include "openvic-extension/utility/ClassBindings.hpp"
#include "openvic-extension/utility/UITools.hpp"
using namespace godot;
using namespace OpenVic;
-using OpenVic::Utilities::godot_to_std_string;
using OpenVic::Utilities::std_view_to_godot_string;
-using OpenVic::Utilities::std_view_to_godot_string_name;
StringName const& GFXPieChartTexture::_slice_identifier_key() {
static StringName const slice_identifier_key = "identifier";
diff --git a/extension/src/openvic-extension/classes/GUINode.cpp b/extension/src/openvic-extension/classes/GUINode.cpp
index 89701e0..f95e3cd 100644
--- a/extension/src/openvic-extension/classes/GUINode.cpp
+++ b/extension/src/openvic-extension/classes/GUINode.cpp
@@ -10,9 +10,6 @@
using namespace godot;
using namespace OpenVic;
-using OpenVic::Utilities::godot_to_std_string;
-using OpenVic::Utilities::std_view_to_godot_string;
-
#define APPLY_TO_CHILD_TYPES(F) \
F(Button, button) \
F(CheckBox, check_box) \
@@ -28,8 +25,9 @@ using OpenVic::Utilities::std_view_to_godot_string;
F(GFXPieChartTexture, gfx_pie_chart_texture)
void GUINode::_bind_methods() {
- OV_BIND_SMETHOD(generate_gui_element, { "gui_file", "gui_element", "name" }, DEFVAL(String {}));
- OV_BIND_METHOD(GUINode::add_gui_element, { "gui_file", "gui_element", "name" }, DEFVAL(String {}));
+ OV_BIND_SMETHOD(generate_gui_element, { "gui_scene", "gui_element", "name" }, DEFVAL(String {}));
+ OV_BIND_METHOD(GUINode::add_gui_element, { "gui_scene", "gui_element", "name" }, DEFVAL(String {}));
+ OV_BIND_SMETHOD(get_gui_position, { "gui_scene", "gui_position" });
#define GET_BINDINGS(type, name) \
OV_BIND_SMETHOD(get_##name##_from_node, { "node" }); \
@@ -55,19 +53,19 @@ GUINode::GUINode() {
set_mouse_filter(MOUSE_FILTER_IGNORE);
}
-Control* GUINode::generate_gui_element(String const& gui_file, String const& gui_element, String const& name) {
+Control* GUINode::generate_gui_element(String const& gui_scene, String const& gui_element, String const& name) {
Control* result = nullptr;
- if (!UITools::generate_gui_element(gui_file, gui_element, name, result)) {
- UtilityFunctions::push_error("Error generating GUI element ", gui_element, " from GUI file ", gui_file);
+ if (!UITools::generate_gui_element(gui_scene, gui_element, name, result)) {
+ UtilityFunctions::push_error("Error generating GUI element ", gui_element, " from GUI scene ", gui_scene);
}
return result;
}
-Error GUINode::add_gui_element(String const& gui_file, String const& gui_element, String const& name) {
+Error GUINode::add_gui_element(String const& gui_scene, String const& gui_element, String const& name) {
Error err = OK;
Control* result = nullptr;
- if (!UITools::generate_gui_element(gui_file, gui_element, name, result)) {
- UtilityFunctions::push_error("Error generating GUI element ", gui_element, " from GUI file ", gui_file);
+ if (!UITools::generate_gui_element(gui_scene, gui_element, name, result)) {
+ UtilityFunctions::push_error("Error generating GUI element ", gui_element, " from GUI scene ", gui_scene);
err = FAILED;
}
if (result != nullptr) {
@@ -76,6 +74,12 @@ Error GUINode::add_gui_element(String const& gui_file, String const& gui_element
return err;
}
+Vector2 GUINode::get_gui_position(String const& gui_scene, String const& gui_position) {
+ GUI::Position const* position = UITools::get_gui_position(gui_scene, gui_position);
+ ERR_FAIL_NULL_V(position, {});
+ return Utilities::to_godot_fvec2(position->get_position());
+}
+
template<std::derived_from<godot::Node> T>
static T* _cast_node(Node* node) {
ERR_FAIL_NULL_V(node, nullptr);
diff --git a/extension/src/openvic-extension/classes/GUINode.hpp b/extension/src/openvic-extension/classes/GUINode.hpp
index e38ed1f..0fbfc66 100644
--- a/extension/src/openvic-extension/classes/GUINode.hpp
+++ b/extension/src/openvic-extension/classes/GUINode.hpp
@@ -25,13 +25,15 @@ namespace OpenVic {
GUINode();
static godot::Control* generate_gui_element(
- godot::String const& gui_file, godot::String const& gui_element, godot::String const& name = ""
+ godot::String const& gui_scene, godot::String const& gui_element, godot::String const& name = ""
);
godot::Error add_gui_element(
- godot::String const& gui_file, godot::String const& gui_element, godot::String const& name = ""
+ godot::String const& gui_scene, godot::String const& gui_element, godot::String const& name = ""
);
+ static godot::Vector2 get_gui_position(godot::String const& gui_scene, godot::String const& gui_position);
+
static godot::Button* get_button_from_node(godot::Node* node);
static godot::CheckBox* get_check_box_from_node(godot::Node* node);
static godot::Label* get_label_from_node(godot::Node* node);
diff --git a/extension/src/openvic-extension/utility/UITools.cpp b/extension/src/openvic-extension/utility/UITools.cpp
index e1cd873..1fcc574 100644
--- a/extension/src/openvic-extension/utility/UITools.cpp
+++ b/extension/src/openvic-extension/utility/UITools.cpp
@@ -37,17 +37,28 @@ GFX::Sprite const* UITools::get_gfx_sprite(godot::String const& gfx_sprite) {
return sprite;
}
-GUI::Element const* UITools::get_gui_element(godot::String const& gui_file, godot::String const& gui_element) {
+GUI::Element const* UITools::get_gui_element(godot::String const& gui_scene, godot::String const& gui_element) {
GameSingleton const* game_singleton = GameSingleton::get_singleton();
ERR_FAIL_NULL_V(game_singleton, nullptr);
GUI::Scene const* scene =
- game_singleton->get_game_manager().get_ui_manager().get_scene_by_identifier(godot_to_std_string(gui_file));
- ERR_FAIL_NULL_V_MSG(scene, nullptr, vformat("Failed to find GUI file %s", gui_file));
+ game_singleton->get_game_manager().get_ui_manager().get_scene_by_identifier(godot_to_std_string(gui_scene));
+ ERR_FAIL_NULL_V_MSG(scene, nullptr, vformat("Failed to find GUI scene %s", gui_scene));
GUI::Element const* element = scene->get_scene_element_by_identifier(godot_to_std_string(gui_element));
- ERR_FAIL_NULL_V_MSG(element, nullptr, vformat("Failed to find GUI element %s in GUI file %s", gui_element, gui_file));
+ ERR_FAIL_NULL_V_MSG(element, nullptr, vformat("Failed to find GUI element %s in GUI scene %s", gui_element, gui_scene));
return element;
}
+GUI::Position const* UITools::get_gui_position(String const& gui_scene, String const& gui_position) {
+ GameSingleton const* game_singleton = GameSingleton::get_singleton();
+ ERR_FAIL_NULL_V(game_singleton, nullptr);
+ GUI::Scene const* scene =
+ game_singleton->get_game_manager().get_ui_manager().get_scene_by_identifier(godot_to_std_string(gui_scene));
+ ERR_FAIL_NULL_V_MSG(scene, nullptr, vformat("Failed to find GUI scene %s", gui_scene));
+ GUI::Position const* position = scene->get_scene_position_by_identifier(godot_to_std_string(gui_position));
+ ERR_FAIL_NULL_V_MSG(position, nullptr, vformat("Failed to find GUI position %s in GUI scene %s", gui_position, gui_scene));
+ return position;
+}
+
/* GUI::Element tree -> godot::Control tree conversion code below: */
namespace OpenVic {
@@ -65,9 +76,9 @@ namespace OpenVic {
}
template<std::derived_from<Control> T>
-static T* new_control(GUI::Element const& element, String const& name) {
- T* node = memnew(T);
- ERR_FAIL_NULL_V(node, nullptr);
+static bool new_control(T*& node, GUI::Element const& element, String const& name) {
+ node = memnew(T);
+ ERR_FAIL_NULL_V(node, false);
using enum GUI::Element::orientation_t;
using enum Control::LayoutPreset;
@@ -83,20 +94,32 @@ static T* new_control(GUI::Element const& element, String const& name) {
node->set_name(name);
}
+ bool ret = true;
const decltype(orientation_map)::const_iterator it = orientation_map.find(element.get_orientation());
if (it != orientation_map.end()) {
node->set_anchors_and_offsets_preset(it->second);
} else {
UtilityFunctions::push_error("Invalid orientation for GUI element ", std_view_to_godot_string(element.get_name()));
+ ret = false;
}
+
node->set_position(Utilities::to_godot_fvec2(element.get_position()));
node->set_h_size_flags(Control::SizeFlags::SIZE_SHRINK_BEGIN);
node->set_v_size_flags(Control::SizeFlags::SIZE_SHRINK_BEGIN);
node->set_focus_mode(Control::FOCUS_NONE);
- return node;
+ return ret;
}
+static bool add_theme_stylebox(Control* control, StringName const& theme_name, Ref<Texture2D> const& texture) {
+ Ref<StyleBoxTexture> stylebox;
+ stylebox.instantiate();
+ ERR_FAIL_NULL_V(stylebox, false);
+ stylebox->set_texture(texture);
+ control->add_theme_stylebox_override(theme_name, stylebox);
+ return true;
+};
+
static bool generate_icon(generate_gui_args_t&& args) {
GUI::Icon const& icon = static_cast<GUI::Icon const&>(args.element);
@@ -106,7 +129,8 @@ static bool generate_icon(generate_gui_args_t&& args) {
bool ret = true;
if (icon.get_sprite() != nullptr) {
if (icon.get_sprite()->is_type<GFX::TextureSprite>()) {
- TextureRect* godot_texture_rect = new_control<TextureRect>(icon, args.name);
+ TextureRect* godot_texture_rect = nullptr;
+ ret &= new_control(godot_texture_rect, icon, args.name);
ERR_FAIL_NULL_V_MSG(godot_texture_rect, false, vformat("Failed to create TextureRect for GUI icon %s", icon_name));
GFX::TextureSprite const* texture_sprite = icon.get_sprite()->cast_to<GFX::TextureSprite>();
@@ -120,7 +144,8 @@ static bool generate_icon(generate_gui_args_t&& args) {
args.result = godot_texture_rect;
} else if (icon.get_sprite()->is_type<GFX::MaskedFlag>()) {
- TextureRect* godot_texture_rect = new_control<TextureRect>(icon, args.name);
+ TextureRect* godot_texture_rect = nullptr;
+ ret &= new_control(godot_texture_rect, icon, args.name);
ERR_FAIL_NULL_V_MSG(godot_texture_rect, false, vformat("Failed to create TextureRect for GUI icon %s", icon_name));
GFX::MaskedFlag const* masked_flag = icon.get_sprite()->cast_to<GFX::MaskedFlag>();
@@ -134,7 +159,8 @@ static bool generate_icon(generate_gui_args_t&& args) {
args.result = godot_texture_rect;
} else if (icon.get_sprite()->is_type<GFX::ProgressBar>()) {
- TextureProgressBar* godot_progress_bar = new_control<TextureProgressBar>(icon, args.name);
+ TextureProgressBar* godot_progress_bar = nullptr;
+ ret &= new_control(godot_progress_bar, icon, args.name);
ERR_FAIL_NULL_V_MSG(
godot_progress_bar, false, vformat("Failed to create TextureProgressBar for GUI icon %s", icon_name)
);
@@ -210,7 +236,8 @@ static bool generate_icon(generate_gui_args_t&& args) {
args.result = godot_progress_bar;
} else if (icon.get_sprite()->is_type<GFX::PieChart>()) {
- TextureRect* godot_texture_rect = new_control<TextureRect>(icon, args.name);
+ TextureRect* godot_texture_rect = nullptr;
+ ret &= new_control(godot_texture_rect, icon, args.name);
ERR_FAIL_NULL_V_MSG(godot_texture_rect, false, vformat("Failed to create TextureRect for GUI icon %s", icon_name));
GFX::PieChart const* pie_chart = icon.get_sprite()->cast_to<GFX::PieChart>();
@@ -219,7 +246,7 @@ static bool generate_icon(generate_gui_args_t&& args) {
godot_texture_rect->set_texture(texture);
// TODO - work out why this is needed
Vector2 pos = godot_texture_rect->get_position();
- pos.x -= texture->get_width() / 2;
+ pos.x -= texture->get_width() / 2.0f;
godot_texture_rect->set_position(pos);
} else {
UtilityFunctions::push_error("Failed to make GFXPieChartTexture for GUI icon ", icon_name);
@@ -228,12 +255,18 @@ static bool generate_icon(generate_gui_args_t&& args) {
args.result = godot_texture_rect;
} else if (icon.get_sprite()->is_type<GFX::LineChart>()) {
-
+ // TODO - generate line chart
} else {
UtilityFunctions::push_error("Invalid sprite type ", std_view_to_godot_string(icon.get_sprite()->get_type()),
" for GUI icon ", icon_name);
ret = false;
}
+
+ if (args.result != nullptr) {
+ const float scale = icon.get_scale();
+ args.result->set_scale({ scale, scale });
+ // TODO - rotation (may have to translate as godot rotates around the top left corner)
+ }
} else {
UtilityFunctions::push_error("Null sprite for GUI icon ", icon_name);
ret = false;
@@ -247,7 +280,8 @@ static bool generate_button(generate_gui_args_t&& args) {
// TODO - shortcut, sprite, text
const String button_name = std_view_to_godot_string(button.get_name());
- Button* godot_button = new_control<Button>(button, args.name);
+ Button* godot_button = nullptr;
+ bool ret = new_control(godot_button, button, args.name);
ERR_FAIL_NULL_V_MSG(godot_button, false, vformat("Failed to create Button for GUI button %s", button_name));
godot_button->set_mouse_filter(Control::MOUSE_FILTER_PASS);
@@ -256,8 +290,6 @@ static bool generate_button(generate_gui_args_t&& args) {
godot_button->set_text(std_view_to_godot_string(button.get_text()));
}
- bool ret = true;
-
using enum GFXButtonStateTexture::ButtonState;
static constexpr std::array<GFXButtonStateTexture::ButtonState, 3> button_states { HOVER, PRESSED, DISABLED };
@@ -310,10 +342,10 @@ static bool generate_button(generate_gui_args_t&& args) {
};
static const StringName theme_name_normal = "normal";
- ret &= add_stylebox(theme_name_normal, texture);
+ ret &= add_theme_stylebox(godot_button, theme_name_normal, texture);
for (Ref<GFXButtonStateTexture> const& button_state_texture : button_state_textures) {
- ret &= add_stylebox(button_state_texture->get_button_state_theme(), button_state_texture);
+ ret &= add_theme_stylebox(godot_button, button_state_texture->get_button_state_theme(), button_state_texture);
}
}
} else {
@@ -350,10 +382,10 @@ static bool generate_checkbox(generate_gui_args_t&& args) {
// TODO - shortcut, sprite, text
const String checkbox_name = std_view_to_godot_string(checkbox.get_name());
- CheckBox* godot_checkbox = new_control<CheckBox>(checkbox, args.name);
+ CheckBox* godot_checkbox = nullptr;
+ bool ret = new_control(godot_checkbox, checkbox, args.name);
ERR_FAIL_NULL_V_MSG(godot_checkbox, false, vformat("Failed to create CheckBox for GUI checkbox %s", checkbox_name));
- bool ret = true;
if (checkbox.get_sprite() != nullptr) {
GFX::TextureSprite const* texture_sprite = checkbox.get_sprite()->cast_to<GFX::TextureSprite>();
if (texture_sprite != nullptr) {
@@ -393,7 +425,8 @@ static bool generate_text(generate_gui_args_t&& args) {
const String text_name = std_view_to_godot_string(text.get_name());
- Label* godot_label = new_control<Label>(text, args.name);
+ Label* godot_label = nullptr;
+ bool ret = new_control(godot_label, text, args.name);
ERR_FAIL_NULL_V_MSG(godot_label, false, vformat("Failed to create Label for GUI text %s", text_name));
godot_label->set_text(std_view_to_godot_string(text.get_text()));
@@ -411,9 +444,9 @@ static bool generate_text(generate_gui_args_t&& args) {
godot_label->set_horizontal_alignment(it->second);
} else {
UtilityFunctions::push_error("Invalid text format (horizontal alignment) for GUI text ", text_name);
+ ret = false;
}
- bool ret = true;
if (text.get_font() != nullptr) {
const StringName font_file = std_view_to_godot_string_name(text.get_font()->get_fontname());
const Ref<Font> font = args.asset_manager.get_font(font_file);
@@ -436,29 +469,55 @@ static bool generate_overlapping_elements(generate_gui_args_t&& args) {
const String overlapping_elements_name = std_view_to_godot_string(overlapping_elements.get_name());
- GUIOverlappingElementsBox* box = new_control<GUIOverlappingElementsBox>(overlapping_elements, args.name);
+ GUIOverlappingElementsBox* box = nullptr;
+ bool ret = new_control(box, overlapping_elements, args.name);
ERR_FAIL_NULL_V_MSG(
box, false,
vformat("Failed to create GUIOverlappingElementsBox for GUI overlapping elements %s", overlapping_elements_name)
);
- const bool ret = box->set_gui_overlapping_elements_box(&overlapping_elements) == OK;
+ ret &= box->set_gui_overlapping_elements_box(&overlapping_elements) == OK;
args.result = box;
return ret;
}
-static bool generate_listbox(generate_gui_args_t&& args) {
- GUI::ListBox const& listbox = static_cast<GUI::ListBox const&>(args.element);
+template<std::derived_from<GUI::Element> T>
+requires requires(T const& element) {
+ { element.get_size() } -> std::same_as<fvec2_t>;
+}
+static bool generate_placeholder(generate_gui_args_t&& args, Color colour) {
+ T const& cast_element = static_cast<T const&>(args.element);
- const String listbox_name = std_view_to_godot_string(listbox.get_name());
+ static const String type_name = std_view_to_godot_string(T::get_type_static());
+ const String placeholder_name = std_view_to_godot_string(cast_element.get_name());
+ const Vector2 godot_size = Utilities::to_godot_fvec2(cast_element.get_size());
- ColorRect* godot_rect = new_control<ColorRect>(listbox, args.name);
- ERR_FAIL_NULL_V_MSG(godot_rect, false, vformat("Failed to create ColorRect for GUI listbox %s", listbox_name));
+ UtilityFunctions::push_warning(
+ "Generating placeholder ColorRect for GUI ", type_name, " ", placeholder_name, " (size ", godot_size, ")"
+ );
- godot_rect->set_custom_minimum_size(Utilities::to_godot_fvec2(listbox.get_size()));
- godot_rect->set_color({ 1.0f, 0.5f, 0.0f, 0.2f });
+ ColorRect* godot_rect = nullptr;
+ bool ret = new_control(godot_rect, cast_element, args.name);
+ ERR_FAIL_NULL_V_MSG(
+ godot_rect, false, vformat("Failed to create placeholder ColorRect for GUI %s %s", type_name, placeholder_name)
+ );
+
+ godot_rect->set_custom_minimum_size(godot_size);
+ godot_rect->set_color(colour);
args.result = godot_rect;
- return true;
+ return ret;
+}
+
+static bool generate_listbox(generate_gui_args_t&& args) {
+ return generate_placeholder<GUI::ListBox>(std::move(args), { 0.0f, 0.0f, 1.0f, 0.3f });
+}
+
+static bool generate_texteditbox(generate_gui_args_t&& args) {
+ return generate_placeholder<GUI::TextEditBox>(std::move(args), { 0.0f, 1.0f, 0.0f, 0.3f });
+}
+
+static bool generate_scrollbar(generate_gui_args_t&& args) {
+ return generate_placeholder<GUI::Scrollbar>(std::move(args), { 1.0f, 0.0f, 0.0f, 0.3f });
}
/* Forward declaration for use in generate_window. */
@@ -470,13 +529,13 @@ static bool generate_window(generate_gui_args_t&& args) {
// TODO - moveable, fullscreen, dontRender (disable visibility?)
const String window_name = std_view_to_godot_string(window.get_name());
- Panel* godot_panel = new_control<Panel>(window, args.name);
+ Panel* godot_panel = nullptr;
+ bool ret = new_control(godot_panel, window, args.name);
ERR_FAIL_NULL_V_MSG(godot_panel, false, vformat("Failed to create Panel for GUI window %s", window_name));
godot_panel->set_custom_minimum_size(Utilities::to_godot_fvec2(window.get_size()));
godot_panel->set_self_modulate({ 1.0f, 1.0f, 1.0f, 0.0f });
- bool ret = true;
for (std::unique_ptr<GUI::Element> const& element : window.get_window_elements()) {
Control* node = nullptr;
const bool element_ret = generate_element(element.get(), "", args.asset_manager, node);
@@ -502,6 +561,8 @@ static bool generate_element(GUI::Element const* element, String const& name, As
{ GUI::Text::get_type_static(), &generate_text },
{ GUI::OverlappingElementsBox::get_type_static(), &generate_overlapping_elements },
{ GUI::ListBox::get_type_static(), &generate_listbox },
+ { GUI::TextEditBox::get_type_static(), &generate_texteditbox },
+ { GUI::Scrollbar::get_type_static(), &generate_scrollbar },
{ GUI::Window::get_type_static(), &generate_window }
};
const decltype(type_map)::const_iterator it = type_map.find(element->get_type());
@@ -521,7 +582,7 @@ bool UITools::generate_gui_element(
}
bool UITools::generate_gui_element(
- godot::String const& gui_file, godot::String const& gui_element, godot::String const& name, godot::Control*& result
+ godot::String const& gui_scene, godot::String const& gui_element, godot::String const& name, godot::Control*& result
) {
- return generate_gui_element(get_gui_element(gui_file, gui_element), name, result);
+ return generate_gui_element(get_gui_element(gui_scene, gui_element), name, result);
}
diff --git a/extension/src/openvic-extension/utility/UITools.hpp b/extension/src/openvic-extension/utility/UITools.hpp
index 65cf17a..6092853 100644
--- a/extension/src/openvic-extension/utility/UITools.hpp
+++ b/extension/src/openvic-extension/utility/UITools.hpp
@@ -7,12 +7,13 @@
namespace OpenVic::UITools {
GFX::Sprite const* get_gfx_sprite(godot::String const& gfx_sprite);
- GUI::Element const* get_gui_element(godot::String const& gui_file, godot::String const& gui_element);
+ GUI::Element const* get_gui_element(godot::String const& gui_scene, godot::String const& gui_element);
+ GUI::Position const* get_gui_position(godot::String const& gui_scene, godot::String const& gui_position);
bool generate_gui_element(
GUI::Element const* element, godot::String const& name, godot::Control*& result
);
bool generate_gui_element(
- godot::String const& gui_file, godot::String const& gui_element, godot::String const& name, godot::Control*& result
+ godot::String const& gui_scene, godot::String const& gui_element, godot::String const& name, godot::Control*& result
);
}
diff --git a/extension/src/openvic-extension/utility/Utilities.cpp b/extension/src/openvic-extension/utility/Utilities.cpp
index a3fa40a..5957b70 100644
--- a/extension/src/openvic-extension/utility/Utilities.cpp
+++ b/extension/src/openvic-extension/utility/Utilities.cpp
@@ -1,7 +1,5 @@
#include "Utilities.hpp"
-#include <numbers>
-
#include <godot_cpp/classes/file_access.hpp>
#include <godot_cpp/classes/resource_loader.hpp>
#include <godot_cpp/classes/translation_server.hpp>
diff --git a/extension/src/openvic-extension/utility/Utilities.hpp b/extension/src/openvic-extension/utility/Utilities.hpp
index 9bbc700..9b45abc 100644
--- a/extension/src/openvic-extension/utility/Utilities.hpp
+++ b/extension/src/openvic-extension/utility/Utilities.hpp
@@ -11,23 +11,23 @@
namespace OpenVic::Utilities {
- inline std::string godot_to_std_string(godot::String const& str) {
+ _FORCE_INLINE_ std::string godot_to_std_string(godot::String const& str) {
return str.ascii().get_data();
}
- inline godot::String std_to_godot_string(std::string const& str) {
+ _FORCE_INLINE_ godot::String std_to_godot_string(std::string const& str) {
return str.c_str();
}
- inline godot::String std_view_to_godot_string(std::string_view str) {
+ _FORCE_INLINE_ godot::String std_view_to_godot_string(std::string_view const& str) {
return std_to_godot_string(static_cast<std::string>(str));
}
- inline godot::StringName std_to_godot_string_name(std::string const& str) {
+ _FORCE_INLINE_ godot::StringName std_to_godot_string_name(std::string const& str) {
return str.c_str();
}
- inline godot::StringName std_view_to_godot_string_name(std::string_view str) {
+ _FORCE_INLINE_ godot::StringName std_view_to_godot_string_name(std::string_view const& str) {
return std_to_godot_string_name(static_cast<std::string>(str));
}
@@ -37,15 +37,15 @@ namespace OpenVic::Utilities {
godot::String date_to_formatted_string(Date date);
- inline godot::Color to_godot_color(IsColour auto colour) {
+ _FORCE_INLINE_ godot::Color to_godot_color(IsColour auto colour) {
return { colour.redf(), colour.greenf(), colour.bluef(), colour.alphaf() };
}
- inline godot::Vector2i to_godot_ivec2(ivec2_t vec) {
+ _FORCE_INLINE_ godot::Vector2i to_godot_ivec2(ivec2_t vec) {
return { vec.x, vec.y };
}
- inline godot::Vector2 to_godot_fvec2(fvec2_t vec) {
+ _FORCE_INLINE_ godot::Vector2 to_godot_fvec2(fvec2_t vec) {
return { vec.x, vec.y };
}
diff --git a/game/src/Game/Autoload/Events.gd b/game/src/Game/Autoload/Events.gd
index 4f38f61..091a122 100644
--- a/game/src/Game/Autoload/Events.gd
+++ b/game/src/Game/Autoload/Events.gd
@@ -1,9 +1,11 @@
## Events are exclusively for the purpose of handling global signals
## This is to reduce "signal bubbling" which is when a signal callback is used to "bubble" the signal callbacks up the scene tree.
-## It does such by providing a global interface of signals that are connected to and emitted by that are garunteed to exist.
+## It does such by providing a global interface of signals that are connected to and emitted by that are guaranteed to exist.
extends Node
-var Options: OptionsEventsObject
+var Options : OptionsEventsObject
+var NationManagementScreens : NationManagementScreensEventsObject
func _init() -> void:
Options = OptionsEventsObject.new()
+ NationManagementScreens = NationManagementScreensEventsObject.new()
diff --git a/game/src/Game/Autoload/Events/NationManagementScreens.gd b/game/src/Game/Autoload/Events/NationManagementScreens.gd
new file mode 100644
index 0000000..4bdca6d
--- /dev/null
+++ b/game/src/Game/Autoload/Events/NationManagementScreens.gd
@@ -0,0 +1,25 @@
+class_name NationManagementScreensEventsObject
+extends RefCounted
+
+signal update_active_nation_management_screen(screen : NationManagement.Screen)
+
+var _current_screen : NationManagement.Screen = NationManagement.Screen.NONE
+
+# Set the current nation management screen. This emits an update signal to force
+# the argument screen to update, even if it was already the current screen.
+# Used by miscellaneous screen opening buttons (e.g. in province overview panel)
+# and by the close and toggle functions below.
+func open_nation_management_screen(screen : NationManagement.Screen) -> void:
+ _current_screen = screen
+ update_active_nation_management_screen.emit(_current_screen)
+
+# Close the screen if it is already open. Used for screens' close buttons.
+func close_nation_management_screen(screen : NationManagement.Screen) -> void:
+ if screen == _current_screen:
+ open_nation_management_screen(NationManagement.Screen.NONE)
+
+# Either switch to the screen or close it if it is already open. Used for topbar's buttons.
+func toggle_nation_management_screen(screen : NationManagement.Screen) -> void:
+ if screen == _current_screen:
+ screen = NationManagement.Screen.NONE
+ open_nation_management_screen(screen)
diff --git a/game/src/Game/GameSession/GameSession.tscn b/game/src/Game/GameSession/GameSession.tscn
index c7a8003..d2fc3a3 100644
--- a/game/src/Game/GameSession/GameSession.tscn
+++ b/game/src/Game/GameSession/GameSession.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=10 format=3 uid="uid://bgnupcshe1m7r"]
+[gd_scene load_steps=18 format=3 uid="uid://bgnupcshe1m7r"]
[ext_resource type="Script" path="res://src/Game/GameSession/GameSession.gd" id="1_eklvp"]
[ext_resource type="PackedScene" uid="uid://cvl76duuym1wq" path="res://src/Game/MusicConductor/MusicPlayer.tscn" id="2_kt6aa"]
@@ -6,9 +6,17 @@
[ext_resource type="PackedScene" uid="uid://dvdynl6eir40o" path="res://src/Game/GameSession/GameSessionMenu.tscn" id="3_bvmqh"]
[ext_resource type="Script" path="res://src/Game/GameSession/Topbar.gd" id="4_2kbih"]
[ext_resource type="PackedScene" uid="uid://dkehmdnuxih2r" path="res://src/Game/GameSession/MapView.tscn" id="4_xkg5j"]
+[ext_resource type="Script" path="res://src/Game/GameSession/NationManagementScreen/ProductionMenu.gd" id="5_16755"]
[ext_resource type="Script" path="res://src/Game/GameSession/ProvinceOverviewPanel.gd" id="5_lfv8l"]
[ext_resource type="PackedScene" uid="uid://cnbfxjy1m6wja" path="res://src/Game/Menu/OptionMenu/OptionsMenu.tscn" id="6_p5mnx"]
+[ext_resource type="Script" path="res://src/Game/GameSession/NationManagementScreen/BudgetMenu.gd" id="6_vninv"]
+[ext_resource type="Script" path="res://src/Game/GameSession/NationManagementScreen/TechnologyMenu.gd" id="7_r712c"]
[ext_resource type="PackedScene" uid="uid://d3g6wbvwflmyk" path="res://src/Game/Menu/SaveLoadMenu/SaveLoadMenu.tscn" id="8_4g7ko"]
+[ext_resource type="Script" path="res://src/Game/GameSession/NationManagementScreen/PoliticsMenu.gd" id="8_ppdek"]
+[ext_resource type="Script" path="res://src/Game/GameSession/NationManagementScreen/PopulationMenu.gd" id="10_laee7"]
+[ext_resource type="Script" path="res://src/Game/GameSession/NationManagementScreen/TradeMenu.gd" id="10_mv1r6"]
+[ext_resource type="Script" path="res://src/Game/GameSession/NationManagementScreen/DiplomacyMenu.gd" id="11_fu7ys"]
+[ext_resource type="Script" path="res://src/Game/GameSession/NationManagementScreen/MilitaryMenu.gd" id="12_6h6nc"]
[node name="GameSession" type="Control" node_paths=PackedStringArray("_game_session_menu")]
editor_description = "SS-102, UI-546"
@@ -34,6 +42,46 @@ layout_mode = 1
anchors_preset = 15
script = ExtResource("4_2kbih")
+[node name="ProductionMenu" type="GUINode" parent="Topbar"]
+layout_mode = 1
+anchors_preset = 15
+script = ExtResource("5_16755")
+
+[node name="BudgetMenu" type="GUINode" parent="Topbar"]
+layout_mode = 1
+anchors_preset = 15
+script = ExtResource("6_vninv")
+
+[node name="TechnologyMenu" type="GUINode" parent="Topbar"]
+layout_mode = 1
+anchors_preset = 15
+script = ExtResource("7_r712c")
+
+[node name="PoliticsMenu" type="GUINode" parent="Topbar"]
+layout_mode = 1
+anchors_preset = 15
+script = ExtResource("8_ppdek")
+
+[node name="PopulationMenu" type="GUINode" parent="Topbar"]
+layout_mode = 1
+anchors_preset = 15
+script = ExtResource("10_laee7")
+
+[node name="TradeMenu" type="GUINode" parent="Topbar"]
+layout_mode = 1
+anchors_preset = 15
+script = ExtResource("10_mv1r6")
+
+[node name="DiplomacyMenu" type="GUINode" parent="Topbar"]
+layout_mode = 1
+anchors_preset = 15
+script = ExtResource("11_fu7ys")
+
+[node name="MilitaryMenu" type="GUINode" parent="Topbar"]
+layout_mode = 1
+anchors_preset = 15
+script = ExtResource("12_6h6nc")
+
[node name="MapControlPanel" parent="." instance=ExtResource("3_afh6d")]
layout_mode = 1
anchors_preset = 3
diff --git a/game/src/Game/GameSession/NationManagementScreen/BudgetMenu.gd b/game/src/Game/GameSession/NationManagementScreen/BudgetMenu.gd
new file mode 100644
index 0000000..7158333
--- /dev/null
+++ b/game/src/Game/GameSession/NationManagementScreen/BudgetMenu.gd
@@ -0,0 +1,34 @@
+extends GUINode
+
+var _active : bool = false
+
+const _screen : NationManagement.Screen = NationManagement.Screen.BUDGET
+
+func _ready() -> void:
+ GameSingleton.gamestate_updated.connect(_update_info)
+
+ Events.NationManagementScreens.update_active_nation_management_screen.connect(_on_update_active_nation_management_screen)
+
+ add_gui_element("country_budget", "country_budget")
+
+ var close_button : Button = get_button_from_nodepath(^"./country_budget/close_button")
+ if close_button:
+ close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen))
+
+ _update_info()
+
+func _notification(what : int) -> void:
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _update_info()
+
+func _on_update_active_nation_management_screen(active_screen : NationManagement.Screen) -> void:
+ _active = active_screen == _screen
+ _update_info()
+
+func _update_info() -> void:
+ if _active:
+ # TODO - update UI state
+ show()
+ else:
+ hide()
diff --git a/game/src/Game/GameSession/NationManagementScreen/DiplomacyMenu.gd b/game/src/Game/GameSession/NationManagementScreen/DiplomacyMenu.gd
new file mode 100644
index 0000000..fb11a31
--- /dev/null
+++ b/game/src/Game/GameSession/NationManagementScreen/DiplomacyMenu.gd
@@ -0,0 +1,34 @@
+extends GUINode
+
+var _active : bool = false
+
+const _screen : NationManagement.Screen = NationManagement.Screen.DIPLOMACY
+
+func _ready() -> void:
+ GameSingleton.gamestate_updated.connect(_update_info)
+
+ Events.NationManagementScreens.update_active_nation_management_screen.connect(_on_update_active_nation_management_screen)
+
+ add_gui_element("country_diplomacy", "country_diplomacy")
+
+ var close_button : Button = get_button_from_nodepath(^"./country_diplomacy/close_button")
+ if close_button:
+ close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen))
+
+ _update_info()
+
+func _notification(what : int) -> void:
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _update_info()
+
+func _on_update_active_nation_management_screen(active_screen : NationManagement.Screen) -> void:
+ _active = active_screen == _screen
+ _update_info()
+
+func _update_info() -> void:
+ if _active:
+ # TODO - update UI state
+ show()
+ else:
+ hide()
diff --git a/game/src/Game/GameSession/NationManagementScreen/MilitaryMenu.gd b/game/src/Game/GameSession/NationManagementScreen/MilitaryMenu.gd
new file mode 100644
index 0000000..f3cc486
--- /dev/null
+++ b/game/src/Game/GameSession/NationManagementScreen/MilitaryMenu.gd
@@ -0,0 +1,34 @@
+extends GUINode
+
+var _active : bool = false
+
+const _screen : NationManagement.Screen = NationManagement.Screen.MILITARY
+
+func _ready() -> void:
+ GameSingleton.gamestate_updated.connect(_update_info)
+
+ Events.NationManagementScreens.update_active_nation_management_screen.connect(_on_update_active_nation_management_screen)
+
+ add_gui_element("country_military", "country_military")
+
+ var close_button : Button = get_button_from_nodepath(^"./country_military/close_button")
+ if close_button:
+ close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen))
+
+ _update_info()
+
+func _notification(what : int) -> void:
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _update_info()
+
+func _on_update_active_nation_management_screen(active_screen : NationManagement.Screen) -> void:
+ _active = active_screen == _screen
+ _update_info()
+
+func _update_info() -> void:
+ if _active:
+ # TODO - update UI state
+ show()
+ else:
+ hide()
diff --git a/game/src/Game/GameSession/NationManagementScreen/PoliticsMenu.gd b/game/src/Game/GameSession/NationManagementScreen/PoliticsMenu.gd
new file mode 100644
index 0000000..7237bf5
--- /dev/null
+++ b/game/src/Game/GameSession/NationManagementScreen/PoliticsMenu.gd
@@ -0,0 +1,34 @@
+extends GUINode
+
+var _active : bool = false
+
+const _screen : NationManagement.Screen = NationManagement.Screen.POLITICS
+
+func _ready() -> void:
+ GameSingleton.gamestate_updated.connect(_update_info)
+
+ Events.NationManagementScreens.update_active_nation_management_screen.connect(_on_update_active_nation_management_screen)
+
+ add_gui_element("country_politics", "country_politics")
+
+ var close_button : Button = get_button_from_nodepath(^"./country_politics/close_button")
+ if close_button:
+ close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen))
+
+ _update_info()
+
+func _notification(what : int) -> void:
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _update_info()
+
+func _on_update_active_nation_management_screen(active_screen : NationManagement.Screen) -> void:
+ _active = active_screen == _screen
+ _update_info()
+
+func _update_info() -> void:
+ if _active:
+ # TODO - update UI state
+ show()
+ else:
+ hide()
diff --git a/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd b/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd
new file mode 100644
index 0000000..29bd56b
--- /dev/null
+++ b/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd
@@ -0,0 +1,34 @@
+extends GUINode
+
+var _active : bool = false
+
+const _screen : NationManagement.Screen = NationManagement.Screen.POPULATION
+
+func _ready() -> void:
+ GameSingleton.gamestate_updated.connect(_update_info)
+
+ Events.NationManagementScreens.update_active_nation_management_screen.connect(_on_update_active_nation_management_screen)
+
+ add_gui_element("country_pops", "country_pop")
+
+ var close_button : Button = get_button_from_nodepath(^"./country_pop/close_button")
+ if close_button:
+ close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen))
+
+ _update_info()
+
+func _notification(what : int) -> void:
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _update_info()
+
+func _on_update_active_nation_management_screen(active_screen : NationManagement.Screen) -> void:
+ _active = active_screen == _screen
+ _update_info()
+
+func _update_info() -> void:
+ if _active:
+ # TODO - update UI state
+ show()
+ else:
+ hide()
diff --git a/game/src/Game/GameSession/NationManagementScreen/ProductionMenu.gd b/game/src/Game/GameSession/NationManagementScreen/ProductionMenu.gd
new file mode 100644
index 0000000..938f8e7
--- /dev/null
+++ b/game/src/Game/GameSession/NationManagementScreen/ProductionMenu.gd
@@ -0,0 +1,34 @@
+extends GUINode
+
+var _active : bool = false
+
+const _screen : NationManagement.Screen = NationManagement.Screen.PRODUCTION
+
+func _ready() -> void:
+ GameSingleton.gamestate_updated.connect(_update_info)
+
+ Events.NationManagementScreens.update_active_nation_management_screen.connect(_on_update_active_nation_management_screen)
+
+ add_gui_element("country_production", "country_production")
+
+ var close_button : Button = get_button_from_nodepath(^"./country_production/close_button")
+ if close_button:
+ close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen))
+
+ _update_info()
+
+func _notification(what : int) -> void:
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _update_info()
+
+func _on_update_active_nation_management_screen(active_screen : NationManagement.Screen) -> void:
+ _active = active_screen == _screen
+ _update_info()
+
+func _update_info() -> void:
+ if _active:
+ # TODO - update UI state
+ show()
+ else:
+ hide()
diff --git a/game/src/Game/GameSession/NationManagementScreen/TechnologyMenu.gd b/game/src/Game/GameSession/NationManagementScreen/TechnologyMenu.gd
new file mode 100644
index 0000000..a80ed1e
--- /dev/null
+++ b/game/src/Game/GameSession/NationManagementScreen/TechnologyMenu.gd
@@ -0,0 +1,34 @@
+extends GUINode
+
+var _active : bool = false
+
+const _screen : NationManagement.Screen = NationManagement.Screen.TECHNOLOGY
+
+func _ready() -> void:
+ GameSingleton.gamestate_updated.connect(_update_info)
+
+ Events.NationManagementScreens.update_active_nation_management_screen.connect(_on_update_active_nation_management_screen)
+
+ add_gui_element("country_technology", "country_technology")
+
+ var close_button : Button = get_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 _notification(what : int) -> void:
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _update_info()
+
+func _on_update_active_nation_management_screen(active_screen : NationManagement.Screen) -> void:
+ _active = active_screen == _screen
+ _update_info()
+
+func _update_info() -> void:
+ if _active:
+ # TODO - update UI state
+ show()
+ else:
+ hide()
diff --git a/game/src/Game/GameSession/NationManagementScreen/TradeMenu.gd b/game/src/Game/GameSession/NationManagementScreen/TradeMenu.gd
new file mode 100644
index 0000000..775f31a
--- /dev/null
+++ b/game/src/Game/GameSession/NationManagementScreen/TradeMenu.gd
@@ -0,0 +1,34 @@
+extends GUINode
+
+var _active : bool = false
+
+const _screen : NationManagement.Screen = NationManagement.Screen.TRADE
+
+func _ready() -> void:
+ GameSingleton.gamestate_updated.connect(_update_info)
+
+ Events.NationManagementScreens.update_active_nation_management_screen.connect(_on_update_active_nation_management_screen)
+
+ add_gui_element("country_trade", "country_trade")
+
+ var close_button : Button = get_button_from_nodepath(^"./country_trade/close_button")
+ if close_button:
+ close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen))
+
+ _update_info()
+
+func _notification(what : int) -> void:
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _update_info()
+
+func _on_update_active_nation_management_screen(active_screen : NationManagement.Screen) -> void:
+ _active = active_screen == _screen
+ _update_info()
+
+func _update_info() -> void:
+ if _active:
+ # TODO - update UI state
+ show()
+ else:
+ hide()
diff --git a/game/src/Game/GameSession/ProvinceOverviewPanel.gd b/game/src/Game/GameSession/ProvinceOverviewPanel.gd
index 6fe28d7..cb76241 100644
--- a/game/src/Game/GameSession/ProvinceOverviewPanel.gd
+++ b/game/src/Game/GameSession/ProvinceOverviewPanel.gd
@@ -121,7 +121,7 @@ func _ready() -> void:
GameSingleton.province_selected.connect(_on_province_selected)
GameSingleton.gamestate_updated.connect(_update_info)
- if add_gui_element("province_interface.gui", "province_view") != OK:
+ if add_gui_element("province_interface", "province_view") != OK:
push_error("Failed to generate province overview panel!")
return
@@ -144,7 +144,7 @@ func _ready() -> void:
_administrative_percentage_label = get_label_from_nodepath(^"./province_view/province_view_header/admin_efficiency")
_owner_percentage_label = get_label_from_nodepath(^"./province_view/province_view_header/owner_presence")
_province_modifiers_overlapping_elements_box = get_gui_overlapping_elements_box_from_nodepath(^"./province_view/province_view_header/province_modifiers")
- if _province_modifiers_overlapping_elements_box and _province_modifiers_overlapping_elements_box.set_gui_child_element_name("province_interface.gui", "prov_state_modifier") != OK:
+ if _province_modifiers_overlapping_elements_box and _province_modifiers_overlapping_elements_box.set_gui_child_element_name("province_interface", "prov_state_modifier") != OK:
_province_modifiers_overlapping_elements_box = null # hide province modifiers box since we can't do anything with it
_terrain_type_texture = get_gfx_icon_texture_from_nodepath(^"./province_view/province_view_header/prov_terrain")
_life_rating_bar = get_progress_bar_from_nodepath(^"./province_view/province_view_header/liferating")
@@ -168,7 +168,7 @@ func _ready() -> void:
_pop_cultures_piechart = get_gfx_pie_chart_texture_from_nodepath(^"./province_view/province_statistics/culture_chart")
_supply_limit_label = get_label_from_nodepath(^"./province_view/province_statistics/supply_limit_label")
_cores_overlapping_elements_box = get_gui_overlapping_elements_box_from_nodepath(^"./province_view/province_statistics/core_icons")
- if _cores_overlapping_elements_box and _cores_overlapping_elements_box.set_gui_child_element_name("province_interface.gui", "province_core") != OK:
+ if _cores_overlapping_elements_box and _cores_overlapping_elements_box.set_gui_child_element_name("province_interface", "province_core") != OK:
_cores_overlapping_elements_box = null # hide cores box since we can't do anything with it
_buildings_panel = get_panel_from_nodepath(^"./province_view/province_buildings")
@@ -176,7 +176,7 @@ func _ready() -> void:
var target_slot_count : int = GameSingleton.get_province_building_count()
var slot_y : float = 0.0
for current_slot_count : int in target_slot_count:
- var slot := GUINode.generate_gui_element("province_interface.gui", "building", "building_slot_%d" % current_slot_count)
+ var slot := GUINode.generate_gui_element("province_interface", "building", "building_slot_%d" % current_slot_count)
if slot:
_buildings_panel.add_child(slot)
slot.set_position(Vector2(0.0, slot_y))
diff --git a/game/src/Game/GameSession/Topbar.gd b/game/src/Game/GameSession/Topbar.gd
index 05eb985..3cfc0e6 100644
--- a/game/src/Game/GameSession/Topbar.gd
+++ b/game/src/Game/GameSession/Topbar.gd
@@ -1,5 +1,7 @@
extends GUINode
+@export var _outliner_guinode : GUINode
+
var _speed_up_button : Button
var _speed_down_button : Button
var _speed_indicator_button : Button
@@ -7,11 +9,16 @@ var _speed_indicator_texture : GFXIconTexture
var _date_label : Label
var _country_name_label : Label
+# NationManagement.Screen-Button
+var _nation_management_buttons : Dictionary
+# NationManagement.Screen-GFXIconTexture
+var _nation_management_button_textures : Dictionary
+
func _ready() -> void:
GameSingleton.gamestate_updated.connect(_update_info)
GameSingleton.clock_state_changed.connect(_update_speed_controls)
- add_gui_element("topbar.gui", "topbar")
+ add_gui_element("topbar", "topbar")
hide_nodes([
^"./topbar/topbar_outlinerbutton_bg",
@@ -20,10 +27,12 @@ func _ready() -> void:
const player_country : String = "SLV"
+ # 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)
+ # 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)
@@ -47,6 +56,31 @@ func _ready() -> void:
_speed_indicator_button.pressed.connect(_on_play_pause_button_pressed)
_speed_indicator_texture = GUINode.get_gfx_icon_texture_from_node(_speed_indicator_button)
+ # Nation management screens
+ const screen_nodepaths : Dictionary = {
+ NationManagement.Screen.PRODUCTION : ^"./topbar/topbarbutton_production",
+ NationManagement.Screen.BUDGET : ^"./topbar/topbarbutton_budget",
+ NationManagement.Screen.TECHNOLOGY : ^"./topbar/topbarbutton_tech",
+ NationManagement.Screen.POLITICS : ^"./topbar/topbarbutton_politics",
+ NationManagement.Screen.POPULATION : ^"./topbar/topbarbutton_pops",
+ NationManagement.Screen.TRADE : ^"./topbar/topbarbutton_trade",
+ NationManagement.Screen.DIPLOMACY : ^"./topbar/topbarbutton_diplomacy",
+ NationManagement.Screen.MILITARY : ^"./topbar/topbarbutton_military"
+ }
+ for screen in screen_nodepaths:
+ var button : Button = get_button_from_nodepath(screen_nodepaths[screen])
+ if button:
+ button.pressed.connect(
+ Events.NationManagementScreens.toggle_nation_management_screen.bind(screen)
+ )
+ var icon : GFXIconTexture = get_gfx_icon_texture_from_node(button)
+ if icon:
+ _nation_management_buttons[screen] = button
+ _nation_management_button_textures[screen] = icon
+ Events.NationManagementScreens.update_active_nation_management_screen.connect(
+ _on_update_active_nation_management_screen
+ )
+
_update_info()
_update_speed_controls()
@@ -92,3 +126,8 @@ func _on_increase_speed_button_pressed() -> void:
func _on_decrease_speed_button_pressed() -> void:
print("Speed down!")
GameSingleton.decrease_speed()
+
+func _on_update_active_nation_management_screen(active_screen : NationManagement.Screen) -> void:
+ for screen in _nation_management_buttons:
+ _nation_management_button_textures[screen].set_icon_index(1 + int(screen == active_screen))
+ _nation_management_buttons[screen].queue_redraw()
diff --git a/game/src/Game/GameStart.gd b/game/src/Game/GameStart.gd
index 7a52846..0aadbb9 100644
--- a/game/src/Game/GameStart.gd
+++ b/game/src/Game/GameStart.gd
@@ -48,7 +48,7 @@ func _save_setting(file : ConfigFile) -> void:
func _setup_compatibility_mode_paths() -> void:
# To test mods, set your base path to Victoria II and then pass mods in reverse order with --mod="mod" for each mod.
-
+
var arg_base_path : String = ArgumentParser.get_argument(&"base-path", "")
var arg_search_path : String = ArgumentParser.get_argument(&"search-path", "")
diff --git a/game/src/Game/GlobalClass/NationManagement.gd b/game/src/Game/GlobalClass/NationManagement.gd
new file mode 100644
index 0000000..3b73bde
--- /dev/null
+++ b/game/src/Game/GlobalClass/NationManagement.gd
@@ -0,0 +1,13 @@
+class_name NationManagement
+
+enum Screen {
+ NONE,
+ PRODUCTION,
+ BUDGET,
+ TECHNOLOGY,
+ POLITICS,
+ POPULATION,
+ TRADE,
+ DIPLOMACY,
+ MILITARY
+}