OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / player / player_input.gd

60 lines · gd ref:
extends Node
## Reads local input and exposes synced properties.
## Only the authority writes; remotes receive via InputSynchronizer.

var input_direction: Vector2 = Vector2.ZERO
var camera_rotation_y: float = 0.0
var camera_pitch: float = 0.0
var wants_jump: bool = false

## Benchmark mode: generate synthetic circular movement instead of real input.
var benchmark: bool = false

## DRIVEN BY A BOT. When true this node stops reading Input and leaves the four
## synced fields exactly as they were set from outside, so a brain can steer this
## player.
##
## An early-return branch, the same shape `benchmark` already uses, and for the
## same reason: _physics_process rewrites input_direction and wants_jump from
## Input on EVERY physics frame, so anything written from outside is erased within
## a frame unless this function is told to stand down.
##
## ⚠ THIS IS THE WHOLE POINT OF A BOT AS A TEST. A driven player writes the same
## input_direction / camera_rotation_y / wants_jump a human does and is replicated
## by the same MultiplayerSynchronizer, so it exercises the identical ephemeral
## path. A bot that teleported its body instead would prove nothing about
## replication -- which is why nothing here moves a position.
var driven: bool = false
var _benchmark_angle: float = 0.0
const BENCHMARK_CIRCLE_PERIOD: float = 6.0  # seconds per full circle


func _physics_process(delta: float) -> void:
	if not is_multiplayer_authority():
		return
	if driven:
		return                  # a brain owns these fields; see `driven`
	if benchmark:
		input_direction = Vector2(0, -1)
		_benchmark_angle += (TAU / BENCHMARK_CIRCLE_PERIOD) * delta
		camera_rotation_y = _benchmark_angle
		wants_jump = false
		# Drive camera head rotation directly — no mouse input in headless mode.
		# _process_local() reads camera_head.global_transform to determine forward
		# direction, so we must rotate it here for circular movement to work.
		var player: Node = get_parent()
		if player:
			var cam_head: Node3D = player.get_node_or_null("CameraHead")
			if cam_head:
				cam_head.rotation.y = _benchmark_angle
		return
	# NOT WHILE TYPING (editor redesign E0): movement POLLS the keyboard, so focus in a
	# text field (chat, texture search) never reached it and typing "wasd" walked you.
	var km := get_node_or_null("/root/Keymap")
	if km != null and not km.movement_allowed():
		input_direction = Vector2.ZERO
		wants_jump = false
		return
	input_direction = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
	wants_jump = Input.is_action_just_pressed("jump")