aboutsummaryrefslogtreecommitdiff
path: root/game/src/GameSession/MapControlPanel
diff options
context:
space:
mode:
Diffstat (limited to 'game/src/GameSession/MapControlPanel')
-rw-r--r--game/src/GameSession/MapControlPanel/MapControlPanel.gd57
-rw-r--r--game/src/GameSession/MapControlPanel/MapControlPanel.tscn107
-rw-r--r--game/src/GameSession/MapControlPanel/Minimap.gd105
-rw-r--r--game/src/GameSession/MapControlPanel/Minimap.gdshader18
4 files changed, 287 insertions, 0 deletions
diff --git a/game/src/GameSession/MapControlPanel/MapControlPanel.gd b/game/src/GameSession/MapControlPanel/MapControlPanel.gd
new file mode 100644
index 0000000..0cef057
--- /dev/null
+++ b/game/src/GameSession/MapControlPanel/MapControlPanel.gd
@@ -0,0 +1,57 @@
+extends PanelContainer
+
+signal game_session_menu_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
+signal zoom_out_button_pressed
+
+@export var _mapmodes_grid : GridContainer
+
+var _mapmode_button_group : ButtonGroup
+
+# REQUIREMENTS:
+# * UI-550, UI-552, UI-554, UI-561
+func _add_mapmode_button(identifier : String) -> void:
+ var button := Button.new()
+ button.text = identifier
+ button.tooltip_text = identifier
+ button.toggle_mode = true
+ button.button_group = _mapmode_button_group
+ button.mouse_filter = MOUSE_FILTER_PASS
+ _mapmodes_grid.add_child(button)
+ if _mapmode_button_group.get_pressed_button() == null:
+ button.button_pressed = true
+
+func _ready():
+ _mapmode_button_group = ButtonGroup.new()
+ _mapmode_button_group.pressed.connect(_mapmode_pressed)
+ for index in GameSingleton.get_mapmode_count():
+ _add_mapmode_button(GameSingleton.get_mapmode_identifier(index))
+
+# REQUIREMENTS:
+# * UIFUN-10
+func _on_game_session_menu_button_pressed() -> void:
+ game_session_menu_button_pressed.emit()
+
+# REQUIREMENTS:
+# * SS-76
+# * UIFUN-129, UIFUN-131, UIFUN-133
+func _mapmode_pressed(button : BaseButton) -> void:
+ GameSingleton.set_mapmode(button.tooltip_text)
+
+func _on_map_view_camera_changed(near_left : Vector2, far_left : Vector2, far_right : Vector2, near_right : Vector2) -> void:
+ map_view_camera_changed.emit(near_left, far_left, far_right, near_right)
+
+func _on_minimap_clicked(pos_clicked : Vector2) -> void:
+ minimap_clicked.emit(pos_clicked)
+
+# REQUIREMENTS:
+# * UIFUN-269
+func _on_zoom_in_button_pressed() -> void:
+ zoom_in_button_pressed.emit()
+
+# REQUIREMENTS:
+# * UIFUN-270
+func _on_zoom_out_button_pressed() -> void:
+ zoom_out_button_pressed.emit()
diff --git a/game/src/GameSession/MapControlPanel/MapControlPanel.tscn b/game/src/GameSession/MapControlPanel/MapControlPanel.tscn
new file mode 100644
index 0000000..91e2e7e
--- /dev/null
+++ b/game/src/GameSession/MapControlPanel/MapControlPanel.tscn
@@ -0,0 +1,107 @@
+[gd_scene load_steps=7 format=3 uid="uid://g524p8lr574w"]
+
+[ext_resource type="Script" path="res://src/GameSession/MapControlPanel/MapControlPanel.gd" id="1_ign64"]
+[ext_resource type="Shader" path="res://src/GameSession/MapControlPanel/Minimap.gdshader" id="2_rinsg"]
+[ext_resource type="Script" path="res://src/GameSession/MapControlPanel/Minimap.gd" id="3_s4dml"]
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_bhuqb"]
+shader = ExtResource("2_rinsg")
+shader_parameter/province_shape_subdivisions = null
+shader_parameter/selected_index = null
+
+[sub_resource type="InputEventAction" id="InputEventAction_5nck3"]
+action = &"ui_cancel"
+
+[sub_resource type="Shortcut" id="Shortcut_fc1tk"]
+events = [SubResource("InputEventAction_5nck3")]
+
+[node name="MapControlPanel" type="PanelContainer" node_paths=PackedStringArray("_mapmodes_grid")]
+editor_description = "SS-103"
+mouse_filter = 1
+script = ExtResource("1_ign64")
+_mapmodes_grid = NodePath("MapPanelMargin/MapPanelList/MapDisplayList/MapmodesGrid")
+
+[node name="MapPanelMargin" type="MarginContainer" parent="."]
+layout_mode = 2
+theme_override_constants/margin_left = 5
+theme_override_constants/margin_top = 5
+theme_override_constants/margin_right = 5
+theme_override_constants/margin_bottom = 5
+
+[node name="MapPanelList" type="HBoxContainer" parent="MapPanelMargin"]
+layout_mode = 2
+theme_override_constants/separation = 6
+alignment = 1
+
+[node name="MapDisplayList" type="VBoxContainer" parent="MapPanelMargin/MapPanelList"]
+layout_mode = 2
+alignment = 1
+
+[node name="MapmodesGrid" type="GridContainer" parent="MapPanelMargin/MapPanelList/MapDisplayList"]
+editor_description = "UI-750"
+layout_mode = 2
+columns = 11
+
+[node name="Minimap" type="PanelContainer" parent="MapPanelMargin/MapPanelList/MapDisplayList"]
+editor_description = "UI-549"
+layout_mode = 2
+size_flags_horizontal = 4
+size_flags_vertical = 4
+mouse_filter = 1
+
+[node name="MinimapTexture" type="ColorRect" parent="MapPanelMargin/MapPanelList/MapDisplayList/Minimap"]
+editor_description = "UI-751, FS-338"
+material = SubResource("ShaderMaterial_bhuqb")
+layout_mode = 2
+color = Color(0.921569, 0.835294, 0.701961, 1)
+
+[node name="ViewportQuad" type="Control" parent="MapPanelMargin/MapPanelList/MapDisplayList/Minimap" node_paths=PackedStringArray("_minimap_texture")]
+layout_mode = 2
+mouse_filter = 1
+script = ExtResource("3_s4dml")
+_minimap_texture = NodePath("../MinimapTexture")
+
+[node name="AuxiliaryPanel" type="VBoxContainer" parent="MapPanelMargin/MapPanelList"]
+editor_description = "UI-761"
+layout_mode = 2
+
+[node name="GameSessionMenuButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel"]
+editor_description = "UI-9"
+layout_mode = 2
+mouse_filter = 1
+shortcut = SubResource("Shortcut_fc1tk")
+text = "ESC"
+
+[node name="LedgerButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel"]
+editor_description = "UI-860"
+layout_mode = 2
+mouse_filter = 1
+text = "L"
+
+[node name="FindButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel"]
+editor_description = "UI-861"
+layout_mode = 2
+mouse_filter = 1
+text = "F"
+
+[node name="ZoomButtonsContainer" type="HBoxContainer" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel"]
+layout_mode = 2
+alignment = 1
+
+[node name="ZoomInButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel/ZoomButtonsContainer"]
+editor_description = "UI-862"
+layout_mode = 2
+mouse_filter = 1
+text = "+"
+
+[node name="ZoomOutButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel/ZoomButtonsContainer"]
+editor_description = "UI-863"
+layout_mode = 2
+mouse_filter = 1
+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/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/GameSession/MapControlPanel/Minimap.gd b/game/src/GameSession/MapControlPanel/Minimap.gd
new file mode 100644
index 0000000..1f9b75e
--- /dev/null
+++ b/game/src/GameSession/MapControlPanel/Minimap.gd
@@ -0,0 +1,105 @@
+extends Control
+
+signal minimap_clicked(pos_clicked : Vector2)
+
+const _action_click : StringName = &"map_click"
+
+@export var _minimap_texture : Control
+var _minimap_shader : ShaderMaterial
+
+var _viewport_points : PackedVector2Array
+
+func _ready():
+ _minimap_texture.custom_minimum_size = Vector2(GameSingleton.get_aspect_ratio(), 1.0) * 150
+ var minimap_material := _minimap_texture.get_material()
+ if Events.ShaderManager.set_up_shader(minimap_material, false) != OK:
+ push_error("Failed to set up minimap shader")
+ else:
+ _minimap_shader = minimap_material
+ GameSingleton.province_selected.connect(_on_province_selected)
+
+func _on_province_selected(index : int) -> void:
+ if _minimap_shader != null:
+ _minimap_shader.set_shader_parameter(Events.ShaderManager.param_selected_index, index)
+
+# REQUIREMENTS
+# * SS-80
+# * UI-752
+func _draw() -> void:
+ if _viewport_points.size() > 1:
+ draw_multiline(_viewport_points, Color.WHITE, -1)
+
+# REQUIREMENTS
+# * SS-81
+# * UIFUN-127
+func _unhandled_input(event : InputEvent):
+ if event is InputEventMouse and Input.is_action_pressed(_action_click):
+ var pos_clicked := get_local_mouse_position() / size - Vector2(0.5, 0.5)
+ if abs(pos_clicked.x) < 0.5 and abs(pos_clicked.y) < 0.5:
+ minimap_clicked.emit(pos_clicked)
+
+# Returns the point on the line going through p and q with the specific x coord
+func _intersect_x(p : Vector2, q : Vector2, x : float) -> Vector2:
+ if p.x == q.x:
+ return Vector2(x, 0.5 * (p.y + q.y))
+ var t := (x - q.x) / (p.x - q.x)
+ return q + t * (p - q)
+
+# Returns the point on the line going through p and q with the specific y coord
+func _intersect_y(p : Vector2, q : Vector2, y : float) -> Vector2:
+ if p.y == q.y:
+ return Vector2(0.5 * (p.x + q.x), y)
+ var t := (y - q.y) / (p.y - q.y)
+ return q + t * (p - q)
+
+const _one_x := Vector2(1, 0)
+
+func _add_line_looped_over_x(left : Vector2, right : Vector2) -> void:
+ if left.x < 0:
+ if right.x < 0:
+ _viewport_points.push_back(left + _one_x)
+ _viewport_points.push_back(right + _one_x)
+ else:
+ var mid_point := _intersect_x(left, right, 0)
+ _viewport_points.push_back(mid_point)
+ _viewport_points.push_back(right)
+ mid_point.x = 1
+ _viewport_points.push_back(left + _one_x)
+ _viewport_points.push_back(mid_point)
+ elif right.x > 1:
+ if left.x > 1:
+ _viewport_points.push_back(left - _one_x)
+ _viewport_points.push_back(right - _one_x)
+ else:
+ var mid_point := _intersect_x(left, right, 1)
+ _viewport_points.push_back(left)
+ _viewport_points.push_back(mid_point)
+ mid_point.x = 0
+ _viewport_points.push_back(mid_point)
+ _viewport_points.push_back(right - _one_x)
+ else:
+ _viewport_points.push_back(left)
+ _viewport_points.push_back(right)
+
+# This can break if the viewport is rotated too far!
+func _on_map_view_camera_changed(near_left : Vector2, far_left : Vector2, far_right : Vector2, near_right : Vector2) -> void:
+ # Bound far y coords
+ if far_left.y < 0:
+ far_left = _intersect_y(near_left, far_left, 0)
+ if far_right.y < 0:
+ far_right = _intersect_y(near_right, far_right, 0)
+ # Bound near y coords
+ if near_left.y > 1:
+ near_left = _intersect_y(near_left, far_left, 1)
+ if near_right.y > 1:
+ near_right = _intersect_y(near_right, far_right, 1)
+
+ _viewport_points.clear()
+ _add_line_looped_over_x(near_left, near_right)
+ _add_line_looped_over_x(far_left, far_right)
+ _add_line_looped_over_x(far_left, near_left)
+ _add_line_looped_over_x(near_right, far_right)
+
+ for i in _viewport_points.size():
+ _viewport_points[i] *= size
+ queue_redraw()
diff --git a/game/src/GameSession/MapControlPanel/Minimap.gdshader b/game/src/GameSession/MapControlPanel/Minimap.gdshader
new file mode 100644
index 0000000..608abe2
--- /dev/null
+++ b/game/src/GameSession/MapControlPanel/Minimap.gdshader
@@ -0,0 +1,18 @@
+shader_type canvas_item;
+
+#include "res://src/GameSession/ProvinceIndexSampler.gdshaderinc"
+
+// Index of the currently selected province
+uniform uint selected_index;
+
+const vec3 land_colour = vec3(0.5);
+const vec3 selected_colour = vec3(1.0, 1.0, 0.0);
+
+void fragment() {
+ uvec3 data = read_uvec3(UV);
+ uint index = uvec2_to_uint(data.rg);
+ float is_land = float(data.b != 0u);
+ float is_selected = float(index == selected_index);
+ COLOR.rgb = mix(COLOR.rgb, land_colour, is_land);
+ COLOR.rgb = mix(COLOR.rgb, selected_colour, is_selected);
+}