From bd29fae9ca2f1d3b612d561cf161a3745ff44dcc Mon Sep 17 00:00:00 2001 From: bradjrenshaw Date: Fri, 6 May 2022 19:47:11 -0400 Subject: [PATCH 01/13] Initial refactor of mouse handling. --- stardew-access/Features/MouseHandler.cs | 50 +++++++++++++++++++++++++ stardew-access/Features/Other.cs | 26 ------------- stardew-access/ModEntry.cs | 14 ++++++- 3 files changed, 63 insertions(+), 27 deletions(-) create mode 100644 stardew-access/Features/MouseHandler.cs diff --git a/stardew-access/Features/MouseHandler.cs b/stardew-access/Features/MouseHandler.cs new file mode 100644 index 0000000..88b09c8 --- /dev/null +++ b/stardew-access/Features/MouseHandler.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using StardewValley; + +namespace stardew_access.Features +{ + public class MouseHandler + { + + public Vector2 ViewingOffset { get; set; } = Vector2.Zero; + + public Vector2 PlayerFacingVector + { + get + { +switch (Game1.player.FacingDirection) + { + case 0: + return new Vector2(0, - Game1.tileSize); + case 1: + return new Vector2(Game1.tileSize, 0); + case 2: + return new Vector2(0, Game1.tileSize); + case 3: + return new Vector2(-Game1.tileSize, 0); + default: + return Vector2.Zero; + } + } + } + + public Vector2 PlayerPosition + { + get + { + int x = Game1.player.GetBoundingBox().Center.X - Game1.viewport.X; + int y = Game1.player.GetBoundingBox().Center.Y - Game1.viewport.Y; + return new Vector2(x, y); + } + } + + public void SnapMouseToPlayer() + { + Vector2 snapPosition = this.PlayerPosition + this.PlayerFacingVector + this.ViewingOffset; + if (Utility.isOnScreen(snapPosition, 0)) + Game1.setMousePosition((int)snapPosition.X, (int)snapPosition.Y); + } + } +} diff --git a/stardew-access/Features/Other.cs b/stardew-access/Features/Other.cs index a21698f..826c01d 100644 --- a/stardew-access/Features/Other.cs +++ b/stardew-access/Features/Other.cs @@ -41,32 +41,6 @@ namespace stardew_access.Features MainClass.ScreenReader.Say($"{currentLocation.Name} Entered", true); } - public static void SnapMouseToPlayer() - { - int x = Game1.player.GetBoundingBox().Center.X - Game1.viewport.X; - int y = Game1.player.GetBoundingBox().Center.Y - Game1.viewport.Y; - - int offset = 64; - - switch (Game1.player.FacingDirection) - { - case 0: - y -= offset; - break; - case 1: - x += offset; - break; - case 2: - y += offset; - break; - case 3: - x -= offset; - break; - } - - Game1.setMousePosition(x, y); - } - public static void narrateHudMessages() { try diff --git a/stardew-access/ModEntry.cs b/stardew-access/ModEntry.cs index 59dbb2f..7718b08 100644 --- a/stardew-access/ModEntry.cs +++ b/stardew-access/ModEntry.cs @@ -20,6 +20,7 @@ namespace stardew_access private static StaticTiles? sTiles; private static IScreenReader? screenReader; private static IModHelper? modHelper; + private static MouseHandler? mouse; internal static ModConfig Config { get => config; set => config = value; } public static IModHelper? ModHelper { get => modHelper; } @@ -62,6 +63,17 @@ namespace stardew_access set => screenReader = value; } + + public static MouseHandler Mouse + { +get + { + if (mouse == null) + mouse = new MouseHandler(); + return mouse; + } + } + #endregion /********* @@ -131,7 +143,7 @@ namespace stardew_access Other.narrateCurrentLocation(); if (Config.SnapMouse) - Other.SnapMouseToPlayer(); + Mouse.SnapMouseToPlayer(); if (!ReadTile.isReadingTile && Config.ReadTile) { From 8dd96d84b3c634acac4b453a87eed86958ef5883 Mon Sep 17 00:00:00 2001 From: bradjrenshaw Date: Sun, 8 May 2022 01:47:32 -0400 Subject: [PATCH 02/13] Refactoring mouse handling into a separate class. --- stardew-access/Features/MouseHandler.cs | 19 +++++++++++++------ stardew-access/ModEntry.cs | 3 +-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/stardew-access/Features/MouseHandler.cs b/stardew-access/Features/MouseHandler.cs index 88b09c8..f0bccd7 100644 --- a/stardew-access/Features/MouseHandler.cs +++ b/stardew-access/Features/MouseHandler.cs @@ -8,9 +8,9 @@ namespace stardew_access.Features public class MouseHandler { - public Vector2 ViewingOffset { get; set; } = Vector2.Zero; + private Vector2 ViewingOffset = Vector2.Zero; - public Vector2 PlayerFacingVector + private Vector2 PlayerFacingVector { get { @@ -30,7 +30,7 @@ switch (Game1.player.FacingDirection) } } - public Vector2 PlayerPosition + private Vector2 PlayerPosition { get { @@ -40,11 +40,18 @@ switch (Game1.player.FacingDirection) } } - public void SnapMouseToPlayer() + private void SnapMouseToPlayer() { Vector2 snapPosition = this.PlayerPosition + this.PlayerFacingVector + this.ViewingOffset; - if (Utility.isOnScreen(snapPosition, 0)) - Game1.setMousePosition((int)snapPosition.X, (int)snapPosition.Y); + Point snapPoint = new Point((int)snapPosition.X, (int)snapPosition.Y); + if (Utility.isOnScreen(snapPoint, 0)) + Game1.setMousePosition(snapPoint.X, snapPoint.Y); + } + +public void update() + { + if (MainClass.Config.SnapMouse) + this.SnapMouseToPlayer(); } } } diff --git a/stardew-access/ModEntry.cs b/stardew-access/ModEntry.cs index 7718b08..28c19fe 100644 --- a/stardew-access/ModEntry.cs +++ b/stardew-access/ModEntry.cs @@ -142,8 +142,7 @@ get // Narrate current location's name Other.narrateCurrentLocation(); - if (Config.SnapMouse) - Mouse.SnapMouseToPlayer(); + Mouse.update(); if (!ReadTile.isReadingTile && Config.ReadTile) { From 797e0ab13658ccc3f1fbeb877c2c5262e9074d43 Mon Sep 17 00:00:00 2001 From: bradjrenshaw Date: Sun, 8 May 2022 01:55:38 -0400 Subject: [PATCH 03/13] Add cursor keys to mod config. --- stardew-access/ModConfig.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/stardew-access/ModConfig.cs b/stardew-access/ModConfig.cs index 98c19df..388d7fd 100644 --- a/stardew-access/ModConfig.cs +++ b/stardew-access/ModConfig.cs @@ -26,6 +26,16 @@ namespace stardew_access public KeybindList ReadTileKey { get; set; } = KeybindList.Parse("J"); public KeybindList ReadStandingTileKey { get; set; } = KeybindList.Parse("LeftAlt + J"); + //Tile viewer keys + public KeybindList TileCursorUpKey { get; set; } = KeybindList.Parse("Up"); + public KeybindList TileCursorRightKey { get; set; } = KeybindList.Parse("Right"); + public KeybindList TileCursorDownKey { get; set; } = KeybindList.Parse("Down"); + public KeybindList TileCursorLeftKey { get; set; } = KeybindList.Parse("Left"); + public KeybindList TileCursorPreciseUpKey { get; set; } = KeybindList.Parse("LeftShift + Up"); + public KeybindList TileCursorPreciseRightKey { get; set; } = KeybindList.Parse("LeftShift + Right"); + public KeybindList TileCursorPreciseDownKey { get; set; } = KeybindList.Parse("LeftShift + Down"); + public KeybindList TileCursorPreciseLeftKey { get; set; } = KeybindList.Parse("LeftShift + Left"); + #endregion // TODO Add the exclusion and focus list too From 0b318b29ad1647d32ffd0f156a7b193eee621142 Mon Sep 17 00:00:00 2001 From: bradjrenshaw Date: Sun, 8 May 2022 18:46:37 -0400 Subject: [PATCH 04/13] MouseHandler refactoring. --- stardew-access/Features/MouseHandler.cs | 27 +++++++++++++++++++++++++ stardew-access/Features/Radar.cs | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/stardew-access/Features/MouseHandler.cs b/stardew-access/Features/MouseHandler.cs index f0bccd7..fb3f618 100644 --- a/stardew-access/Features/MouseHandler.cs +++ b/stardew-access/Features/MouseHandler.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using Microsoft.Xna.Framework; +using xTile; using StardewValley; + namespace stardew_access.Features { public class MouseHandler @@ -40,6 +42,23 @@ switch (Game1.player.FacingDirection) } } + private static (int, int) GetMapTileDimensions() + { + Map map = Game1.currentLocation.map; + return (map.Layers[0].LayerWidth, map.Layers[0].LayerHeight); + } + + public bool MoveTileView(Vector2 delta) + { + Vector2 dest = this.PlayerPosition + this.PlayerFacingVector + this.ViewingOffset + delta; + if (Utility.isOnScreen(dest, 0)) + { + this.ViewingOffset += delta; + return true; + } + return false; + } + private void SnapMouseToPlayer() { Vector2 snapPosition = this.PlayerPosition + this.PlayerFacingVector + this.ViewingOffset; @@ -53,5 +72,13 @@ public void update() if (MainClass.Config.SnapMouse) this.SnapMouseToPlayer(); } + + private static bool IsTileOnMap(Vector2 tile) + { + (int width, int height) dimensions = GetMapTileDimensions(); + if (tile.X < 0 || tile.X >= dimensions.width) return false; + if (tile.Y < 0 || tile.Y >= dimensions.height) return false; + return true; } } +} diff --git a/stardew-access/Features/Radar.cs b/stardew-access/Features/Radar.cs index 86b5e46..5253de9 100644 --- a/stardew-access/Features/Radar.cs +++ b/stardew-access/Features/Radar.cs @@ -1,4 +1,4 @@ -using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework; using StardewValley; using StardewValley.Objects; From bc6ec49619de41d315555fbe311aebc13953732f Mon Sep 17 00:00:00 2001 From: bradjrenshaw Date: Mon, 9 May 2022 23:53:29 -0400 Subject: [PATCH 05/13] Initial implementation of cursor movement and mouse snapping to cursor location. --- stardew-access/Features/MouseHandler.cs | 116 +++++++++++++++++++----- 1 file changed, 91 insertions(+), 25 deletions(-) diff --git a/stardew-access/Features/MouseHandler.cs b/stardew-access/Features/MouseHandler.cs index fb3f618..5b615f6 100644 --- a/stardew-access/Features/MouseHandler.cs +++ b/stardew-access/Features/MouseHandler.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using Microsoft.Xna.Framework; using xTile; using StardewValley; +using StardewValley.Menus; +using stardew_access.Features; namespace stardew_access.Features @@ -11,15 +13,18 @@ namespace stardew_access.Features { private Vector2 ViewingOffset = Vector2.Zero; + private Vector2 relativeOffsetLockPosition = Vector2.Zero; + private Boolean relativeOffsetLock = false; + private Vector2 prevPlayerPosition = Vector2.Zero, prevFacing = Vector2.Zero; private Vector2 PlayerFacingVector { get { -switch (Game1.player.FacingDirection) + switch (Game1.player.FacingDirection) { case 0: - return new Vector2(0, - Game1.tileSize); + return new Vector2(0, -Game1.tileSize); case 1: return new Vector2(Game1.tileSize, 0); case 2: @@ -36,24 +41,55 @@ switch (Game1.player.FacingDirection) { get { - int x = Game1.player.GetBoundingBox().Center.X - Game1.viewport.X; - int y = Game1.player.GetBoundingBox().Center.Y - Game1.viewport.Y; + int x = Game1.player.GetBoundingBox().Center.X; + int y = Game1.player.GetBoundingBox().Center.Y; return new Vector2(x, y); } } - private static (int, int) GetMapTileDimensions() + private Vector2 getTileCursorPosition() { - Map map = Game1.currentLocation.map; - return (map.Layers[0].LayerWidth, map.Layers[0].LayerHeight); + Vector2 target = this.PlayerPosition; + if (this.relativeOffsetLock) + { + target += this.relativeOffsetLockPosition; + } + else + { + target += this.PlayerFacingVector + this.ViewingOffset; + } + return target; } - - public bool MoveTileView(Vector2 delta) + + private void cursorMoveInput(Vector2 delta, Boolean precise = false) { - Vector2 dest = this.PlayerPosition + this.PlayerFacingVector + this.ViewingOffset + delta; + if (!tryMoveTileView(delta)) return; + Vector2 position = this.getTileCursorPosition(); + String ?name = TileInfo.getNameAtTile(position / Game1.tileSize); + if (name == null) + { + name = "empty tile"; + } + if (precise) + { + MainClass.ScreenReader.Say($"{position.X}, {position.Y}", true); + } + else + { + MainClass.ScreenReader.Say($"{name}, {(int)(position.X / Game1.tileSize)}, {(int)(position.Y / Game1.tileSize)}", true); + } + } + + private bool tryMoveTileView(Vector2 delta) + { + Vector2 dest = this.getTileCursorPosition() + delta; if (Utility.isOnScreen(dest, 0)) { - this.ViewingOffset += delta; + if (this.relativeOffsetLock) + this.relativeOffsetLockPosition += delta; + else + this.ViewingOffset += delta; + return true; } return false; @@ -61,24 +97,54 @@ switch (Game1.player.FacingDirection) private void SnapMouseToPlayer() { - Vector2 snapPosition = this.PlayerPosition + this.PlayerFacingVector + this.ViewingOffset; - Point snapPoint = new Point((int)snapPosition.X, (int)snapPosition.Y); - if (Utility.isOnScreen(snapPoint, 0)) - Game1.setMousePosition(snapPoint.X, snapPoint.Y); + Vector2 cursorPosition = this.getTileCursorPosition(); + if (allowMouseSnap(cursorPosition)) + Game1.setMousePosition((int)cursorPosition.X - Game1.viewport.X, (int)cursorPosition.Y - Game1.viewport.Y); } -public void update() + public void update() { + if (this.prevFacing != this.PlayerFacingVector || this.prevPlayerPosition != this.PlayerPosition) + { + this.ViewingOffset = Vector2.Zero; + } + this.prevFacing = this.PlayerFacingVector; + this.prevPlayerPosition = this.PlayerPosition; if (MainClass.Config.SnapMouse) - this.SnapMouseToPlayer(); + this.SnapMouseToPlayer(); + if (MainClass.Config.TileCursorUpKey.JustPressed()) + { + this.cursorMoveInput(new Vector2(0, -Game1.tileSize)); + } + else if (MainClass.Config.TileCursorRightKey.JustPressed()) + { + this.cursorMoveInput(new Vector2(Game1.tileSize, 0)); + } + else if (MainClass.Config.TileCursorDownKey.JustPressed()) + { + this.cursorMoveInput(new Vector2(0, Game1.tileSize)); + } + else if (MainClass.Config.TileCursorLeftKey.JustPressed()) + { + this.cursorMoveInput(new Vector2(-Game1.tileSize, 0)); + } + } + + + private static bool allowMouseSnap(Vector2 point) + { + if (!Utility.isOnScreen(point, 0)) return false; + + //prevent mousing over the toolbar or any other UI component with the tile cursor + foreach (IClickableMenu menu in Game1.onScreenMenus) + { + if (menu.allClickableComponents == null) continue; + foreach (ClickableComponent component in menu.allClickableComponents) + { + if (component.containsPoint((int)point.X, (int)point.Y)) return false; + } + } + return true; } - - private static bool IsTileOnMap(Vector2 tile) - { - (int width, int height) dimensions = GetMapTileDimensions(); - if (tile.X < 0 || tile.X >= dimensions.width) return false; - if (tile.Y < 0 || tile.Y >= dimensions.height) return false; - return true; } } -} From 838273b3ce1449cc52bcae9d35e0233281ab4c0f Mon Sep 17 00:00:00 2001 From: bradjrenshaw Date: Tue, 10 May 2022 00:05:35 -0400 Subject: [PATCH 06/13] Read blocked or empty tiles if no object is on a tile. --- stardew-access/Features/MouseHandler.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/stardew-access/Features/MouseHandler.cs b/stardew-access/Features/MouseHandler.cs index 5b615f6..b93c96b 100644 --- a/stardew-access/Features/MouseHandler.cs +++ b/stardew-access/Features/MouseHandler.cs @@ -65,10 +65,17 @@ namespace stardew_access.Features { if (!tryMoveTileView(delta)) return; Vector2 position = this.getTileCursorPosition(); - String ?name = TileInfo.getNameAtTile(position / Game1.tileSize); + Vector2 tile = position / Game1.tileSize; + String ?name = TileInfo.getNameAtTile(tile); if (name == null) { - name = "empty tile"; + if (TileInfo.isCollidingAtTile((int)tile.X, (int)tile.Y)) + { + name = "blocked"; + } else + { + name = "empty"; + } } if (precise) { From 332dd858a85dff9372fc3d88877fc8b647520bac Mon Sep 17 00:00:00 2001 From: bradjrenshaw Date: Tue, 10 May 2022 14:21:17 -0400 Subject: [PATCH 07/13] Fixed bug with tile cursor not passing exact integer tile values causing terrain features like crops to not be read out. --- stardew-access/Features/MouseHandler.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/stardew-access/Features/MouseHandler.cs b/stardew-access/Features/MouseHandler.cs index b93c96b..ecdcf7d 100644 --- a/stardew-access/Features/MouseHandler.cs +++ b/stardew-access/Features/MouseHandler.cs @@ -63,9 +63,9 @@ namespace stardew_access.Features private void cursorMoveInput(Vector2 delta, Boolean precise = false) { - if (!tryMoveTileView(delta)) return; + if (!tryMoveTileView(delta)) return; Vector2 position = this.getTileCursorPosition(); - Vector2 tile = position / Game1.tileSize; + Vector2 tile = new Vector2((float)Math.Floor(position.X / Game1.tileSize), (float)Math.Floor(position.Y / Game1.tileSize)); String ?name = TileInfo.getNameAtTile(tile); if (name == null) { @@ -79,7 +79,7 @@ namespace stardew_access.Features } if (precise) { - MainClass.ScreenReader.Say($"{position.X}, {position.Y}", true); + MainClass.ScreenReader.Say($"{name}, {position.X}, {position.Y}", true); } else { @@ -111,6 +111,7 @@ namespace stardew_access.Features public void update() { + //Reset the viewing cursor to the player when they turn or move. This will not reset the locked offset relative cursor position. if (this.prevFacing != this.PlayerFacingVector || this.prevPlayerPosition != this.PlayerPosition) { this.ViewingOffset = Vector2.Zero; @@ -119,6 +120,7 @@ namespace stardew_access.Features this.prevPlayerPosition = this.PlayerPosition; if (MainClass.Config.SnapMouse) this.SnapMouseToPlayer(); + if (MainClass.Config.TileCursorUpKey.JustPressed()) { this.cursorMoveInput(new Vector2(0, -Game1.tileSize)); @@ -137,7 +139,6 @@ namespace stardew_access.Features } } - private static bool allowMouseSnap(Vector2 point) { if (!Utility.isOnScreen(point, 0)) return false; From a8bcaf6cef30fe5832f7be838d9c560459c68aa9 Mon Sep 17 00:00:00 2001 From: bradjrenshaw Date: Tue, 10 May 2022 14:37:43 -0400 Subject: [PATCH 08/13] Refactored keyboard tile cursor input to be triggered at the same time as the rest of keyboard input; fix bug in reading UI components with tile cursor. --- stardew-access/Features/MouseHandler.cs | 43 ++++++++++++------------- stardew-access/ModEntry.cs | 3 ++ 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/stardew-access/Features/MouseHandler.cs b/stardew-access/Features/MouseHandler.cs index ecdcf7d..678b8c4 100644 --- a/stardew-access/Features/MouseHandler.cs +++ b/stardew-access/Features/MouseHandler.cs @@ -61,6 +61,26 @@ namespace stardew_access.Features return target; } + public void HandleInput() + { + if (MainClass.Config.TileCursorUpKey.JustPressed()) + { + this.cursorMoveInput(new Vector2(0, -Game1.tileSize)); + } + else if (MainClass.Config.TileCursorRightKey.JustPressed()) + { + this.cursorMoveInput(new Vector2(Game1.tileSize, 0)); + } + else if (MainClass.Config.TileCursorDownKey.JustPressed()) + { + this.cursorMoveInput(new Vector2(0, Game1.tileSize)); + } + else if (MainClass.Config.TileCursorLeftKey.JustPressed()) + { + this.cursorMoveInput(new Vector2(-Game1.tileSize, 0)); + } + } + private void cursorMoveInput(Vector2 delta, Boolean precise = false) { if (!tryMoveTileView(delta)) return; @@ -120,23 +140,6 @@ namespace stardew_access.Features this.prevPlayerPosition = this.PlayerPosition; if (MainClass.Config.SnapMouse) this.SnapMouseToPlayer(); - - if (MainClass.Config.TileCursorUpKey.JustPressed()) - { - this.cursorMoveInput(new Vector2(0, -Game1.tileSize)); - } - else if (MainClass.Config.TileCursorRightKey.JustPressed()) - { - this.cursorMoveInput(new Vector2(Game1.tileSize, 0)); - } - else if (MainClass.Config.TileCursorDownKey.JustPressed()) - { - this.cursorMoveInput(new Vector2(0, Game1.tileSize)); - } - else if (MainClass.Config.TileCursorLeftKey.JustPressed()) - { - this.cursorMoveInput(new Vector2(-Game1.tileSize, 0)); - } } private static bool allowMouseSnap(Vector2 point) @@ -146,11 +149,7 @@ namespace stardew_access.Features //prevent mousing over the toolbar or any other UI component with the tile cursor foreach (IClickableMenu menu in Game1.onScreenMenus) { - if (menu.allClickableComponents == null) continue; - foreach (ClickableComponent component in menu.allClickableComponents) - { - if (component.containsPoint((int)point.X, (int)point.Y)) return false; - } + if (menu.isWithinBounds((int)point.X - Game1.viewport.X, (int)point.Y - Game1.viewport.Y)) return false; } return true; } diff --git a/stardew-access/ModEntry.cs b/stardew-access/ModEntry.cs index 28c19fe..2dd3899 100644 --- a/stardew-access/ModEntry.cs +++ b/stardew-access/ModEntry.cs @@ -267,6 +267,9 @@ get ReadTile.run(manuallyTriggered: true); return; } + + // Tile viewing cursor keys + Mouse.HandleInput(); } public static void ErrorLog(string message) From c8bf29b6d09c3064120c4617acaf97428632dbc0 Mon Sep 17 00:00:00 2001 From: bradjrenshaw Date: Tue, 10 May 2022 15:09:54 -0400 Subject: [PATCH 09/13] Added precise tile cursor movement (defaults to 8 pixels per key press). --- stardew-access/Features/MouseHandler.cs | 18 +++++++++++++++++- stardew-access/ModConfig.cs | 3 ++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/stardew-access/Features/MouseHandler.cs b/stardew-access/Features/MouseHandler.cs index 678b8c4..33af128 100644 --- a/stardew-access/Features/MouseHandler.cs +++ b/stardew-access/Features/MouseHandler.cs @@ -63,7 +63,23 @@ namespace stardew_access.Features public void HandleInput() { - if (MainClass.Config.TileCursorUpKey.JustPressed()) + if (MainClass.Config.TileCursorPreciseUpKey.JustPressed()) + { + this.cursorMoveInput(new Vector2(0, -MainClass.Config.TileCursorPreciseMovementDistance), true); + } + else if (MainClass.Config.TileCursorPreciseRightKey.JustPressed()) + { + this.cursorMoveInput(new Vector2(MainClass.Config.TileCursorPreciseMovementDistance, 0), true); + } + else if (MainClass.Config.TileCursorPreciseDownKey.JustPressed()) + { + this.cursorMoveInput(new Vector2(0, MainClass.Config.TileCursorPreciseMovementDistance), true); + } + else if (MainClass.Config.TileCursorPreciseLeftKey.JustPressed()) + { + this.cursorMoveInput(new Vector2(-MainClass.Config.TileCursorPreciseMovementDistance, 0), true); + } + else if (MainClass.Config.TileCursorUpKey.JustPressed()) { this.cursorMoveInput(new Vector2(0, -Game1.tileSize)); } diff --git a/stardew-access/ModConfig.cs b/stardew-access/ModConfig.cs index 388d7fd..445fa1b 100644 --- a/stardew-access/ModConfig.cs +++ b/stardew-access/ModConfig.cs @@ -25,6 +25,7 @@ namespace stardew_access public KeybindList TimeNSeasonKey { get; set; } = KeybindList.Parse("Q"); public KeybindList ReadTileKey { get; set; } = KeybindList.Parse("J"); public KeybindList ReadStandingTileKey { get; set; } = KeybindList.Parse("LeftAlt + J"); + public int TileCursorPreciseMovementDistance { get; set; } = 8; //Tile viewer keys public KeybindList TileCursorUpKey { get; set; } = KeybindList.Parse("Up"); @@ -35,7 +36,7 @@ namespace stardew_access public KeybindList TileCursorPreciseRightKey { get; set; } = KeybindList.Parse("LeftShift + Right"); public KeybindList TileCursorPreciseDownKey { get; set; } = KeybindList.Parse("LeftShift + Down"); public KeybindList TileCursorPreciseLeftKey { get; set; } = KeybindList.Parse("LeftShift + Left"); - + public KeybindList ToggleRelativeCursorLockKey { get; set; } = KeybindList.Parse("L"); #endregion // TODO Add the exclusion and focus list too From 955ffac65bbb7cbd5d91e1efcd49df8bfc89dbac Mon Sep 17 00:00:00 2001 From: bradjrenshaw Date: Tue, 10 May 2022 15:22:32 -0400 Subject: [PATCH 10/13] Implementation of relative offset lock (keep mouse in position relative to you as yo umove). --- stardew-access/Features/MouseHandler.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/stardew-access/Features/MouseHandler.cs b/stardew-access/Features/MouseHandler.cs index 33af128..f909ab9 100644 --- a/stardew-access/Features/MouseHandler.cs +++ b/stardew-access/Features/MouseHandler.cs @@ -63,7 +63,18 @@ namespace stardew_access.Features public void HandleInput() { - if (MainClass.Config.TileCursorPreciseUpKey.JustPressed()) + if (MainClass.Config.ToggleRelativeCursorLockKey.JustPressed()) + { + this.relativeOffsetLock = !this.relativeOffsetLock; + if (this.relativeOffsetLock) + { + this.relativeOffsetLockPosition = this.PlayerFacingVector + this.ViewingOffset; + } else { + this.relativeOffsetLockPosition = Vector2.Zero; + } + MainClass.ScreenReader.Say("Relative cursor lock " + (this.relativeOffsetLock ? "enabled" : "disabled") + ".", true); + } + else if (MainClass.Config.TileCursorPreciseUpKey.JustPressed()) { this.cursorMoveInput(new Vector2(0, -MainClass.Config.TileCursorPreciseMovementDistance), true); } From 7a1b768bdbed437bbafaf0691cdf89b6ab971464 Mon Sep 17 00:00:00 2001 From: bradjrenshaw Date: Tue, 10 May 2022 16:31:54 -0400 Subject: [PATCH 11/13] Added option to allow tile cursor to view the entire map regardless if it is visible or not. --- stardew-access/Features/MouseHandler.cs | 13 ++++++++++--- stardew-access/ModConfig.cs | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/stardew-access/Features/MouseHandler.cs b/stardew-access/Features/MouseHandler.cs index f909ab9..a84f52e 100644 --- a/stardew-access/Features/MouseHandler.cs +++ b/stardew-access/Features/MouseHandler.cs @@ -6,7 +6,6 @@ using StardewValley; using StardewValley.Menus; using stardew_access.Features; - namespace stardew_access.Features { public class MouseHandler @@ -137,13 +136,13 @@ namespace stardew_access.Features private bool tryMoveTileView(Vector2 delta) { Vector2 dest = this.getTileCursorPosition() + delta; - if (Utility.isOnScreen(dest, 0)) + if (!isPositionOnMap(dest)) return false; + if ((MainClass.Config.LimitTileCursorToScreen && Utility.isOnScreen(dest, 0)) || !MainClass.Config.LimitTileCursorToScreen) { if (this.relativeOffsetLock) this.relativeOffsetLockPosition += delta; else this.ViewingOffset += delta; - return true; } return false; @@ -180,5 +179,13 @@ namespace stardew_access.Features } return true; } + + private static bool isPositionOnMap(Vector2 position) + { + Map map = Game1.currentLocation.map; + if (position.X < 0 || position.X > map.Layers[0].DisplayWidth) return false; + if (position.Y < 0 || position.Y > map.Layers[0].DisplayHeight) return false; + return true; + } } } diff --git a/stardew-access/ModConfig.cs b/stardew-access/ModConfig.cs index 445fa1b..479c25d 100644 --- a/stardew-access/ModConfig.cs +++ b/stardew-access/ModConfig.cs @@ -25,6 +25,7 @@ namespace stardew_access public KeybindList TimeNSeasonKey { get; set; } = KeybindList.Parse("Q"); public KeybindList ReadTileKey { get; set; } = KeybindList.Parse("J"); public KeybindList ReadStandingTileKey { get; set; } = KeybindList.Parse("LeftAlt + J"); + public bool LimitTileCursorToScreen { get; set; } = false; public int TileCursorPreciseMovementDistance { get; set; } = 8; //Tile viewer keys From 8446049c55c348ccce4d83b9927d8f758b455c6b Mon Sep 17 00:00:00 2001 From: bradjrenshaw Date: Tue, 10 May 2022 16:36:23 -0400 Subject: [PATCH 12/13] Rename MouseHandler to TileViewer for accuracy --- .../Features/{MouseHandler.cs => TileViewer.cs} | 2 +- stardew-access/ModEntry.cs | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) rename stardew-access/Features/{MouseHandler.cs => TileViewer.cs} (99%) diff --git a/stardew-access/Features/MouseHandler.cs b/stardew-access/Features/TileViewer.cs similarity index 99% rename from stardew-access/Features/MouseHandler.cs rename to stardew-access/Features/TileViewer.cs index a84f52e..4d06f8f 100644 --- a/stardew-access/Features/MouseHandler.cs +++ b/stardew-access/Features/TileViewer.cs @@ -8,7 +8,7 @@ using stardew_access.Features; namespace stardew_access.Features { - public class MouseHandler + public class TileViewer { private Vector2 ViewingOffset = Vector2.Zero; diff --git a/stardew-access/ModEntry.cs b/stardew-access/ModEntry.cs index 2dd3899..d46348e 100644 --- a/stardew-access/ModEntry.cs +++ b/stardew-access/ModEntry.cs @@ -20,7 +20,7 @@ namespace stardew_access private static StaticTiles? sTiles; private static IScreenReader? screenReader; private static IModHelper? modHelper; - private static MouseHandler? mouse; + private static TileViewer? tileViewer; internal static ModConfig Config { get => config; set => config = value; } public static IModHelper? ModHelper { get => modHelper; } @@ -64,13 +64,13 @@ namespace stardew_access set => screenReader = value; } - public static MouseHandler Mouse + public static TileViewer TileViewer { get { - if (mouse == null) - mouse = new MouseHandler(); - return mouse; + if (tileViewer == null) + tileViewer = new TileViewer(); + return tileViewer; } } @@ -142,7 +142,8 @@ get // Narrate current location's name Other.narrateCurrentLocation(); - Mouse.update(); + //handle TileCursor update logic + TileViewer.update(); if (!ReadTile.isReadingTile && Config.ReadTile) { @@ -269,7 +270,7 @@ get } // Tile viewing cursor keys - Mouse.HandleInput(); + TileViewer.HandleInput(); } public static void ErrorLog(string message) From 55b9255dc84467af0c9433cb6e4253afd4660869 Mon Sep 17 00:00:00 2001 From: bradjrenshaw Date: Tue, 10 May 2022 16:41:07 -0400 Subject: [PATCH 13/13] Formatting and code cleanup; added documentation and some clarifying comments. --- stardew-access/Features/TileViewer.cs | 59 ++++++++++++++++++++++----- stardew-access/ModEntry.cs | 2 +- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/stardew-access/Features/TileViewer.cs b/stardew-access/Features/TileViewer.cs index 4d06f8f..2b07fde 100644 --- a/stardew-access/Features/TileViewer.cs +++ b/stardew-access/Features/TileViewer.cs @@ -8,9 +8,14 @@ using stardew_access.Features; namespace stardew_access.Features { + + /// + /// Allows browsing of the map and snapping mouse to tiles with the arrow keys + /// public class TileViewer { + //None of these positions take viewport into account; other functions are responsible later private Vector2 ViewingOffset = Vector2.Zero; private Vector2 relativeOffsetLockPosition = Vector2.Zero; private Boolean relativeOffsetLock = false; @@ -46,7 +51,11 @@ namespace stardew_access.Features } } - private Vector2 getTileCursorPosition() + /// + /// Return the position of the tile cursor in pixels from the upper-left corner of the map. + /// + /// Vector2 + public Vector2 GetTileCursorPosition() { Vector2 target = this.PlayerPosition; if (this.relativeOffsetLock) @@ -60,6 +69,19 @@ namespace stardew_access.Features return target; } + /// + /// Return the tile at the position of the tile cursor. + /// + /// Vector2 + public Vector2 GetViewingTile() + { + Vector2 position = this.GetTileCursorPosition(); + return new Vector2((int)position.X / Game1.tileSize, (int)position.Y / Game1.tileSize); + } + + /// + /// Handle keyboard input related to the tile viewer. + /// public void HandleInput() { if (MainClass.Config.ToggleRelativeCursorLockKey.JustPressed()) @@ -68,12 +90,14 @@ namespace stardew_access.Features if (this.relativeOffsetLock) { this.relativeOffsetLockPosition = this.PlayerFacingVector + this.ViewingOffset; - } else { + } + else + { this.relativeOffsetLockPosition = Vector2.Zero; } MainClass.ScreenReader.Say("Relative cursor lock " + (this.relativeOffsetLock ? "enabled" : "disabled") + ".", true); } - else if (MainClass.Config.TileCursorPreciseUpKey.JustPressed()) + else if (MainClass.Config.TileCursorPreciseUpKey.JustPressed()) { this.cursorMoveInput(new Vector2(0, -MainClass.Config.TileCursorPreciseMovementDistance), true); } @@ -109,16 +133,18 @@ namespace stardew_access.Features private void cursorMoveInput(Vector2 delta, Boolean precise = false) { - if (!tryMoveTileView(delta)) return; - Vector2 position = this.getTileCursorPosition(); - Vector2 tile = new Vector2((float)Math.Floor(position.X / Game1.tileSize), (float)Math.Floor(position.Y / Game1.tileSize)); - String ?name = TileInfo.getNameAtTile(tile); + if (!tryMoveTileView(delta)) return; + Vector2 position = this.GetTileCursorPosition(); + Vector2 tile = this.GetViewingTile(); + String? name = TileInfo.getNameAtTile(tile); if (name == null) { + // Report if a tile is empty or blocked if there is nothing on it if (TileInfo.isCollidingAtTile((int)tile.X, (int)tile.Y)) { name = "blocked"; - } else + } + else { name = "empty"; } @@ -135,14 +161,18 @@ namespace stardew_access.Features private bool tryMoveTileView(Vector2 delta) { - Vector2 dest = this.getTileCursorPosition() + delta; + Vector2 dest = this.GetTileCursorPosition() + delta; if (!isPositionOnMap(dest)) return false; if ((MainClass.Config.LimitTileCursorToScreen && Utility.isOnScreen(dest, 0)) || !MainClass.Config.LimitTileCursorToScreen) { if (this.relativeOffsetLock) + { this.relativeOffsetLockPosition += delta; + } else + { this.ViewingOffset += delta; + } return true; } return false; @@ -150,11 +180,15 @@ namespace stardew_access.Features private void SnapMouseToPlayer() { - Vector2 cursorPosition = this.getTileCursorPosition(); - if (allowMouseSnap(cursorPosition)) + Vector2 cursorPosition = this.GetTileCursorPosition(); + if (allowMouseSnap(cursorPosition)) + // Must account for viewport here Game1.setMousePosition((int)cursorPosition.X - Game1.viewport.X, (int)cursorPosition.Y - Game1.viewport.Y); } + /// + /// Handle tile viewer logic. + /// public void update() { //Reset the viewing cursor to the player when they turn or move. This will not reset the locked offset relative cursor position. @@ -170,11 +204,13 @@ namespace stardew_access.Features private static bool allowMouseSnap(Vector2 point) { + // Utility.isOnScreen treats a vector as a pixel position, not a tile position if (!Utility.isOnScreen(point, 0)) return false; //prevent mousing over the toolbar or any other UI component with the tile cursor foreach (IClickableMenu menu in Game1.onScreenMenus) { + //must account for viewport here if (menu.isWithinBounds((int)point.X - Game1.viewport.X, (int)point.Y - Game1.viewport.Y)) return false; } return true; @@ -182,6 +218,7 @@ namespace stardew_access.Features private static bool isPositionOnMap(Vector2 position) { + //position does not take viewport into account since the entire map needs to be checked. Map map = Game1.currentLocation.map; if (position.X < 0 || position.X > map.Layers[0].DisplayWidth) return false; if (position.Y < 0 || position.Y > map.Layers[0].DisplayHeight) return false; diff --git a/stardew-access/ModEntry.cs b/stardew-access/ModEntry.cs index d46348e..28776c4 100644 --- a/stardew-access/ModEntry.cs +++ b/stardew-access/ModEntry.cs @@ -66,7 +66,7 @@ namespace stardew_access public static TileViewer TileViewer { -get + get { if (tileViewer == null) tileViewer = new TileViewer();