diff --git a/src/TerraSharp/Core/Settings.Json.cs b/src/TerraSharp/Core/Settings.Json.cs index ebba47e..61888a0 100644 --- a/src/TerraSharp/Core/Settings.Json.cs +++ b/src/TerraSharp/Core/Settings.Json.cs @@ -88,6 +88,7 @@ public static partial class Settings [nameof(ColTown)] = "Esp.TownNpcs.Color", [nameof(EspBossRainbow)] = "Esp.Bosses.Rainbow", [nameof(ColBoss)] = "Esp.Bosses.Color", + [nameof(EspBossCursor)] = "Esp.Bosses.Cursor", [nameof(EspItems)] = "Esp.Items.Enabled", [nameof(ColItems)] = "Esp.Items.Color", [nameof(EspProjHostile)] = "Esp.HostileProjectiles.Enabled", diff --git a/src/TerraSharp/Core/Settings.cs b/src/TerraSharp/Core/Settings.cs index 53fe4ee..f8bfa7d 100644 --- a/src/TerraSharp/Core/Settings.cs +++ b/src/TerraSharp/Core/Settings.cs @@ -42,7 +42,7 @@ public static partial class Settings public static bool AutoFish, AutoRecast = true, FishEnemies, Sonar; public static bool Esp, EspNames = true, EspHealth = true, EspHealthText, EspDistance, EspLines, EspProjPath = true; - public static bool EspLocal, EspPlayers = true, EspHostile = true, EspCritters, EspTown, EspBossRainbow = true, EspItems, EspProjHostile, EspProjFriendly, EspWaypoints = true; + public static bool EspLocal, EspPlayers = true, EspHostile = true, EspCritters, EspTown, EspBossRainbow = true, EspBossCursor = true, EspItems, EspProjHostile, EspProjFriendly, EspWaypoints = true; public static EspBoxStyle EspStyle; public static float EspThickness = 1f, EspMaxDistance; // tiles, 0 = unlimited public static Color ColLocal = Color.White, ColPlayers = new(70, 200, 255), ColHostile = new(235, 60, 60), ColCritters = new(200, 170, 120), ColTown = new(80, 220, 110), ColBoss = new(255, 120, 40), ColItems = new(255, 210, 70), ColProjHostile = new(255, 80, 200), ColProjFriendly = new(120, 160, 255), ColWaypoint = new(220, 90, 255); diff --git a/src/TerraSharp/UI/MainWindow.Pages.cs b/src/TerraSharp/UI/MainWindow.Pages.cs index 9b44729..89aeb28 100644 --- a/src/TerraSharp/UI/MainWindow.Pages.cs +++ b/src/TerraSharp/UI/MainWindow.Pages.cs @@ -155,6 +155,7 @@ public sealed partial class MainWindow Toggle("Tracers", ref Settings.EspLines); Group("Targets"); + Toggle("Boss cursor", ref Settings.EspBossCursor); ToggleColor("Bosses (Rainbow)", ref Settings.EspBossRainbow, ref Settings.ColBoss, nameof(Settings.ColBoss)); ToggleColor("Critters", ref Settings.EspCritters, ref Settings.ColCritters, nameof(Settings.ColCritters)); ToggleColor("Friendly projectiles", ref Settings.EspProjFriendly, ref Settings.ColProjFriendly, nameof(Settings.ColProjFriendly)); diff --git a/src/TerraSharp/UI/MainWindow.Tooltips.cs b/src/TerraSharp/UI/MainWindow.Tooltips.cs index d99ed43..9bbf979 100644 --- a/src/TerraSharp/UI/MainWindow.Tooltips.cs +++ b/src/TerraSharp/UI/MainWindow.Tooltips.cs @@ -45,6 +45,7 @@ public sealed partial class MainWindow ["Distance"] = "Shown in feet. 1 tile = 2 ft.", ["Tracers"] = "Draws lines from you to each target.", ["Projectile paths"] = "Shows projectile paths until they hit a block or expire.", + ["Boss cursor"] = "Shows off-screen bosses at the screen edge with their map head.", ["Bosses (Rainbow)"] = "Cycles boss colors. Turn off to use the chosen color.", ["Spelunker"] = "Makes ores, gems and treasure glow.", ["Hunter"] = "Makes enemies glow.", diff --git a/src/TerraSharp/Visuals/Esp.cs b/src/TerraSharp/Visuals/Esp.cs index cb0a5e8..d32eab5 100644 --- a/src/TerraSharp/Visuals/Esp.cs +++ b/src/TerraSharp/Visuals/Esp.cs @@ -39,6 +39,46 @@ public static class Esp if (Settings.EspWaypoints) foreach (Waypoint waypoint in Waypoints.Current) Box(spriteBatch, waypoint.Position, _player.width, _player.height, Premultiplied(Settings.ColWaypoint), waypoint.Name, -1, -1, true, true); + if (Settings.EspBossCursor) + DrawBossCursors(spriteBatch); + } + + // Off-screen bosses get their map head and an arrow at the screen edge. + static void DrawBossCursors(SpriteBatch spriteBatch) + { + const float Margin = 40f; + var center = new Vector2(Main.screenWidth / 2f, Main.screenHeight / 2f); + Color color = Premultiplied(Settings.EspBossRainbow ? Rainbow() : Settings.ColBoss); + for (int i = 0; i < Main.maxNPCs; i++) + { + NPC npc = Main.npc[i]; + if (!npc.active) + continue; + + int head = npc.GetBossHeadTextureIndex(); + if (head < 0 && !npc.boss) + continue; + + Vector2 topLeft = Render.ToScreen(npc.position), bottomRight = Render.ToScreen(npc.position + new Vector2(npc.width, npc.height)); + if (bottomRight.X >= 0 && bottomRight.Y >= 0 && topLeft.X <= Main.screenWidth && topLeft.Y <= Main.screenHeight) + continue; + + Vector2 offset = (topLeft + bottomRight) / 2f - center; + float scale = Math.Min((center.X - Margin) / Math.Abs(offset.X), (center.Y - Margin) / Math.Abs(offset.Y)); + Vector2 position = center + offset * scale, direction = Vector2.Normalize(offset), side = new(-direction.Y, direction.X); + + Vector2 tip = position + direction * 28f, back = tip - direction * 10f; + Render.Line(spriteBatch, back + side * 8f, tip, color, 2f); + Render.Line(spriteBatch, back - side * 8f, tip, color, 2f); + + if (GameTextures.Get("NpcHeadBoss", head) is { } texture) + spriteBatch.Draw(texture, position, null, Color.White, npc.GetBossHeadRotation(), new Vector2(texture.Width, texture.Height) / 2f, 1f, npc.GetBossHeadSpriteEffects(), 0f); + else + Render.Fill(spriteBatch, new Rectangle((int)position.X - 6, (int)position.Y - 6, 12, 12), color); + + if (Settings.EspDistance) + Render.TextCenteredAt(spriteBatch, $"{(int)(Vector2.Distance(npc.Center, _player.Center) / 8f)} ft", position.X, position.Y + 18f, color, 0.7f); + } } static void DrawProjectiles(SpriteBatch spriteBatch)