extends Node2D var options = {} var base_pos = Vector2i(0,0) # Called when the node enters the scene tree for the first time. func _ready(): default_options() load_map("res://Maps/default.xp") # $"Player ship".position = Vector2(500., 500.) if not multiplayer.is_server(): return multiplayer.peer_connected.connect(add_player) multiplayer.peer_disconnected.connect(del_player) # Spawn already connected players for id in multiplayer.get_peers(): add_player(id) # Spawn the local player unless this is a dedicated server export. if not OS.has_feature("dedicated_server"): add_player(1) func _exit_tree(): if not multiplayer.is_server(): return multiplayer.peer_connected.disconnect(add_player) multiplayer.peer_disconnected.disconnect(del_player) func add_player(id: int): var player_ship = preload("res://World/PlayerShip.tscn").instantiate() # Set player id. player_ship.player = id player_ship.position = Vector2(600, 600) if id == 1: player_ship.position = Vector2(800, 600) player_ship.name = str(id) $Players.add_child(player_ship, true) func del_player(id: int): if not $Players.has_node(str(id)): return $Players.get_node(str(id)).queue_free() func default_options(): options["gravity"] = 100 options["mapheight"] = 100 func load_map(file_name): parse_map_file(file_name) apply_options() func parse_map_file(file_name): # Remove current map if any $TileMap.clear() # Build a dictionary that translates letter codes from # the map format to tiles var tile_dictionary = {} var atlas_source = $TileMap.tile_set.get_source(0) for i in range(atlas_source.get_tiles_count()): var tile_id = atlas_source.get_tile_id(i) var tile_data = atlas_source.get_tile_data(tile_id, 0) var letter_code = tile_data.get_custom_data("Letter code") for letter in letter_code: tile_dictionary[letter] = tile_id # Load the map from file var mapfile = FileAccess.open(file_name, FileAccess.READ) if not mapfile: print("Couldn't open map file") return var multi_line_mode_option = "" var multi_line_terminator = "" var multi_line_content = "" var line_number = 0 while not mapfile.eof_reached(): var line = mapfile.get_line() line_number += 1 if multi_line_mode_option: if line.contains(multi_line_terminator): options[multi_line_mode_option] = multi_line_content multi_line_mode_option = "" else: multi_line_content += line else: # Remove comments var comment_pos = line.find('#') if comment_pos >= 0: line = line.left(comment_pos) # Get rid of extra whitespace line = line.strip_edges() # If what is left over is an empty line, skip it if line.length() == 0: continue var option = line.split(':', true, 1) if option.size() != 2: print("Invalid data on line ", line_number) continue # Multiline values expand over many lindes until a specified keyword is reached if option[1].contains("\\multiline:"): multi_line_mode_option = option[0].strip_edges().to_lower() multi_line_terminator = option[1].split("\\multiline:")[1].strip_edges() continue options[option[0].strip_edges().to_lower()] = option[1].strip_edges() if multi_line_mode_option != "": print("EOF reached before end of multiline") var edge_wrap = false if options.has("edgewrap"): edge_wrap = (options["edgewrap"] == "yes") if options.has("mapdata") and options.has("mapwidth") and options.has("mapheight"): var width = int(options["mapwidth"]) var height = int(options["mapheight"]) var data = options["mapdata"] for iy in range(height): for ix in range(width): var letter_code = data[iy * width + ix] if tile_dictionary.has(letter_code): $TileMap.set_cell(0, Vector2i(ix, iy), 0, tile_dictionary[letter_code]) if edge_wrap: $TileMap.set_cell(0, Vector2i(ix + width, iy), 0, tile_dictionary[letter_code]) $TileMap.set_cell(0, Vector2i(ix + width, iy + height), 0, tile_dictionary[letter_code]) $TileMap.set_cell(0, Vector2i(ix, iy + height), 0, tile_dictionary[letter_code]) else: print("Map data or dimensions missing") func apply_options(): var width = int(options["mapwidth"]) var height = int(options["mapheight"]) get_node("Map boundaries/CollisionShape2D").shape.size = 64 * Vector2i(width, height) get_node("Map boundaries").position = 64 * Vector2i(width, height) / 2 # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta): pass