hurrmmm/godot/control_scheme/controller.gd

133 lines
3.8 KiB
GDScript3
Raw Normal View History

2023-11-11 09:15:31 -07:00
extends Node3D
@export var camera: Camera3D
2023-11-11 13:08:24 -07:00
@export var initial_target: Node3D
var target: Targetable = null
2023-11-11 09:15:31 -07:00
@export var sensitivity := 0.01
2023-11-11 17:24:52 -07:00
@export var charge_time := 1.7
@export var min_charge := 0.2
2023-11-11 09:15:31 -07:00
2023-11-11 20:45:57 -07:00
var camera_tweening = false
2023-11-11 22:20:13 -07:00
var time_targets := Dictionary()
2023-11-11 13:08:24 -07:00
func _ready():
2023-11-11 20:45:57 -07:00
set_target(initial_target, false)
2023-11-11 22:38:31 -07:00
time_targets[0] = target
2023-11-11 21:25:18 -07:00
camera.set_as_top_level(true)
2023-11-11 20:45:57 -07:00
ControllerEventBus.billiard_touched_billiard.connect(_on_billiard_touched_billiard)
2023-11-11 22:20:13 -07:00
TAS_System.FrameIncremented.connect(frame_inc)
TAS_System.FramesAdvanced.connect(frames_change)
TAS_System.FramesRegressed.connect(frames_change)
2023-11-11 22:38:31 -07:00
TAS_System.FramesReset.connect(frames_reset)
2023-11-11 22:20:13 -07:00
func frame_inc(frame: int):
time_targets[frame] = target
2023-11-12 03:17:46 -07:00
func frames_change(_start: int, end: int):
2023-11-11 22:20:13 -07:00
if time_targets[end] != target:
set_target(time_targets[end].get_billiard())
2023-11-11 22:38:31 -07:00
func frames_reset():
time_targets = Dictionary()
time_targets[0] = target
2023-11-11 22:20:13 -07:00
2023-11-11 20:45:57 -07:00
func _on_billiard_touched_billiard(who: Billiard, touched: Billiard):
var who_target = Targetable.is_targetable(who)
if who_target != target or who.can_hit:
return
set_target(touched)
ControllerEventBus.new_target.emit(touched)
2023-11-11 13:08:24 -07:00
2023-11-11 16:12:46 -07:00
func get_charge():
return %radial_ui.charge_amount
2023-11-11 09:15:31 -07:00
func _input(event):
2023-11-11 17:24:52 -07:00
var billiard := target.get_billiard()
2023-11-11 21:25:18 -07:00
if camera_tweening or not MouseControl.mouse_is_locked():
2023-11-11 20:45:57 -07:00
return
2023-11-11 21:25:18 -07:00
if event is InputEventMouseMotion and get_charge() == 0.0 :
2023-11-11 09:15:31 -07:00
rotate_view(event.relative*sensitivity)
2023-11-11 17:24:52 -07:00
if event.is_action_released("charge") and not billiard.can_hit and charge_tween != null:
release()
2023-11-11 21:25:18 -07:00
if event.is_action_pressed("charge") and charge_tween == null:
if billiard.can_hit:
charge(event.get_action_strength("charge"))
else:
$NoChargesSound.play()
2023-11-11 17:24:52 -07:00
2023-11-11 21:32:30 -07:00
func _process(_delta):
2023-11-11 09:15:31 -07:00
transform.origin = target.global_position
2023-11-11 20:45:57 -07:00
%camera_spot.look_at(target.global_position)
if not camera_tweening:
camera.global_transform = %camera_spot.global_transform
else:
2023-11-11 21:25:18 -07:00
camera.global_position = lerp(camera.global_position, %camera_spot.global_position, 0.5)
camera.global_rotation = lerp(camera.global_rotation, %camera_spot.global_rotation, 0.5)
var epsilon: float = 0.005
2023-11-11 20:45:57 -07:00
if (camera.global_position - %camera_spot.global_position).length() <= epsilon and (camera.global_rotation - %camera_spot.global_rotation).length() <= epsilon:
camera_tweening = false
2023-11-11 17:24:52 -07:00
if get_charge() >= 1.0:
cancel_charge()
2023-11-11 09:15:31 -07:00
2023-11-11 17:24:52 -07:00
func cancel_charge():
%radial_ui.set_charge(0.0)
%ChargeSound.stop()
2023-11-11 14:56:43 -07:00
if charge_tween != null:
charge_tween.kill()
2023-11-11 17:24:52 -07:00
charge_tween = null
var billiard := target.get_billiard()
billiard.can_hit = true
func release():
if get_charge() <= min_charge:
cancel_charge()
2023-11-11 14:56:43 -07:00
return
2023-11-11 17:24:52 -07:00
%ChargeReleaseSound.volume_db = get_charge() * 12
%ChargeReleaseSound.play()
var billiard := target.get_billiard()
2023-11-11 21:32:30 -07:00
TAS_System.StartIncrementingFrames()
2023-11-11 22:20:13 -07:00
billiard.hit((target.global_position - %camera_spot.global_position).normalized(), get_charge())
2023-11-11 20:45:57 -07:00
2023-11-11 17:24:52 -07:00
%radial_ui.set_charge(0.0)
%ChargeSound.stop()
if charge_tween != null:
charge_tween.kill()
charge_tween = null
var charge_tween: Tween = null
func charge(_amount: float):
var billiard := target.get_billiard()
billiard.can_hit = false
if charge_tween != null:
charge_tween.kill()
2023-11-11 14:56:43 -07:00
charge_tween = create_tween()
charge_tween.tween_method(%radial_ui.set_charge, 0.0, 1.0, charge_time)
2023-11-11 17:24:52 -07:00
%ChargeSound.play()
2023-11-11 14:56:43 -07:00
2023-11-11 09:15:31 -07:00
func rotate_view(amount: Vector2):
rotate_y(-amount.x)
%rotate_helper.rotate_z(amount.y)
%rotate_helper.rotation_degrees.z = clampf(%rotate_helper.rotation_degrees.z, -77, 77)
2023-11-11 20:45:57 -07:00
func set_target(node: Node3D, should_create_tween=true):
camera_tweening = should_create_tween
2023-11-11 13:08:24 -07:00
var ntarget = Targetable.is_targetable(node)
2023-11-11 20:45:57 -07:00
var billiard = ntarget.get_billiard()
billiard.can_hit = true
2023-11-11 13:08:24 -07:00
if ntarget == null:
push_error("Node is node targetable", node)
return
if target != null:
target.unmake_target()
ntarget.make_target()
target = ntarget