class_name AttackTowerComponent extends TowerComponent var power := 1 var speed_base := 2.0 var speed := 1 @onready var shoot_cooldown := $ShootCooldown @onready var shoot_sound := $ShootSound var range_component: RangeTowerComponent: get(): return current_tower.components[ComponentType.Range] func _ready() -> void: update_power() level_changed.connect(update_power) update_speed() level_changed.connect(update_speed) func update_power(): if level <= 2: power = level else: power = 1 + max(1, level - ceil(level / 2.0)) func update_speed(): speed = max(1, 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) 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)