diff options
Diffstat (limited to 'Game/Network.gd')
-rw-r--r-- | Game/Network.gd | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/Game/Network.gd b/Game/Network.gd new file mode 100644 index 0000000..021de69 --- /dev/null +++ b/Game/Network.gd @@ -0,0 +1,132 @@ +extends Node + + +var players = {} + + +func _ready(): + multiplayer.connected_to_server.connect(_on_connected_to_server) + multiplayer.peer_connected.connect(_on_peer_connected) + + multiplayer.allow_object_decoding = true + + +func host_game(): + var peer = ENetMultiplayerPeer.new() + peer.create_server(1234, 2) + + multiplayer.multiplayer_peer = peer + players[1] = Client.player + +func join_game(): + var peer = ENetMultiplayerPeer.new() + peer.create_client("127.0.0.1", 1234) + + multiplayer.multiplayer_peer = peer + + +func _on_connected_to_server(): + print("connected to server") + +func _on_peer_connected(id): + print("peer connected: ", id) + add_to_players.rpc(to_rpc_object(Client.player)) + + +func to_rpc_object(object: Variant): + var remote_object = {} + var properties = object.get_rpc_properties() + for property in properties: + var property_class = properties[property] + if object[property] is Dictionary: + remote_object[property] = {} + for key in object[property]: + remote_object[property][key] = to_rpc_object(object[property][key]) + elif property_class: + remote_object[property] = to_rpc_object(object[property]) + else: + remote_object[property] = object[property] + + return remote_object + + +func from_rpc_object(remote_object: Dictionary, remote_class_path: String): + var object + var remote_class = load(remote_class_path) + if remote_class is PackedScene: + object = remote_class.instantiate() + elif remote_class is GDScript: + object = remote_class.new() + else: + assert(false, "unexpected remote class type") + + var properties = object.get_rpc_properties() + for property in properties: + var property_class = properties[property] + if object[property] is Dictionary: + for key in object[property]: + object[property][key] = from_rpc_object(remote_object[property], property_class) + elif property_class: + object[property] = from_rpc_object(remote_object[property], property_class) + else: + object[property] = remote_object[property] + + return object + + +func merge_with_rpc_object(object: Variant, remote_object: Dictionary): + var properties = object.get_rpc_properties() + for property in properties: + var property_class = properties[property] + if object[property] is Dictionary: + object[property] = {} + for key in remote_object[property]: + object[property][key] = from_rpc_object(remote_object[property][key], property_class) + elif property_class: + object[property] = merge_with_rpc_object(object[property], remote_object[property]) + else: + object[property] = remote_object[property] + + return object + + +@rpc("call_local", "any_peer") +func add_to_players(remote_player: Dictionary): + var id = multiplayer.get_remote_sender_id() + var player = from_rpc_object(remote_player, "res://Game/Player.gd") + players[id] = player + + +@rpc("call_local", "any_peer") +func update_player(remote_player: Dictionary): + var id = multiplayer.get_remote_sender_id() + var player = merge_with_rpc_object(players[id], remote_player) + players[id] = player + + +@rpc("any_peer") +func place_tower(remote_tower: Dictionary, position: Vector2): + var remote_player_id = multiplayer.get_remote_sender_id() + + var tower = from_rpc_object(remote_tower, "res://Towers/Tower.tscn") + tower.owner_id = remote_player_id + + players[remote_player_id].towers[tower.global_position] = tower + + Client.stage.place_tower(tower, position) + + +@rpc("any_peer") +func destroy_tower(remote_tower: Dictionary): + var player = players[remote_tower.owner_id] as Player + var tower = player.towers.get(remote_tower.global_position) + + Client.stage.destroy_tower(tower) + + +@rpc("any_peer") +func spawn_unit(remote_unit: Dictionary, remote_spawn: Dictionary): + var unit = from_rpc_object(remote_unit, "res://Units/Unit.tscn") + var spawn = from_rpc_object(remote_spawn, "res://Stages/Paths/Spawn.tscn") + + Client.stage.spawn_unit(unit, spawn) |