using System.Collections.Generic; using Domain.Input; using Extensions; using UnityEngine; namespace Domain { public class KeyHistory { private readonly LimitedSizeList _lastPresses = new(10); private readonly LimitedSizeList _lastPressesWithSpecial = new(20); private const int AlphabetSize = 26; private const int CustomKeysSize = 4; private const int SpecialKeysSize = 1; private readonly int[] _customKeys = { VKeyCode.Cedilla, VKeyCode.Interpunct, VKeyCode.AccentClosed, VKeyCode.AccentOpen }; private readonly int[] _specialKeys = { VKeyCode.Shift }; private readonly bool[] _isPressed = new bool[AlphabetSize + CustomKeysSize + SpecialKeysSize]; private readonly bool[] _wasPressed = new bool[AlphabetSize + CustomKeysSize + SpecialKeysSize]; public void KeyPressed(int key, bool isSpecial = false) { if (!isSpecial) _lastPresses.Add(key); _lastPressesWithSpecial.Add(key); } public void CheckPresses() { const int aIndex = 0x41; const int zIndex = 0x5A; for (int i = aIndex, j = 0; i <= zIndex; i++, j++) { _wasPressed[j] = _isPressed[j]; short state = Win32API.GetAsyncKeyState(i); if (!_wasPressed[j] && state != 0) { _isPressed[j] = true; KeyPressed(i); }else if (_isPressed[j] && state == 0) { _isPressed[j] = false; } } for (int i = 0; i < _customKeys.Length; i++) { int pressIndex = AlphabetSize + i; _wasPressed[pressIndex] = _isPressed[pressIndex]; short state = Win32API.GetAsyncKeyState(_customKeys[i]); if (!_wasPressed[pressIndex] && state != 0) { _isPressed[pressIndex] = true; KeyPressed(_customKeys[i]); }else if (_isPressed[pressIndex] && state == 0) { _isPressed[pressIndex] = false; } } for (int i = 0; i < _specialKeys.Length; i++) { int pressIndex = AlphabetSize + CustomKeysSize + i; _wasPressed[pressIndex] = _isPressed[pressIndex]; short state = Win32API.GetAsyncKeyState(_specialKeys[i]); if (!_wasPressed[pressIndex] && state != 0) { _isPressed[pressIndex] = true; KeyPressed(_specialKeys[i], true); }else if (_isPressed[pressIndex] && state == 0) { _isPressed[pressIndex] = false; } } } public bool ContainsSequence(List sequence) { if (_lastPresses.List.Count < sequence.Count) return false; for (int i = 0; i < _lastPresses.List.Count; i++) { if (i >= sequence.Count) break; int keyPressed = _lastPresses.List[_lastPresses.List.Count - 1 - i]; int sequenceKey = sequence[sequence.Count - 1 - i]; if (keyPressed != sequenceKey) { return false; } } _lastPresses.List.Clear(); _lastPressesWithSpecial.List.Clear(); return true; } public bool ContainsSequence(List sequence, int beginning, bool mustAppear) { if (_lastPressesWithSpecial.List.Count < sequence.Count + 1) { if (mustAppear) return false; } else { if (_lastPressesWithSpecial.List[^(sequence.Count + 1)] != beginning && mustAppear) return false; if (_lastPressesWithSpecial.List[^(sequence.Count + 1)] == beginning && !mustAppear) return false; } return ContainsSequence(sequence); } } }