aboutsummaryrefslogtreecommitdiff
path: root/game/src/Game/GameSession
diff options
context:
space:
mode:
Diffstat (limited to 'game/src/Game/GameSession')
-rw-r--r--game/src/Game/GameSession/GameSession.tscn10
-rw-r--r--game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd4
-rw-r--r--game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn3
-rw-r--r--game/src/Game/GameSession/MapView.gd15
-rw-r--r--game/src/Game/GameSession/SearchPanel.gd143
5 files changed, 170 insertions, 5 deletions
diff --git a/game/src/Game/GameSession/GameSession.tscn b/game/src/Game/GameSession/GameSession.tscn
index d54970f..018aad8 100644
--- a/game/src/Game/GameSession/GameSession.tscn
+++ b/game/src/Game/GameSession/GameSession.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=19 format=3 uid="uid://bgnupcshe1m7r"]
+[gd_scene load_steps=20 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"]
@@ -9,6 +9,7 @@
[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="Script" path="res://src/Game/GameSession/SearchPanel.gd" id="5_t260f"]
[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"]
@@ -111,6 +112,12 @@ anchor_bottom = 1.0
grow_horizontal = 0
grow_vertical = 0
+[node name="SearchPanel" type="GUINode" parent="UICanvasLayer/UI" node_paths=PackedStringArray("_map_view")]
+layout_mode = 1
+anchors_preset = 15
+script = ExtResource("5_t260f")
+_map_view = NodePath("../../../MapView")
+
[node name="GameSessionMenu" parent="UICanvasLayer/UI" instance=ExtResource("3_bvmqh")]
visible = false
layout_mode = 1
@@ -153,6 +160,7 @@ grow_horizontal = 0
[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="search_button_pressed" from="UICanvasLayer/UI/MapControlPanel" to="UICanvasLayer/UI/SearchPanel" method="toggle_visibility"]
[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"]
diff --git a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd
index eb4dd9f..61de6ae 100644
--- a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd
+++ b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd
@@ -1,6 +1,7 @@
extends PanelContainer
signal game_session_menu_button_pressed
+signal search_button_pressed
signal map_view_camera_changed(near_left : Vector2, far_left : Vector2, far_right : Vector2, near_right : Vector2)
signal minimap_clicked(pos_clicked : Vector2)
signal zoom_in_button_pressed
@@ -35,6 +36,9 @@ func _ready() -> void:
func _on_game_session_menu_button_pressed() -> void:
game_session_menu_button_pressed.emit()
+func _on_search_button_pressed() -> void:
+ search_button_pressed.emit()
+
# REQUIREMENTS:
# * SS-76
# * UIFUN-129, UIFUN-131, UIFUN-133, UIFUN-140, UIFUN-141, UIFUN-142
diff --git a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn
index 7578c82..d49cf61 100644
--- a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn
+++ b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn
@@ -80,7 +80,7 @@ focus_mode = 0
mouse_filter = 1
text = "L"
-[node name="FindButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel"]
+[node name="SearchButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel"]
editor_description = "UI-861"
layout_mode = 2
focus_mode = 0
@@ -108,5 +108,6 @@ text = "-"
[connection signal="map_view_camera_changed" from="." to="MapPanelMargin/MapPanelList/MapDisplayList/Minimap/ViewportQuad" method="_on_map_view_camera_changed"]
[connection signal="minimap_clicked" from="MapPanelMargin/MapPanelList/MapDisplayList/Minimap/ViewportQuad" to="." method="_on_minimap_clicked"]
[connection signal="pressed" from="MapPanelMargin/MapPanelList/AuxiliaryPanel/GameSessionMenuButton" to="." method="_on_game_session_menu_button_pressed"]
+[connection signal="pressed" from="MapPanelMargin/MapPanelList/AuxiliaryPanel/SearchButton" to="." method="_on_search_button_pressed"]
[connection signal="pressed" from="MapPanelMargin/MapPanelList/AuxiliaryPanel/ZoomButtonsContainer/ZoomInButton" to="." method="_on_zoom_in_button_pressed"]
[connection signal="pressed" from="MapPanelMargin/MapPanelList/AuxiliaryPanel/ZoomButtonsContainer/ZoomOutButton" to="." method="_on_zoom_out_button_pressed"]
diff --git a/game/src/Game/GameSession/MapView.gd b/game/src/Game/GameSession/MapView.gd
index 01755ec..d77cfe5 100644
--- a/game/src/Game/GameSession/MapView.gd
+++ b/game/src/Game/GameSession/MapView.gd
@@ -134,18 +134,27 @@ func _map_to_world_coords(pos : Vector2) -> Vector3:
pos = pos * _map_mesh_dims + _map_mesh_corner
return Vector3(pos.x, 0, pos.y)
-func _viewport_to_map_coords(pos_viewport : Vector2) -> Vector2:
+func _viewport_to_world_coords(pos_viewport : Vector2) -> Vector3:
var ray_origin := _camera.project_ray_origin(pos_viewport)
var ray_normal := _camera.project_ray_normal(pos_viewport)
# Plane with normal (0,1,0) facing upwards, at a distance 0 from the origin
var intersection : Variant = Plane(0, 1, 0, 0).intersects_ray(ray_origin, ray_normal)
if typeof(intersection) == TYPE_VECTOR3:
- return _world_to_map_coords(intersection as Vector3)
+ return intersection
else:
# Normals parallel to the xz-plane could cause null intersections,
# but the camera's orientation should prevent such normals
push_error("Invalid intersection: ", intersection)
- return Vector2(0.5, 0.5)
+ return _map_to_world_coords(Vector2(0.5, 0.5))
+
+func _viewport_to_map_coords(pos_viewport : Vector2) -> Vector2:
+ return _world_to_map_coords(_viewport_to_world_coords(pos_viewport))
+
+func look_at_map_position(pos : Vector2) -> void:
+ var viewport_centre : Vector2 = Vector2(0.5, 0.5) * _viewport_dims / GuiScale.get_current_guiscale()
+ var pos_delta : Vector3 = _map_to_world_coords(pos) - _viewport_to_world_coords(viewport_centre)
+ _camera.position.x += pos_delta.x
+ _camera.position.z += pos_delta.z
func zoom_in() -> void:
_zoom_target -= _zoom_target_step
diff --git a/game/src/Game/GameSession/SearchPanel.gd b/game/src/Game/GameSession/SearchPanel.gd
new file mode 100644
index 0000000..5554226
--- /dev/null
+++ b/game/src/Game/GameSession/SearchPanel.gd
@@ -0,0 +1,143 @@
+extends GUINode
+
+@export var _map_view : MapView
+
+var _search_panel : Panel
+var _search_line_edit : LineEdit
+var _results_list_box : GUIListBox
+var _result_buttons : Array[Button]
+
+var _drag_active : bool = false
+var _drag_anchor : Vector2
+
+func _ready() -> void:
+ MenuSingleton.search_cache_changed.connect(_update_results_base)
+
+ add_gui_element("goto", "goto_box")
+
+ remove_node(^"./goto_box/goto")
+
+ _search_panel = get_panel_from_nodepath(^"./goto_box")
+
+ var close_button : Button = get_button_from_nodepath(^"./goto_box/cancel")
+ if close_button:
+ close_button.pressed.connect(hide)
+
+ var panel_button : Button = get_button_from_nodepath(^"./goto_box/goto_box")
+ if panel_button:
+ panel_button.button_down.connect(_start_drag)
+ panel_button.button_up.connect(_end_drag)
+ if _search_panel:
+ # Move to back so it's not drawn over the results list
+ _search_panel.move_child(panel_button, 0)
+
+ _search_line_edit = get_line_edit_from_nodepath(^"./goto_box/goto_edit")
+ if _search_line_edit:
+ _search_line_edit.text_changed.connect(_search_string_updated)
+ # Restrict to desired size (by default it's a bit too tall, probably due to font size)
+ _search_line_edit.set_size(_search_line_edit.get_minimum_size())
+
+ _results_list_box = get_gui_listbox_from_nodepath(^"./goto_box/provinces")
+ if _results_list_box:
+ _results_list_box.scroll_index_changed.connect(_update_results_scroll)
+
+ _results_list_box.set_position(_results_list_box.get_position() - Vector2(4, 0))
+
+ hide()
+
+ MenuSingleton.generate_search_cache()
+
+func toggle_visibility() -> void:
+ if is_visible():
+ hide()
+ else:
+ show()
+ if _search_line_edit:
+ _search_line_edit.grab_focus()
+
+func _start_drag() -> void:
+ if _search_panel:
+ _drag_anchor = _search_panel.get_position() - get_window().get_mouse_position()
+ _drag_active = true
+
+func _end_drag() -> void:
+ _drag_active = false
+
+func _input(event : InputEvent) -> void:
+ if _drag_active and event is InputEventMouseMotion:
+ _search_panel.set_position(_drag_anchor + get_window().get_mouse_position())
+
+func _notification(what : int) -> void:
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ MenuSingleton.generate_search_cache()
+
+func _search_string_updated(search_string : String) -> void:
+ MenuSingleton.update_search_results(search_string)
+ _update_results_base()
+
+func _update_results_base() -> void:
+ if not _results_list_box:
+ return
+
+ var result_count : int = MenuSingleton.get_search_result_row_count()
+
+ var result_height : float = 0.0
+ if result_count > 0 and (_results_list_box.get_child_count() > 0 or _add_result_button()):
+ result_height = _results_list_box.get_child(0).get_size().y
+
+ _results_list_box.set_fixed(result_count, result_height, false)
+ _update_results_scroll()
+
+func _add_result_button() -> bool:
+ if not _results_list_box:
+ return false
+
+ var child : Panel = GUINode.generate_gui_element("menubar", "save_game_entry")
+ if not child:
+ return false
+
+ var button : Button = GUINode.get_button_from_node(child.get_node(^"./game"))
+ if not button:
+ child.queue_free()
+ return false
+
+ button.pressed.connect(_result_selected.bind(_result_buttons.size()))
+
+ _results_list_box.add_child(child)
+ _result_buttons.push_back(button)
+
+ return true
+
+func _update_results_scroll(scroll_index : int = -1) -> void:
+ if not _results_list_box:
+ return
+
+ if scroll_index >= 0:
+ _results_list_box.set_scroll_index(scroll_index, false)
+
+ scroll_index = _results_list_box.get_scroll_index()
+
+ var results : PackedStringArray = MenuSingleton.get_search_result_rows(scroll_index, _results_list_box.get_fixed_visible_items())
+
+ if results.size() < _result_buttons.size():
+ _result_buttons.resize(results.size())
+ _results_list_box.clear_children(results.size())
+ else:
+ while _result_buttons.size() < results.size() and _add_result_button():
+ pass # Button is added in the loop condition
+
+ for index : int in min(results.size(), _result_buttons.size()):
+ _result_buttons[index].set_text(results[index])
+
+func _result_selected(index : int) -> void:
+ if _map_view:
+ _map_view.look_at_map_position(MenuSingleton.get_search_result_position(index))
+ else:
+ push_error("SearchPanel missing MapView reference!")
+
+ if _search_line_edit:
+ # This triggers a search results update, preventing further get_search_result_position(index) calls
+ _search_line_edit.clear()
+
+ hide()