Updated API

master
Mohammad Shoaib 2022-02-13 20:28:37 +05:30
parent 96e5d5a8cc
commit 94d6f38e66
2 changed files with 87 additions and 7 deletions

View File

@ -10,16 +10,49 @@ namespace stardew_access.ScreenReader
{ {
} }
/// <summary>
/// Search the area using Breadth First Search algorithm(BFS).
/// </summary>
/// <param name="center">The starting point.</param>
/// <param name="limit">The limiting factor or simply radius of the search area.</param>
/// <returns>A dictionary with all the detected tiles along with the name of the object on it and it's category.</returns>
public Dictionary<Vector2, (string, string)> SearchNearbyTiles(Vector2 center, int limit)
{
/*
* How to use the Dictionary to get the name and category of a tile:-
*
* string? objectName = detectedTiles.GetValueOrDefault(center).Item1;
* string? objectCategory = detectedTiles.GetValueOrDefault(center).Item2;
*
* Here detectedTiles is the Dictionary returned by this method
*/
return new Radar().SearchNearbyTiles(center, limit, false);
}
/// <summary>
/// Check the tile for any object
/// </summary>
/// <param name="tile">The tile where we want to check the name and category of object if any</param>
/// <returns>Name of the object as the first item (Item1) and category as the second item (Item2). Returns null if no object found.</returns>
public (string?, string?) GetNameWithCategoryNameAtTile(Vector2 tile) public (string?, string?) GetNameWithCategoryNameAtTile(Vector2 tile)
{ {
return ReadTile.getNameWithCategoryNameAtTile(tile); return ReadTile.getNameWithCategoryNameAtTile(tile);
} }
/// <summary>
/// Check the tile for any object
/// </summary>
/// <param name="tile">The tile where we want to check the name and category of object if any</param>
/// <returns>Name of the object. Returns null if no object found.</returns>
public string? GetNameAtTile(Vector2 tile) public string? GetNameAtTile(Vector2 tile)
{ {
return ReadTile.getNameAtTile(tile); return ReadTile.getNameAtTile(tile);
} }
/// <summary>Speaks the text via the loaded screen reader (if any).</summary>
/// <param name="text">The text to be narrated.</param>
/// <param name="interrupt">Whether to skip the currently speaking text or not.</param>
public void Say(String text, Boolean interrupt) public void Say(String text, Boolean interrupt)
{ {
if (MainClass.GetScreenReader() == null) if (MainClass.GetScreenReader() == null)
@ -28,6 +61,10 @@ namespace stardew_access.ScreenReader
MainClass.GetScreenReader().Say(text, interrupt); MainClass.GetScreenReader().Say(text, interrupt);
} }
/// <summary>Speaks the text via the loaded screen reader (if any).
/// <br/>Skips the text narration if the previously narrated text was the same as the one provided.</summary>
/// <param name="text">The text to be narrated.</param>
/// <param name="interrupt">Whether to skip the currently speaking text or not.</param>
public void SayWithChecker(String text, Boolean interrupt) public void SayWithChecker(String text, Boolean interrupt)
{ {
if (MainClass.GetScreenReader() == null) if (MainClass.GetScreenReader() == null)
@ -36,6 +73,11 @@ namespace stardew_access.ScreenReader
MainClass.GetScreenReader().SayWithChecker(text, interrupt); MainClass.GetScreenReader().SayWithChecker(text, interrupt);
} }
/// <summary>Speaks the text via the loaded screen reader (if any).
/// <br/>Skips the text narration if the previously narrated text was the same as the one provided.
/// <br/><br/>Use this when narrating hovered component in menus to avoid interference.</summary>
/// <param name="text">The text to be narrated.</param>
/// <param name="interrupt">Whether to skip the currently speaking text or not.</param>
public void SayWithMenuChecker(String text, Boolean interrupt) public void SayWithMenuChecker(String text, Boolean interrupt)
{ {
if (MainClass.GetScreenReader() == null) if (MainClass.GetScreenReader() == null)
@ -44,6 +86,11 @@ namespace stardew_access.ScreenReader
MainClass.GetScreenReader().SayWithMenuChecker(text, interrupt); MainClass.GetScreenReader().SayWithMenuChecker(text, interrupt);
} }
/// <summary>Speaks the text via the loaded screen reader (if any).
/// <br/>Skips the text narration if the previously narrated text was the same as the one provided.
/// <br/><br/>Use this when narrating chat messages to avoid interference.</summary>
/// <param name="text">The text to be narrated.</param>
/// <param name="interrupt">Whether to skip the currently speaking text or not.</param>
public void SayWithChatChecker(String text, Boolean interrupt) public void SayWithChatChecker(String text, Boolean interrupt)
{ {
if (MainClass.GetScreenReader() == null) if (MainClass.GetScreenReader() == null)
@ -52,6 +99,13 @@ namespace stardew_access.ScreenReader
MainClass.GetScreenReader().SayWithChatChecker(text, interrupt); MainClass.GetScreenReader().SayWithChatChecker(text, interrupt);
} }
/// <summary>Speaks the text via the loaded screen reader (if any).
/// <br/>Skips the text narration if the previously narrated text was the same as the one provided.
/// <br/><br/>Use this when narrating texts based on tile position to avoid interference.</summary>
/// <param name="text">The text to be narrated.</param>
/// <param name="x">The X location of tile.</param>
/// <param name="y">The Y location of tile.</param>
/// <param name="interrupt">Whether to skip the currently speaking text or not.</param>
public void SayWithTileQuery(String text, int x, int y, Boolean interrupt) public void SayWithTileQuery(String text, int x, int y, Boolean interrupt)
{ {
if (MainClass.GetScreenReader() == null) if (MainClass.GetScreenReader() == null)

View File

@ -108,7 +108,7 @@ namespace stardew_access.Features
furnitures.Clear(); furnitures.Clear();
npcs.Clear(); npcs.Clear();
BFS(currPosition, range); SearchNearbyTiles(currPosition, range);
if (MainClass.radarDebug) if (MainClass.radarDebug)
MainClass.GetMonitor().Log($"\nRead Tile stopped\n\n", StardewModdingAPI.LogLevel.Debug); MainClass.GetMonitor().Log($"\nRead Tile stopped\n\n", StardewModdingAPI.LogLevel.Debug);
@ -122,8 +122,12 @@ namespace stardew_access.Features
/// </summary> /// </summary>
/// <param name="center">The starting point.</param> /// <param name="center">The starting point.</param>
/// <param name="limit">The limiting factor or simply radius of the search area.</param> /// <param name="limit">The limiting factor or simply radius of the search area.</param>
public void BFS(Vector2 center, int limit) /// <param name="playSound">True by default if False then it will not play sound and only return the list of detected tiles(for api).</param>
/// <returns>A dictionary with all the detected tiles along with the name of the object on it and it's category.</returns>
public Dictionary<Vector2, (string, string)> SearchNearbyTiles(Vector2 center, int limit, bool playSound = true)
{ {
Dictionary<Vector2, (string, string)> detectedTiles = new Dictionary<Vector2, (string, string)>();
Queue<Vector2> toSearch = new Queue<Vector2>(); Queue<Vector2> toSearch = new Queue<Vector2>();
List<Vector2> searched = new List<Vector2>(); List<Vector2> searched = new List<Vector2>();
int[] dirX = { -1, 0, 1, 0 }; int[] dirX = { -1, 0, 1, 0 };
@ -136,7 +140,17 @@ namespace stardew_access.Features
while (toSearch.Count > 0) while (toSearch.Count > 0)
{ {
Vector2 item = toSearch.Dequeue(); Vector2 item = toSearch.Dequeue();
CheckTile(item); if (playSound)
CheckTileAndPlaySound(item);
else
{
(bool, string?, string) tileInfo = CheckTile(item);
if (tileInfo.Item1 && tileInfo.Item2 != null)
{
// Add detected tile to the dictionary
detectedTiles.Add(item, (tileInfo.Item2, tileInfo.Item3));
}
}
count++; count++;
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
@ -151,6 +165,7 @@ namespace stardew_access.Features
} }
} }
return detectedTiles;
} }
/// <summary> /// <summary>
@ -160,7 +175,7 @@ namespace stardew_access.Features
/// <param name="center">The starting point of the search.</param> /// <param name="center">The starting point of the search.</param>
/// <param name="searched">The list of searched items.</param> /// <param name="searched">The list of searched items.</param>
/// <param name="limit">The radius of search</param> /// <param name="limit">The radius of search</param>
/// <returns></returns> /// <returns>Returns true if the tile is valid for search.</returns>
public bool isValid(Vector2 item, Vector2 center, List<Vector2> searched, int limit) public bool isValid(Vector2 item, Vector2 center, List<Vector2> searched, int limit)
{ {
if (Math.Abs(item.X - center.X) > limit) if (Math.Abs(item.X - center.X) > limit)
@ -174,12 +189,23 @@ namespace stardew_access.Features
return true; return true;
} }
public void CheckTile(Vector2 position) public (bool, string?, string) CheckTile(Vector2 position)
{
(string?, CATEGORY?) tileDetail = ReadTile.getNameWithCategoryAtTile(position);
if (tileDetail.Item1 == null)
return (false, null, CATEGORY.Others.ToString());
if (tileDetail.Item2 == null)
tileDetail.Item2 = CATEGORY.Others;
return (true, tileDetail.Item1, tileDetail.Item2.ToString());
}
public void CheckTileAndPlaySound(Vector2 position)
{ {
try try
{ {
Dictionary<Vector2, Netcode.NetRef<TerrainFeature>> terrainFeature = Game1.currentLocation.terrainFeatures.FieldDict;
if (Game1.currentLocation.isObjectAtTile((int)position.X, (int)position.Y)) if (Game1.currentLocation.isObjectAtTile((int)position.X, (int)position.Y))
{ {
(string?, CATEGORY) objDetails = ReadTile.getObjectAtTile((int)position.X, (int)position.Y); (string?, CATEGORY) objDetails = ReadTile.getObjectAtTile((int)position.X, (int)position.Y);