From f84ad4faebe823da52fe281a88a66ccc8762e2f8 Mon Sep 17 00:00:00 2001 From: LeonardoVAC Date: Fri, 16 Oct 2026 00:38:59 -0300 Subject: [PATCH] feat: Add chest finder ESP --- src/TerraSharp/Core/Hotkeys.cs | 1 + src/TerraSharp/Core/Settings.Json.cs | 5 ++- src/TerraSharp/Core/Settings.cs | 8 +++-- src/TerraSharp/UI/MainWindow.Pages.cs | 9 ++++++ src/TerraSharp/UI/MainWindow.Tooltips.cs | 2 ++ src/TerraSharp/UI/WindowManager.cs | 3 +- src/TerraSharp/Visuals/Esp.cs | 40 ++++++++++++++++++++++++ 7 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/TerraSharp/Core/Hotkeys.cs b/src/TerraSharp/Core/Hotkeys.cs index adf48ea..27c9b42 100644 --- a/src/TerraSharp/Core/Hotkeys.cs +++ b/src/TerraSharp/Core/Hotkeys.cs @@ -76,6 +76,7 @@ public static class Hotkeys Toggle("Visuals", "Shine", "Shine", () => Settings.Shine, v => Settings.Shine = v), Toggle("Visuals", "FullBright", "Full Bright", () => Settings.FullBright, v => Settings.FullBright = v), Toggle("Visuals", "ExtendedZoom", "Extended Zoom", () => Settings.ExtendedZoom, v => Settings.ExtendedZoom = v), + Toggle("Visuals", "ChestFinder", "Chest Finder", () => Settings.EspChests, v => Settings.EspChests = v), Toggle("World", "FreezeTime", "Freeze Time", () => Settings.FreezeTime, v => Settings.FreezeTime = v), Toggle("World", "SpawnRate", "Spawn Rate", () => Settings.SpawnRateBoost, v => Settings.SpawnRateBoost = v), diff --git a/src/TerraSharp/Core/Settings.Json.cs b/src/TerraSharp/Core/Settings.Json.cs index 7c1f2c4..6bc6683 100644 --- a/src/TerraSharp/Core/Settings.Json.cs +++ b/src/TerraSharp/Core/Settings.Json.cs @@ -101,6 +101,9 @@ public static partial class Settings [nameof(ColProjFriendly)] = "Esp.FriendlyProjectiles.Color", [nameof(EspWaypoints)] = "Esp.Waypoints.Enabled", [nameof(ColWaypoint)] = "Esp.Waypoints.Color", + [nameof(EspChests)] = "Esp.Chests.Enabled", + [nameof(ColChests)] = "Esp.Chests.Color", + [nameof(EspChestsListed)] = "Esp.Chests.OnlyListed", [nameof(DamageMelee)] = "DamageNumbers.Melee.Enabled", [nameof(ColDamageMelee)] = "DamageNumbers.Melee.Color", @@ -128,7 +131,7 @@ public static partial class Settings [nameof(LogBallistics)] = "Ballistics.Log", }; - static readonly string[] ListPaths = ["Items.AutoSell.Items"]; + static readonly string[] ListPaths = ["Items.AutoSell.Items", "Esp.Chests.Items"]; static void SetValue(Dictionary document, string path, object value) { diff --git a/src/TerraSharp/Core/Settings.cs b/src/TerraSharp/Core/Settings.cs index ece8938..d3ba91f 100644 --- a/src/TerraSharp/Core/Settings.cs +++ b/src/TerraSharp/Core/Settings.cs @@ -43,10 +43,11 @@ 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, EspBossCursor = 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, EspChests, EspChestsListed; + public static readonly HashSet ChestList = []; 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); + 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), ColChests = new(240, 170, 60); public static bool DamageMelee, DamageRanged, DamageMagic, DamageSummon; public static Color ColDamageMelee = new(255, 110, 60), ColDamageRanged = new(120, 230, 90), ColDamageMagic = new(90, 150, 255), ColDamageSummon = new(200, 110, 255); public static bool Spelunker, Hunter, Shine, NightOwl, DangerSense, BiomeSight, FullBright, ExtendedZoom; @@ -97,6 +98,7 @@ public static partial class Settings document["Binds"] = binds; SetValue(document, ListPaths[0], SortedList(SellList)); + SetValue(document, ListPaths[1], SortedList(ChestList)); var windows = new Dictionary(); foreach (Window window in WindowManager.All) @@ -128,6 +130,7 @@ public static partial class Settings TryLoad(setting.Value, () => Apply(setting.Key, Convert.ToString(value, CultureInfo.InvariantCulture) ?? "")); LoadList(document, ListPaths[0], SellList); + LoadList(document, ListPaths[1], ChestList); foreach (KeyValuePair bind in Section(document, "Binds")) TryLoad("Binds." + bind.Key, () => Binds[bind.Key] = (Keys)Enum.Parse(typeof(Keys), (string)bind.Value)); @@ -231,6 +234,7 @@ public static partial class Settings foreach (KeyValuePair pair in Defaults) typeof(Settings).GetField(pair.Key)!.SetValue(null, pair.Value); SellList.Clear(); + ChestList.Clear(); } public static string Hex(Color color) => $"{color.R:X2}{color.G:X2}{color.B:X2}{color.A:X2}"; diff --git a/src/TerraSharp/UI/MainWindow.Pages.cs b/src/TerraSharp/UI/MainWindow.Pages.cs index 5b2c719..e62de77 100644 --- a/src/TerraSharp/UI/MainWindow.Pages.cs +++ b/src/TerraSharp/UI/MainWindow.Pages.cs @@ -171,6 +171,15 @@ public sealed partial class MainWindow Group("Targets"); Toggle("Boss cursor", ref Settings.EspBossCursor); ToggleColor("Bosses (Rainbow)", ref Settings.EspBossRainbow, ref Settings.ColBoss, nameof(Settings.ColBoss)); + ToggleColor("Chests", ref Settings.EspChests, ref Settings.ColChests, nameof(Settings.ColChests)); + if (Settings.EspChests) + Sub(() => + { + if (Toggle("Only with listed items", ref Settings.EspChestsListed)) + Note($"{Settings.ChestList.Count} items listed. Multiplayer: only opened chests."); + if (Buttons(WindowManager.ChestList.Open ? "Close Item List" : "Edit Item List") == 0) + WindowManager.Toggle(WindowManager.ChestList); + }); ToggleColor("Critters", ref Settings.EspCritters, ref Settings.ColCritters, nameof(Settings.ColCritters)); ToggleColor("Friendly projectiles", ref Settings.EspProjFriendly, ref Settings.ColProjFriendly, nameof(Settings.ColProjFriendly)); ToggleColor("Ground items", ref Settings.EspItems, ref Settings.ColItems, nameof(Settings.ColItems)); diff --git a/src/TerraSharp/UI/MainWindow.Tooltips.cs b/src/TerraSharp/UI/MainWindow.Tooltips.cs index ef81ed9..8a8fb12 100644 --- a/src/TerraSharp/UI/MainWindow.Tooltips.cs +++ b/src/TerraSharp/UI/MainWindow.Tooltips.cs @@ -59,6 +59,8 @@ public sealed partial class MainWindow ["Biome Sight"] = "Makes Corruption, Crimson and Hallow blocks glow.", ["Full Bright"] = "Lights everything at full brightness.", ["Extended Zoom"] = "Zoom in up to 8x and out until the edge of what the game draws.", + ["Chests"] = "Marks chests. Their contents can be filtered with an item list.", + ["Only with listed items"] = "Only marks chests holding an item from the list.", ["Map Teleport"] = "Right-click the fullscreen map to teleport there.", ["Reveal Map"] = "Reveals the whole map. Multiplayer only reveals areas the server has sent.", ["Full Heal"] = "Refills health and mana.", diff --git a/src/TerraSharp/UI/WindowManager.cs b/src/TerraSharp/UI/WindowManager.cs index c630096..0e64603 100644 --- a/src/TerraSharp/UI/WindowManager.cs +++ b/src/TerraSharp/UI/WindowManager.cs @@ -16,11 +16,12 @@ public static class WindowManager public static readonly NpcBrowser Npcs = new(); public static readonly ItemEditor Editor = new(); public static readonly ItemPicker SellList = new("sellList", "Auto Sell List", new Vector2(680, 130), Settings.SellList); + public static readonly ItemPicker ChestList = new("chestList", "Chest Finder Items", new Vector2(700, 140), Settings.ChestList); const int TitleHeight = 40; const int MaxInputLength = 40; - static readonly List Stack = [Items, Buffs, Npcs, Editor, SellList, Menu]; + static readonly List Stack = [Items, Buffs, Npcs, Editor, SellList, ChestList, Menu]; static Window? _dragging; static Vector2 _dragOffset; diff --git a/src/TerraSharp/Visuals/Esp.cs b/src/TerraSharp/Visuals/Esp.cs index d32eab5..dd8696c 100644 --- a/src/TerraSharp/Visuals/Esp.cs +++ b/src/TerraSharp/Visuals/Esp.cs @@ -36,6 +36,8 @@ public static class Esp DrawNpcs(spriteBatch); if (Settings.EspItems) DrawItems(spriteBatch); + if (Settings.EspChests) + DrawChests(spriteBatch); 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); @@ -156,6 +158,44 @@ public static class Esp } } + // Multiplayer clients only know the contents of chests they have opened. + static void DrawChests(SpriteBatch spriteBatch) + { + Color color = Premultiplied(Settings.ColChests); + for (int i = 0; i < Main.maxChests; i++) + { + Chest? chest = Main.chest[i]; + if (chest is not null && ChestLabel(chest) is { } label) + Box(spriteBatch, new Vector2(chest.x * 16, chest.y * 16), 32, 32, color, label, -1, -1, true, true); + } + } + + static string? ChestLabel(Chest chest) + { + string name = string.IsNullOrEmpty(chest.name) ? "Chest" : chest.name; + if (!Settings.EspChestsListed) + return name; + if (chest.item is null) + return null; + + Item? first = null; + int matches = 0; + foreach (Item? item in chest.item) + { + if (item is null || item.type == 0 || !Settings.ChestList.Contains(item.type)) + continue; + + first ??= item; + matches++; + } + + if (first is null) + return null; + + string found = first.stack > 1 ? $"{first.Name} x{first.stack}" : first.Name; + return matches > 1 ? $"{name}: {found} +{matches - 1}" : $"{name}: {found}"; + } + // Anchors and scale match Main.DrawInterface_14_EntityHealthBars. static (Vector2 Position, float Scale) NpcBar(NPC npc) {