gamestate.gd 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. extends Node
  2. # Signals to let lobby GUI know what's going on.
  3. signal player_list_changed()
  4. signal connection_failed()
  5. signal connection_succeeded()
  6. signal game_ended()
  7. signal game_error(what)
  8. # Default game server port. Can be any number between 1024 and 49151.
  9. # Not on the list of registered or common ports as of November 2020:
  10. # https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
  11. const DEFAULT_PORT = 10567
  12. # Max number of players.
  13. const MAX_PEERS = 12
  14. var peer = null
  15. # Name for my player.
  16. var player_name = "The Warrior"
  17. # Names for remote players in id:name format.
  18. var players = {}
  19. var players_ready = []
  20. func _ready():
  21. get_tree().connect("network_peer_connected", self, "_player_connected")
  22. get_tree().connect("network_peer_disconnected", self,"_player_disconnected")
  23. get_tree().connect("connected_to_server", self, "_connected_ok")
  24. get_tree().connect("connection_failed", self, "_connected_fail")
  25. get_tree().connect("server_disconnected", self, "_server_disconnected")
  26. # Callback from SceneTree.
  27. func _player_connected(id):
  28. # Registration of a client beings here, tell the connected player that we are here.
  29. rpc_id(id, "register_player", player_name)
  30. # Callback from SceneTree.
  31. func _player_disconnected(id):
  32. if has_node("/root/World"): # Game is in progress.
  33. if get_tree().is_network_server():
  34. emit_signal("game_error", "Player " + players[id] + " disconnected")
  35. end_game()
  36. else: # Game is not in progress.
  37. # Unregister this player.
  38. unregister_player(id)
  39. # Callback from SceneTree, only for clients (not server).
  40. func _connected_ok():
  41. # We just connected to a server
  42. emit_signal("connection_succeeded")
  43. # Callback from SceneTree, only for clients (not server).
  44. func _server_disconnected():
  45. emit_signal("game_error", "Server disconnected")
  46. end_game()
  47. # Callback from SceneTree, only for clients (not server).
  48. func _connected_fail():
  49. get_tree().set_network_peer(null) # Remove peer
  50. emit_signal("connection_failed")
  51. # Lobby management functions.
  52. remote func register_player(new_player_name):
  53. var id = get_tree().get_rpc_sender_id()
  54. print(id)
  55. players[id] = new_player_name
  56. emit_signal("player_list_changed")
  57. func unregister_player(id):
  58. players.erase(id)
  59. emit_signal("player_list_changed")
  60. remote func pre_start_game(spawn_points):
  61. # Change scene.
  62. var world = load("res://world.tscn").instance()
  63. get_tree().get_root().add_child(world)
  64. get_tree().get_root().get_node("Lobby").hide()
  65. var player_scene = load("res://player.tscn")
  66. for p_id in spawn_points:
  67. var spawn_pos = world.get_node("SpawnPoints/" + str(spawn_points[p_id])).position
  68. var player = player_scene.instance()
  69. player.set_name(str(p_id)) # Use unique ID as node name.
  70. player.position=spawn_pos
  71. player.set_network_master(p_id) #set unique id as master.
  72. if p_id == get_tree().get_network_unique_id():
  73. # If node for this peer id, set name.
  74. player.set_player_name(player_name)
  75. else:
  76. # Otherwise set name from peer.
  77. player.set_player_name(players[p_id])
  78. world.get_node("Players").add_child(player)
  79. # Set up score.
  80. world.get_node("Score").add_player(get_tree().get_network_unique_id(), player_name)
  81. for pn in players:
  82. world.get_node("Score").add_player(pn, players[pn])
  83. if not get_tree().is_network_server():
  84. # Tell server we are ready to start.
  85. rpc_id(1, "ready_to_start", get_tree().get_network_unique_id())
  86. elif players.size() == 0:
  87. post_start_game()
  88. remote func post_start_game():
  89. get_tree().set_pause(false) # Unpause and unleash the game!
  90. remote func ready_to_start(id):
  91. assert(get_tree().is_network_server())
  92. if not id in players_ready:
  93. players_ready.append(id)
  94. if players_ready.size() == players.size():
  95. for p in players:
  96. rpc_id(p, "post_start_game")
  97. post_start_game()
  98. func host_game(new_player_name):
  99. player_name = new_player_name
  100. peer = NetworkedMultiplayerENet.new()
  101. peer.create_server(DEFAULT_PORT, MAX_PEERS)
  102. get_tree().set_network_peer(peer)
  103. func join_game(ip, new_player_name):
  104. player_name = new_player_name
  105. peer = NetworkedMultiplayerENet.new()
  106. peer.create_client(ip, DEFAULT_PORT)
  107. get_tree().set_network_peer(peer)
  108. func get_player_list():
  109. return players.values()
  110. func get_player_name():
  111. return player_name
  112. func begin_game():
  113. assert(get_tree().is_network_server())
  114. # Create a dictionary with peer id and respective spawn points, could be improved by randomizing.
  115. var spawn_points = {}
  116. spawn_points[1] = 0 # Server in spawn point 0.
  117. var spawn_point_idx = 1
  118. for p in players:
  119. spawn_points[p] = spawn_point_idx
  120. spawn_point_idx += 1
  121. # Call to pre-start game with the spawn points.
  122. for p in players:
  123. rpc_id(p, "pre_start_game", spawn_points)
  124. pre_start_game(spawn_points)
  125. func end_game():
  126. if has_node("/root/World"): # Game is in progress.
  127. # End it
  128. get_node("/root/World").queue_free()
  129. emit_signal("game_ended")
  130. players.clear()