From 5b35174ffab42f0331f1a6527ef6bbab7a3dbdcb Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Sat, 21 Dec 2024 14:15:11 +0100 Subject: next commit --- Game/Client.gd | 9 +- Game/Lobby/Server/index.php | 7 +- Game/Lobby/game_lobby.gd | 5 +- Game/Network.gd | 16 ++-- Game/Selection/SelectionManager.gd | 164 +++++++++++++++++++++++++++++++++--- Game/States/Build/StateBuild.gd | 5 +- Game/States/Default/StateDefault.gd | 5 +- 7 files changed, 178 insertions(+), 33 deletions(-) (limited to 'Game') diff --git a/Game/Client.gd b/Game/Client.gd index 6e08a58..0af4e9d 100644 --- a/Game/Client.gd +++ b/Game/Client.gd @@ -33,10 +33,13 @@ func _notification(what: int) -> void: func initialize_stage(stage: Stage): current_stage = stage + + if not selection: + selection = preload("res://Game/Selection/SelectionManager.tscn").instantiate() + add_child(selection) func ready_stage(_stage: Stage): - selection = preload("res://Game/Selection/SelectionManager.tscn").instantiate() - add_child(selection) + pass func place_tower(tower: Tower): @@ -118,7 +121,7 @@ func get_config() -> ConfigFile: config.load("user://config") if not FileAccess.file_exists("user://config"): - config.set_value("general", "host_default_port", 1234) + config.set_value("general", "host_default_port", 8911) config.set_value("general", "game_lobby_server_base_url", "http://localhost:8910") config.save("user://config") diff --git a/Game/Lobby/Server/index.php b/Game/Lobby/Server/index.php index ae734a6..1086d24 100644 --- a/Game/Lobby/Server/index.php +++ b/Game/Lobby/Server/index.php @@ -36,7 +36,7 @@ if (php_sapi_name() == 'cli') { return; } -$url = parse_url("$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"); +$url = parse_url("http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"); $method = $_SERVER['REQUEST_METHOD']; if ($method == 'POST') { @@ -49,7 +49,10 @@ if ($method == 'POST') { $response = []; if ($method == 'POST' && $url['path'] == '/host') { - $ip = filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP); + $ip = filter_var( + $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'], + FILTER_VALIDATE_IP + ); if ($ip === false) { $response = [ diff --git a/Game/Lobby/game_lobby.gd b/Game/Lobby/game_lobby.gd index 6bfa8be..ffc66f3 100644 --- a/Game/Lobby/game_lobby.gd +++ b/Game/Lobby/game_lobby.gd @@ -42,8 +42,8 @@ func request( get_tree().root.add_child(config.node) if config.method == HTTPClient.METHOD_POST: - config.set("id", current_game_id) - config.set("secret", current_secret) + config.data["id"] = current_game_id + config.data["secret"] = current_secret var response = HTTPResponse.new() config.node.request_completed.connect( @@ -60,6 +60,7 @@ func request( get_tree().root.remove_child(config.node) ) + config.node.request( "%s%s" % [server_base_url, url], config.headers, diff --git a/Game/Network.gd b/Game/Network.gd index 2858d98..4413548 100644 --- a/Game/Network.gd +++ b/Game/Network.gd @@ -61,13 +61,15 @@ func _on_disconnected_from_server(): func _on_peer_connected(id: int): print(multiplayer.get_unique_id(), ": peer connected: ", id) - ask_game_running.rpc_id(id) - is_game_running.connect(func(is_running: bool): - if not is_running: - add_to_players.rpc_id(id, inst_to_dict(Client.player)) - elif is_running: - get_tree().change_scene_to_file("res://UI/Start.tscn") - ) + add_to_players.rpc_id(id, inst_to_dict(Client.player)) + # TODO: check why bug and adds more players than intended + #ask_game_running.rpc_id(id) + #is_game_running.connect(func(is_running: bool): + #if not is_running: + #add_to_players.rpc_id(id, inst_to_dict(Client.player)) + #elif is_running: + #get_tree().change_scene_to_file("res://UI/Start.tscn") + #) func _on_peer_disconnected(id: int): print(multiplayer.get_unique_id(), ": peer disconnected: ", id) 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) diff --git a/Game/States/Build/StateBuild.gd b/Game/States/Build/StateBuild.gd index 0bd5efb..303a2b1 100644 --- a/Game/States/Build/StateBuild.gd +++ b/Game/States/Build/StateBuild.gd @@ -8,9 +8,8 @@ static var current_builder_element: BuilderElement func _state_enter(): %BuildGrid.visible = true - if Tower.selected_towers: - for tower in Tower.selected_towers.duplicate(): - tower.is_selected = false + for tower: Tower in Client.selection.get_nodes().duplicate(): + tower.is_selected = false func _state_exit(): diff --git a/Game/States/Default/StateDefault.gd b/Game/States/Default/StateDefault.gd index b7b630c..014eb40 100644 --- a/Game/States/Default/StateDefault.gd +++ b/Game/States/Default/StateDefault.gd @@ -16,6 +16,5 @@ func _state_unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("select"): # if not multi selecting if not event.is_double_click() and not Input.is_action_pressed("select_multiple"): - if Tower.selected_towers: - for tower in Tower.selected_towers.duplicate(): - tower.is_selected = false + for tower: Tower in Client.selection.get_nodes().duplicate(): + tower.is_selected = false -- cgit v1.2.3