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; } } -}