Files
millimeters-of-aluminum/scenes/ship/builder/module.gd
2025-12-05 15:50:48 +01:00

138 lines
4.5 KiB
GDScript

class_name Module extends OrbitalBody3D
@export var ship_name: String = "Unnamed Ship" # Only relevant for the root module
@export var hull_integrity: float = 100.0 # This could also be a calculated property later
const COMPONENT_GRID_SIZE = 64.0
func _ready():
super._ready()
child_entered_tree.connect(_on_child_entered_tree)
# Handle existing children (if any existed before ready)
for child in get_children():
_enforce_child_physics_mode(child)
func _on_child_entered_tree(node: Node):
_enforce_child_physics_mode(node)
func _enforce_child_physics_mode(node: Node):
# Only affect OrbitalBody3D children that are NOT the module itself
if node is OrbitalBody3D and node != self:
# We only enforce ANCHORED if this Module is a COMPOSITE (Root)
if physics_mode == PhysicsMode.COMPOSITE:
node.physics_mode = PhysicsMode.ANCHORED
# print("Module '%s' enforced ANCHORED mode on child '%s'" % [name, node.name])
# --- Helper functions to get children by type ---
func get_structural_pieces() -> Array[StructuralPiece]:
var pieces: Array[StructuralPiece]
for child in get_children():
if child is StructuralPiece:
pieces.append(child)
return pieces
func get_components() -> Array[Component]:
var components: Array[Component]
for child in get_children():
if child is Component:
components.append(child)
return components
func set_initial_velocity(velocity: Vector3):
linear_velocity = velocity
for piece in get_structural_pieces():
piece.linear_velocity = velocity
# --- UPDATED: Logic now uses the helper function ---
func get_attachment_points() -> Array:
var points = []
# Iterate through all StructuralPiece children directly
for piece in get_structural_pieces():
var piece_center = piece.global_position
# --- Hullplates (Interior Grid) ---
# if piece is Hullplate:
# for i in range(-1, 2, 2):
# for j in range(-1, 2, 2):
# var offset = Vector2(i, j) * (COMPONENT_GRID_SIZE / 2.0)
# points.append({
# "position": piece_center + offset,
# "type": Component.AttachmentType.INTERIOR_WALL,
# "piece": piece
# })
# # --- Bulkheads (Interior and Exterior Edge Attachments) ---
# elif piece is Bulkhead:
# var interior_point = piece_center + piece.transform.origin.y * (COMPONENT_GRID_SIZE / 2.0)
# points.append({
# "position": interior_point,
# "type": Component.AttachmentType.INTERIOR_WALL,
# "piece": piece
# })
# var exterior_point = piece_center - piece.transform.origin.y * (COMPONENT_GRID_SIZE / 2.0)
# points.append({
# "position": exterior_point,
# "type": Component.AttachmentType.EXTERIOR_HULL,
# "piece": piece
# })
return points
# --- This function remains largely the same ---
func attach_component(component: Component, global_pos: Vector3, parent_piece: StructuralPiece):
component.position = global_pos - global_position
component.attached_piece = parent_piece
add_child(component)
component.owner = self
component.physics_mode = PhysicsMode.ANCHORED
recalculate_physical_properties()
# --- UPDATED: Logic now uses the helper function ---
func _recalculate_collision_shape():
# This logic is much simpler now. We just iterate over relevant children.
var _combined_polygons = []
for piece in get_structural_pieces():
# You would use logic here to transform the piece's local shape
# into the Module's local space and add it to the list.
# Example Placeholder (requires full implementation):
# var piece_collision_shape = piece.find_child("CollisionShape2D")
# if piece_collision_shape:
# combined_polygons.append(piece_collision_shape.shape.points)
pass
# NOTE: The OrbitalBody3D's _update_mass_and_inertia() takes care of mass!
pass
# --- UPDATED: Clear module now iterates over all relevant children ---
func clear_module():
# We queue_free both structural pieces and components
for piece in get_structural_pieces():
piece.queue_free()
for component in get_components():
component.queue_free()
_recalculate_collision_shape()
# Damage can have a position for breach effects.
func take_damage(amount: float, damage_position: Vector2):
hull_integrity -= amount
print("%s hull integrity at %.1f%%" % [ship_name, hull_integrity])
if hull_integrity <= 0:
destroy_ship()
else:
# Find the LifeSupport component and check for a breach
for child in get_children():
if child is LifeSupport: # Assuming LifeSupport becomes a Component class
child.check_for_breach(damage_position, self)
func destroy_ship():
print("%s has been destroyed!" % ship_name)
# Add explosion/destruction effects here
queue_free()