class_name AttackTowerComponent extends TowerComponent var power := 1 var speed_base := 1.0 var speed := 1 var shoot_cooldown := Timer.new() var shoot_sound := AudioStreamPlayer2D.new() @export var range_component: RangeTowerComponent: get(): return current_tower.components[ComponentType.Range] func _init() -> void: type = ComponentType.Attack set_sprite(preload("res://Towers/Components/Assets/attack-component.png")) update_power() update_speed() level_changed.connect(update_power) level_changed.connect(update_speed) func update_power(): power = ceil(level / 2.0) func update_speed(): speed = level - ceil(level / 2.0) shoot_cooldown.wait_time = speed_base / speed func update_range(): shoot_sound.max_distance = range_component.range * Client.current_stage.map.tile_set.tile_size.x func on_add(tower: Tower): super.on_add(tower) shoot_cooldown.one_shot = true tower.add_child(shoot_cooldown) shoot_sound.stream = preload("res://Towers/Assets/shoot.ogg") tower.add_child(shoot_sound) update_range() range_component.range_changed.connect(update_range) func process(_delta: float): if shoot_cooldown.is_stopped() and not range_component.units_in_range.is_empty(): shoot() shoot_cooldown.start() func shoot(): var target = range_component.units_in_range[0] for component in current_tower.components.values(): if component.has_method("on_shoot"): component.on_shoot(target) shoot_fx.rpc() if is_melee_range(): target.set_hp(target.hp - 1) else: # TODO target.set_hp(target.hp - 1) @rpc("authority", "call_local") func shoot_fx(): shoot_sound.play() func is_melee_range(): return range_component.range <= (Client.current_stage.map.tile_set.tile_size.x * 2)