using System;
using UnityEngine;
using UnityEngine.InputSystem;
using NeonTea.Quakeball.Interface;
using NeonTea.Quakeball.Networking.Packets;
namespace NeonTea.Quakeball.Players {
/// A controller class for a local player. Handles input and updates the relevant components.
[RequireComponent(typeof(Player))]
public class LocalPlayer : MonoBehaviour {
public int DisableInput;
public float SyncInterval = 1;
public float MovementUpdateInterval = 1f;
public Player Player { private set; get; }
public InputAction LookAction { private set; get; }
private InputAction MoveAction;
private InputAction CrouchAction;
private InputAction JumpAction;
private InputAction ShootAction;
private InputAction SwitchUpAction;
private InputAction[] WeaponSwitchActions = new InputAction[9];
private float PreviousPlayerUpdate = -1;
private float PreviousPlayerFullSync = -1;
private bool WantsToJump = false;
private void Awake() {
Player = GetComponent();
CrouchAction = new InputAction("crouch", binding: "/buttonEast");
CrouchAction.AddBinding("/leftShift");
JumpAction = new InputAction("crouch", binding: "/buttonSouth");
JumpAction.AddBinding("/space");
JumpAction.performed += _ => {
WantsToJump = true;
};
LookAction = new InputAction("look", binding: "/leftStick");
LookAction.AddBinding("/delta");
MoveAction = new InputAction("move", binding: "/rightStick");
MoveAction.AddCompositeBinding("Dpad")
.With("Up", "/w")
.With("Down", "/s")
.With("Left", "/a")
.With("Right", "/d");
ShootAction = new InputAction("Shoot", binding: "/leftButton");
ShootAction.performed += _ => {
if (Networking.Net.Singleton.Instance != null) {
ShootData shootData = new ShootData(Player.Pitch, Player.Yaw, Player.CreateSyncPacket());
Networking.Net.Singleton.Instance.LocalPlayerAction(PlayerAction.Shoot, shootData);
}
Player.Shoot();
};
Action CreateLambda(int number) {
return (context) => {
Player.SwitchItem(number);
Player.CurrentItem.Animator.enabled = true;
};
}
for (int i = 0; i < 9; i++) {
WeaponSwitchActions[i] = new InputAction($"Switch to weapon {i + 1}", binding: $"/{i + 1}");
WeaponSwitchActions[i].performed += CreateLambda(i);
}
Terminal.Singleton.RegisterCommand("tp", args => {
if (args.Length != 3) {
return false;
}
transform.position = new Vector3(float.Parse(args[0]), float.Parse(args[1]), float.Parse(args[2]));
return true;
}, "tp x y z - Teleports the local player to the specified coordinates.");
}
private void Update() {
if (DisableInput > 0 || !Application.isFocused) {
CrouchAction.Disable();
JumpAction.Disable();
LookAction.Disable();
MoveAction.Disable();
ShootAction.Disable();
foreach (InputAction action in WeaponSwitchActions) {
action.Disable();
}
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
} else {
CrouchAction.Enable();
JumpAction.Enable();
LookAction.Enable();
MoveAction.Enable();
ShootAction.Enable();
foreach (InputAction action in WeaponSwitchActions) {
action.Enable();
}
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
OptionsData Opts = Options.Get();
Vector2 LookInput = LookAction.ReadValue() * Opts.LookSensitivity;
Player.Pitch = Mathf.Clamp(Player.Pitch - LookInput.y * (Opts.InvertVerticalLook ? -1 : 1), -90, 90);
Player.Yaw += LookInput.x;
if (Time.time - PreviousPlayerUpdate >= MovementUpdateInterval) {
PreviousPlayerUpdate = Time.time;
if (Player.IsDead) {
return;
}
Vector2 MovementInput = MoveAction.ReadValue();
Vector3 Move = new Vector3(MovementInput.x, 0, MovementInput.y);
Move = Quaternion.Euler(0, Player.Yaw, 0) * Move;
Player.MoveDirection = Move;
Player.CurrentMoveStyle = CrouchAction.ReadValue() > 0 ? (byte)1 : (byte)0;
if (Networking.Net.Singleton.Instance != null) {
Networking.Net.Singleton.Instance.UpdateLocalPlayer();
}
if (WantsToJump) {
bool Jumped = Player.Jump();
if (Jumped && Networking.Net.Singleton.Instance != null) {
Networking.Net.Singleton.Instance.LocalPlayerAction(PlayerAction.Jump);
}
}
WantsToJump = false;
}
if (Time.time - PreviousPlayerFullSync >= SyncInterval) {
PreviousPlayerFullSync = Time.time;
if (Networking.Net.Singleton.Instance != null) {
Networking.Net.Singleton.Instance.SendPlayerSync();
}
}
}
}
}