summaryrefslogtreecommitdiff
path: root/src/SMAPI/Events/EventArgsInput.cs
blob: 0cf0828ba7d0ac4d12863852a422779b5eeed767 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
using System;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using StardewValley;

namespace StardewModdingAPI.Events
{
    /// <summary>Event arguments when a button is pressed or released.</summary>
    public class EventArgsInput : EventArgs
    {
        /*********
        ** Accessors
        *********/
        /// <summary>The button on the controller, keyboard, or mouse.</summary>
        public SButton Button { get; }

        /// <summary>The current cursor position.</summary>
        public ICursorPosition Cursor { get; }

        /// <summary>Whether the input should trigger actions on the affected tile.</summary>
        public bool IsActionButton { get; }

        /// <summary>Whether the input should use tools on the affected tile.</summary>
        public bool IsUseToolButton { get; }

        /// <summary>Whether a mod has indicated the key was already handled.</summary>
        public bool IsSuppressed { get; private set; }


        /*********
        ** Public methods
        *********/
        /// <summary>Construct an instance.</summary>
        /// <param name="button">The button on the controller, keyboard, or mouse.</param>
        /// <param name="cursor">The cursor position.</param>
        /// <param name="isActionButton">Whether the input should trigger actions on the affected tile.</param>
        /// <param name="isUseToolButton">Whether the input should use tools on the affected tile.</param>
        public EventArgsInput(SButton button, ICursorPosition cursor, bool isActionButton, bool isUseToolButton)
        {
            this.Button = button;
            this.Cursor = cursor;
            this.IsActionButton = isActionButton;
            this.IsUseToolButton = isUseToolButton;
        }

        /// <summary>Prevent the game from handling the current button press. This doesn't prevent other mods from receiving the event.</summary>
        public void SuppressButton()
        {
            this.SuppressButton(this.Button);
        }

        /// <summary>Prevent the game from handling a button press. This doesn't prevent other mods from receiving the event.</summary>
        /// <param name="button">The button to suppress.</param>
        public void SuppressButton(SButton button)
        {
            if (button == this.Button)
                this.IsSuppressed = true;

            // keyboard
            if (button.TryGetKeyboard(out Keys key))
                Game1.oldKBState = new KeyboardState(Game1.oldKBState.GetPressedKeys().Union(new[] { key }).ToArray());

            // controller
            else if (button.TryGetController(out Buttons controllerButton))
            {
                var newState = GamePad.GetState(PlayerIndex.One);
                var thumbsticks = Game1.oldPadState.ThumbSticks;
                var triggers = Game1.oldPadState.Triggers;
                var buttons = Game1.oldPadState.Buttons;
                var dpad = Game1.oldPadState.DPad;

                switch (controllerButton)
                {
                    // d-pad
                    case Buttons.DPadDown:
                        dpad = new GamePadDPad(dpad.Up, newState.DPad.Down, dpad.Left, dpad.Right);
                        break;
                    case Buttons.DPadLeft:
                        dpad = new GamePadDPad(dpad.Up, dpad.Down, newState.DPad.Left, dpad.Right);
                        break;
                    case Buttons.DPadRight:
                        dpad = new GamePadDPad(dpad.Up, dpad.Down, dpad.Left, newState.DPad.Right);
                        break;
                    case Buttons.DPadUp:
                        dpad = new GamePadDPad(newState.DPad.Up, dpad.Down, dpad.Left, dpad.Right);
                        break;

                    // trigger
                    case Buttons.LeftTrigger:
                        triggers = new GamePadTriggers(newState.Triggers.Left, triggers.Right);
                        break;
                    case Buttons.RightTrigger:
                        triggers = new GamePadTriggers(triggers.Left, newState.Triggers.Right);
                        break;

                    // thumbstick
                    case Buttons.LeftThumbstickDown:
                    case Buttons.LeftThumbstickLeft:
                    case Buttons.LeftThumbstickRight:
                    case Buttons.LeftThumbstickUp:
                        thumbsticks = new GamePadThumbSticks(newState.ThumbSticks.Left, thumbsticks.Right);
                        break;
                    case Buttons.RightThumbstickDown:
                    case Buttons.RightThumbstickLeft:
                    case Buttons.RightThumbstickRight:
                    case Buttons.RightThumbstickUp:
                        thumbsticks = new GamePadThumbSticks(newState.ThumbSticks.Right, thumbsticks.Left);
                        break;

                    // buttons
                    default:
                        var mask =
                            (buttons.A == ButtonState.Pressed ? Buttons.A : 0)
                            | (buttons.B == ButtonState.Pressed ? Buttons.B : 0)
                            | (buttons.Back == ButtonState.Pressed ? Buttons.Back : 0)
                            | (buttons.BigButton == ButtonState.Pressed ? Buttons.BigButton : 0)
                            | (buttons.LeftShoulder == ButtonState.Pressed ? Buttons.LeftShoulder : 0)
                            | (buttons.LeftStick == ButtonState.Pressed ? Buttons.LeftStick : 0)
                            | (buttons.RightShoulder == ButtonState.Pressed ? Buttons.RightShoulder : 0)
                            | (buttons.RightStick == ButtonState.Pressed ? Buttons.RightStick : 0)
                            | (buttons.Start == ButtonState.Pressed ? Buttons.Start : 0)
                            | (buttons.X == ButtonState.Pressed ? Buttons.X : 0)
                            | (buttons.Y == ButtonState.Pressed ? Buttons.Y : 0);
                        mask = mask ^ controllerButton;
                        buttons = new GamePadButtons(mask);
                        break;
                }

                Game1.oldPadState = new GamePadState(thumbsticks, triggers, buttons, dpad);
            }

            // mouse
            else if (button == SButton.MouseLeft || button == SButton.MouseMiddle || button == SButton.MouseRight || button == SButton.MouseX1 || button == SButton.MouseX2)
            {
                Game1.oldMouseState = new MouseState(
                    x: Game1.oldMouseState.X,
                    y: Game1.oldMouseState.Y,
                    scrollWheel: Game1.oldMouseState.ScrollWheelValue,
                    leftButton: button == SButton.MouseLeft ? ButtonState.Pressed : Game1.oldMouseState.LeftButton,
                    middleButton: button == SButton.MouseMiddle ? ButtonState.Pressed : Game1.oldMouseState.MiddleButton,
                    rightButton: button == SButton.MouseRight ? ButtonState.Pressed : Game1.oldMouseState.RightButton,
                    xButton1: button == SButton.MouseX1 ? ButtonState.Pressed : Game1.oldMouseState.XButton1,
                    xButton2: button == SButton.MouseX2 ? ButtonState.Pressed : Game1.oldMouseState.XButton2
                );
            }
        }
    }
}