extends Building @export var ammo_cap: int = 10 @export var fire_cooldown_time: float = 0.2 @export var reload_time: float = 1.0 @export var bullet_scene: PackedScene = preload("res://objects/bullet.tscn") @export var fire_position: Vector3 = Vector3(0,1,0) @export var shot_impulse: float = 100 @export var lead_shot_factor: float = 0.01 @onready var consumer: Consumer = $Consumer enum LoadState {UNLOADED, RELOADING, LOADED} @onready var ammo: int = 0 var loaded: LoadState = LoadState.UNLOADED var cooldown_timer: float = 0.0 var reload_timer: float = 0.0 var current_target: Enemy = null func _on_consumer_item_added(item: Item) -> void: pass func _process(delta: float) -> void: if loaded == LoadState.UNLOADED: if consumer.take_any_item_from_storage(): #Engine.time_scale = 1.0 loaded = LoadState.RELOADING if loaded == LoadState.RELOADING: reload_timer += delta if reload_timer >= reload_time: loaded = LoadState.LOADED ammo = ammo_cap reload_timer = 0.0 if loaded == LoadState.LOADED: cooldown_timer += delta if cooldown_timer >= fire_cooldown_time: cooldown_timer -= fire_cooldown_time if current_target == null: search_for_enemy() if current_target != null: fire_at_target() func check_target_status() -> void: if current_target.is_queued_for_deletion(): current_target = null func search_for_enemy() -> void: var enemies: Array[Node] = get_tree().get_nodes_in_group("Enemies") var closest: float = 9999999999 for enemy in enemies: if enemy is Enemy: if !enemy.sighted: continue var distance_sqr = global_position.distance_squared_to(enemy.global_position) if distance_sqr <= closest: var params: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.new() params.collision_mask = 0b00101 params.from = to_global(fire_position) params.to = enemy.global_position var result: Dictionary = get_world_3d().direct_space_state.intersect_ray(params) #DebugDraw3D.draw_line_hit(params.from, params.to, result["position"] if result.has("position") else Vector3(), result.has("position"), 0.25, Color.YELLOW, Color.BLACK, 1.0) if result.has("collider"): if !result["collider"] is PhysicsBody3D: continue var body: PhysicsBody3D = result["collider"] if body is Enemy: current_target = body closest = body.global_position.distance_squared_to(global_position) func fire_at_target() -> void: #Engine.time_scale = 0.1 var bullet: RigidBody3D = bullet_scene.instantiate() add_child(bullet) bullet.global_position = to_global(fire_position) var aim_target: Vector3 = current_target.global_position var range: float = global_position.distance_to(current_target.global_position) aim_target += current_target.linear_velocity * lead_shot_factor * range DebugDraw3D.draw_sphere(aim_target, 0.25, Color.RED, 0.1) bullet.look_at(aim_target) bullet.apply_impulse((aim_target - bullet.global_position).normalized()*shot_impulse) current_target = null ammo -= 1 if ammo <= 0: loaded = LoadState.UNLOADED