gamestate.gd 4.8 KB

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