extends Area3D class_name BattleAttackArea @onready var character: Character = (get_owner() as Character) @onready var battle: Battle = (%Battle as Battle) @onready var collision: CollisionShape3D = (%BattleAttackAreaCollision as CollisionShape3D) var is_active: bool var alive_time: float var attack_info: Struct.AttackInfo var attack_id_set: Dictionary = {} var attack_hit_info_list: Array[Struct.AttackHitInfo] = [] func _ready(): body_entered.connect(on_body_entered) func _process(delta: float) -> void: if is_active: alive_time -= delta if alive_time <= 0: settle_attack_all() set_active(false) settle_attack() func refresh_attack_area(attack_info_new: Struct.AttackInfo) -> void: settle_attack_all() attack_info = attack_info_new var offset_xz: Vector2 = attack_info.attack_dir * attack_info.attack_box.offset.x var offset_y: float = attack_info.attack_box.offset.y var offset: Vector3 = Vector3(offset_xz.x, offset_y, offset_xz.y) var shape: Shape3D = attack_info.attack_box.shape collision.position = offset collision.shape = shape attack_id_set.clear() alive_time = Setting.animation_frame_rate set_active(false) set_active(true) func settle_attack_all() -> void: while attack_hit_info_list.size() > 0: settle_attack() func settle_attack() -> void: if len(attack_hit_info_list) == 0: return var attack_hit_info: Struct.AttackHitInfo = attack_hit_info_list.pop_at(0) if not attack_hit_info.hit_target: return battle.on_attack_character(attack_hit_info.hit_target, attack_hit_info.attack_info) func on_body_entered(body: Node3D): call_deferred("on_body_entereddeferred", body) func on_body_entereddeferred(body: Node3D): if not body is Character: return var character_to: Character = body as Character if attack_id_set.has(character_to.id): return if attack_info.attack.is_rebound: if character_to != character and character_to.get_status("is_floating"): return var attack_hit_info: Struct.AttackHitInfo = Struct.AttackHitInfo.new() attack_hit_info.attack_info = attack_info attack_hit_info.hit_target = character_to attack_hit_info_list.append(attack_hit_info) attack_id_set[character_to.id] = true func set_active(value: bool) -> void: if value: alive_time = Setting.animation_frame_rate else: alive_time = 0 is_active = value collision.disabled = not value