'''冲刺控制组件
		注：该组件只适用于继承自CharaterBody2D的角色。
		
		基础移动控制：
			
		外部调用移动：
			dash()
			full_recover_dash_count()
			recover_dash_count()
		
		内部调用：
			speed_approach() 此函数将当前速度趋近向目标速度
'''
class_name DashComponent extends ComponentBase

##最大的冲刺次数
@export var maxium_dash_count:int = 1
##Dash时的速度
@export var dash_speed: float = 240
##结束Dash的速度
@export var end_dash_speed: float = 160
##Dash的冷却时间
@export var dash_cold_down: float = .2
##是否在组件ready时自动补充所有的Dash次数
@export var auto_recover_dash_count_at_ready: bool = true

var characterbody:CharacterBody2D

var last_dash_count: int

##此变量为总开关，如果关闭，则在物理更新里无论如何也是不会更新Dash的，这里默认为false，因为Dash需要手动触发，最好不要常开
var can_dash: bool = false

var _dash_timer: float									#Dash计时器
var _is_dashing: bool = false							#标记Dash状态
var _dash_direction: Vector2							#存储Dash的Direction

##当Dash count 重置为最大时，发出
signal dash_count_recovered
signal dash_brusted
signal dash_prepared

func _init_component()-> void:
	characterbody = component_owner as CharacterBody2D
	assert(characterbody,"组件没有正确的绑定CharacterBody2D")
	
	if auto_recover_dash_count_at_ready:
		full_recover_dash_count()

func _physics_process(delta: float) -> void:
	if Engine.is_editor_hint():
		return
	
	#不允许Dash则直接return
	if not can_dash: return
	
	_update_dash(delta)
	characterbody.move_and_slide()

func _update_dash(delta) -> void:
	return

##整合之后的函数，如果不需要额外的逻辑，可以直接通过这个触发Dash
func integrate_dash(dash_dir: Vector2) -> bool:
	if not predash(dash_dir):
		return false
	await get_tree().process_frame					#等待一帧
	can_dash = true
	brust_dash()
	return true

##dash函数，输入一个Dash的方向，返回是否成功
func brust_dash() -> bool:
	var old: Vector2 = characterbody.velocity;
	var burst: Vector2  = _dash_direction.normalized() * dash_speed;
	
	if sign(old.x) == sign(burst.x) and abs(old.x) > abs(burst.x):
		burst.x = old.x
	
	characterbody.velocity = burst
	dash_brusted.emit()
	return true

##dash准备函数，需要在dash的前一帧触发
func predash(dash_dir: Vector2) -> bool:
	if not get_can_dash():
		return false
	
	print("Dash更新中")
	last_dash_count = maxi(last_dash_count -1,0)
	_is_dashing = true
	
	_dash_direction = dash_dir
	return true

##停止Dash，实际上是关闭Dash标识符
func stop_dash(force_stop: bool = false) -> void:
	if force_stop:
		characterbody.velocity = Vector2.ZERO
		characterbody.move_and_slide()
	_is_dashing = false

##完全回复的Dash次数
func full_recover_dash_count() -> void:
	last_dash_count = maxium_dash_count

##回复指定数量的Dash次数
func recover_dash_count(recover_count : int) -> void:
	last_dash_count = clampi(last_dash_count+ recover_count, 0,maxium_dash_count)

##子类可以重写此方法以自定义Dash的条件
func get_can_dash() -> bool:
	return last_dash_count > 0
