Changes

Jump to navigation Jump to search
swap 'APIs' and 'data structures' section positions
Line 2: Line 2:     
The input API lets you check and suppress controller/keyboard/mouse state.
 
The input API lets you check and suppress controller/keyboard/mouse state.
  −
==Data structures==
  −
===SButton===
  −
SMAPI's <tt>SButton</tt> constants unify the [https://docs.microsoft.com/en-us/previous-versions/windows/xna/bb975202(v%3dxnagamestudio.40) <tt>Buttons</tt>], [https://docs.microsoft.com/en-us/previous-versions/windows/xna/bb197781(v%3dxnagamestudio.40) <tt>Keys</tt>], [https://docs.microsoft.com/en-us/previous-versions/windows/xna/bb198097(v%3dxnagamestudio.40) <tt>MouseState</tt>], and <tt>InputButton</tt> 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 <tt>SButton</tt>:
  −
<source lang="c#">
  −
SButton key = Keys.A.ToSButton(); // SButton.A
  −
SButton button = Buttons.A.ToSButton(); // SButton.ControllerA
  −
SButton input = new InputButton(true).ToSButton(); // SButton.MouseLeft
  −
</source>
  −
  −
You can also convert <tt>SButton</tt> to the other constants. This uses a <tt>TryGet</tt> approach since <tt>SButton</tt> is a superset of the others (e.g. you can't convert <tt>SButton.ControllerA</tt> to a keyboard value):
  −
<source lang="c#">
  −
SButton value = SButton.A;
  −
if (value.TryGetKeyboard(out Keys key))
  −
  ...;
  −
if (value.TryGetController(out Buttons button))
  −
  ...;
  −
if (value.TryGetStardewInput(out InputButton input))
  −
  ...;
  −
</source>
  −
  −
Two last extensions let you check how the button is mapped in the game:
  −
<source lang="c#">
  −
SButton button = SButton.MouseLeft;
  −
if (button.IsUseToolButton())
  −
  // use tool
  −
else if (button.IsActionButton())
  −
  // perform action
  −
</source>
  −
  −
You can use <tt>SButton</tt> values directly in your [[../Config|config model]], and they'll be represented by their names:
  −
{| class="wikitable"
  −
| <source lang="c#">
  −
internal class ModConfig
  −
{
  −
  public SButton DoThingButton { get; set; } = SButton.LeftControl;
  −
}
  −
</source>
  −
| &rarr;
  −
| <source lang="json">
  −
{
  −
  "DoThingButton": "LeftControl"
  −
}
  −
</source>
  −
|}
  −
  −
===ICursorPosition===
  −
SMAPI's <tt>ICursorPosition</tt> provides the cursor position in four coordinate systems:
  −
* <tt>AbsolutePixels</tt> is the pixel position relative to the top-left corner of the in-game map, adjusted for [[Modding:Modder Guide/Game Fundamentals#Zoom level|zoom]] but not [[Modding:Modder Guide/Game Fundamentals#UI scaling|UI scaling]].
  −
* <tt>ScreenPixels</tt> is the pixel position relative to the top-left corner of the visible screen, adjusted for [[Modding:Modder Guide/Game Fundamentals#Zoom level|zoom]] but not [[Modding:Modder Guide/Game Fundamentals#UI scaling|UI scaling]].
  −
* <tt>Tile</tt> is the [[Modding:Modder Guide/Game Fundamentals#Tiles|tile position]] under the cursor.
  −
* <tt>GrabTile</tt> 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 <tt>Tile</tt> if that's too far from the player.
  −
  −
This is returned by the <tt>this.Helper.Input.GetCursorPosition()</tt> method and in the event args for some input events.
  −
  −
'''The pixel positions are ''not'' adjusted for [[Modding:Modder Guide/Game Fundamentals#UI scaling|UI scaling]]''' (i.e. they're non-UI mode). Whether you need UI or non-UI positions depends how you're using them, so you can use <tt>cursorPos.GetScaledAbsolutePixels()</tt> or <tt>cursorPos.GetScaledScreenPixels()</tt> to adjust them automatically for the current mode or <tt>Utility.ModifyCoordinatesForUIScale</tt> to always get UI mode coordinates.
      
==APIs==
 
==APIs==
Line 66: Line 8:  
<dt><tt>IsDown</tt></dt>
 
<dt><tt>IsDown</tt></dt>
 
<dd>
 
<dd>
You can check if any controller/keyboard/mouse button is currently pressed by calling the <tt>IsDown(button)</tt> method. For example:
+
You can check if any [[#SButton|controller/keyboard/mouse button]] is currently pressed by calling the <tt>IsDown(button)</tt> method. For example:
 
<source lang="c#">
 
<source lang="c#">
 
bool isShiftPressed = this.Helper.Input.IsDown(SButton.LeftShift) || this.Helper.Input.IsDown(SButton.RightShift);
 
bool isShiftPressed = this.Helper.Input.IsDown(SButton.LeftShift) || this.Helper.Input.IsDown(SButton.RightShift);
Line 74: Line 16:  
<dt><tt>GetState</tt></dt>
 
<dt><tt>GetState</tt></dt>
 
<dd>
 
<dd>
For more finetuned control, you can check the button state relative to the previous game tick:
+
For more finetuned control, you can check the [[#SButton|button]] state relative to the previous game tick:
 
<source lang="c#">
 
<source lang="c#">
 
SButtonState state = this.Helper.Input.GetState(SButton.LeftShift);
 
SButtonState state = this.Helper.Input.GetState(SButton.LeftShift);
Line 106: Line 48:     
===Check cursor position===
 
===Check cursor position===
The <tt>GetCursorPosition()</tt> method provides the cursor position in three coordinate systems; see [[#ICursorPosition|ICursorPosition]].
+
The <tt>GetCursorPosition()</tt> method provides the [[#ICursorPosition|cursor position in three coordinate systems|ICursorPosition]].
    
For example:
 
For example:
Line 116: Line 58:     
===Suppress input===
 
===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.
+
You can prevent the game from handling any [[#SButton|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:
Line 138: Line 80:  
</source></li>
 
</source></li>
 
</ul>
 
</ul>
 +
 +
==Data structures==
 +
===SButton===
 +
SMAPI's <tt>SButton</tt> constants unify the [https://docs.microsoft.com/en-us/previous-versions/windows/xna/bb975202(v%3dxnagamestudio.40) <tt>Buttons</tt>], [https://docs.microsoft.com/en-us/previous-versions/windows/xna/bb197781(v%3dxnagamestudio.40) <tt>Keys</tt>], [https://docs.microsoft.com/en-us/previous-versions/windows/xna/bb198097(v%3dxnagamestudio.40) <tt>MouseState</tt>], and <tt>InputButton</tt> 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 <tt>SButton</tt>:
 +
<source lang="c#">
 +
SButton key = Keys.A.ToSButton(); // SButton.A
 +
SButton button = Buttons.A.ToSButton(); // SButton.ControllerA
 +
SButton input = new InputButton(true).ToSButton(); // SButton.MouseLeft
 +
</source>
 +
 +
You can also convert <tt>SButton</tt> to the other constants. This uses a <tt>TryGet</tt> approach since <tt>SButton</tt> is a superset of the others (e.g. you can't convert <tt>SButton.ControllerA</tt> to a keyboard value):
 +
<source lang="c#">
 +
SButton value = SButton.A;
 +
if (value.TryGetKeyboard(out Keys key))
 +
  ...;
 +
if (value.TryGetController(out Buttons button))
 +
  ...;
 +
if (value.TryGetStardewInput(out InputButton input))
 +
  ...;
 +
</source>
 +
 +
Two last extensions let you check how the button is mapped in the game:
 +
<source lang="c#">
 +
SButton button = SButton.MouseLeft;
 +
if (button.IsUseToolButton())
 +
  // use tool
 +
else if (button.IsActionButton())
 +
  // perform action
 +
</source>
 +
 +
You can use <tt>SButton</tt> values directly in your [[../Config|config model]], and they'll be represented by their names:
 +
{| class="wikitable"
 +
| <source lang="c#">
 +
internal class ModConfig
 +
{
 +
  public SButton DoThingButton { get; set; } = SButton.LeftControl;
 +
}
 +
</source>
 +
| &rarr;
 +
| <source lang="json">
 +
{
 +
  "DoThingButton": "LeftControl"
 +
}
 +
</source>
 +
|}
 +
 +
===ICursorPosition===
 +
SMAPI's <tt>ICursorPosition</tt> provides the cursor position in four coordinate systems:
 +
* <tt>AbsolutePixels</tt> is the pixel position relative to the top-left corner of the in-game map, adjusted for [[Modding:Modder Guide/Game Fundamentals#Zoom level|zoom]] but not [[Modding:Modder Guide/Game Fundamentals#UI scaling|UI scaling]].
 +
* <tt>ScreenPixels</tt> is the pixel position relative to the top-left corner of the visible screen, adjusted for [[Modding:Modder Guide/Game Fundamentals#Zoom level|zoom]] but not [[Modding:Modder Guide/Game Fundamentals#UI scaling|UI scaling]].
 +
* <tt>Tile</tt> is the [[Modding:Modder Guide/Game Fundamentals#Tiles|tile position]] under the cursor.
 +
* <tt>GrabTile</tt> 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 <tt>Tile</tt> if that's too far from the player.
 +
 +
This is returned by the <tt>this.Helper.Input.GetCursorPosition()</tt> method and in the event args for some input events.
 +
 +
'''The pixel positions are ''not'' adjusted for [[Modding:Modder Guide/Game Fundamentals#UI scaling|UI scaling]]''' (i.e. they're non-UI mode). Whether you need UI or non-UI positions depends how you're using them, so you can use <tt>cursorPos.GetScaledAbsolutePixels()</tt> or <tt>cursorPos.GetScaledScreenPixels()</tt> to adjust them automatically for the current mode or <tt>Utility.ModifyCoordinatesForUIScale</tt> to always get UI mode coordinates.
    
==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
translators
8,404

edits

Navigation menu