diff options
author | Daniel Weipert <git@mail.dweipert.de> | 2024-12-21 14:15:11 +0100 |
---|---|---|
committer | Daniel Weipert <git@mail.dweipert.de> | 2024-12-21 14:15:11 +0100 |
commit | 5b35174ffab42f0331f1a6527ef6bbab7a3dbdcb (patch) | |
tree | 071530353b02f45fffc26aa4b0f43f7b901b3046 /Game/Selection/SelectionManager.gd | |
parent | a854a1862a30632e49520f6e1e11333d5c8ff241 (diff) |
Diffstat (limited to 'Game/Selection/SelectionManager.gd')
-rw-r--r-- | Game/Selection/SelectionManager.gd | 164 |
1 files changed, 151 insertions, 13 deletions
diff --git a/Game/Selection/SelectionManager.gd b/Game/Selection/SelectionManager.gd index 49cb319..86f08af 100644 --- a/Game/Selection/SelectionManager.gd +++ b/Game/Selection/SelectionManager.gd @@ -2,29 +2,167 @@ class_name SelectionManager extends Node +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) + var selection_groups := {} -signal selected_group_changed +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:#Array[String]: + # TODO: remove bound to Tower + # TODO: use static function on Tower get_sort_conditions? + + 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() + ) + + 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 + + +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) |