/// <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>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())); }
/// <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 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); }