paratate/systems/bullets/bullet_behaviors/bullet_behavior.gd

64 lines
2.3 KiB
GDScript

@abstract
class_name BulletBehavior
extends Resource
## Controls the movment and actions of a [Bullet].
@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_delay_cooldowns: Dictionary[Bullet, float] = {}
var _bullet_interval_cooldowns: Dictionary[Bullet, float] = {}
## Performs behavior-specific initialization for a [Bullet].
func init_bullet(bullet: Bullet) -> void:
if action_on_delay:
_bullet_delay_cooldowns[bullet] = action_delay
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_delay_cooldowns.erase(bullet)
_bullet_interval_cooldowns.erase(bullet)
_deinit_bullet(bullet)
## Processes one tick of a [Bullet]'s movement.
func process_bullet(bullet: Bullet, delta: float) -> void:
if action_on_delay and _bullet_delay_cooldowns.has(bullet):
_bullet_delay_cooldowns[bullet] -= delta
if _bullet_delay_cooldowns[bullet] <= 0.0:
_bullet_delay_cooldowns.erase(bullet)
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
action_on_interval.perform(bullet)
_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