Files
trenchlock/scripts/tetromino.gd
2026-01-13 08:31:42 +01:00

142 lines
4.0 KiB
GDScript

## Represents a 3D tetromino (tower block) with shape, position, and rotation.
##
## Manages 3D grid cell data, mesh instances, position/rotation state,
## synergy detection, and material effects.
class_name Tetromino
extends Node3D
# Data
@export var resource: TetrominoDefinition
# Visual
@export var mesh_color: Color = Color.WHITE
var _material: StandardMaterial3D
var _is_ghost: bool = false
var _original_color: Color = Color.WHITE
# Runtime
@onready var base_damage: int = resource.base_damage
@onready var fire_rate: float = resource.fire_rate
@onready var synergy_radius: float = resource.synergy_radius
@onready var synergy_tags: PackedStringArray = resource.synergy_tags
@onready var _mesh_instance: MeshInstance3D = get_node("Visuals/MeshInstance3D")
# Grid state
var grid_position: Vector3i = Vector3i.ZERO
var rotation_quat: Quaternion = Quaternion.IDENTITY
var _grid_cells: PackedVector3Array = [] # Relative cell coordinates
func _ready() -> void:
#_initialize_material()
#_set_mesh_representation()
pass
## Initializes the material for visual representation.
func _initialize_material() -> void:
_material = StandardMaterial3D.new()
_material.albedo_color = mesh_color
_material.metallic = 0.3
_material.roughness = 0.7
## Creates a simple mesh representation based on shape type.
func _set_mesh_representation() -> void:
_mesh_instance.mesh = resource.mesh
#_mesh_instance.set_surface_override_material(0, _material)
_grid_cells = resource.grid_cells
## Creates a simple box mesh for tetromino visualization.
func _create_box_mesh(width: float, height: float, depth: float) -> BoxMesh:
var box = BoxMesh.new()
box.size = Vector3(width, height, depth)
return box
## Gets the grid cells occupied by this tetromino at its current position.
func get_grid_cells(at_position: Vector3i = grid_position) -> PackedVector3Array:
var result = PackedVector3Array()
for cell in _grid_cells:
result.append(at_position + Vector3i(cell.x, cell.y, cell.z))
return result
## Gets grid cells with a specific rotation applied.
func get_grid_cells_with_rotation(at_position: Vector3i, rotation: Quaternion) -> PackedVector3Array:
var result = PackedVector3Array()
# Apply rotation to relative grid cells
for cell in _grid_cells:
var rotated = rotation * Vector3(cell)
var rotated_int = Vector3i(rotated.round())
result.append(at_position + rotated_int)
return result
## Gets the bounds (AABB) of this tetromino.
func get_bounds() -> AABB:
var min_cell = Vector3i.ZERO
var max_cell = Vector3i.ZERO
for cell in _grid_cells:
min_cell = min_cell.min(cell)
max_cell = max_cell.max(cell)
var size = Vector3(max_cell - min_cell) + Vector3.ONE
var pos = grid_position + min_cell
return AABB(Vector3(pos), size)
## Sets the color/material of the tetromino.
func set_color(color: Color) -> void:
mesh_color = color
_original_color = color
if _material:
_material.albedo_color = color
## Enables/disables ghost mode (semi-transparent, movable state).
func set_ghost_mode(enabled: bool) -> void:
_is_ghost = enabled
if enabled:
# Create material if needed
if not _material:
_initialize_material()
# Make semi-transparent
var ghost_color = _original_color
ghost_color.a = 0.5
_material.albedo_color = ghost_color
_mesh_instance.set_surface_override_material(0, _material)
else:
# Restore original appearance
if _material:
_material.albedo_color = _original_color
_material.albedo_color.a = 1.0
_mesh_instance.set_surface_override_material(0, _material)
## Enables/disables highlight for visual feedback.
func set_highlighted(enabled: bool) -> void:
if _material:
_material.emission_enabled = enabled
if enabled:
_material.emission = mesh_color
_material.emission_energy_multiplier = 2.0
else:
_material.emission_energy_multiplier = 0.0
## Returns string representation for debugging.
func _to_string() -> String:
return "Tetromino3D[type=%s, pos=%v, cells=%d]" % [
resource.shape_type,
grid_position,
_grid_cells.size()
]