Difference between revisions of "Modding:Modder Guide/APIs/Input"
Pathoschild (talk | contribs) (→Check button state: update for SMAPI 3.3 release, tweak for readability) |
Pathoschild (talk | contribs) (→Suppress input: clarify how suppression affects events and other input methods) |
||
Line 117: | Line 117: | ||
You can prevent the game from handling any controller/keyboard/mouse button press (including clicks) by ''suppressing'' it. This suppression will remain in effect until the player releases the button. This won't prevent other mods from handling it. | You can prevent the game from handling any controller/keyboard/mouse button press (including clicks) by ''suppressing'' it. This suppression will remain in effect until the player releases the button. This won't prevent other mods from handling it. | ||
− | For example | + | For example: |
<source lang="c#"> | <source lang="c#"> | ||
+ | // prevent game from seeing that LeftShift is pressed | ||
this.Helper.Input.Suppress(SButton.LeftShift); | this.Helper.Input.Suppress(SButton.LeftShift); | ||
− | |||
− | + | // that works for clicks too: | |
− | |||
this.Helper.Input.Suppress(SButton.MouseLeft); | this.Helper.Input.Suppress(SButton.MouseLeft); | ||
+ | |||
+ | // check if a button is being suppressed: | ||
+ | bool suppressed = this.Helper.Input.IsSuppressed(SButton.LeftShift); | ||
</source> | </source> | ||
− | You can | + | Side-effects: |
+ | <ul> | ||
+ | <li>The [[Modding:Modder Guide/APIs/Events#Input.ButtonReleased|<tt>ButtonReleased</tt> event]] will be raised on the next tick for the suppressed input.</li> | ||
+ | <li>Methods like <tt>helper.Input.IsDown(button)</tt> and <tt>helper.Input.GetState(button)</tt> will show the button as released for the duration of the suppression, even if it's physically still pressed. You can use <tt>helper.Input.IsSuppressed(button)</tt> to check if that's the case (it will only be true until the button is physically released): | ||
<source lang="c#"> | <source lang="c#"> | ||
− | + | bool isPhysicallyDown = helper.Input.IsDown(button) || helper.Input.IsSuppressed(button); | |
− | + | </source></li> | |
− | </ | + | </ul> |
==See also== | ==See also== | ||
* [[../Events#Input|Input events]] | * [[../Events#Input|Input events]] | ||
* [[Modding:Player Guide/Key Bindings]] for a list of valid <tt>SButton</tt> values | * [[Modding:Player Guide/Key Bindings]] for a list of valid <tt>SButton</tt> values |
Revision as of 02:57, 3 August 2020
- Get started
- Game fundamentals
- Test & troubleshoot
- Release
- API reference
- Basic SMAPI APIs:
- Advanced SMAPI APIs:
- Specific guides
The input API lets you check and suppress controller/keyboard/mouse state.
Data structures
SButton
SMAPI's SButton constants unify the Buttons, Keys, MouseState, and InputButton constants. SMAPI events use this to let you handle controller, keyboard, and mouse input without needing separate code for each. See Modding:Player Guide/Key Bindings for a list of values.
SMAPI provides extensions to convert any of the other constants to SButton:
SButton key = Keys.A.ToSButton(); // SButton.A
SButton button = Buttons.A.ToSButton(); // SButton.ControllerA
SButton input = new InputButton(true).ToSButton(); // SButton.MouseLeft
You can also convert SButton to the other constants. This uses a TryGet approach since SButton is a superset of the others (e.g. you can't convert SButton.ControllerA to a keyboard value):
SButton value = SButton.A;
if (value.TryGetKeyboard(out Keys key))
...;
if (value.TryGetController(out Buttons button))
...;
if (value.TryGetStardewInput(out InputButton input))
...;
Two last extensions let you check how the button is mapped in the game:
SButton button = SButton.MouseLeft;
if (button.IsUseToolButton())
// use tool
else if (button.IsActionButton())
// perform action
You can use SButton values directly in your config model, and they'll be represented by their names:
internal class ModConfig
{
public SButton DoThingButton { get; set; } = SButton.LeftControl;
}
|
→ | {
"DoThingButton": "LeftControl"
}
|
ICursorPosition
SMAPI's ICursorPosition provides the cursor position in four coordinate systems:
- AbsolutePixels is the pixel position relative to the top-left corner of the in-game map.
- ScreenPixels is the pixel position relative to the top-left corner of the visible screen, adjusted for game zoom.
- Tile is the tile position under the cursor.
- GrabTile is the tile position that the game considers under the cursor for the purposes of clicking actions. This automatically accounts for controller mode. This may be different than Tile if that's too far from the player.
This is returned by the this.Helper.Input.GetCursorPosition() method and in the event args for some input events.
APIs
Check button state
- IsDown
-
You can check if any controller/keyboard/mouse button is currently pressed by calling the IsDown(button) method. For example:
bool isShiftPressed = this.Helper.Input.IsDown(SButton.LeftShift) || this.Helper.Input.IsDown(SButton.RightShift);
- GetState
-
For more finetuned control, you can check the button state relative to the previous game tick:
SButtonState state = this.Helper.Input.GetState(SButton.LeftShift); bool isDown = (state == SButtonState.Pressed || state == SButtonState.Held);
Available button states:
previous tick current tick resulting state up up None up down Pressed down down Held down up Released
Check cursor position
The GetCursorPosition() method provides the cursor position in three coordinate systems; see ICursorPosition.
For example:
// draw text at the cursor position
ICursorPosition cursorPos = this.Helper.Input.GetCursorPosition();
Game1.spriteBatch.DrawString(Game1.smallFont, "some text", cursorPos.ScreenPixels, Color.Black);
Suppress input
You can prevent the game from handling any controller/keyboard/mouse button press (including clicks) by suppressing it. This suppression will remain in effect until the player releases the button. This won't prevent other mods from handling it.
For example:
// prevent game from seeing that LeftShift is pressed
this.Helper.Input.Suppress(SButton.LeftShift);
// that works for clicks too:
this.Helper.Input.Suppress(SButton.MouseLeft);
// check if a button is being suppressed:
bool suppressed = this.Helper.Input.IsSuppressed(SButton.LeftShift);
Side-effects:
- The ButtonReleased event will be raised on the next tick for the suppressed input.
- Methods like helper.Input.IsDown(button) and helper.Input.GetState(button) will show the button as released for the duration of the suppression, even if it's physically still pressed. You can use helper.Input.IsSuppressed(button) to check if that's the case (it will only be true until the button is physically released):
bool isPhysicallyDown = helper.Input.IsDown(button) || helper.Input.IsSuppressed(button);
See also
- Input events
- Modding:Player Guide/Key Bindings for a list of valid SButton values