class_name SpawnController extends Node3D var attack_spawners: Array[Node3D] var defend_spawners: Array[Node3D] var server_side_character_scene: PackedScene = null var server_side_character_path: String = "player/server_side_character/server_side_character.tscn" var player_space: Node3D # Called when the node enters the scene tree for the first time. func _ready() -> void: var err : Error = load_scene(server_side_character_path) if err != OK: logger.error("coudn't load the spawnable node, err " + str(err)) if multiplayer.is_server(): for spawner in $Attack.get_children(): attack_spawners.append(spawner) for spawner in $Defend.get_children(): defend_spawners.append(spawner) else: get_existing_players.rpc_id(1) func prepare_spawn_location(id: int, team: String): logger.debug("preparing spawn location") var transform : Transform3D match team: consts.TEAM_ATTACK: transform = attack_spawners[0].global_transform attack_spawners.append(attack_spawners.pop_front()) consts.TEAM_DEFEND: transform = defend_spawners[0].global_transform defend_spawners.append(defend_spawners.pop_front()) consts.TEAM_UNDEFINED: logger.warning("can't spawn a player, the team is undefined") _: logger.warning("can't spawn a player, unknown team") logger.debug("triggering spawn") spawn_player.rpc(id, transform) @rpc("any_peer", "call_remote", "reliable") func get_existing_players() -> void: if multiplayer.is_server(): for child in player_space.get_children(): # -- TODO: It must no look like that if child.name != str(multiplayer.get_unique_id()): spawn_player.rpc_id(multiplayer.get_remote_sender_id(), child.player_id, child.global_transform) @rpc("authority", "reliable", "call_local") func spawn_player(id: int, transform: Transform3D): logger.info("spawn is triggered " + str(multiplayer.get_unique_id()) + " " + str(id)) var node: ServerSideCharacter = server_side_character_scene.instantiate() node.player_id = id node.global_transform = transform node.name = str(id) player_space.add_child(node) # -- TODO: It should be defined once, stop copy-pasting func load_scene(rel_path: String) -> Error : var path := consts.SCENES_PATH + rel_path logger.info("loading scene from " + path) if not ResourceLoader.exists(path): logger.error("scene " + path + " doesn't exist") return ERR_DOES_NOT_EXIST var scene: PackedScene = ResourceLoader.load(path) if scene.can_instantiate(): # -- TODO: May we should case to a real type instead server_side_character_scene = scene else: logger.error("can't initialize") return ERR_CANT_OPEN return OK