123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- extends Node
- # Default game server port. Can be any number between 1024 and 49151.
- # Not on the list of registered or common ports as of November 2020:
- # https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
- const DEFAULT_PORT = 10567
- # Max number of players.
- const MAX_PEERS = 12
- var peer = null
- # Name for my player.
- var player_name = "The Warrior"
- # Names for remote players in id:name format.
- var players = {}
- var players_ready = []
- # Signals to let lobby GUI know what's going on.
- signal player_list_changed()
- signal connection_failed()
- signal connection_succeeded()
- signal game_ended()
- signal game_error(what)
- # Callback from SceneTree.
- func _player_connected(id):
- # Registration of a client beings here, tell the connected player that we are here.
- rpc_id(id, "register_player", player_name)
- # Callback from SceneTree.
- func _player_disconnected(id):
- if has_node("/root/World"): # Game is in progress.
- if get_tree().is_network_server():
- emit_signal("game_error", "Player " + players[id] + " disconnected")
- end_game()
- else: # Game is not in progress.
- # Unregister this player.
- unregister_player(id)
- # Callback from SceneTree, only for clients (not server).
- func _connected_ok():
- # We just connected to a server
- emit_signal("connection_succeeded")
- # Callback from SceneTree, only for clients (not server).
- func _server_disconnected():
- emit_signal("game_error", "Server disconnected")
- end_game()
- # Callback from SceneTree, only for clients (not server).
- func _connected_fail():
- get_tree().set_network_peer(null) # Remove peer
- emit_signal("connection_failed")
- # Lobby management functions.
- remote func register_player(new_player_name):
- var id = get_tree().get_rpc_sender_id()
- print(id)
- players[id] = new_player_name
- emit_signal("player_list_changed")
- func unregister_player(id):
- players.erase(id)
- emit_signal("player_list_changed")
- remote func pre_start_game(spawn_points):
- # Change scene.
- var world = load("res://world.tscn").instance()
- get_tree().get_root().add_child(world)
- get_tree().get_root().get_node("Lobby").hide()
- var player_scene = load("res://player.tscn")
- for p_id in spawn_points:
- var spawn_pos = world.get_node("SpawnPoints/" + str(spawn_points[p_id])).position
- var player = player_scene.instance()
- player.set_name(str(p_id)) # Use unique ID as node name.
- player.position=spawn_pos
- player.set_network_master(p_id) #set unique id as master.
- if p_id == get_tree().get_network_unique_id():
- # If node for this peer id, set name.
- player.set_player_name(player_name)
- else:
- # Otherwise set name from peer.
- player.set_player_name(players[p_id])
- world.get_node("Players").add_child(player)
- # Set up score.
- world.get_node("Score").add_player(get_tree().get_network_unique_id(), player_name)
- for pn in players:
- world.get_node("Score").add_player(pn, players[pn])
- if not get_tree().is_network_server():
- # Tell server we are ready to start.
- rpc_id(1, "ready_to_start", get_tree().get_network_unique_id())
- elif players.size() == 0:
- post_start_game()
- remote func post_start_game():
- get_tree().set_pause(false) # Unpause and unleash the game!
- remote func ready_to_start(id):
- assert(get_tree().is_network_server())
- if not id in players_ready:
- players_ready.append(id)
- if players_ready.size() == players.size():
- for p in players:
- rpc_id(p, "post_start_game")
- post_start_game()
- func host_game(new_player_name):
- player_name = new_player_name
- peer = NetworkedMultiplayerENet.new()
- peer.create_server(DEFAULT_PORT, MAX_PEERS)
- get_tree().set_network_peer(peer)
- func join_game(ip, new_player_name):
- player_name = new_player_name
- peer = NetworkedMultiplayerENet.new()
- peer.create_client(ip, DEFAULT_PORT)
- get_tree().set_network_peer(peer)
- func get_player_list():
- return players.values()
- func get_player_name():
- return player_name
- func begin_game():
- assert(get_tree().is_network_server())
- # Create a dictionary with peer id and respective spawn points, could be improved by randomizing.
- var spawn_points = {}
- spawn_points[1] = 0 # Server in spawn point 0.
- var spawn_point_idx = 1
- for p in players:
- spawn_points[p] = spawn_point_idx
- spawn_point_idx += 1
- # Call to pre-start game with the spawn points.
- for p in players:
- rpc_id(p, "pre_start_game", spawn_points)
- pre_start_game(spawn_points)
- func end_game():
- if has_node("/root/World"): # Game is in progress.
- # End it
- get_node("/root/World").queue_free()
- emit_signal("game_ended")
- players.clear()
- func _ready():
- get_tree().connect("network_peer_connected", self, "_player_connected")
- get_tree().connect("network_peer_disconnected", self,"_player_disconnected")
- 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")
|