@tool @abstract class_name Tetromino extends Node2D var segments: Array[TetrominoSegment] var grid: TileMapLayer var current_grid_position: Vector2i: set = set_current_grid_position var current_segment_positions: Array[Vector2i]: set = set_current_segment_positions @onready var base_segment: TetrominoSegment = $BaseSegment func init(init_grid: TileMapLayer, init_position: Vector2i) -> void: grid = init_grid current_grid_position = init_position func _ready() -> void: for segment in %Segments.get_children(): segments.append(segment) current_segment_positions = get_default_segment_positions() func set_current_grid_position(value: Vector2i) -> void: current_grid_position = value global_position = ( grid.map_to_local(current_grid_position) # shift to upper left corner of tile - (grid.tile_set.tile_size / 2.0) # apply map offset + grid.position ) func set_current_segment_positions(value: Array[Vector2i]) -> void: current_segment_positions = value for index in segments.size(): var segment = segments[index] segment.position = current_segment_positions[index] * grid.tile_set.tile_size @abstract func get_default_segment_positions() -> Array[Vector2i] func get_rotated_segment_positions(direction: float) -> Array[Vector2i]: var mapped := current_segment_positions.map(func (p: Vector2i) -> Vector2i: if direction > 0: return Vector2i( p.y, -p.x ) else: return Vector2i( -p.y, -p.x ) ) var result: Array[Vector2i] result.assign(mapped) return result func do_rotation(direction: float) -> void: current_segment_positions = get_rotated_segment_positions(direction) func get_grid_occupations(offset: Vector2i = Vector2.ZERO, rotation_direction: float = 0.0) -> Array[Vector2i]: var grid_occupations: Array[Vector2i] grid_occupations.append(current_grid_position + offset) if rotation_direction != 0.0: grid_occupations.append_array(get_rotated_segment_positions(rotation_direction).map(func (p: Vector2i): return current_grid_position + offset + p )) else: grid_occupations.append_array(current_segment_positions.map(func (p: Vector2i): return current_grid_position + offset + p )) return grid_occupations func get_grid_segments() -> Dictionary[Vector2i, TetrominoSegment]: var grid_segments: Dictionary[Vector2i, TetrominoSegment] grid_segments.set(current_grid_position, base_segment) for index in segments.size(): var segment = segments[index] grid_segments.set(current_grid_position + current_segment_positions[index], segment) return grid_segments