Add tetromino movement
This commit is contained in:
@@ -20,6 +20,7 @@ signal placement_invalid(reason: String)
|
||||
var _grid: Dictionary = {} # Key: Vector3i, Value: GridCell3D
|
||||
var _tetrominoes: Array[Tetromino] = []
|
||||
var _occupied_cells: Dictionary = {} # Key: Vector3i, Value: Tetromino3D reference
|
||||
var selected_tetromino: Tetromino
|
||||
|
||||
# Ray casting for placement validation
|
||||
var _space_state: PhysicsDirectSpaceState3D
|
||||
@@ -28,6 +29,20 @@ var _space_state: PhysicsDirectSpaceState3D
|
||||
func _ready() -> void:
|
||||
_space_state = get_world_3d().direct_space_state
|
||||
_initialize_grid()
|
||||
|
||||
# Connect to every tetrominos already present on board
|
||||
var curr_tetrominos = $TetrominoContainer.get_children();
|
||||
for t in curr_tetrominos:
|
||||
t.selected.connect(_on_tetromino_selected)
|
||||
t.deselected.connect(_on_tetromino_deselected)
|
||||
|
||||
func _on_tetromino_selected(tetromino: Tetromino):
|
||||
print("Tetromino selected")
|
||||
selected_tetromino = tetromino
|
||||
|
||||
func _on_tetromino_deselected(tetromino: Tetromino):
|
||||
print("Tetromino deselected")
|
||||
selected_tetromino = null
|
||||
|
||||
|
||||
## Initializes the 3D grid structure with empty cells.
|
||||
@@ -72,16 +87,16 @@ func is_cell_empty(grid_pos: Vector3i) -> bool:
|
||||
|
||||
|
||||
## Attempts to place a tetromino at the given grid position with optional rotation.
|
||||
func place_tetromino(tetromino: Tetromino, grid_position: Vector3i, rotation: Quaternion = Quaternion.IDENTITY) -> bool:
|
||||
func place_tetromino(tetromino: Tetromino, grid_position: Vector3i, rot: Quaternion = Quaternion.IDENTITY) -> bool:
|
||||
# Validate placement
|
||||
if not _can_place_tetromino(tetromino, grid_position, rotation):
|
||||
if not _can_place_tetromino(tetromino, grid_position, rot):
|
||||
placement_invalid.emit("Invalid placement: overlapping or out of bounds")
|
||||
return false
|
||||
|
||||
# Update tetromino state
|
||||
tetromino.grid_position = grid_position
|
||||
tetromino.rotation_quat = rotation
|
||||
tetromino.world_position = grid_to_world(grid_position)
|
||||
tetromino.rotation_quat = rot
|
||||
tetromino.global_position = grid_to_world(grid_position)
|
||||
|
||||
# Mark cells as occupied
|
||||
var cells = tetromino.get_grid_cells(grid_position)
|
||||
@@ -97,8 +112,8 @@ func place_tetromino(tetromino: Tetromino, grid_position: Vector3i, rotation: Qu
|
||||
|
||||
## Moves a tetromino to a new position (used during combat).
|
||||
func move_tetromino(tetromino: Tetromino, new_grid_position: Vector3i) -> bool:
|
||||
if tetromino not in _tetrominoes:
|
||||
return false
|
||||
#if tetromino not in _tetrominoes:
|
||||
#return false
|
||||
|
||||
# Clear old occupation
|
||||
var old_cells = tetromino.get_grid_cells(tetromino.grid_position)
|
||||
@@ -107,20 +122,20 @@ func move_tetromino(tetromino: Tetromino, new_grid_position: Vector3i) -> bool:
|
||||
if cell_pos in _grid:
|
||||
_grid[cell_pos].owner = null
|
||||
|
||||
# Validate new position
|
||||
if not _can_place_tetromino(tetromino, new_grid_position, tetromino.rotation_quat):
|
||||
# Restore old occupation
|
||||
for cell_pos in old_cells:
|
||||
_occupied_cells[cell_pos] = tetromino
|
||||
if cell_pos in _grid:
|
||||
_grid[cell_pos].owner = tetromino
|
||||
placement_invalid.emit("Cannot move to target position")
|
||||
return false
|
||||
## Validate new position
|
||||
#if not _can_place_tetromino(tetromino, new_grid_position, tetromino.rotation_quat):
|
||||
## Restore old occupation
|
||||
#for cell_pos in old_cells:
|
||||
#_occupied_cells[cell_pos] = tetromino
|
||||
#if cell_pos in _grid:
|
||||
#_grid[cell_pos].owner = tetromino
|
||||
#placement_invalid.emit("Cannot move to target position")
|
||||
#return false
|
||||
|
||||
# Update position
|
||||
var old_position = tetromino.grid_position
|
||||
tetromino.grid_position = new_grid_position
|
||||
tetromino.world_position = grid_to_world(new_grid_position)
|
||||
tetromino.global_position = grid_to_world(new_grid_position)
|
||||
|
||||
# Mark cells as occupied
|
||||
var new_cells = tetromino.get_grid_cells(new_grid_position)
|
||||
@@ -129,7 +144,7 @@ func move_tetromino(tetromino: Tetromino, new_grid_position: Vector3i) -> bool:
|
||||
if cell_pos in _grid:
|
||||
_grid[cell_pos].owner = tetromino
|
||||
|
||||
tetromino_moved.emit(tetromino, grid_to_world(old_position), tetromino.world_position)
|
||||
tetromino_moved.emit(tetromino, grid_to_world(old_position), tetromino.global_position)
|
||||
return true
|
||||
|
||||
|
||||
@@ -194,13 +209,13 @@ func get_tetromino_at(grid_pos: Vector3i) -> Tetromino:
|
||||
## Gets all adjacent tetrominoes within synergy radius.
|
||||
func get_adjacent_tetrominoes(tetromino: Tetromino, synergy_radius: float = 2.5) -> Array[Tetromino]:
|
||||
var adjacent: Array[Tetromino] = []
|
||||
var world_pos = tetromino.world_position
|
||||
var world_pos = tetromino.global_position
|
||||
|
||||
for other in _tetrominoes:
|
||||
if other == tetromino:
|
||||
continue
|
||||
|
||||
var distance = world_pos.distance_to(other.world_position)
|
||||
var distance = world_pos.distance_to(other.global_position)
|
||||
if distance <= synergy_radius:
|
||||
adjacent.append(other)
|
||||
|
||||
@@ -208,9 +223,9 @@ func get_adjacent_tetrominoes(tetromino: Tetromino, synergy_radius: float = 2.5)
|
||||
|
||||
|
||||
## Validates whether a tetromino can be placed at the given position with rotation.
|
||||
func _can_place_tetromino(tetromino: Tetromino, grid_position: Vector3i, rotation: Quaternion) -> bool:
|
||||
func _can_place_tetromino(tetromino: Tetromino, grid_position: Vector3i, rot: Quaternion) -> bool:
|
||||
# Get the cells this tetromino would occupy
|
||||
var cells = tetromino.get_grid_cells_with_rotation(grid_position, rotation)
|
||||
var cells = tetromino.get_grid_cells_with_rotation(grid_position, rot)
|
||||
|
||||
# Check all cells are within bounds and empty
|
||||
for cell_pos in cells:
|
||||
@@ -222,7 +237,7 @@ func _can_place_tetromino(tetromino: Tetromino, grid_position: Vector3i, rotatio
|
||||
return false
|
||||
|
||||
# Raycast check for physical obstacles
|
||||
if not _validate_placement_raycast(tetromino, grid_position, rotation):
|
||||
if not _validate_placement_raycast(tetromino, grid_position):
|
||||
return false
|
||||
|
||||
return true
|
||||
@@ -230,7 +245,7 @@ func _can_place_tetromino(tetromino: Tetromino, grid_position: Vector3i, rotatio
|
||||
|
||||
## Performs raycast validation for tetromino placement.
|
||||
## Checks for physical obstacles using raycasting.
|
||||
func _validate_placement_raycast(tetromino: Tetromino, grid_position: Vector3i, rotation: Quaternion) -> bool:
|
||||
func _validate_placement_raycast(tetromino: Tetromino, grid_position: Vector3i) -> bool:
|
||||
if not _space_state:
|
||||
return true
|
||||
|
||||
|
||||
Reference in New Issue
Block a user