summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/release-notes.md1
-rw-r--r--src/SMAPI/Framework/Input/SInputState.cs89
-rw-r--r--src/SMAPI/Framework/SGame.cs1
3 files changed, 49 insertions, 42 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md
index ece388c7..d1a78aaa 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -23,6 +23,7 @@
* Fixed error if a mod loads a PNG while the game is loading (e.g. custom map tilesheets via `IAssetLoader`).
* Fixed assets loaded by temporary content managers not being editable by mods.
* Fixed assets not reloaded consistently when the player switches language.
+ * Fixed input suppression not working consistently for clicks.
* Fixed console command input not saved to the log.
* Fixed `helper.ModRegistry.GetApi` interface validation errors not mentioning which interface caused the issue.
* **Breaking changes** (see [migration guide](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.3)):
diff --git a/src/SMAPI/Framework/Input/SInputState.cs b/src/SMAPI/Framework/Input/SInputState.cs
index 1b224737..5e8efa62 100644
--- a/src/SMAPI/Framework/Input/SInputState.cs
+++ b/src/SMAPI/Framework/Input/SInputState.cs
@@ -81,22 +81,16 @@ namespace StardewModdingAPI.Framework.Input
Point mousePosition = new Point((int)(this.RealMouse.X * (1.0 / Game1.options.zoomLevel)), (int)(this.RealMouse.Y * (1.0 / Game1.options.zoomLevel))); // derived from Game1::getMouseX
var activeButtons = this.DeriveStatuses(this.ActiveButtons, realKeyboard, realMouse, realController);
- // get suppressed states
- GamePadState suppressedController = realController;
- KeyboardState suppressedKeyboard = realKeyboard;
- MouseState suppressedMouse = realMouse;
- if (this.SuppressButtons.Count > 0)
- this.UpdateSuppression(activeButtons, ref suppressedKeyboard, ref suppressedMouse, ref suppressedController);
-
- // update
+ // update real states
this.ActiveButtons = activeButtons;
this.RealController = realController;
this.RealKeyboard = realKeyboard;
this.RealMouse = realMouse;
- this.SuppressedController = suppressedController;
- this.SuppressedKeyboard = suppressedKeyboard;
- this.SuppressedMouse = suppressedMouse;
this.MousePosition = mousePosition;
+
+ // update suppressed states
+ this.SuppressButtons.RemoveWhere(p => !this.GetStatus(activeButtons, p).IsDown());
+ this.UpdateSuppression();
}
catch (InvalidOperationException)
{
@@ -104,6 +98,20 @@ namespace StardewModdingAPI.Framework.Input
}
}
+ /// <summary>Apply input suppression to current input.</summary>
+ public void UpdateSuppression()
+ {
+ GamePadState suppressedController = this.RealController;
+ KeyboardState suppressedKeyboard = this.RealKeyboard;
+ MouseState suppressedMouse = this.RealMouse;
+
+ this.SuppressGivenStates(this.ActiveButtons, ref suppressedKeyboard, ref suppressedMouse, ref suppressedController);
+
+ this.SuppressedController = suppressedController;
+ this.SuppressedKeyboard = suppressedKeyboard;
+ this.SuppressedMouse = suppressedMouse;
+ }
+
/// <summary>Get the gamepad state visible to the game.</summary>
[Obsolete("This method should only be called by the game itself.")]
public override GamePadState GetGamePadState()
@@ -145,71 +153,68 @@ namespace StardewModdingAPI.Framework.Input
return buttons.Any(button => this.IsDown(button.ToSButton()));
}
- /// <summary>Apply input suppression for the given input states.</summary>
+
+ /*********
+ ** Private methods
+ *********/
+ /// <summary>Whether input should be suppressed in the current context.</summary>
+ private bool ShouldSuppressNow()
+ {
+ return Game1.chatBox != null && !Game1.chatBox.isActive();
+ }
+
+ /// <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>
- public void UpdateSuppression(IDictionary<SButton, InputStatus> activeButtons, ref KeyboardState keyboardState, ref MouseState mouseState, ref GamePadState gamePadState)
+ private void SuppressGivenStates(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>();
+ 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)
- mouseButtons.Add(button);
+ suppressMouse.Add(button);
else if (button.TryGetKeyboard(out Keys key))
- keyboardButtons.Add(key);
+ suppressKeys.Add(key);
else if (gamePadState.IsConnected && button.TryGetController(out Buttons _))
- controllerButtons.Add(button);
+ suppressButtons.Add(button);
}
// suppress keyboard keys
- if (keyboardState.GetPressedKeys().Any() && keyboardButtons.Any())
- keyboardState = new KeyboardState(keyboardState.GetPressedKeys().Except(keyboardButtons).ToArray());
+ if (keyboardState.GetPressedKeys().Any() && suppressKeys.Any())
+ keyboardState = new KeyboardState(keyboardState.GetPressedKeys().Except(suppressKeys).ToArray());
// suppress controller keys
- if (gamePadState.IsConnected && controllerButtons.Any())
+ if (gamePadState.IsConnected && suppressButtons.Any())
{
GamePadStateBuilder builder = new GamePadStateBuilder(gamePadState);
- builder.SuppressButtons(controllerButtons);
+ builder.SuppressButtons(suppressButtons);
gamePadState = builder.ToGamePadState();
}
// suppress mouse buttons
- if (mouseButtons.Any())
+ if (suppressMouse.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
+ 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
);
}
}
-
- /*********
- ** Private methods
- *********/
- /// <summary>Whether input should be suppressed in the current context.</summary>
- private bool ShouldSuppressNow()
- {
- return Game1.chatBox != null && !Game1.chatBox.isActive();
- }
-
/// <summary>Get the status of all pressed or released buttons relative to their previous status.</summary>
/// <param name="previousStatuses">The previous button statuses.</param>
/// <param name="keyboard">The keyboard state.</param>
diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs
index c8c30834..63f7f073 100644
--- a/src/SMAPI/Framework/SGame.cs
+++ b/src/SMAPI/Framework/SGame.cs
@@ -613,6 +613,7 @@ namespace StardewModdingAPI.Framework
/*********
** Game update
*********/
+ this.Input.UpdateSuppression();
try
{
base.Update(gameTime);