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)