Files
millimeters-of-aluminum/src/scenes/ship/components/hardware/thruster.gd
2025-11-18 10:55:10 +01:00

76 lines
2.3 KiB
GDScript

# Thruster.gd
class_name Thruster
extends Component
@onready var pin_joint_a: PinJoint2D = $PinJointA
@onready var pin_joint_b: PinJoint2D = $PinJointB
# Max force the thruster can produce (in scaled Newtons).
@export var max_thrust: float = 0.1
# Engine efficiency. Higher is better (more "bang for your buck").
# Measures how much momentum change you get per unit of fuel.
@export var specific_impulse_isp: float = 300.0
# The type of fuel resource this thruster consumes.
@export var enabled: bool = true
@export var fuel_resource_name: String = "ChemicalFuel"
@export var main_thruster: bool = true
# A state variable to track if the thruster is active
var is_firing: bool = false
func _ready() -> void:
super()
# TODO: Figure out where this should go if anywhere
# --- Self-connecting logic ---
#if ship and ship.get_path():
#var ship_path = ship.get_path()
#var self_path = get_path()
#
## --- Configure Pin Joint A ---
#pin_joint_a.node_b = ship_path
#
## --- Configure Pin Joint B ---
#pin_joint_b.node_b = ship_path
#else:
#print("Thruster Warning: 'Attach To Node' path is not set for ", self.name)
# This thruster announces its existence to the whole scene tree.
add_to_group("ship_thrusters")
# This function calculates how much fuel is needed for a given thrust level and duration.
func calculate_fuel_consumption(thrust_force: float, delta_time: float) -> float:
if thrust_force <= 0: return 0.0
# Standard rocket equation using Isp. g0 is standard gravity (9.81).
var mass_flow_rate = thrust_force / (specific_impulse_isp * 9.81)
return mass_flow_rate * delta_time
# --- Public Methods ---
# The controller calls this ONCE to activate the thruster.
func turn_on():
#print("THRUSTER: Recieved Turn On Signal")
if enabled:
is_firing = true
await get_tree().physics_frame
#print(" - firing: %s" % is_firing)
# The controller calls this ONCE to deactivate the thruster.
func turn_off():
#print("THRUSTER: Recieved Turn Off Signal")
is_firing = false
await get_tree().physics_frame
#print(" - firing: %s" % is_firing)
func _integrate_forces(state: PhysicsDirectBodyState3D):
# Call the base class integration
super(state)
# If the thruster is active, apply a constant central force in its local "up" direction.
if is_firing:
apply_central_force(Vector3.UP * max_thrust)