You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
6.5 KiB
214 lines
6.5 KiB
extends Node
|
|
|
|
# Default game port
|
|
const DEFAULT_PORT = 8128
|
|
|
|
# Max number of players
|
|
const MAX_PLAYERS = 4
|
|
const MAX_PEERS = MAX_PLAYERS - 1
|
|
|
|
|
|
var world_scene = preload("res://scenes/game/world.tscn")
|
|
var path_player_scene = preload("res://scenes/player/PathPlayerBase.tscn")
|
|
var path_player_controls_scene = preload("res://scenes/player/PathPlayerControls.tscn")
|
|
var path_player_bot_scene = preload("res://scenes/player/PathPlayerBot.tscn")
|
|
var full_player_scene = preload("res://scenes/player/FullPlayer.tscn")
|
|
|
|
# Name for my player
|
|
var player_name = "Undefined"
|
|
var player_color = Color("#000000")
|
|
var full = false
|
|
|
|
puppet var slave_full = false
|
|
|
|
# Names for remote players in id:name format
|
|
var players = {}
|
|
|
|
# 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(msg)
|
|
|
|
# Callback from SceneTree
|
|
func _player_connected(id):
|
|
pass
|
|
|
|
# Callback from SceneTree
|
|
func _player_disconnected(id):
|
|
if (get_tree().is_network_server()):
|
|
if (has_node("/root/world")): # Game is in progress
|
|
emit_signal("game_error", "Player " + players[id].name + " disconnected")
|
|
end_game()
|
|
else: # Game is not in progress
|
|
# If we are the server, send to the new dude all the already registered players
|
|
unregister_player(id)
|
|
for p_id in players:
|
|
# Erase in the server
|
|
rpc_id(p_id, "unregister_player", id)
|
|
|
|
# Callback from SceneTree, only for clients (not server)
|
|
func _connected_ok():
|
|
# Registration of a client beings here, tell everyone that we are here
|
|
rpc("register_player", get_tree().get_network_unique_id(), player_name, player_color)
|
|
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(id, new_player_name, new_player_color):
|
|
if (get_tree().is_network_server()):
|
|
# If we are the server, let everyone know about the new player
|
|
rpc_id(id, "register_player", 1, player_name, player_color) # Send myself to new dude
|
|
rset_id(id, "slave_full", full)
|
|
for p_id in players: # Then, for each remote player
|
|
rpc_id(id, "register_player", p_id, players[p_id].name, players[p_id].color) # Send player to new dude
|
|
rpc_id(p_id, "register_player", id, new_player_name, new_player_color) # Send new dude to player
|
|
|
|
players[id] = {"name" : new_player_name, "color" : new_player_color}
|
|
emit_signal("player_list_changed")
|
|
|
|
remote func unregister_player(id):
|
|
players.erase(id)
|
|
emit_signal("player_list_changed")
|
|
|
|
remote func pre_start_game(spawn_points):
|
|
# Change scene
|
|
var world = world_scene.instance()
|
|
get_tree().get_root().add_child(world)
|
|
|
|
get_tree().get_root().get_node("lobby").hide()
|
|
|
|
full = slave_full
|
|
|
|
for p_id in spawn_points:
|
|
var player
|
|
var controls
|
|
if full:
|
|
player = full_player_scene.instance()
|
|
else:
|
|
player = path_player_scene.instance()
|
|
|
|
player.set_network_master(p_id)
|
|
player.set_name(str(p_id))
|
|
|
|
world.get_node("players").add_child(player)
|
|
|
|
if (p_id == get_tree().get_network_unique_id()):
|
|
# If node for this peer id, set name
|
|
player.set_player_name(player_name)
|
|
player.set_player_color(player_color)
|
|
controls = path_player_controls_scene.instance()
|
|
world.add_child(controls)
|
|
controls.set_player(player.get_path())
|
|
controls.set_network_master(p_id)
|
|
else:
|
|
# Otherwise set name from peer
|
|
player.set_player_name(players[p_id].name)
|
|
player.set_player_color(players[p_id].color)
|
|
|
|
player.set_start(player.get_index())
|
|
|
|
var bots = false
|
|
if bots:
|
|
for index in range(4-spawn_points.size()):
|
|
var bot_index = spawn_points.size() + index
|
|
var player = path_player_scene.instance()
|
|
player.set_name("bot_player" + str(bot_index))
|
|
world.get_node("players").add_child(player)
|
|
if get_tree().is_network_server():
|
|
var bot = path_player_bot_scene.instance()
|
|
bot.set_name("bot" + str(bot_index))
|
|
world.add_child(bot)
|
|
bot.set_player(player.get_path())
|
|
bot.set_network_master(get_tree().get_network_unique_id())
|
|
player.set_start(bot_index)
|
|
|
|
|
|
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!
|
|
|
|
var players_ready = []
|
|
|
|
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, new_player_color, new_full):
|
|
player_name = new_player_name
|
|
player_color = new_player_color
|
|
full = new_full
|
|
slave_full = full
|
|
var host = NetworkedMultiplayerENet.new()
|
|
host.create_server(DEFAULT_PORT, MAX_PEERS)
|
|
get_tree().set_network_peer(host)
|
|
|
|
func join_game(ip, new_player_name, new_player_color):
|
|
player_name = new_player_name
|
|
player_color = new_player_color
|
|
var host = NetworkedMultiplayerENet.new()
|
|
host.create_client(ip, DEFAULT_PORT)
|
|
get_tree().set_network_peer(host)
|
|
|
|
func get_player_list():
|
|
return players.values()
|
|
|
|
func get_player_name():
|
|
return player_name
|
|
|
|
func get_player_color():
|
|
return player_color
|
|
|
|
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()
|
|
get_tree().set_network_peer(null) # End networking
|
|
|
|
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")
|