|  |  |  | extends Area3D | 
					
						
							|  |  |  | class_name Hitbox | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @export var pushbox_curve: Curve | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @onready var character: Character = (get_owner() as Character) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var radius: float | 
					
						
							|  |  |  | var pushbox_list: Array[Hitbox] = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func _ready(): | 
					
						
							|  |  |  | 	var collisionShape3D: CollisionShape3D = $CollisionShape3D as CollisionShape3D | 
					
						
							|  |  |  | 	var shape: CylinderShape3D             = collisionShape3D.shape as CylinderShape3D | 
					
						
							|  |  |  | 	radius = shape.radius * scale.x | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func _process(delta) -> void: | 
					
						
							|  |  |  | 	var speed_dir: Vector2 = character.get_status("speed_dir") as Vector2 | 
					
						
							|  |  |  | 	if speed_dir.length() == 0: | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	var is_skill_running: bool = character.get_status("is_skill_running") as bool | 
					
						
							|  |  |  | 	if not is_skill_running: | 
					
						
							|  |  |  | 		character.set_status("speed_down_push_rate", 0) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	var skill_cfg: SkillCfg = character.get_status("skill_cfg") as SkillCfg | 
					
						
							|  |  |  | 	if not skill_cfg: | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	if skill_cfg.ignore_push: | 
					
						
							|  |  |  | 		character.set_status("speed_down_push_rate", 0) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	var speed_down_push_rate: float = 0 | 
					
						
							|  |  |  | 	var pos: Vector2                = character.pos2D() | 
					
						
							|  |  |  | 	for pushbox: Hitbox in pushbox_list: | 
					
						
							|  |  |  | 		var target_pos: Vector2 = pushbox.character.pos2D() | 
					
						
							|  |  |  | 		var dir: Vector2        = target_pos - pos | 
					
						
							|  |  |  | 		if speed_dir.dot(dir) <= 0: | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		var dist: float = dir.length() | 
					
						
							|  |  |  | 		if dist == 0: | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		var dist_rate = clamp(dist/(radius+pushbox.radius), 0, 1) | 
					
						
							|  |  |  | 		speed_down_push_rate = max(speed_down_push_rate, pushbox_curve.sample(dist_rate)) | 
					
						
							|  |  |  | 	character.set_status("speed_down_push_rate", speed_down_push_rate) | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_area_entered(area: Area3D): | 
					
						
							|  |  |  | 	if area is Hitbox: | 
					
						
							|  |  |  | 		pushbox_list.append(area) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_area_exited(area: Area3D): | 
					
						
							|  |  |  | 	if area is Hitbox: | 
					
						
							|  |  |  | 		pushbox_list.erase(area) |