131 lines
4.7 KiB
GDScript
131 lines
4.7 KiB
GDScript
extends TileMap
|
|
|
|
var base_positions: Array[Vector2i] = []
|
|
|
|
# Called when the node enters the scene tree for the first time.
|
|
func _ready():
|
|
MapConfig.reset_to_defaults()
|
|
|
|
|
|
|
|
func load_map(file_name: String):
|
|
MapConfig.num_errors = 0
|
|
MapConfig.reset_to_defaults()
|
|
parse_map_file(file_name)
|
|
apply_options()
|
|
prints("Loaded", MapConfig.mapname, "by", MapConfig.mapauthor)
|
|
if MapConfig.num_errors > 0:
|
|
push_error("Map contains ", MapConfig.num_errors, " errors")
|
|
|
|
|
|
func parse_map_file(file_name):
|
|
# Remove current map if any
|
|
clear()
|
|
|
|
# Build a dictionary that translates letter codes from
|
|
# the map format to tiles
|
|
var tile_dictionary = {}
|
|
var atlas_source = 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):
|
|
MapConfig.set_option(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
|
|
MapConfig.set_option(option[0].strip_edges(), option[1].strip_edges())
|
|
if multi_line_mode_option != "":
|
|
print("EOF reached before end of multiline")
|
|
|
|
if MapConfig.mapdata.length() > 0 and MapConfig.mapwidth > 0 and MapConfig.mapheight > 0:
|
|
for iy in range(MapConfig.mapheight):
|
|
for ix in range(MapConfig.mapwidth):
|
|
var letter_code = MapConfig.mapdata[iy * MapConfig.mapwidth + ix]
|
|
if tile_dictionary.has(letter_code):
|
|
match letter_code:
|
|
# Cannon
|
|
"c", "d", "r", "f":
|
|
var cannon = preload("res://World/cannon.tscn").instantiate()
|
|
cannon.position = 64*Vector2i(ix, iy) + Vector2i(32, 32)
|
|
match letter_code:
|
|
"c":
|
|
cannon.rotation_degrees = 180
|
|
"d":
|
|
cannon.rotation_degrees = 270
|
|
"r":
|
|
cannon.rotation_degrees = 0
|
|
"f":
|
|
cannon.rotation_degrees = 90
|
|
if MapConfig.edgewrap:
|
|
if ix < MapConfig.mapwidth / 2:
|
|
cannon.position.x += 64*MapConfig.mapwidth
|
|
if iy < MapConfig.mapheight / 2:
|
|
cannon.position.y += 64*MapConfig.mapheight
|
|
$"../Cannons".add_child(cannon, true)
|
|
|
|
_:
|
|
set_cell(0, Vector2i(ix, iy), 0, tile_dictionary[letter_code])
|
|
if "_0123456789".contains(letter_code):
|
|
base_positions.push_back(Vector2i(ix, iy))
|
|
if MapConfig.edgewrap:
|
|
if ix < MapConfig.mapwidth / 2:
|
|
base_positions[-1].x += MapConfig.mapwidth
|
|
if iy < MapConfig.mapheight / 2:
|
|
base_positions[-1].y += MapConfig.mapheight
|
|
if MapConfig.edgewrap:
|
|
set_cell(0, Vector2i(ix + MapConfig.mapwidth, iy), 0, tile_dictionary[letter_code])
|
|
set_cell(0, Vector2i(ix + MapConfig.mapwidth, iy + MapConfig.mapheight), 0, tile_dictionary[letter_code])
|
|
set_cell(0, Vector2i(ix, iy + MapConfig.mapheight), 0, tile_dictionary[letter_code])
|
|
|
|
else:
|
|
print("Map data or dimensions missing")
|
|
|
|
func apply_options():
|
|
if MapConfig.edgewrap:
|
|
$"../Map boundaries/CollisionShape2D".shape.size = 64 * Vector2i(MapConfig.mapwidth, MapConfig.mapheight)
|
|
$"../Map boundaries".position = 64 * Vector2i(MapConfig.mapwidth, MapConfig.mapheight)
|
|
if not $"../Map boundaries".is_connected("body_exited", $".."._on_map_boundaries_body_exited):
|
|
$"../Map boundaries".connect("body_exited", $".."._on_map_boundaries_body_exited)
|
|
else:
|
|
if $"../Map boundaries".is_connected("body_exited", $".."._on_map_boundaries_body_exited):
|
|
$"../Map boundaries".disconnect("body_exited", $".."._on_map_boundaries_body_exited)
|
|
|
|
# Engine.physics_ticks_per_second = MapConfig.framespersecond
|