class_name VesselWeaponComponent extends Node # The fleet's gun. It does NOT pick its own targets: the player aims it with # the fire stick, and it shoots along whatever heading that stick reports for # as long as it is held. # # It used to seek the nearest enemy in range and fire on its own, which meant # combat happened whether or not the player did anything - there was nothing # to aim, and nothing to decide. Firing is now an action like any other, and # the right-hand stick is what performs it. # # `fire_direction` is set every frame by FireStickController from the stick's # own reading, and cleared the moment it is released. Zero means "not firing", # which is the resting state. var capability_id: String = "weapon" var fire_range: float var fire_cooldown: float var projectile_damage: int var fire_timer: float = 0.0 var fire_direction: Vector2 = Vector2.ZERO var projectile_scene: PackedScene = preload("res://Projectile.tscn") func apply_stats() -> void: var ship: Node = get_parent() var state: Node = ship.get_tree().root.get_node("GameState") fire_range = state.vessel_stat(ship.vessel_type, "fire_range") fire_cooldown = state.vessel_stat(ship.vessel_type, "fire_cooldown") projectile_damage = int(state.vessel_stat(ship.vessel_type, "damage")) # Called by FireStickController. A zero vector stops the gun. func set_fire_direction(direction: Vector2) -> void: fire_direction = direction if direction.length() > 0.001 else Vector2.ZERO func is_firing() -> bool: return fire_direction != Vector2.ZERO func tick(delta: float) -> void: # The cooldown runs down whether or not the trigger is held, so tapping # the stick in a new direction is not punished by a timer that only # started when the stick moved. fire_timer -= delta if fire_direction == Vector2.ZERO or fire_timer > 0.0: return var ship: Node2D = get_parent() var projectile: Node2D = projectile_scene.instantiate() projectile.position = ship.position projectile.damage = projectile_damage ship.get_tree().root.add_child(projectile) # Aimed by DIRECTION, not at a target: launch() takes a displacement, so # the gun's own range decides how far the shot is sent. projectile.launch(fire_direction.normalized() * fire_range) fire_timer = fire_cooldown