using System.Collections.Generic; using System; using System.Collections; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.EventSystems; using NeonTea.Quakeball.Player; using TMPro; namespace NeonTea.Quakeball.Interface { public class Terminal : MonoBehaviour { public RectTransform TerminalPanel; public TMP_InputField InputField; public TMP_Text TextField; public LocalPlayer Player; private InputAction ToggleTerminalAction; private InputAction SubmitTerminal; private float DesiredTerminalPos; private bool IsOpen = false; private Dictionary> Commands = new Dictionary>(); private List Messages = new List(); private string Text = ""; private List PreviousRuns = new List(); private int CurrentScroll = -1; private bool JustScrolled = false; public static string INFO_COLOR = "#FE8"; public static string ERROR_COLOR = "#F33"; void Start() { ToggleTerminalAction = new InputAction("Toggle Terminal", binding: "/backquote"); ToggleTerminalAction.Enable(); ToggleTerminalAction.performed += ToggleTerminal; SubmitTerminal = new InputAction("Terminal Submit", binding: "/enter"); SubmitTerminal.Enable(); SubmitTerminal.performed += Submit; SubmitTerminal = new InputAction("Terminal ScrollUp", binding: "/uparrow"); SubmitTerminal.Enable(); SubmitTerminal.performed += _ => { Scroll(1); }; SubmitTerminal = new InputAction("Terminal ScrollDown", binding: "/downarrow"); SubmitTerminal.Enable(); SubmitTerminal.performed += _ => { Scroll(-1); }; DesiredTerminalPos = (TerminalPanel.rect.height / 2) * (IsOpen ? -1 : 1); InputField.restoreOriginalTextOnEscape = false; InputField.onValueChanged.AddListener(_ => { if (JustScrolled) { JustScrolled = false; return; } CurrentScroll = -1; }); AddMessage($"Welcome to Quakeball!"); } public void ToggleTerminal(InputAction.CallbackContext context) { IsOpen = !IsOpen; DesiredTerminalPos = (TerminalPanel.rect.height / 2) * (IsOpen ? -1 : 1); if (IsOpen) { InputField.text = ""; } InputField.readOnly = true; if (Player != null) { Player.DisableInput = IsOpen; } } void Update() { Vector3 pos = TerminalPanel.anchoredPosition; pos.y = Mathf.Lerp(pos.y, DesiredTerminalPos, Time.deltaTime * 10); TerminalPanel.anchoredPosition = pos; if (IsOpened() && EventSystem.current.currentSelectedGameObject != InputField) { InputField.Select(); InputField.ActivateInputField(); InputField.readOnly = false; } } public bool RegisterCommand(string name, Func command) { if (Commands.ContainsKey(name)) { return false; } Commands.Add(name, command); return true; } public void Run(string command) { string[] parts = command.Split(new char[] { ' ' }); string name = parts[0]; if (Commands.ContainsKey(name)) { Func func = Commands[name]; string[] args = new string[parts.Length - 1]; Array.Copy(parts, 1, args, 0, parts.Length - 1); if (func(args)) { AddMessage(command); } else { AddMessage($"{command}"); } } else { AddMessage($"{command}"); AddMessage("No such command exists!"); } PreviousRuns.Insert(0, command); } public void AddMessage(string message) { Messages.Add(message); Text = String.Join("\n", Messages.ToArray()); TextField.text = Text; } private void Scroll(int amount) { if (IsOpened() && PreviousRuns.Count > 0) { JustScrolled = true; CurrentScroll = Math.Min(Math.Max(0, CurrentScroll + amount), PreviousRuns.Count - 1); InputField.text = PreviousRuns[CurrentScroll]; } } private void Submit(InputAction.CallbackContext context) { if (IsOpened()) { Run(InputField.text); InputField.text = ""; } } private bool IsOpened() { return IsOpen && (TerminalPanel.anchoredPosition.y + TerminalPanel.rect.height / 2) < 10; } } }