aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author George L. Albany <Megacake1234@gmail.com>2024-05-07 01:15:50 +0200
committer GitHub <noreply@github.com>2024-05-07 01:15:50 +0200
commitc29cc0dabe3e3c7d03280e74d2d10fc3cc479c7f (patch)
tree059fe3b320d6ed41416aee3853c5eb8e8ca36583
parent8c8ee1524f51d44acd1d1894eda5984956cba9a6 (diff)
parent7def4dd2e7987c20163c6a419bcc0506b5a670d9 (diff)
Merge pull request #226 from Spartan322/click-mask-guinodes
Improve map view and game panel user experience
-rw-r--r--extension/src/openvic-extension/classes/GUINode.cpp159
-rw-r--r--extension/src/openvic-extension/classes/GUINode.hpp30
-rw-r--r--game/src/Game/GameSession/GameSession.tscn70
-rw-r--r--game/src/Game/GameSession/GameSessionMenu.tscn1
-rw-r--r--game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn2
-rw-r--r--game/src/Game/GameSession/MapView.gd85
-rw-r--r--game/src/Game/GameSession/ProvinceOverviewPanel.gd6
-rw-r--r--game/src/Game/GameSession/Topbar.gd6
-rw-r--r--game/src/Game/Menu/SaveLoadMenu/SaveLoadMenu.tscn1
-rw-r--r--game/src/Game/MusicConductor/MusicPlayer.tscn1
10 files changed, 282 insertions, 79 deletions
diff --git a/extension/src/openvic-extension/classes/GUINode.cpp b/extension/src/openvic-extension/classes/GUINode.cpp
index 73ebb0c..c9af7e2 100644
--- a/extension/src/openvic-extension/classes/GUINode.cpp
+++ b/extension/src/openvic-extension/classes/GUINode.cpp
@@ -1,7 +1,35 @@
#include "GUINode.hpp"
+#include <limits>
+
+#include <godot_cpp/classes/bit_map.hpp>
+#include <godot_cpp/classes/button.hpp>
+#include <godot_cpp/classes/canvas_item.hpp>
+#include <godot_cpp/classes/check_box.hpp>
+#include <godot_cpp/classes/control.hpp>
+#include <godot_cpp/classes/image.hpp>
+#include <godot_cpp/classes/label.hpp>
+#include <godot_cpp/classes/node.hpp>
+#include <godot_cpp/classes/object.hpp>
+#include <godot_cpp/classes/panel.hpp>
+#include <godot_cpp/classes/ref.hpp>
+#include <godot_cpp/classes/style_box.hpp>
#include <godot_cpp/classes/style_box_texture.hpp>
+#include <godot_cpp/classes/texture2d.hpp>
+#include <godot_cpp/classes/texture_progress_bar.hpp>
+#include <godot_cpp/classes/texture_rect.hpp>
+#include <godot_cpp/core/defs.hpp>
+#include <godot_cpp/core/error_macros.hpp>
+#include <godot_cpp/core/object.hpp>
+#include <godot_cpp/core/property_info.hpp>
+#include <godot_cpp/variant/node_path.hpp>
+#include <godot_cpp/variant/rect2.hpp>
+#include <godot_cpp/variant/string.hpp>
+#include <godot_cpp/variant/string_name.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
+#include <godot_cpp/variant/variant.hpp>
+#include <godot_cpp/variant/vector2.hpp>
+#include <godot_cpp/variant/vector2i.hpp>
#include "openvic-extension/utility/ClassBindings.hpp"
#include "openvic-extension/utility/UITools.hpp"
@@ -31,6 +59,15 @@ void GUINode::_bind_methods() {
OV_BIND_METHOD(GUINode::add_gui_element, { "gui_scene", "gui_element", "name" }, DEFVAL(String {}));
OV_BIND_SMETHOD(get_gui_position, { "gui_scene", "gui_position" });
+ OV_BIND_METHOD(GUINode::get_click_mask);
+ OV_BIND_METHOD(GUINode::set_click_mask, { "mask" });
+ ADD_PROPERTY(
+ PropertyInfo(Variant::OBJECT, "click_mask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), "set_click_mask", "get_click_mask"
+ );
+
+ OV_BIND_METHOD(GUINode::set_click_mask_from_nodepaths, { "paths" });
+ OV_BIND_METHOD(GUINode::update_click_mask);
+
#define GET_BINDINGS(type, name) \
OV_BIND_SMETHOD(get_##name##_from_node, { "node" }); \
OV_BIND_METHOD(GUINode::get_##name##_from_nodepath, { "path" });
@@ -56,7 +93,7 @@ GUINode::GUINode() {
set_anchors_and_offsets_preset(PRESET_FULL_RECT);
set_h_grow_direction(GROW_DIRECTION_BOTH);
set_v_grow_direction(GROW_DIRECTION_BOTH);
- set_mouse_filter(MOUSE_FILTER_IGNORE);
+ set_mouse_filter(MOUSE_FILTER_STOP);
}
Control* GUINode::generate_gui_element(String const& gui_scene, String const& gui_element, String const& name) {
@@ -196,3 +233,123 @@ String GUINode::format_province_name(String const& province_identifier) {
static const String province_prefix = "PROV";
return province_prefix + province_identifier;
}
+
+Ref<BitMap> GUINode::get_click_mask() const {
+ return _click_mask;
+}
+
+void GUINode::set_click_mask(Ref<BitMap> const& mask) {
+ if (_click_mask == mask) {
+ return;
+ }
+ _click_mask = mask;
+ queue_redraw();
+ update_minimum_size();
+}
+
+bool GUINode::_update_click_mask_for(Ref<Image> const& img, int index) {
+ ERR_FAIL_INDEX_V(index, _mask_controls.size(), false);
+ Control* control = _mask_controls[index];
+ if (!UtilityFunctions::is_instance_valid(control) && !control->is_inside_tree()) {
+ _mask_controls.remove_at(index);
+ return false;
+ }
+ ERR_FAIL_COND_V(img.is_null(), false);
+ Ref<Texture2D> texture = get_texture_from_node(control);
+ ERR_FAIL_COND_V(texture.is_null(), false);
+ Ref<Image> texture_img = texture->get_image();
+ if (img->is_empty()) {
+ img->copy_from(texture_img);
+ } else {
+ if (img->get_format() != texture_img->get_format()) {
+ img->convert(texture_img->get_format());
+ }
+ Vector2i img_size = img->get_size();
+ Vector2i total_size = control->get_screen_position() + texture_img->get_size();
+ Vector2i new_img_size = img_size.max(total_size);
+ if (new_img_size != img_size) {
+ img->crop(new_img_size.x, new_img_size.y);
+ }
+ img->blend_rect(texture_img, texture_img->get_used_rect(), control->get_position());
+ }
+ ERR_FAIL_COND_V(img->is_empty(), false);
+ return true;
+}
+
+void GUINode::update_click_mask() {
+ static constexpr real_t max_real = std::numeric_limits<real_t>::max();
+ static const Point2 max_point { max_real, max_real };
+ if (_mask_controls.size() == 0) {
+ return;
+ }
+
+ if (_click_mask.is_null()) {
+ _click_mask.instantiate();
+ }
+ Ref<Image> img;
+ img.instantiate();
+ Vector2 size = get_size();
+ img->create(size.x, size.y, false, Image::Format::FORMAT_RGBA8);
+ Point2 highest_position = { max_real, max_real };
+ for (int index = 0; index < _mask_controls.size(); index++) {
+ if (!_update_click_mask_for(img, index)) {
+ continue;
+ }
+ Vector2 screen_pos = _mask_controls[index]->get_screen_position();
+ highest_position = highest_position.min(screen_pos);
+ }
+ ERR_FAIL_COND(img.is_null());
+ ERR_FAIL_COND(highest_position == max_point);
+ _texture_region = Rect2(Point2(), img->get_size());
+ _position_rect = Rect2(highest_position, _texture_region.get_size());
+ _click_mask->create_from_image_alpha(img);
+ queue_redraw();
+ update_minimum_size();
+}
+
+void GUINode::set_click_mask_from_nodepaths(TypedArray<NodePath> const& paths) {
+ // TODO: Update to use https://github.com/godotengine/godot/pull/90916
+ // for(godot::Control* control : _mask_controls) {
+ // control->set_mouse_filter(Control::MouseFilter::MOUSE_FILTER_STOP);
+ // }
+ _mask_controls.clear();
+ for (int index = 0; index < paths.size(); index++) {
+ Control* control = _cast_node<Control>(get_node_internal(paths[index]));
+ ERR_CONTINUE(control == nullptr);
+ control->set_mouse_filter(Control::MouseFilter::MOUSE_FILTER_IGNORE);
+ _mask_controls.push_back(control);
+ }
+ update_click_mask();
+}
+
+bool GUINode::_has_point(godot::Vector2 const& p_point) const {
+ if (!_click_mask.is_valid()) {
+ return Control::_has_point(p_point);
+ }
+
+ Point2 point = p_point;
+ Rect2 rect;
+ Size2 mask_size = _click_mask->get_size();
+
+ if (!_position_rect.has_area()) {
+ rect.size = mask_size;
+ } else {
+ // we need to transform the point from our scaled / translated image back to our mask image
+ Point2 ofs = _position_rect.position;
+ Size2 scale = mask_size / _position_rect.size;
+
+ // offset and scale the new point position to adjust it to the bitmask size
+ point -= ofs;
+ point *= scale;
+
+ // finally, we need to check if the point is inside a rectangle with a position >= 0,0 and a size <= mask_size
+ rect.position = _texture_region.position.min(Point2 {});
+ rect.size = mask_size.min(_texture_region.size);
+ }
+
+ if (!rect.has_point(point)) {
+ return false;
+ }
+
+ return _click_mask->get_bitv(point);
+}
diff --git a/extension/src/openvic-extension/classes/GUINode.hpp b/extension/src/openvic-extension/classes/GUINode.hpp
index 3dbe403..8d926cc 100644
--- a/extension/src/openvic-extension/classes/GUINode.hpp
+++ b/extension/src/openvic-extension/classes/GUINode.hpp
@@ -1,17 +1,27 @@
#pragma once
+#include <godot_cpp/classes/bit_map.hpp>
#include <godot_cpp/classes/button.hpp>
#include <godot_cpp/classes/check_box.hpp>
+#include <godot_cpp/classes/control.hpp>
+#include <godot_cpp/classes/image.hpp>
+#include <godot_cpp/classes/input_event.hpp>
#include <godot_cpp/classes/label.hpp>
+#include <godot_cpp/classes/node.hpp>
#include <godot_cpp/classes/panel.hpp>
+#include <godot_cpp/classes/ref.hpp>
+#include <godot_cpp/classes/texture2d.hpp>
#include <godot_cpp/classes/texture_progress_bar.hpp>
#include <godot_cpp/classes/texture_rect.hpp>
+#include <godot_cpp/templates/vector.hpp>
+#include <godot_cpp/variant/node_path.hpp>
+#include <godot_cpp/variant/rect2.hpp>
+#include <godot_cpp/variant/string.hpp>
+#include <godot_cpp/variant/vector2.hpp>
-#include <openvic-simulation/interface/GUI.hpp>
-
-#include "openvic-extension/classes/GFXSpriteTexture.hpp"
#include "openvic-extension/classes/GFXMaskedFlagTexture.hpp"
#include "openvic-extension/classes/GFXPieChartTexture.hpp"
+#include "openvic-extension/classes/GFXSpriteTexture.hpp"
#include "openvic-extension/classes/GUIListBox.hpp"
#include "openvic-extension/classes/GUIOverlappingElementsBox.hpp"
#include "openvic-extension/classes/GUIScrollbar.hpp"
@@ -20,6 +30,11 @@ namespace OpenVic {
class GUINode : public godot::Control {
GDCLASS(GUINode, godot::Control)
+ godot::Ref<godot::BitMap> _click_mask;
+ godot::Vector<Control*> _mask_controls;
+ godot::Rect2 _texture_region;
+ godot::Rect2 _position_rect;
+
protected:
static void _bind_methods();
@@ -73,5 +88,14 @@ namespace OpenVic {
static godot::String int_to_formatted_string(int64_t val);
static godot::String float_to_formatted_string(float val, int32_t decimal_places);
static godot::String format_province_name(godot::String const& province_identifier);
+
+ godot::Ref<godot::BitMap> get_click_mask() const;
+ void set_click_mask(godot::Ref<godot::BitMap> const& mask);
+
+ void set_click_mask_from_nodepaths(godot::TypedArray<godot::NodePath> const& paths);
+ bool _update_click_mask_for(godot::Ref<godot::Image> const& img, int index);
+ void update_click_mask();
+
+ bool _has_point(godot::Vector2 const& point) const override;
};
}
diff --git a/game/src/Game/GameSession/GameSession.tscn b/game/src/Game/GameSession/GameSession.tscn
index d2fc3a3..343ddfe 100644
--- a/game/src/Game/GameSession/GameSession.tscn
+++ b/game/src/Game/GameSession/GameSession.tscn
@@ -28,63 +28,76 @@ grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
script = ExtResource("1_eklvp")
-_game_session_menu = NodePath("GameSessionMenu")
+_game_session_menu = NodePath("UICanvasLayer/UI/GameSessionMenu")
[node name="MapView" parent="." instance=ExtResource("4_xkg5j")]
-[node name="ProvinceOverviewPanel" type="GUINode" parent="."]
+[node name="UICanvasLayer" type="CanvasLayer" parent="."]
+
+[node name="UI" type="Control" parent="UICanvasLayer"]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+mouse_filter = 2
+
+[node name="ProvinceOverviewPanel" type="GUINode" parent="UICanvasLayer/UI"]
layout_mode = 1
anchors_preset = 15
+mouse_force_pass_scroll_events = false
script = ExtResource("5_lfv8l")
-[node name="Topbar" type="GUINode" parent="."]
+[node name="Topbar" type="GUINode" parent="UICanvasLayer/UI"]
layout_mode = 1
anchors_preset = 15
+mouse_force_pass_scroll_events = false
script = ExtResource("4_2kbih")
-[node name="ProductionMenu" type="GUINode" parent="Topbar"]
+[node name="ProductionMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"]
layout_mode = 1
anchors_preset = 15
script = ExtResource("5_16755")
-[node name="BudgetMenu" type="GUINode" parent="Topbar"]
+[node name="BudgetMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"]
layout_mode = 1
anchors_preset = 15
script = ExtResource("6_vninv")
-[node name="TechnologyMenu" type="GUINode" parent="Topbar"]
+[node name="TechnologyMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"]
layout_mode = 1
anchors_preset = 15
script = ExtResource("7_r712c")
-[node name="PoliticsMenu" type="GUINode" parent="Topbar"]
+[node name="PoliticsMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"]
layout_mode = 1
anchors_preset = 15
script = ExtResource("8_ppdek")
-[node name="PopulationMenu" type="GUINode" parent="Topbar"]
+[node name="PopulationMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"]
layout_mode = 1
anchors_preset = 15
script = ExtResource("10_laee7")
-[node name="TradeMenu" type="GUINode" parent="Topbar"]
+[node name="TradeMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"]
layout_mode = 1
anchors_preset = 15
script = ExtResource("10_mv1r6")
-[node name="DiplomacyMenu" type="GUINode" parent="Topbar"]
+[node name="DiplomacyMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"]
layout_mode = 1
anchors_preset = 15
script = ExtResource("11_fu7ys")
-[node name="MilitaryMenu" type="GUINode" parent="Topbar"]
+[node name="MilitaryMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"]
layout_mode = 1
anchors_preset = 15
script = ExtResource("12_6h6nc")
-[node name="MapControlPanel" parent="." instance=ExtResource("3_afh6d")]
+[node name="MapControlPanel" parent="UICanvasLayer/UI" instance=ExtResource("3_afh6d")]
layout_mode = 1
-anchors_preset = 3
+anchors_preset = -1
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
@@ -92,7 +105,7 @@ anchor_bottom = 1.0
grow_horizontal = 0
grow_vertical = 0
-[node name="GameSessionMenu" parent="." instance=ExtResource("3_bvmqh")]
+[node name="GameSessionMenu" parent="UICanvasLayer/UI" instance=ExtResource("3_bvmqh")]
visible = false
layout_mode = 1
anchors_preset = 8
@@ -107,11 +120,12 @@ offset_bottom = 165.0
grow_horizontal = 2
grow_vertical = 2
-[node name="OptionsMenu" parent="." instance=ExtResource("6_p5mnx")]
+[node name="OptionsMenu" parent="UICanvasLayer/UI" instance=ExtResource("6_p5mnx")]
visible = false
layout_mode = 1
+mouse_force_pass_scroll_events = false
-[node name="SaveLoadMenu" parent="." instance=ExtResource("8_4g7ko")]
+[node name="SaveLoadMenu" parent="UICanvasLayer/UI" instance=ExtResource("8_4g7ko")]
visible = false
layout_mode = 1
anchors_preset = -1
@@ -120,7 +134,7 @@ anchor_right = 0.5
offset_left = -640.0
offset_right = 640.0
-[node name="MusicPlayer" parent="." instance=ExtResource("2_kt6aa")]
+[node name="MusicPlayer" parent="UICanvasLayer/UI" instance=ExtResource("2_kt6aa")]
layout_mode = 1
anchors_preset = 1
anchor_left = 1.0
@@ -129,15 +143,13 @@ offset_left = -150.0
offset_right = 0.0
grow_horizontal = 0
-[connection signal="map_view_camera_changed" from="MapView" to="MapControlPanel" method="_on_map_view_camera_changed"]
-[connection signal="game_session_menu_button_pressed" from="MapControlPanel" to="." method="_on_game_session_menu_button_pressed"]
-[connection signal="minimap_clicked" from="MapControlPanel" to="MapView" method="_on_minimap_clicked"]
-[connection signal="mouse_entered" from="MapControlPanel" to="MapView" method="_on_mouse_exited_viewport"]
-[connection signal="mouse_exited" from="MapControlPanel" to="MapView" method="_on_mouse_entered_viewport"]
-[connection signal="zoom_in_button_pressed" from="MapControlPanel" to="MapView" method="zoom_in"]
-[connection signal="zoom_out_button_pressed" from="MapControlPanel" to="MapView" method="zoom_out"]
-[connection signal="load_button_pressed" from="GameSessionMenu" to="SaveLoadMenu" method="show_for_load"]
-[connection signal="options_button_pressed" from="GameSessionMenu" to="OptionsMenu" method="show"]
-[connection signal="save_button_pressed" from="GameSessionMenu" to="SaveLoadMenu" method="show_for_save"]
-[connection signal="back_button_pressed" from="OptionsMenu" to="MapView" method="enable_processing"]
-[connection signal="back_button_pressed" from="OptionsMenu" to="OptionsMenu" method="hide"]
+[connection signal="map_view_camera_changed" from="MapView" to="UICanvasLayer/UI/MapControlPanel" method="_on_map_view_camera_changed"]
+[connection signal="game_session_menu_button_pressed" from="UICanvasLayer/UI/MapControlPanel" to="." method="_on_game_session_menu_button_pressed"]
+[connection signal="minimap_clicked" from="UICanvasLayer/UI/MapControlPanel" to="MapView" method="_on_minimap_clicked"]
+[connection signal="zoom_in_button_pressed" from="UICanvasLayer/UI/MapControlPanel" to="MapView" method="zoom_in"]
+[connection signal="zoom_out_button_pressed" from="UICanvasLayer/UI/MapControlPanel" to="MapView" method="zoom_out"]
+[connection signal="load_button_pressed" from="UICanvasLayer/UI/GameSessionMenu" to="UICanvasLayer/UI/SaveLoadMenu" method="show_for_load"]
+[connection signal="options_button_pressed" from="UICanvasLayer/UI/GameSessionMenu" to="UICanvasLayer/UI/OptionsMenu" method="show"]
+[connection signal="save_button_pressed" from="UICanvasLayer/UI/GameSessionMenu" to="UICanvasLayer/UI/SaveLoadMenu" method="show_for_save"]
+[connection signal="back_button_pressed" from="UICanvasLayer/UI/OptionsMenu" to="MapView" method="enable_processing"]
+[connection signal="back_button_pressed" from="UICanvasLayer/UI/OptionsMenu" to="UICanvasLayer/UI/OptionsMenu" method="hide"]
diff --git a/game/src/Game/GameSession/GameSessionMenu.tscn b/game/src/Game/GameSession/GameSessionMenu.tscn
index af81f09..9885c7b 100644
--- a/game/src/Game/GameSession/GameSessionMenu.tscn
+++ b/game/src/Game/GameSession/GameSessionMenu.tscn
@@ -7,6 +7,7 @@
[node name="GameSessionMenu" type="PanelContainer" node_paths=PackedStringArray("_main_menu_dialog", "_quit_dialog")]
process_mode = 3
editor_description = "UI-68"
+mouse_force_pass_scroll_events = false
theme = ExtResource("1_2onog")
theme_type_variation = &"SessionPanel"
script = ExtResource("1_usq6o")
diff --git a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn
index 6731358..7578c82 100644
--- a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn
+++ b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn
@@ -17,7 +17,7 @@ events = [SubResource("InputEventAction_5nck3")]
[node name="MapControlPanel" type="PanelContainer" node_paths=PackedStringArray("_mapmodes_grid")]
editor_description = "SS-103, UI-548"
-mouse_filter = 1
+mouse_force_pass_scroll_events = false
script = ExtResource("1_ign64")
_mapmodes_grid = NodePath("MapPanelMargin/MapPanelList/MapDisplayList/MapmodesGrid")
diff --git a/game/src/Game/GameSession/MapView.gd b/game/src/Game/GameSession/MapView.gd
index 2ab7c34..a83c790 100644
--- a/game/src/Game/GameSession/MapView.gd
+++ b/game/src/Game/GameSession/MapView.gd
@@ -16,14 +16,13 @@ const _action_click : StringName = &"map_click"
@export var _camera : Camera3D
-@export var _cardinal_move_speed : float = 1.0
+@export var _cardinal_move_speed : float = 2.5
@export var _edge_move_threshold: float = 0.01
@export var _edge_move_speed: float = 2.5
var _drag_anchor : Vector2
var _drag_active : bool = false
var _mouse_over_viewport : bool = true
-var _window_in_focus : bool = true
@export var _zoom_target_min : float = 0.10
@export var _zoom_target_max : float = 5.0
@@ -122,17 +121,6 @@ func _ready() -> void:
_map_text.generate_map_names()
-func _notification(what : int) -> void:
- match what:
- NOTIFICATION_WM_MOUSE_ENTER: # Mouse inside window
- _on_mouse_entered_viewport()
- NOTIFICATION_WM_MOUSE_EXIT: # Mouse out of window
- _on_mouse_exited_viewport()
- NOTIFICATION_WM_WINDOW_FOCUS_IN: # Window comes into focus
- _on_window_entered_focus()
- NOTIFICATION_WM_WINDOW_FOCUS_OUT: # Window goes out of focus
- _on_window_exited_focus()
-
func _world_to_map_coords(pos : Vector3) -> Vector2:
return (Vector2(pos.x, pos.z) - _map_mesh_corner) / _map_mesh_dims
@@ -163,14 +151,34 @@ func zoom_out() -> void:
# cursor location. I'm not sure if we want to preserve this behavior.
_zoom_position = Vector2()
+func set_hovered_province_index(hover_index : int) -> void:
+ _map_shader_material.set_shader_parameter(GameLoader.ShaderManager.param_hover_index, hover_index)
+
+func set_hovered_province_at(pos : Vector2) -> void:
+ var hover_index := GameSingleton.get_province_index_from_uv_coords(pos)
+ set_hovered_province_index(hover_index)
+
+func unset_hovered_province() -> void:
+ set_hovered_province_index(0)
+
func _on_province_selected(index : int) -> void:
_map_shader_material.set_shader_parameter(GameLoader.ShaderManager.param_selected_index, index)
print("Province selected with index: ", index)
+func _input(event : InputEvent) -> void:
+ if event is InputEventMouseMotion:
+ _mouse_pos_viewport = get_window().get_mouse_position()
+ elif _drag_active and event.is_action_released(_action_drag):
+ _drag_active = false
+
# REQUIREMENTS
# * SS-31
func _unhandled_input(event : InputEvent) -> void:
- if event.is_action_pressed(_action_click):
+ if event is InputEventMouseMotion:
+ _mouse_over_viewport = true
+ set_hovered_province_at(_viewport_to_map_coords(_mouse_pos_viewport))
+
+ elif event.is_action_pressed(_action_click):
if _mouse_over_viewport:
# Check if the mouse is outside of bounds
if _map_mesh.is_valid_uv_coord(_mouse_pos_map):
@@ -182,17 +190,16 @@ func _unhandled_input(event : InputEvent) -> void:
push_warning("Drag being activated while already active!")
_drag_active = true
_drag_anchor = _mouse_pos_map
- elif event.is_action_released(_action_drag):
- if not _drag_active:
- push_warning("Drag being deactivated while already not active!")
- _drag_active = false
elif event.is_action_pressed(_action_zoom_in, true):
zoom_in()
elif event.is_action_pressed(_action_zoom_out, true):
zoom_out()
-func _physics_process(delta : float) -> void:
- _mouse_pos_viewport = get_viewport().get_mouse_position()
+func _process(delta : float) -> void:
+ if _is_viewport_inactive():
+ _mouse_over_viewport = false
+ unset_hovered_province()
+
_viewport_dims = Vector2(Resolution.get_current_resolution())
# Process movement
_movement_process(delta)
@@ -222,7 +229,7 @@ func _movement_process(delta : float) -> void:
# REQUIREMENTS
# * UIFUN-125
func _edge_scrolling_vector() -> Vector2:
- if not _window_in_focus:
+ if _is_viewport_inactive():
return Vector2()
var mouse_vector := _mouse_pos_viewport * GuiScale.get_current_guiscale() / _viewport_dims - Vector2(0.5, 0.5)
# Only scroll if outside the move threshold.
@@ -233,11 +240,12 @@ func _edge_scrolling_vector() -> Vector2:
# REQUIREMENTS
# * SS-75
func _cardinal_movement_vector() -> Vector2:
- var move := Vector2(
- float(Input.is_action_pressed(_action_east)) - float(Input.is_action_pressed(_action_west)),
- float(Input.is_action_pressed(_action_south)) - float(Input.is_action_pressed(_action_north))
- )
- return move * _cardinal_move_speed
+ return Input.get_vector(
+ _action_west,
+ _action_east,
+ _action_north,
+ _action_south
+ ) * _cardinal_move_speed
func _clamp_over_map() -> void:
_camera.position.x = _map_mesh_corner.x + fposmod(_camera.position.x - _map_mesh_corner.x, _map_mesh_dims.x)
@@ -291,23 +299,7 @@ func _update_minimap_viewport() -> void:
map_view_camera_changed.emit(near_left, far_left, far_right, near_right)
func _update_mouse_map_position() -> void:
- if _mouse_over_viewport:
- _mouse_pos_map = _viewport_to_map_coords(_mouse_pos_viewport)
- var hover_index := GameSingleton.get_province_index_from_uv_coords(_mouse_pos_map)
- _map_shader_material.set_shader_parameter(GameLoader.ShaderManager.param_hover_index, hover_index)
-
-func _on_mouse_entered_viewport() -> void:
- _mouse_over_viewport = true
-
-func _on_mouse_exited_viewport() -> void:
- _mouse_over_viewport = false
- _map_shader_material.set_shader_parameter(GameLoader.ShaderManager.param_hover_index, 0)
-
-func _on_window_entered_focus() -> void:
- _window_in_focus = true
-
-func _on_window_exited_focus() -> void:
- _window_in_focus = false
+ _mouse_pos_map = _viewport_to_map_coords(_mouse_pos_viewport)
func _on_minimap_clicked(pos_clicked : Vector2) -> void:
pos_clicked *= _map_mesh_dims
@@ -315,10 +307,13 @@ func _on_minimap_clicked(pos_clicked : Vector2) -> void:
_camera.position.z = pos_clicked.y
_clamp_over_map()
+func _is_viewport_inactive() -> bool:
+ return not get_window().has_focus() or get_window().is_input_handled()
+
func enable_processing() -> void:
set_process_unhandled_input(true)
- set_physics_process(true)
+ set_process(true)
func disable_processing() -> void:
set_process_unhandled_input(false)
- set_physics_process(false)
+ set_process(false)
diff --git a/game/src/Game/GameSession/ProvinceOverviewPanel.gd b/game/src/Game/GameSession/ProvinceOverviewPanel.gd
index 13e7111..42f6765 100644
--- a/game/src/Game/GameSession/ProvinceOverviewPanel.gd
+++ b/game/src/Game/GameSession/ProvinceOverviewPanel.gd
@@ -125,6 +125,12 @@ func _ready() -> void:
push_error("Failed to generate province overview panel!")
return
+ # Disables all consuming invisible panel
+ var prov_view := get_panel_from_nodepath(^"./province_view")
+ if prov_view:
+ prov_view.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ set_click_mask_from_nodepaths([^"./province_view/background"])
+
var close_button : Button = get_button_from_nodepath(^"./province_view/close_button")
if close_button:
close_button.pressed.connect(_on_close_button_pressed)
diff --git a/game/src/Game/GameSession/Topbar.gd b/game/src/Game/GameSession/Topbar.gd
index 92ee75a..8da15e0 100644
--- a/game/src/Game/GameSession/Topbar.gd
+++ b/game/src/Game/GameSession/Topbar.gd
@@ -27,6 +27,12 @@ func _ready() -> void:
const player_country : String = "SLV"
+ # Disables all consuming invisible panel
+ var topbar := get_panel_from_nodepath(^"./topbar")
+ if topbar:
+ topbar.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ set_click_mask_from_nodepaths([^"./topbar/topbar_bg", ^"./topbar/topbar_paper"])
+
# Player country info
var player_flag_texture : GFXMaskedFlagTexture = get_gfx_masked_flag_texture_from_nodepath(^"./topbar/player_flag")
if player_flag_texture:
diff --git a/game/src/Game/Menu/SaveLoadMenu/SaveLoadMenu.tscn b/game/src/Game/Menu/SaveLoadMenu/SaveLoadMenu.tscn
index adc9bdc..38b915c 100644
--- a/game/src/Game/Menu/SaveLoadMenu/SaveLoadMenu.tscn
+++ b/game/src/Game/Menu/SaveLoadMenu/SaveLoadMenu.tscn
@@ -33,6 +33,7 @@ _overwrite_dialog = NodePath("OverwriteDialog")
[node name="SaveLoadPanel" type="PanelContainer" parent="."]
layout_mode = 2
+mouse_force_pass_scroll_events = false
[node name="SaveLoadList" type="VBoxContainer" parent="SaveLoadPanel"]
layout_mode = 2
diff --git a/game/src/Game/MusicConductor/MusicPlayer.tscn b/game/src/Game/MusicConductor/MusicPlayer.tscn
index 27bb476..ef57eac 100644
--- a/game/src/Game/MusicConductor/MusicPlayer.tscn
+++ b/game/src/Game/MusicConductor/MusicPlayer.tscn
@@ -21,6 +21,7 @@ editor_description = "UI-105, UI-107, UI-110, UIFUN-92"
custom_minimum_size = Vector2(150, 0)
layout_mode = 2
focus_mode = 0
+mouse_force_pass_scroll_events = false
alignment = 1
text_overrun_behavior = 3
fit_to_longest_item = false