extends Node const MAX_PEERS = 4 const LOBBY_READY_WAIT_TIME = 3 var world_scene = preload("res://scenes/game/world.tscn") var player_scene = preload("res://scenes/player/Player.tscn") var human_player_scene = preload("res://scenes/player/HumanPlayer.tscn") var bot_player_scene = preload("res://scenes/player/BotPlayer.tscn") var players = {} var game_running:bool = false var dedicated_server:bool = false var game_ready_timer:Timer signal players_changed(players) signal connection_failed() signal connection_succeeded() signal server_disconnected() signal game_ready(ready) signal game_started() signal game_ended() signal game_error(type, data) func _ready(): for argument in OS.get_cmdline_args(): if argument.split("=")[0] == "--port": var err = host_game(int(argument.split("=")[1])) if err != OK: print("Could not create Server!") get_tree().quit() dedicated_server = true func host_game(port:int): var host = NetworkedMultiplayerENet.new() var err = host.create_server(port, MAX_PEERS) get_tree().set_network_peer(host) get_tree().connect("network_peer_connected", self, "_player_connected") get_tree().connect("network_peer_disconnected", self,"_player_disconnected") if game_ready_timer == null: game_ready_timer = Timer.new() game_ready_timer.set_name("game_ready_timer") game_ready_timer.set_timer_process_mode(Timer.TIMER_PROCESS_PHYSICS) game_ready_timer.set_one_shot(true) game_ready_timer.set_autostart(false) game_ready_timer.set_wait_time(LOBBY_READY_WAIT_TIME) game_ready_timer.connect("timeout",self,"start_game") add_child(game_ready_timer) if err == OK: print("Game hosted on Port " + str(port)) else: emit_signal("game_error", "HOST", err) return err func join_game(ip, port:int): get_tree().connect("connected_to_server", self, "_connected_ok") get_tree().connect("connection_failed", self, "_connected_fail") get_tree().connect("server_disconnected", self, "_server_disconnected") var host = NetworkedMultiplayerENet.new() host.create_client(ip, port) get_tree().set_network_peer(host) func _connected_ok(): rpc("set_player", get_tree().get_network_unique_id()) emit_signal("connection_succeeded") func _connected_fail(): get_tree().disconnect("connected_to_server", self, "_connected_ok") get_tree().disconnect("connection_failed", self, "_connected_fail") get_tree().disconnect("server_disconnected", self, "_server_disconnected") get_tree().set_network_peer(null) emit_signal("connection_failed") func _server_disconnected(): quit_game() emit_signal("server_disconnected") func _player_connected(id): pass func _player_disconnected(id): if get_tree().is_network_server(): print("disconnect: " + str(id)) if game_running: # Game is in progress emit_signal("game_error", "DISCONNECTED", [id]) rpc("remove_player" ,id) # TODO! else: rpc("remove_player" ,id) remote func set_player(id, new_name:String = " ", new_color:Color = Color.black, new_ready:bool = false): players[id] = {"name" : new_name, "color" : new_color, "ready" : new_ready, "prepared" : false} emit_signal("players_changed", players) if get_tree().is_network_server(): var all_ready = true for p_id in players: rpc_id(id, "set_player", p_id, players[p_id].name, players[p_id].color, players[p_id].ready) rpc_id(p_id, "set_player", id, new_name, new_color, new_ready) all_ready = all_ready && players[p_id].ready print("set_player:") print(players[id]) rpc("game_ready", all_ready) func update_player(new_name:String = " ", new_color:Color = Color.black, new_ready:bool = false): if get_tree().is_network_server(): set_player(get_tree().get_network_unique_id(), new_name, new_color, new_ready) else: rpc("set_player",get_tree().get_network_unique_id(), new_name, new_color, new_ready) remotesync func remove_player(id): players.erase(id) if has_node("/root/world"): var world = get_node("/root/world") var world_players = world.get_node("players") if world_players.has_node(str(id)): world_players.remove_child(world_players.get_node(str(id))) emit_signal("players_changed", players) if get_tree().is_network_server() && game_running && dedicated_server && players.empty(): print("All players disconnected, close server!") get_tree().quit() remotesync func game_ready(all_ready:bool): if get_tree().is_network_server(): print("game ready: " + str(all_ready)) if all_ready: game_ready_timer.start() else: game_ready_timer.stop() emit_signal("game_ready", all_ready) remotesync func prepare_game(bots:bool): get_tree().set_pause(true) var world = world_scene.instance() get_tree().get_root().add_child(world) get_tree().get_root().get_node("main_menu").hide() for p_id in players: var controls var player = players[p_id] var _player_scene = player_scene.instance() _player_scene.set_network_master(p_id) _player_scene.set_name(str(p_id)) _player_scene.set_player_name(player.name) _player_scene.set_player_color(player.color) world.get_node("players").add_child(_player_scene) if p_id == get_tree().get_network_unique_id(): controls = human_player_scene.instance() controls.set_name("HumanControl_" + str(p_id)) world.add_child(controls) controls.set_player(_player_scene.get_path()) controls.set_network_master(p_id) _player_scene.set_start(_player_scene.get_index()) if bots: for index in range(MAX_PEERS-players.size()): var bot_index = players.size() + index var _player_scene = player_scene.instance() _player_scene.set_name("bot_player" + str(bot_index)) world.get_node("players").add_child(_player_scene) _player_scene.add_to_group("bots") if get_tree().is_network_server(): var bot = bot_player_scene.instance() bot.set_name("bot" + str(bot_index)) world.add_child(bot) bot.set_player(_player_scene.get_path()) bot.set_network_master(get_tree().get_network_unique_id()) _player_scene.set_start(bot_index) if players.has(get_tree().get_network_unique_id()): rpc_id(1, "player_prepared", get_tree().get_network_unique_id()) if get_tree().is_network_server(): if players.has(get_tree().get_network_unique_id()): player_prepared(get_tree().get_network_unique_id()) print("prepare game") print(players) else: rpc_id(1, "player_prepared", get_tree().get_network_unique_id()) func start_game(): if get_tree().is_network_server(): get_tree().set_refuse_new_network_connections(true) print("start game") rpc("prepare_game", false) remotesync func player_prepared(id): if get_tree().is_network_server(): players[id].prepared = true var all_prepared = true for p_id in players: all_prepared = all_prepared && players[p_id].prepared if all_prepared: rpc("post_start_game") remotesync func post_start_game(): get_tree().set_pause(false) game_running = true emit_signal("game_started") func local_game(name:String, color:Color, bots:bool): var localhost = NetworkedMultiplayerENet.new() localhost.create_server(0, 0) get_tree().set_network_peer(localhost) players[get_tree().get_network_unique_id()] = { "name" : name, "color" : color } prepare_game(bots) post_start_game() func quit_game(): if has_node("/root/world"): get_node("/root/world").queue_free() players.clear() get_tree().set_refuse_new_network_connections(false) get_tree().set_network_peer(null) get_tree().get_root().get_node("main_menu").show() game_running = false