extends CharacterBody2D const DEFAULT_SHIP_TEXTURE := "res://assets/Ships/Spaceship_0.png" @export var max_speed := 420.0 @export var reverse_max_speed := 210.0 @export var max_strafe_speed := 210.0 @export var thrust_acceleration := 260.0 @export var brake_acceleration := 540.0 @export var space_drag := 24.0 @export var max_turn_speed := 2.8 @export var turn_acceleration := 7.0 @export var turn_damping := 4.0 @export var base_max_hull := 100.0 @export var base_max_shields := 100.0 @export var base_max_energy := 100.0 @export var base_max_speed := 420.0 @export var base_energy_regeneration := 12.0 @export var max_hull := 100.0 @export var max_shields := 100.0 @export var max_energy := 100.0 var hull := 100.0 var shields := 100.0 var energy := 100.0 var energy_regeneration := 12.0 var angular_velocity := 0.0 var _sprite: Sprite2D func apply_equipment_bonuses(bonuses: Dictionary) -> void: max_hull = base_max_hull + float(bonuses.get("max_hull", 0.0)) max_shields = base_max_shields + float(bonuses.get("max_shields", 0.0)) max_energy = base_max_energy + float(bonuses.get("max_energy", 0.0)) max_speed = base_max_speed + float(bonuses.get("max_speed", 0.0)) energy_regeneration = base_energy_regeneration + float(bonuses.get("energy_regeneration", 0.0)) reverse_max_speed = max_speed * 0.5 max_strafe_speed = max_speed * 0.5 hull = minf(hull, max_hull) shields = minf(shields, max_shields) energy = minf(energy, max_energy) func _ready() -> void: _ensure_input_action(&"ship_thrust", KEY_W) _ensure_input_action(&"ship_brake", KEY_S) _ensure_input_action(&"ship_turn_left", KEY_A) _ensure_input_action(&"ship_turn_right", KEY_D) _ensure_input_action(&"ship_strafe_left", KEY_Q) _ensure_input_action(&"ship_strafe_right", KEY_E) _sprite = $Sprite2D var texture_path := GameState.selected_ship_path if texture_path.is_empty() or not ResourceLoader.exists(texture_path): texture_path = DEFAULT_SHIP_TEXTURE var ship_texture := load(texture_path) as Texture2D if ship_texture: _sprite.texture = ship_texture var largest_dimension := maxf(ship_texture.get_width(), ship_texture.get_height()) _sprite.scale = Vector2.ONE * (64.0 / largest_dimension) func _ensure_input_action(action_name: StringName, physical_key: Key) -> void: if not InputMap.has_action(action_name): InputMap.add_action(action_name, 0.5) var event := InputEventKey.new() event.physical_keycode = physical_key if not InputMap.action_has_event(action_name, event): InputMap.action_add_event(action_name, event) func _physics_process(delta: float) -> void: energy = minf(max_energy, energy + energy_regeneration * delta) var turn_input := Input.get_axis("ship_turn_left", "ship_turn_right") if not is_zero_approx(turn_input): angular_velocity = move_toward( angular_velocity, turn_input * max_turn_speed, turn_acceleration * delta ) else: angular_velocity = move_toward(angular_velocity, 0.0, turn_damping * delta) rotation += angular_velocity * delta var forward := Vector2.UP.rotated(rotation) if Input.is_action_pressed("ship_brake"): var forward_speed := velocity.dot(forward) if forward_speed > 0.0: velocity = velocity.move_toward(Vector2.ZERO, brake_acceleration * delta) else: velocity -= forward * thrust_acceleration * delta var reverse_speed := velocity.dot(forward) if reverse_speed < -reverse_max_speed: velocity += forward * (-reverse_max_speed - reverse_speed) elif Input.is_action_pressed("ship_thrust"): velocity += forward * thrust_acceleration * delta var forward_speed := velocity.dot(forward) if forward_speed > max_speed: velocity += forward * (max_speed - forward_speed) var strafe_input := Input.get_axis("ship_strafe_left", "ship_strafe_right") var right := Vector2.RIGHT.rotated(rotation) if not is_zero_approx(strafe_input): velocity += right * strafe_input * thrust_acceleration * delta var strafe_speed := velocity.dot(right) velocity += right * (clampf(strafe_speed, -max_strafe_speed, max_strafe_speed) - strafe_speed) if ( not Input.is_action_pressed("ship_brake") and not Input.is_action_pressed("ship_thrust") and is_zero_approx(strafe_input) ): velocity = velocity.move_toward(Vector2.ZERO, space_drag * delta) move_and_slide()