99 lines
2.6 KiB
GDScript
99 lines
2.6 KiB
GDScript
class_name PlayerAttack
|
|
extends Area3D
|
|
|
|
signal attacked
|
|
|
|
const COOLDOWN_TIME: float = 0.3
|
|
const HIT_WINDOW_TIME: float = 0.25
|
|
const SWOOP_EFFECT_TIME: float = 0.25
|
|
|
|
@export var _collision_debug_material: Material
|
|
@export var _attack_max_angle: float = PI / 2
|
|
|
|
var _debug_collision_shapes := DebugCollisionShapes.new()
|
|
|
|
var _cooldown_timer: float
|
|
var _hit_window_timer: float
|
|
var _swoop_effect_timer: float
|
|
|
|
@onready var _swoop_mesh: MeshInstance3D = $SwoopMesh
|
|
|
|
|
|
func _ready() -> void:
|
|
_debug_collision_shapes.init(get_children(), self, _collision_debug_material)
|
|
Debugger.add_event("attacked")
|
|
attacked.connect(func() -> void: Debugger.event_emitted("attacked", []))
|
|
body_entered.connect(_on_body_entered)
|
|
position.y = Projectile.HEIGHT
|
|
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
if event.is_action_pressed("attack"):
|
|
_attack()
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
if _cooldown_timer > 0:
|
|
_cooldown_timer -= delta
|
|
|
|
if _hit_window_timer > 0:
|
|
_hit_window_timer -= delta
|
|
elif _debug_collision_shapes.is_visible:
|
|
_debug_collision_shapes.set_visibility(false)
|
|
|
|
if _swoop_effect_timer > 0:
|
|
_swoop_effect_timer -= delta
|
|
|
|
(_swoop_mesh.material_override as StandardMaterial3D).albedo_color = Color(
|
|
1, 1, 1, _swoop_effect_timer / SWOOP_EFFECT_TIME
|
|
)
|
|
_swoop_mesh.visible = _swoop_effect_timer > 0
|
|
|
|
Debugger.text("_cooldown_timer", _cooldown_timer, 2)
|
|
Debugger.text("_hit_window_timer", _hit_window_timer, 2)
|
|
Debugger.text("_swoop_effect_timer", _swoop_effect_timer, 2)
|
|
Debugger.vector(
|
|
"fghdh",
|
|
global_position,
|
|
global_position + global_basis.z.rotated(Vector3.UP, _attack_max_angle) * 2
|
|
)
|
|
Debugger.vector(
|
|
"fghdh2",
|
|
global_position,
|
|
global_position + global_basis.z.rotated(Vector3.UP, -_attack_max_angle) * 2
|
|
)
|
|
|
|
|
|
func _physics_process(_delta: float) -> void:
|
|
monitoring = Input.is_action_just_pressed("attack")
|
|
|
|
|
|
func _attack() -> void:
|
|
if _cooldown_timer > 0:
|
|
return
|
|
|
|
attacked.emit()
|
|
_cooldown_timer = COOLDOWN_TIME
|
|
_hit_window_timer = HIT_WINDOW_TIME
|
|
_swoop_effect_timer = SWOOP_EFFECT_TIME
|
|
_debug_collision_shapes.set_visibility(true)
|
|
|
|
|
|
func _hit_projectile(projectile: Projectile) -> void:
|
|
var diff := projectile.global_position - global_position
|
|
diff.y = 0
|
|
var angle := global_basis.z.angle_to(diff)
|
|
Debugger.vector("ASDSAD", global_position, global_position + global_basis.z)
|
|
Debugger.vector("ASDSAD2", global_position, global_position + diff)
|
|
if angle > _attack_max_angle:
|
|
return
|
|
projectile.queue_free()
|
|
|
|
|
|
func _on_body_entered(node: Node3D) -> void:
|
|
if _hit_window_timer <= 0:
|
|
return
|
|
|
|
if node is Projectile:
|
|
_hit_projectile(node as Projectile)
|