2024-10-20 20:27:08 -06:00
|
|
|
class_name ShotSetup extends Node3D
|
|
|
|
|
2024-11-01 19:50:02 -06:00
|
|
|
enum Phase {
|
|
|
|
AIM,
|
|
|
|
POWER_ADJUST,
|
|
|
|
CURVE_ADJUST,
|
|
|
|
SHOT,
|
|
|
|
FINISHED,
|
|
|
|
}
|
|
|
|
|
2024-10-20 20:27:08 -06:00
|
|
|
const PITCH_MIN := deg_to_rad(-60.0)
|
|
|
|
const PITCH_MAX := deg_to_rad(-5.0)
|
|
|
|
const ZOOM_LENGTH := 0.1
|
|
|
|
|
|
|
|
const ZOOM_MIN := 1.0
|
|
|
|
const ZOOM_MAX := 12.0
|
|
|
|
|
2024-11-01 19:50:02 -06:00
|
|
|
const ARROW_ACCELERATION := 8.0
|
|
|
|
|
2024-11-02 09:30:45 -06:00
|
|
|
const FREE_CAM_RETURN_TIME := 0.618
|
2024-11-01 19:50:02 -06:00
|
|
|
|
|
|
|
@export var control_disabled := false
|
2024-10-20 20:27:08 -06:00
|
|
|
|
|
|
|
var base_speed: float = ProjectSettings.get_setting("game/config/controls/camera/free_camera_speed")
|
|
|
|
|
|
|
|
var x_sensitivity: float = ProjectSettings.get_setting(
|
|
|
|
"game/config/controls/camera/x_axis_sensitivity"
|
|
|
|
)
|
|
|
|
var x_acceleration: float = ProjectSettings.get_setting(
|
|
|
|
"game/config/controls/camera/x_axis_acceleration"
|
|
|
|
)
|
|
|
|
var y_sensitivity: float = ProjectSettings.get_setting(
|
|
|
|
"game/config/controls/camera/y_axis_sensitivity"
|
|
|
|
)
|
|
|
|
var y_acceleration: float = ProjectSettings.get_setting(
|
|
|
|
"game/config/controls/camera/y_axis_acceleration"
|
|
|
|
)
|
|
|
|
|
|
|
|
var invert_pitch: bool = ProjectSettings.get_setting("game/config/controls/camera/invert_pitch")
|
|
|
|
|
2024-11-01 19:50:02 -06:00
|
|
|
var phase: Phase:
|
|
|
|
set(value):
|
|
|
|
if value != phase:
|
|
|
|
_on_phase_change(value)
|
|
|
|
phase = value
|
|
|
|
|
|
|
|
var _free_camera: FreeCamera
|
|
|
|
var _returning_free_camera := false
|
2024-10-20 20:27:08 -06:00
|
|
|
|
|
|
|
@onready var direction: Node3D = %Direction
|
|
|
|
@onready var pitch: Node3D = %Pitch
|
|
|
|
@onready var camera: Camera3D = %Camera
|
2024-11-02 09:49:14 -06:00
|
|
|
|
2024-11-01 19:50:02 -06:00
|
|
|
@onready var arrow: Node3D = %Arrow
|
2024-11-02 09:49:14 -06:00
|
|
|
@onready var arrow_animation: AnimationPlayer = %ArrowAnimation
|
2024-11-01 19:50:02 -06:00
|
|
|
|
|
|
|
@onready var power_bar: ProgressBar = %PowerBar
|
|
|
|
@onready var power_animation: AnimationPlayer = %PowerAnimation
|
|
|
|
|
|
|
|
@onready var curve_bar: ProgressBar = %CurveBar
|
|
|
|
@onready var curve_animation: AnimationPlayer = %CurveAnimation
|
2024-10-20 20:27:08 -06:00
|
|
|
|
|
|
|
@onready var camera_distance := camera.position.z:
|
|
|
|
set = _set_camera_distance
|
|
|
|
|
2024-11-02 09:49:14 -06:00
|
|
|
@onready var phys_ball := preload("res://src/player/physics_ball/physics_ball.tscn")
|
|
|
|
|
2024-10-20 20:27:08 -06:00
|
|
|
@onready var _target_rotation := Vector2(pitch.rotation.x, direction.rotation.y)
|
|
|
|
|
|
|
|
|
|
|
|
func _set_camera_distance(value: float) -> void:
|
|
|
|
var tween := get_tree().create_tween()
|
|
|
|
tween.tween_property(camera, "position", Vector3(0, 0, value), ZOOM_LENGTH).set_trans(
|
|
|
|
Tween.TRANS_SINE
|
|
|
|
)
|
|
|
|
camera_distance = value
|
|
|
|
|
|
|
|
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
|
|
if event is InputEventMouseButton:
|
|
|
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
|
|
|
elif event is InputEventMouseMotion:
|
|
|
|
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
|
|
|
|
camera_motion((event as InputEventMouseMotion).relative)
|
|
|
|
|
|
|
|
|
|
|
|
func camera_motion(motion: Vector2) -> void:
|
2024-11-01 19:50:02 -06:00
|
|
|
if not control_disabled and phase == Phase.AIM:
|
2024-10-20 20:27:08 -06:00
|
|
|
# Can only control camera while aiming
|
|
|
|
_target_rotation.y = _target_rotation.y - deg_to_rad(motion.x * x_sensitivity)
|
|
|
|
_target_rotation.x = clampf(
|
|
|
|
_target_rotation.x - deg_to_rad(motion.y * y_sensitivity) * (-1 if invert_pitch else 1),
|
|
|
|
PITCH_MIN,
|
|
|
|
PITCH_MAX
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2024-11-01 19:50:02 -06:00
|
|
|
func take_shot() -> void:
|
|
|
|
print("WHACK!")
|
|
|
|
print("Power: ", power_bar.value)
|
|
|
|
print("Curve: ", curve_bar.value)
|
|
|
|
|
|
|
|
|
|
|
|
func _on_phase_change(new_phase: Phase) -> void:
|
|
|
|
match new_phase:
|
|
|
|
Phase.AIM:
|
|
|
|
print("AIM PHASE")
|
|
|
|
power_bar.hide()
|
|
|
|
curve_bar.hide()
|
|
|
|
Phase.POWER_ADJUST:
|
|
|
|
curve_bar.hide()
|
|
|
|
|
|
|
|
power_bar.show()
|
|
|
|
power_animation.stop() # Reset if needed
|
|
|
|
Phase.CURVE_ADJUST:
|
|
|
|
curve_bar.show()
|
|
|
|
curve_animation.play("fill")
|
|
|
|
Phase.SHOT:
|
|
|
|
power_bar.hide()
|
|
|
|
curve_bar.hide()
|
|
|
|
take_shot()
|
2024-10-20 20:27:08 -06:00
|
|
|
|
2024-11-01 16:33:13 -06:00
|
|
|
|
2024-11-01 19:50:02 -06:00
|
|
|
func insert_free_cam() -> void:
|
2024-11-02 09:49:14 -06:00
|
|
|
arrow_animation.play("hide")
|
2024-11-01 19:50:02 -06:00
|
|
|
_free_camera = FreeCamera.create(camera)
|
|
|
|
add_sibling(_free_camera)
|
|
|
|
control_disabled = true
|
|
|
|
|
|
|
|
|
|
|
|
func return_free_cam() -> void:
|
|
|
|
# TODO alter shot aim based on free camera selection
|
2024-11-02 09:49:14 -06:00
|
|
|
arrow_animation.play("show")
|
2024-11-01 19:50:02 -06:00
|
|
|
_free_camera.queue_free()
|
|
|
|
_free_camera = null
|
|
|
|
control_disabled = false
|
|
|
|
_returning_free_camera = false
|
|
|
|
|
|
|
|
|
|
|
|
func _process(delta: float) -> void:
|
2024-10-20 20:27:08 -06:00
|
|
|
# Rotation
|
|
|
|
direction.rotation.y = lerp_angle(
|
|
|
|
direction.rotation.y, _target_rotation.y, delta * x_acceleration
|
|
|
|
)
|
|
|
|
pitch.rotation.x = lerp_angle(pitch.rotation.x, _target_rotation.x, delta * y_acceleration)
|
2024-11-01 19:50:02 -06:00
|
|
|
|
|
|
|
arrow.rotation.y = lerp_angle(arrow.rotation.y, _target_rotation.y, delta * ARROW_ACCELERATION)
|
|
|
|
|
|
|
|
# Input Handling
|
|
|
|
if control_disabled:
|
|
|
|
if Input.is_action_just_pressed("camera_cancel"):
|
|
|
|
if is_instance_valid(_free_camera) and not _returning_free_camera:
|
|
|
|
_returning_free_camera = true
|
|
|
|
var tween := get_tree().create_tween()
|
|
|
|
(
|
|
|
|
tween
|
|
|
|
. tween_property(
|
|
|
|
_free_camera,
|
|
|
|
"global_transform",
|
|
|
|
camera.global_transform,
|
|
|
|
FREE_CAM_RETURN_TIME
|
|
|
|
)
|
|
|
|
. set_trans(Tween.TRANS_SINE)
|
|
|
|
)
|
|
|
|
tween.tween_callback(return_free_cam)
|
|
|
|
return
|
|
|
|
|
|
|
|
match phase:
|
|
|
|
Phase.AIM:
|
|
|
|
# Camera zoom
|
|
|
|
if Input.is_action_just_pressed("shot_zoom_in"):
|
|
|
|
camera_distance = max(camera_distance - 1.0, ZOOM_MIN)
|
|
|
|
if Input.is_action_just_pressed("shot_zoom_out"):
|
|
|
|
camera_distance = min(camera_distance + 1.0, ZOOM_MAX)
|
|
|
|
|
|
|
|
# Switch to free cam
|
|
|
|
if (
|
|
|
|
Input.is_action_just_pressed("camera_back")
|
|
|
|
or Input.is_action_just_pressed("camera_forward")
|
|
|
|
or Input.is_action_just_pressed("camera_left")
|
|
|
|
or Input.is_action_just_pressed("camera_right")
|
|
|
|
):
|
|
|
|
insert_free_cam()
|
|
|
|
|
|
|
|
# Advance to next phase
|
|
|
|
if Input.is_action_just_pressed("shot_accept"):
|
|
|
|
phase = Phase.POWER_ADJUST
|
|
|
|
Phase.POWER_ADJUST:
|
|
|
|
if Input.is_action_just_pressed("shot_accept"):
|
|
|
|
# TODO set power gauge parameters if needed
|
|
|
|
power_animation.play("fill")
|
|
|
|
if Input.is_action_just_released("shot_accept") and power_bar.value > 0:
|
|
|
|
power_animation.pause()
|
|
|
|
phase = Phase.CURVE_ADJUST
|
|
|
|
Phase.CURVE_ADJUST:
|
|
|
|
if Input.is_action_just_pressed("shot_accept"):
|
|
|
|
curve_animation.pause()
|
|
|
|
phase = Phase.SHOT
|
|
|
|
Phase.SHOT:
|
|
|
|
# DEBUG: reset to AIM phase
|
|
|
|
phase = Phase.AIM
|