@abstract class_name BulletBehavior extends Resource @export_group("Actions", "action_") ## Delay in seconds before performing [member action_on_delay]. @export_range(0.0, 1.0, 0.01, "or_greater", "suffix:s") var action_delay: float = 0.0 ## Performed once the bullet has existed for [member action_delay] seconds. @export var action_on_delay: BulletAction ## Interval in seconds at which [member action_on_interval] is performed. @export_range(0.0, 1.0, 0.01, "or_greater", "suffix:s") var action_interval: float = 0.0 ## Performed every [member action_interval] seconds. @export var action_on_interval: BulletAction var _bullet_interval_cooldowns: Dictionary[Bullet, float] = {} ## Performs behavior-specific initialization for a [Bullet]. func init_bullet(bullet: Bullet) -> void: if action_on_interval: _bullet_interval_cooldowns[bullet] = action_interval bullet.recycled.connect(deinit_bullet.bind(bullet), CONNECT_ONE_SHOT) _init_bullet(bullet) ## Cleans up behavior-specific state for a [Bullet]. func deinit_bullet(bullet: Bullet) -> void: _bullet_interval_cooldowns.erase(bullet) _deinit_bullet(bullet) ## Processes one tick of a [Bullet]'s movement. func process_bullet(bullet: Bullet, delta: float) -> void: var last_time = bullet.time_elapsed bullet.time_elapsed += delta if last_time < action_delay and bullet.time_elapsed >= action_delay and action_on_delay: action_on_delay.perform(bullet) if action_on_interval: _bullet_interval_cooldowns[bullet] -= delta if _bullet_interval_cooldowns[bullet] <= 0.0: _bullet_interval_cooldowns[bullet] += action_interval _process_bullet(bullet, delta) ## Called when a [Bullet] is spawned with this behavior in order to set up ## behavior-specific state. @abstract func _init_bullet(bullet: Bullet) -> void ## Called when a [Bullet] is recycled in order to clean up behavior-specific state. @abstract func _deinit_bullet(bullet: Bullet) -> void ## Called to process a tick of a [Bullet]'s movement. @abstract func _process_bullet(bullet: Bullet, delta: float) -> void