123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- 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.
- register_player.rpc_id(id, player_name)
- # Callback from SceneTree.
- func _player_disconnected(id):
- if has_node("/root/World"): # Game is in progress.
- if multiplayer.is_server():
- game_error.emit("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
- connection_succeeded.emit()
- # Callback from SceneTree, only for clients (not server).
- func _server_disconnected():
- game_error.emit("Server disconnected")
- end_game()
- # Callback from SceneTree, only for clients (not server).
- func _connected_fail():
- multiplayer.set_network_peer(null) # Remove peer
- connection_failed.emit()
- # Lobby management functions.
- @rpc("any_peer")
- func register_player(new_player_name):
- var id = multiplayer.get_remote_sender_id()
- players[id] = new_player_name
- player_list_changed.emit()
- func unregister_player(id):
- players.erase(id)
- player_list_changed.emit()
- @rpc("call_local")
- func load_world():
- # Change scene.
- var world = load("res://world.tscn").instantiate()
- get_tree().get_root().add_child(world)
- get_tree().get_root().get_node("Lobby").hide()
- # Set up score.
- world.get_node("Score").add_player(multiplayer.get_unique_id(), player_name)
- for pn in players:
- world.get_node("Score").add_player(pn, players[pn])
- get_tree().set_pause(false) # Unpause and unleash the game!
- func host_game(new_player_name):
- player_name = new_player_name
- peer = ENetMultiplayerPeer.new()
- peer.create_server(DEFAULT_PORT, MAX_PEERS)
- multiplayer.set_multiplayer_peer(peer)
- func join_game(ip, new_player_name):
- player_name = new_player_name
- peer = ENetMultiplayerPeer.new()
- peer.create_client(ip, DEFAULT_PORT)
- multiplayer.set_multiplayer_peer(peer)
- func get_player_list():
- return players.values()
- func get_player_name():
- return player_name
- func begin_game():
- assert(multiplayer.is_server())
- load_world.rpc()
- var world = get_tree().get_root().get_node("World")
- var player_scene = load("res://player.tscn")
- # 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
- for p_id in spawn_points:
- var spawn_pos = world.get_node("SpawnPoints/" + str(spawn_points[p_id])).position
- var player = player_scene.instantiate()
- player.synced_position = spawn_pos
- player.name = str(p_id)
- player.set_player_name(player_name if p_id == multiplayer.get_unique_id() else players[p_id])
- world.get_node("Players").add_child(player)
- func end_game():
- if has_node("/root/World"): # Game is in progress.
- # End it
- get_node("/root/World").queue_free()
- game_ended.emit()
- players.clear()
- func _ready():
- multiplayer.peer_connected.connect(self._player_connected)
- multiplayer.peer_disconnected.connect(self._player_disconnected)
- multiplayer.connected_to_server.connect(self._connected_ok)
- multiplayer.connection_failed.connect(self._connected_fail)
- multiplayer.server_disconnected.connect(self._server_disconnected)
|