You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.3 KiB
GDScript
84 lines
2.3 KiB
GDScript
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
|