/// <summary>Update the current button states for the given tick.</summary> public void TrueUpdate() { // update base state base.Update(); // update SMAPI extended data // note: Stardew Valley is *not* in UI mode when this code runs try { float zoomMultiplier = (1f / Game1.options.zoomLevel); // get real values var controller = new GamePadStateBuilder(base.GetGamePadState()); var keyboard = new KeyboardStateBuilder(base.GetKeyboardState()); var mouse = new MouseStateBuilder(base.GetMouseState()); Vector2 cursorAbsolutePos = new Vector2((mouse.X * zoomMultiplier) + Game1.viewport.X, (mouse.Y * zoomMultiplier) + Game1.viewport.Y); Vector2? playerTilePos = Context.IsPlayerFree ? Game1.player.getTileLocation() : (Vector2?)null; HashSet <SButton> reallyDown = new HashSet <SButton>(this.GetPressedButtons(keyboard, mouse, controller)); // apply overrides bool hasOverrides = false; if (this.CustomPressedKeys.Count > 0 || this.CustomReleasedKeys.Count > 0) { // reset overrides that no longer apply this.CustomPressedKeys.RemoveWhere(key => reallyDown.Contains(key)); this.CustomReleasedKeys.RemoveWhere(key => !reallyDown.Contains(key)); // apply overrides if (this.ApplyOverrides(this.CustomPressedKeys, this.CustomReleasedKeys, controller, keyboard, mouse)) { hasOverrides = true; } // remove pressed keys this.CustomPressedKeys.Clear(); } // get button states var pressedButtons = hasOverrides ? new HashSet <SButton>(this.GetPressedButtons(keyboard, mouse, controller)) : reallyDown; var activeButtons = this.DeriveStates(this.ButtonStates, pressedButtons); // update this.HasNewOverrides = false; this.ControllerState = controller.GetState(); this.KeyboardState = keyboard.GetState(); this.MouseState = mouse.GetState(); this.ButtonStates = activeButtons; if (cursorAbsolutePos != this.CursorPositionImpl?.AbsolutePixels || playerTilePos != this.LastPlayerTile) { this.LastPlayerTile = playerTilePos; this.CursorPositionImpl = this.GetCursorPosition(this.MouseState, cursorAbsolutePos, zoomMultiplier); } } catch (InvalidOperationException) { // GetState() may crash for some players if window doesn't have focus but game1.IsActive == true } }
/// <summary>Apply input suppression to the given input states.</summary> /// <param name="activeButtons">The current button states to check.</param> /// <param name="keyboardState">The game's keyboard state for the current tick.</param> /// <param name="mouseState">The game's mouse state for the current tick.</param> /// <param name="gamePadState">The game's controller state for the current tick.</param> private void SuppressGivenStates(IDictionary <SButton, InputStatus> activeButtons, ref KeyboardState keyboardState, ref MouseState mouseState, ref GamePadState gamePadState) { if (this.SuppressButtons.Count == 0) { return; } // gather info HashSet <Keys> suppressKeys = new HashSet <Keys>(); HashSet <SButton> suppressButtons = new HashSet <SButton>(); HashSet <SButton> suppressMouse = new HashSet <SButton>(); foreach (SButton button in this.SuppressButtons) { if (button == SButton.MouseLeft || button == SButton.MouseMiddle || button == SButton.MouseRight || button == SButton.MouseX1 || button == SButton.MouseX2) { suppressMouse.Add(button); } else if (button.TryGetKeyboard(out Keys key)) { suppressKeys.Add(key); } else if (gamePadState.IsConnected && button.TryGetController(out Buttons _)) { suppressButtons.Add(button); } } // suppress keyboard keys if (keyboardState.GetPressedKeys().Any() && suppressKeys.Any()) { keyboardState = new KeyboardState(keyboardState.GetPressedKeys().Except(suppressKeys).ToArray()); } // suppress controller keys if (gamePadState.IsConnected && suppressButtons.Any()) { GamePadStateBuilder builder = new GamePadStateBuilder(gamePadState); builder.SuppressButtons(suppressButtons); gamePadState = builder.ToGamePadState(); } // suppress mouse buttons if (suppressMouse.Any()) { mouseState = new MouseState( x: mouseState.X, y: mouseState.Y, scrollWheel: mouseState.ScrollWheelValue, leftButton: suppressMouse.Contains(SButton.MouseLeft) ? ButtonState.Released : mouseState.LeftButton, middleButton: suppressMouse.Contains(SButton.MouseMiddle) ? ButtonState.Released : mouseState.MiddleButton, rightButton: suppressMouse.Contains(SButton.MouseRight) ? ButtonState.Released : mouseState.RightButton, xButton1: suppressMouse.Contains(SButton.MouseX1) ? ButtonState.Released : mouseState.XButton1, xButton2: suppressMouse.Contains(SButton.MouseX2) ? ButtonState.Released : mouseState.XButton2 ); } }
/// <summary>Apply input overrides to the given states.</summary> /// <param name="pressed">The buttons to mark pressed.</param> /// <param name="released">The buttons to mark released.</param> /// <param name="controller">The game's controller state for the current tick.</param> /// <param name="keyboard">The game's keyboard state for the current tick.</param> /// <param name="mouse">The game's mouse state for the current tick.</param> /// <returns>Returns whether any overrides were applied.</returns> private bool ApplyOverrides(ISet <SButton> pressed, ISet <SButton> released, GamePadStateBuilder controller, KeyboardStateBuilder keyboard, MouseStateBuilder mouse) { if (pressed.Count == 0 && released.Count == 0) { return(false); } // group keys by type IDictionary <SButton, SButtonState> keyboardOverrides = new Dictionary <SButton, SButtonState>(); IDictionary <SButton, SButtonState> controllerOverrides = new Dictionary <SButton, SButtonState>(); IDictionary <SButton, SButtonState> mouseOverrides = new Dictionary <SButton, SButtonState>(); foreach (var button in pressed.Concat(released)) { var newState = this.DeriveState( oldState: this.GetState(button), isDown: pressed.Contains(button) ); if (button == SButton.MouseLeft || button == SButton.MouseMiddle || button == SButton.MouseRight || button == SButton.MouseX1 || button == SButton.MouseX2) { mouseOverrides[button] = newState; } else if (button.TryGetKeyboard(out Keys _)) { keyboardOverrides[button] = newState; } else if (controller.IsConnected && button.TryGetController(out Buttons _)) { controllerOverrides[button] = newState; } } // override states if (keyboardOverrides.Any()) { keyboard.OverrideButtons(keyboardOverrides); } if (controller.IsConnected && controllerOverrides.Any()) { controller.OverrideButtons(controllerOverrides); } if (mouseOverrides.Any()) { mouse.OverrideButtons(mouseOverrides); } return(true); }
/// <summary>Apply input overrides to the current state.</summary> public void ApplyOverrides() { if (this.HasNewOverrides) { var controller = new GamePadStateBuilder(this.ControllerState); var keyboard = new KeyboardStateBuilder(this.KeyboardState); var mouse = new MouseStateBuilder(this.MouseState); if (this.ApplyOverrides(pressed: this.CustomPressedKeys, released: this.CustomReleasedKeys, controller, keyboard, mouse)) { this.ControllerState = controller.GetState(); this.KeyboardState = keyboard.GetState(); this.MouseState = mouse.GetState(); } } }
/// <summary>Apply input suppression for the given input states.</summary> /// <param name="activeButtons">The current button states to check.</param> /// <param name="keyboardState">The game's keyboard state for the current tick.</param> /// <param name="mouseState">The game's mouse state for the current tick.</param> /// <param name="gamePadState">The game's controller state for the current tick.</param> public void UpdateSuppression(IDictionary <SButton, InputStatus> activeButtons, ref KeyboardState keyboardState, ref MouseState mouseState, ref GamePadState gamePadState) { // stop suppressing buttons once released if (this.SuppressButtons.Count != 0) { this.SuppressButtons.RemoveWhere(p => !this.GetStatus(activeButtons, p).IsDown()); } if (this.SuppressButtons.Count == 0) { return; } // gather info HashSet <Keys> keyboardButtons = new HashSet <Keys>(); HashSet <SButton> controllerButtons = new HashSet <SButton>(); HashSet <SButton> mouseButtons = new HashSet <SButton>(); foreach (SButton button in this.SuppressButtons) { if (button == SButton.MouseLeft || button == SButton.MouseMiddle || button == SButton.MouseRight || button == SButton.MouseX1 || button == SButton.MouseX2) { mouseButtons.Add(button); } else if (button.TryGetKeyboard(out Keys key)) { keyboardButtons.Add(key); } else if (gamePadState.IsConnected && button.TryGetController(out Buttons _)) { controllerButtons.Add(button); } } // suppress keyboard keys if (keyboardState.GetPressedKeys().Any() && keyboardButtons.Any()) { keyboardState = new KeyboardState(keyboardState.GetPressedKeys().Except(keyboardButtons).ToArray()); } // suppress controller keys if (gamePadState.IsConnected && controllerButtons.Any()) { GamePadStateBuilder builder = new GamePadStateBuilder(gamePadState); builder.SuppressButtons(controllerButtons); gamePadState = builder.ToGamePadState(); } // suppress mouse buttons if (mouseButtons.Any()) { mouseState = new MouseState( x: mouseState.X, y: mouseState.Y, scrollWheel: mouseState.ScrollWheelValue, leftButton: mouseButtons.Contains(SButton.MouseLeft) ? ButtonState.Pressed : mouseState.LeftButton, middleButton: mouseButtons.Contains(SButton.MouseMiddle) ? ButtonState.Pressed : mouseState.MiddleButton, rightButton: mouseButtons.Contains(SButton.MouseRight) ? ButtonState.Pressed : mouseState.RightButton, xButton1: mouseButtons.Contains(SButton.MouseX1) ? ButtonState.Pressed : mouseState.XButton1, xButton2: mouseButtons.Contains(SButton.MouseX2) ? ButtonState.Pressed : mouseState.XButton2 ); } }
/// <summary>Get the buttons pressed in the given stats.</summary> /// <param name="keyboard">The keyboard state.</param> /// <param name="mouse">The mouse state.</param> /// <param name="controller">The controller state.</param> /// <remarks>Thumbstick direction logic derived from <see cref="ButtonCollection"/>.</remarks> private IEnumerable <SButton> GetPressedButtons(KeyboardStateBuilder keyboard, MouseStateBuilder mouse, GamePadStateBuilder controller) { return(keyboard .GetPressedButtons() .Concat(mouse.GetPressedButtons()) .Concat(controller.GetPressedButtons())); }