diff options
Diffstat (limited to 'Game/Selection')
-rw-r--r-- | Game/Selection/MultiSelectArea.tscn | 2 | ||||
-rw-r--r-- | Game/Selection/SelectableArea.tscn | 12 | ||||
-rw-r--r-- | Game/Selection/SelectionManager.gd | 165 | ||||
-rw-r--r-- | Game/Selection/SelectionManager.gd.uid | 1 | ||||
-rw-r--r-- | Game/Selection/SelectionManager.tscn | 2 | ||||
-rw-r--r-- | Game/Selection/SelectionRectangle.tscn | 2 | ||||
-rw-r--r-- | Game/Selection/multi_select_area.gd.uid | 1 | ||||
-rw-r--r-- | Game/Selection/selectable_area.gd | 20 | ||||
-rw-r--r-- | Game/Selection/selectable_area.gd.uid | 1 | ||||
-rw-r--r-- | Game/Selection/selection_rectangle.gd | 25 | ||||
-rw-r--r-- | Game/Selection/selection_rectangle.gd.uid | 1 |
11 files changed, 192 insertions, 40 deletions
diff --git a/Game/Selection/MultiSelectArea.tscn b/Game/Selection/MultiSelectArea.tscn index 9e6bd43..8fe9455 100644 --- a/Game/Selection/MultiSelectArea.tscn +++ b/Game/Selection/MultiSelectArea.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://bmi8eb80wghjs"] -[ext_resource type="Script" path="res://Game/Selection/multi_select_area.gd" id="1_g76x3"] +[ext_resource type="Script" uid="uid://da81dgensk8is" path="res://Game/Selection/multi_select_area.gd" id="1_g76x3"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_8io84"] diff --git a/Game/Selection/SelectableArea.tscn b/Game/Selection/SelectableArea.tscn index 3f64dec..77d1ab9 100644 --- a/Game/Selection/SelectableArea.tscn +++ b/Game/Selection/SelectableArea.tscn @@ -1,14 +1,20 @@ [gd_scene load_steps=2 format=3 uid="uid://cqktpc8c7ecn3"] -[ext_resource type="Script" path="res://Game/Selection/selectable_area.gd" id="1_8w2y0"] +[ext_resource type="Script" uid="uid://dswexnxms07hn" path="res://Game/Selection/selectable_area.gd" id="1_8w2y0"] [node name="SelectableArea" type="Area2D"] collision_layer = 32 collision_mask = 16 script = ExtResource("1_8w2y0") -[connection signal="area_entered" from="." to="." method="_on_area_entered"] -[connection signal="area_exited" from="." to="." method="_on_area_exited"] +[node name="HoverControl" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 0 +offset_right = 40.0 +offset_bottom = 40.0 +mouse_filter = 1 +mouse_default_cursor_shape = 2 + [connection signal="input_event" from="." to="." method="_on_input_event"] [connection signal="mouse_entered" from="." to="." method="_on_mouse_entered"] [connection signal="mouse_exited" from="." to="." method="_on_mouse_exited"] diff --git a/Game/Selection/SelectionManager.gd b/Game/Selection/SelectionManager.gd index 49cb319..7ea98ff 100644 --- a/Game/Selection/SelectionManager.gd +++ b/Game/Selection/SelectionManager.gd @@ -2,29 +2,166 @@ class_name SelectionManager extends Node -var selection_groups := {} +signal added_to_group(nodes: Array[Node], id: String) +signal removed_from_group(nodes: Array[Node], id: String) +signal moved_to_group(nodes: Array[Node], previous_id: String, new_id: String) -signal selected_group_changed +var selection_groups: Dictionary[String, Array] = {} + +signal selected_group_changed(previous_id: String, new_id: String) var selected_group := "": set(value): + var previous_id := selected_group selected_group = value - selected_group_changed.emit() + selected_group_changed.emit(previous_id, value) + +var node_count: int func _ready() -> void: - pass + Client.multi_select_finished.connect(_on_multi_select_finished) + Client.placed_tower.connect(_on_placed_tower) + + +func add_to_selection_group(nodes: Array[Node], id: String) -> void: + if id not in selection_groups: + selection_groups[id] = [] + + selection_groups[id].append_array(nodes) + node_count += nodes.size() + + if not selected_group: + reset_selected_group() + + added_to_group.emit(nodes, id) -func change_selection_group_id(towers: Array[Tower], previous_id: String, new_id: String) -> void: - if new_id not in selection_groups: - selection_groups[new_id] = [] +func remove_from_selection_group(nodes: Array[Node], id: String, fallback_id: String = "") -> void: + for node in nodes: + selection_groups[id].erase(node) + + if selection_groups[id].is_empty(): + selection_groups.erase(id) + if id == selected_group: + if fallback_id and selection_groups.has(fallback_id): + selected_group = fallback_id + else: + reset_selected_group() - selection_groups[new_id].append_array(towers) + node_count -= nodes.size() + removed_from_group.emit(nodes, id) + + +func move_to_selection_group(nodes: Array[Node], previous_id: String, new_id: String) -> void: + remove_from_selection_group(nodes, previous_id, new_id) + add_to_selection_group(nodes, new_id) + moved_to_group.emit(nodes, previous_id, new_id) + + +func get_ordered_group_ids() -> Array[String]: + var keys = selection_groups.keys() + + keys.sort_custom(func(a, b): + var group_a = selection_groups[a] + var group_b = selection_groups[b] + + return group_a.size() > group_b.size() + ) + + # TODO: also sort in units and make node type checks + + keys.sort_custom(func(a, b): + var group_a = selection_groups[a] + var group_b = selection_groups[b] + var node_a = group_a[0] + var node_b = group_b[0] + var level_a = 0 + var level_b = 0 + + for component in node_a.components.values(): + level_a += component.level + for component in node_b.components.values(): + level_b += component.level + + return level_a > level_b + ) + + keys.sort_custom(func(a, b): + var group_a = selection_groups[a] + var group_b = selection_groups[b] + + return group_a[0].components.size() > group_b[0].components.size() + ) + + return keys as Array[String] + + +func get_selected_nodes() -> Array: + if selected_group: + return selection_groups[selected_group] - for tower in towers: - selection_groups[previous_id].erase(tower) + return [] + + +func get_nodes() -> Array: + var nodes := [] + for id in selection_groups: + nodes.append_array(selection_groups[id]) - if selection_groups[previous_id].is_empty(): - selection_groups.erase(previous_id) - if previous_id == selected_group: - selected_group = new_id + return nodes + + +func go_to_next(): + var ids = get_ordered_group_ids() + var current_idx = ids.find(selected_group) + selected_group = ids[(current_idx + 1) % ids.size()] + + +func go_to_previous(): + var ids = get_ordered_group_ids() + var current_idx = ids.find(selected_group) + selected_group = ids[(current_idx - 1) % ids.size()] + + +func has_selection() -> bool: + return selection_groups.size() > 0 + + +func has_node_in_group(node: Node, id: String) -> bool: + return selection_groups.has(id) and selection_groups[id].has(node) + + +func reset_selected_group(): + var ids = get_ordered_group_ids() + if ids.size() > 0: + selected_group = ids[0] + else: + selected_group = "" + + +func _on_multi_select_finished(_nodes: Array): + #add_to_selection_group(nodes) + reset_selected_group() + + +func _on_placed_tower(tower: Tower): + if tower.owner_id == multiplayer.get_unique_id(): + tower.selected.connect(func(): + _on_selected_tower(tower) + ) + tower.deselected.connect(func(): + _on_deselected_tower(tower) + ) + tower.selection_group_id_changed.connect(func(previous_id: String): + _on_tower_selection_group_id_changed(tower, previous_id) + ) + +func _on_selected_tower(tower: Tower): + if not has_node_in_group(tower, tower.selection_group_id): + add_to_selection_group([tower], tower.selection_group_id) + +func _on_deselected_tower(tower: Tower): + remove_from_selection_group([tower], tower.selection_group_id) + +func _on_tower_selection_group_id_changed(tower: Tower, previous_id: String): + move_to_selection_group([tower], previous_id, tower.selection_group_id) diff --git a/Game/Selection/SelectionManager.gd.uid b/Game/Selection/SelectionManager.gd.uid new file mode 100644 index 0000000..995c5a5 --- /dev/null +++ b/Game/Selection/SelectionManager.gd.uid @@ -0,0 +1 @@ +uid://cxd3b8dhdrdq diff --git a/Game/Selection/SelectionManager.tscn b/Game/Selection/SelectionManager.tscn index e89880f..a4a7ed5 100644 --- a/Game/Selection/SelectionManager.tscn +++ b/Game/Selection/SelectionManager.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=3 uid="uid://mgm4npqeybbr"] -[ext_resource type="Script" path="res://Game/Selection/SelectionManager.gd" id="1_1w5l7"] +[ext_resource type="Script" uid="uid://cxd3b8dhdrdq" path="res://Game/Selection/SelectionManager.gd" id="1_1w5l7"] [node name="SelectionManager" type="Node"] script = ExtResource("1_1w5l7") diff --git a/Game/Selection/SelectionRectangle.tscn b/Game/Selection/SelectionRectangle.tscn index 61517d0..c687bf5 100644 --- a/Game/Selection/SelectionRectangle.tscn +++ b/Game/Selection/SelectionRectangle.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://ic2hc7gr27p3"] -[ext_resource type="Script" path="res://Game/Selection/selection_rectangle.gd" id="1_on0pa"] +[ext_resource type="Script" uid="uid://cku2w6lsd5ylc" path="res://Game/Selection/selection_rectangle.gd" id="1_on0pa"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_nq6xv"] size = Vector2(1, 1) diff --git a/Game/Selection/multi_select_area.gd.uid b/Game/Selection/multi_select_area.gd.uid new file mode 100644 index 0000000..e305d03 --- /dev/null +++ b/Game/Selection/multi_select_area.gd.uid @@ -0,0 +1 @@ +uid://da81dgensk8is diff --git a/Game/Selection/selectable_area.gd b/Game/Selection/selectable_area.gd index 0b3557d..e611835 100644 --- a/Game/Selection/selectable_area.gd +++ b/Game/Selection/selectable_area.gd @@ -1,3 +1,4 @@ +class_name SelectableArea extends Area2D @@ -7,23 +8,22 @@ signal hover_exit signal select_primary(event: InputEvent) signal select_secondary(event: InputEvent) +@export var root: Node2D -#func _on_area_entered(_area: Area2D) -> void: - #hover_enter.emit() -# -# -#func _on_area_exited(_area: Area2D) -> void: - #hover_exit.emit() + +func _ready() -> void: + var cshapes := find_children("*", "CollisionShape2D") + assert(cshapes.size() > 0) + assert(cshapes[0].shape is RectangleShape2D) + $HoverControl.size = cshapes[0].shape.size func _on_mouse_entered() -> void: - if not get_tree().get_first_node_in_group("selection_rectangle").is_active: - hover_enter.emit() + hover_enter.emit() func _on_mouse_exited() -> void: - if not get_tree().get_first_node_in_group("selection_rectangle").is_active: - hover_exit.emit() + hover_exit.emit() func _on_input_event(_viewport: Node, event: InputEvent, _shape_idx: int) -> void: diff --git a/Game/Selection/selectable_area.gd.uid b/Game/Selection/selectable_area.gd.uid new file mode 100644 index 0000000..e8bc17d --- /dev/null +++ b/Game/Selection/selectable_area.gd.uid @@ -0,0 +1 @@ +uid://dswexnxms07hn diff --git a/Game/Selection/selection_rectangle.gd b/Game/Selection/selection_rectangle.gd index b643636..1d1590a 100644 --- a/Game/Selection/selection_rectangle.gd +++ b/Game/Selection/selection_rectangle.gd @@ -1,20 +1,25 @@ extends Area2D +signal hover_entered(node: Node2D) +signal hover_exited(node: Node2D) + @export_group("Color", "color") @export var color_background: Color @export var color_border: Color +@export var is_enabled: bool + var anchor: Vector2 = Vector2.ZERO -var size: Vector2 = Vector2.ZERO : +var size: Vector2 = Vector2.ZERO: set(value): size = value $CollisionShape2D.position = size / 2 $CollisionShape2D.shape.size = abs(size) -var is_active: bool : +var is_active: bool: get(): - return abs(size) > Vector2(1, 1) and Client.state is StateDefault + return abs(size) > Vector2(1, 1) and is_enabled @onready var camera: Camera = get_viewport().get_camera_2d() @@ -47,14 +52,14 @@ func _draw(): if is_active: var rect = Rect2(Vector2.ZERO, size) draw_rect(rect, color_background) - draw_rect(rect, color_border, false, 1.25 / max(camera.zoom.x, camera.zoom.y)) + draw_rect(rect, color_border, false, 1.1 / max(camera.zoom.x, camera.zoom.y)) -func _on_area_entered(area: Area2D) -> void: - if area.get_parent().owner_id == multiplayer.get_unique_id(): - area.get_parent().is_hovered = true +func _on_area_entered(area: SelectableArea) -> void: + if area.root.owner_id == multiplayer.get_unique_id(): + hover_entered.emit(area.root) -func _on_area_exited(area: Area2D) -> void: - if area.get_parent().owner_id == multiplayer.get_unique_id(): - area.get_parent().is_hovered = false +func _on_area_exited(area: SelectableArea) -> void: + if area.root.owner_id == multiplayer.get_unique_id(): + hover_exited.emit(area.root) diff --git a/Game/Selection/selection_rectangle.gd.uid b/Game/Selection/selection_rectangle.gd.uid new file mode 100644 index 0000000..da2379e --- /dev/null +++ b/Game/Selection/selection_rectangle.gd.uid @@ -0,0 +1 @@ +uid://cku2w6lsd5ylc |