From 8c17c38585e318de8daf31629f74b182042863bc Mon Sep 17 00:00:00 2001 From: Jewel Date: Tue, 2 Aug 2022 05:44:07 +0100 Subject: [PATCH] Working 1.4 upgrade --- {UIElements => Images}/spacer.png | Bin ItemChecklist.cs | 33 +- ItemChecklist.csproj | 109 +---- ItemChecklist.sln | 22 + ItemChecklistClientConfig.cs | 43 ++ ItemChecklistGlobalItem.cs | 8 +- ItemChecklistPlayer.cs | 50 ++- ItemChecklistUI.cs | 104 +++-- MagicStorageIntegration.cs | 7 +- SharedUI.cs | 594 ++++++++++++++++--------- UIElements/NewUITextBox.cs | 8 +- UIElements/UIBottomlessPanel.cs | 60 +++ UIElements/UICheckbox.cs | 83 ++-- UIElements/UIDragableElement.cs | 162 +++++++ UIElements/UIGrid.cs | 76 ++-- UIElements/UIHorizontalGrid.cs | 17 +- UIElements/UIHorizontalScrollbar.cs | 9 +- UIElements/UIItemSlot.cs | 269 +++++++---- UIElements/UISilentImageButton.cs | 52 ++- UIElements/UIToggleHoverImageButton.cs | 6 +- Utilities.cs | 131 +++++- 21 files changed, 1291 insertions(+), 552 deletions(-) rename {UIElements => Images}/spacer.png (100%) create mode 100644 ItemChecklist.sln create mode 100644 ItemChecklistClientConfig.cs create mode 100644 UIElements/UIBottomlessPanel.cs create mode 100644 UIElements/UIDragableElement.cs diff --git a/UIElements/spacer.png b/Images/spacer.png similarity index 100% rename from UIElements/spacer.png rename to Images/spacer.png diff --git a/ItemChecklist.cs b/ItemChecklist.cs index c2a1093..d614b35 100644 --- a/ItemChecklist.cs +++ b/ItemChecklist.cs @@ -1,7 +1,9 @@ using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; using Terraria; +using Terraria.GameContent; using Terraria.ModLoader; using Terraria.UI; @@ -15,7 +17,7 @@ namespace ItemChecklist public class ItemChecklist : Mod { static internal ItemChecklist instance; - internal static ModHotKey ToggleChecklistHotKey; + internal static ModKeybind ToggleChecklistHotKey; internal static UserInterface ItemChecklistInterface; internal ItemChecklistUI ItemChecklistUI; internal event Action OnNewItem; @@ -27,21 +29,21 @@ namespace ItemChecklist public override void Load() { // Latest uses ItemID.Sets.IsAMaterial, added 0.10.1.5 - if (ModLoader.version < new Version(0, 10, 1, 5)) + if (BuildInfo.tMLVersion < new Version(0, 10, 1, 5)) { throw new Exception("\nThis mod uses functionality only present in the latest tModLoader. Please update tModLoader to use this mod\n\n"); } instance = this; - ToggleChecklistHotKey = RegisterHotKey("Toggle Item Checklist", "I"); + ToggleChecklistHotKey = KeybindLoader.RegisterKeybind(this, "Toggle Item Checklist", "I"); MagicStorageIntegration.Load(); if (!Main.dedServ) { - UIElements.UICheckbox.checkboxTexture = GetTexture("UIElements/checkBox"); - UIElements.UICheckbox.checkmarkTexture = GetTexture("UIElements/checkMark"); - UIElements.UIHorizontalGrid.moreLeftTexture = GetTexture("UIElements/MoreLeft"); - UIElements.UIHorizontalGrid.moreRightTexture = GetTexture("UIElements/MoreRight"); + UIElements.UICheckbox.checkboxTexture = ItemChecklist.instance.Assets.Request("UIElements/checkBox"); + UIElements.UICheckbox.checkmarkTexture = ItemChecklist.instance.Assets.Request("UIElements/checkMark"); + UIElements.UIHorizontalGrid.moreLeftTexture = ItemChecklist.instance.Assets.Request("UIElements/MoreLeft"); + UIElements.UIHorizontalGrid.moreRightTexture = ItemChecklist.instance.Assets.Request("UIElements/MoreRight"); } } @@ -83,7 +85,7 @@ namespace ItemChecklist { return "NotInGame"; } - return Main.LocalPlayer.GetModPlayer(this).foundItem; + return Main.LocalPlayer.GetModPlayer().foundItem; } else if (message == "RegisterForNewItem") { @@ -93,12 +95,12 @@ namespace ItemChecklist } else { - ErrorLogger.Log("ItemChecklist Call Error: Unknown Message: " + message); + Logger.Error("ItemChecklist Call Error: Unknown Message: " + message); } } catch (Exception e) { - ErrorLogger.Log("ItemChecklist Call Error: " + e.StackTrace + e.Message); + Logger.Error("ItemChecklist Call Error: " + e.StackTrace + e.Message); } return "Failure"; } @@ -107,10 +109,13 @@ namespace ItemChecklist { OnNewItem?.Invoke(type); } + } + public class ItemChecklistSystem : ModSystem + { public override void UpdateUI(GameTime gameTime) { - ItemChecklistInterface?.Update(gameTime); + ItemChecklist.ItemChecklistInterface?.Update(gameTime); } public override void ModifyInterfaceLayers(List layers) @@ -124,11 +129,11 @@ namespace ItemChecklist { if (ItemChecklistUI.Visible) { - ItemChecklistInterface?.Draw(Main.spriteBatch, new GameTime()); + ItemChecklist.ItemChecklistInterface?.Draw(Main.spriteBatch, new GameTime()); if (ItemChecklistUI.hoverText != "") { - float x = Main.fontMouseText.MeasureString(ItemChecklistUI.hoverText).X; + float x = FontAssets.MouseText.Value.MeasureString(ItemChecklistUI.hoverText).X; Vector2 vector = new Vector2((float)Main.mouseX, (float)Main.mouseY) + new Vector2(16f, 16f); if (vector.Y > (float)(Main.screenHeight - 30)) { @@ -138,7 +143,7 @@ namespace ItemChecklist { vector.X = (float)(Main.screenWidth - x - 30); } - Utils.DrawBorderStringFourWay(Main.spriteBatch, Main.fontMouseText, ItemChecklistUI.hoverText, vector.X, vector.Y, new Color((int)Main.mouseTextColor, (int)Main.mouseTextColor, (int)Main.mouseTextColor, (int)Main.mouseTextColor), Color.Black, Vector2.Zero, 1f); + Utils.DrawBorderStringFourWay(Main.spriteBatch, FontAssets.MouseText.Value, ItemChecklistUI.hoverText, vector.X, vector.Y, new Color((int)Main.mouseTextColor, (int)Main.mouseTextColor, (int)Main.mouseTextColor, (int)Main.mouseTextColor), Color.Black, Vector2.Zero, 1f); } } diff --git a/ItemChecklist.csproj b/ItemChecklist.csproj index 7e19dd2..3e0a7bf 100644 --- a/ItemChecklist.csproj +++ b/ItemChecklist.csproj @@ -1,109 +1,14 @@ - - - + + + - Debug - AnyCPU - {F067608B-12F3-49DA-9CF6-6CC5199923CE} - Library - Properties - ItemChecklist ItemChecklist - v4.6 - 512 - true - - - + net6.0 AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - + latest - - lib\MagicStorage_v0.4.3.1.dll - - - ..\..\solutiondlls\Microsoft.Xna.Framework.dll - - - ..\..\solutiondlls\Microsoft.Xna.Framework.Game.dll - - - ..\..\solutiondlls\Microsoft.Xna.Framework.Graphics.dll - - - ..\..\solutiondlls\Microsoft.Xna.Framework.Xact.dll - - - ..\..\..\Modding\tModLoader\references\ReLogic.dll - - - - - - - - - - - False - C:\Program Files (x86)\Steam\steamapps\common\Terraria\Terraria.exe - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - "C:\Program Files (x86)\Steam\steamapps\common\Terraria\tModLoaderServer.exe" -build "$(ProjectDir)\" -eac "$(TargetPath)" - - \ No newline at end of file diff --git a/ItemChecklist.sln b/ItemChecklist.sln new file mode 100644 index 0000000..55973a4 --- /dev/null +++ b/ItemChecklist.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ItemChecklist", "ItemChecklist.csproj", "{08602B6C-8E82-4BB4-A76A-606DF190C754}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {08602B6C-8E82-4BB4-A76A-606DF190C754}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {08602B6C-8E82-4BB4-A76A-606DF190C754}.Debug|Any CPU.Build.0 = Debug|Any CPU + {08602B6C-8E82-4BB4-A76A-606DF190C754}.Release|Any CPU.ActiveCfg = Release|Any CPU + {08602B6C-8E82-4BB4-A76A-606DF190C754}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/ItemChecklistClientConfig.cs b/ItemChecklistClientConfig.cs new file mode 100644 index 0000000..fff9fa3 --- /dev/null +++ b/ItemChecklistClientConfig.cs @@ -0,0 +1,43 @@ +using Microsoft.Xna.Framework; +using System.ComponentModel; +using System.Reflection; +using Terraria.ModLoader; +using Terraria.ModLoader.Config; + +namespace ItemChecklist +{ + class ItemChecklistClientConfig : ModConfig + { + public override ConfigScope Mode => ConfigScope.ClientSide; + + [DefaultValue(true)] + [Label("Show Item Mod Source")] + [Tooltip("Show which mod adds which item in the recipe catalog. Disable for immersion.")] + public bool ShowItemModSource { get; set; } + + [Header("Automatic Settings")] + // non-player specific stuff: + + [DefaultValue(typeof(Vector2), "475, 350")] + [Range(0f, 1920f)] + [Label("Item Checklist Size")] + [Tooltip("Size of the Item Checklist UI. This will automatically save, no need to adjust")] + public Vector2 ItemChecklistSize { get; set; } + + [DefaultValue(typeof(Vector2), "400, 400")] + [Range(0f, 1920f)] + [Label("Item Checklist Poisition")] + [Tooltip("Position of the Item Checklist UI. This will automatically save, no need to adjust")] + public Vector2 ItemChecklistPosition { get; set; } + + internal static void SaveConfig() { + // in-game ModConfig saving from mod code is not supported yet in tmodloader, and subject to change, so we need to be extra careful. + // This code only supports client configs, and doesn't call onchanged. It also doesn't support ReloadRequired or anything else. + MethodInfo saveMethodInfo = typeof(ConfigManager).GetMethod("Save", BindingFlags.Static | BindingFlags.NonPublic); + if (saveMethodInfo != null) + saveMethodInfo.Invoke(null, new object[] { ModContent.GetInstance() }); + else + ItemChecklist.instance.Logger.Warn("In-game SaveConfig failed, code update required"); + } + } +} \ No newline at end of file diff --git a/ItemChecklistGlobalItem.cs b/ItemChecklistGlobalItem.cs index 81bad06..66cc430 100644 --- a/ItemChecklistGlobalItem.cs +++ b/ItemChecklistGlobalItem.cs @@ -6,9 +6,11 @@ namespace ItemChecklist class ItemChecklistGlobalItem : GlobalItem { // OnPIckup only called on LocalPlayer: I think - public override void OnCraft(Item item, Recipe recipe) + public override void OnCreate(Item item, ItemCreationContext context) { - ItemReceived(item); + if (context is RecipeCreationContext rContext) { + ItemReceived(item); + } } // OnPIckup only called on LocalPlayer: i == Main.myPlayer @@ -21,7 +23,7 @@ namespace ItemChecklist // TODO, unloaded items, check against?? internal void ItemReceived(Item item) { - var itemChecklistPlayer = Main.LocalPlayer.GetModPlayer(mod); + var itemChecklistPlayer = Main.LocalPlayer.GetModPlayer(); if (!itemChecklistPlayer.foundItem[item.type] && itemChecklistPlayer.findableItems[item.type]) { Item newItem = new Item(); diff --git a/ItemChecklistPlayer.cs b/ItemChecklistPlayer.cs index dd15378..b87fb17 100644 --- a/ItemChecklistPlayer.cs +++ b/ItemChecklistPlayer.cs @@ -54,7 +54,7 @@ namespace ItemChecklist public override void OnEnterWorld(Player player) { - var itemChecklistPlayer = Main.LocalPlayer.GetModPlayer(mod); + var itemChecklistPlayer = Main.LocalPlayer.GetModPlayer(); ItemChecklistUI.Visible = false; ItemChecklistUI.announce = announcePreference; ItemChecklistUI.collectChestItems = findChestItemsPreference; @@ -100,32 +100,39 @@ namespace ItemChecklist private void ChestCheck() { - if (!Main.dedServ && player.whoAmI == Main.myPlayer) + if (!Main.dedServ && Player.whoAmI == Main.myPlayer) { for (int i = 0; i < 59; i++) { - if (!player.inventory[i].IsAir && !foundItem[player.inventory[i].type] && findableItems[player.inventory[i].type]) + if (!Player.inventory[i].IsAir && !foundItem[Player.inventory[i].type] && findableItems[Player.inventory[i].type]) { - mod.GetGlobalItem().ItemReceived(player.inventory[i]); // TODO: Analyze performance impact? do every 60 frames only? + // Looping because.. nervous that there might be more than one somehow? + foreach (ItemChecklistGlobalItem item in Mod.GetContent()) + { + item.ItemReceived(Player.inventory[i]); // TODO: Analyze performance impact? do every 60 frames only? + } } } - if (player.chest != -1 && (player.chest != player.lastChest || Main.autoPause && Main.gamePaused) && ItemChecklistUI.collectChestItems) + if (Player.chest != -1 && (Player.chest != Player.lastChest || Main.autoPause && Main.gamePaused) && ItemChecklistUI.collectChestItems) { //Main.NewText(player.chest + " " + player.lastChest); Item[] items; - if (player.chest == -2) - items = player.bank.item; - else if (player.chest == -3) - items = player.bank2.item; - else if (player.chest == -4) - items = player.bank3.item; + if (Player.chest == -2) + items = Player.bank.item; + else if (Player.chest == -3) + items = Player.bank2.item; + else if (Player.chest == -4) + items = Player.bank3.item; else - items = Main.chest[player.chest].item; + items = Main.chest[Player.chest].item; for (int i = 0; i < 40; i++) { if (!items[i].IsAir && !foundItem[items[i].type] && findableItems[items[i].type]) { - mod.GetGlobalItem().ItemReceived(items[i]); + foreach (ItemChecklistGlobalItem item in Mod.GetContent()) + { + item.ItemReceived(items[i]); + } } } } @@ -134,20 +141,17 @@ namespace ItemChecklist } } - public override TagCompound Save() + public override void SaveData(TagCompound tag) { // sanitize? should be possible to add item already seen. - return new TagCompound - { - ["FoundItems"] = foundItems.Select(ItemIO.Save).ToList(), - //["SortMode"] = (int)ItemChecklistUI.sortMode, - ["Announce"] = ItemChecklistUI.announce, // Not saving default, saving last used....good thing? - ["CollectChestItems"] = ItemChecklistUI.collectChestItems, - ["ShowCompleted"] = ItemChecklistUI.showCompleted, - }; + tag["FoundItems"] = foundItems.Select(ItemIO.Save).ToList(); + //tag["SortMode"] = (int)ItemChecklistUI.sortMode; + tag["Announce"] = ItemChecklistUI.announce; // Not saving default, saving last used....good thing? + tag["CollectChestItems"] = ItemChecklistUI.collectChestItems; + tag["ShowCompleted"] = ItemChecklistUI.showCompleted; } - public override void Load(TagCompound tag) + public override void LoadData(TagCompound tag) { foundItems = tag.GetList("FoundItems").Select(ItemIO.Load).ToList(); //sortModePreference = (SortModes)tag.GetInt("SortMode"); diff --git a/ItemChecklistUI.cs b/ItemChecklistUI.cs index 73229ea..9d4e106 100644 --- a/ItemChecklistUI.cs +++ b/ItemChecklistUI.cs @@ -6,12 +6,17 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; +using ReLogic.Content; using Terraria; +using Terraria.Audio; +using Terraria.GameContent; using Terraria.GameContent.UI.Elements; using Terraria.ID; using Terraria.ModLoader; using Terraria.UI; +using UIItemSlot = ItemChecklist.UIElements.UIItemSlot; + namespace ItemChecklist { class ItemChecklistUI : UIState @@ -24,6 +29,7 @@ namespace ItemChecklist public UIToggleHoverImageButton collectChestItemsButton; public UIToggleHoverImageButton showBadgeButton; private bool buttonsHaveDummyTextures; + public UIDragableElement mainPanel; public UIPanel checklistPanel; internal NewUITextBox itemNameFilter; internal NewUITextBox itemDescriptionFilter; @@ -64,23 +70,41 @@ namespace ItemChecklist collectChestItems = false; showBadge = false; - checklistPanel = new UIPanel(); - checklistPanel.SetPadding(10); - checklistPanel.Left.Pixels = 0; - checklistPanel.HAlign = 1f; - checklistPanel.Top.Set(85f, 0f); - checklistPanel.Left.Set(-40f, 0f); - checklistPanel.Width.Set(250f, 0f); - checklistPanel.Height.Set(-125, 1f); - checklistPanel.BackgroundColor = new Color(73, 94, 171); + mainPanel = new UIDragableElement(); + //mainPanel.SetPadding(0); + //mainPanel.PaddingTop = 4; + mainPanel.Left.Set(400f, 0f); + mainPanel.Top.Set(400f, 0f); + mainPanel.Width.Set(475f, 0f); // + 30 + mainPanel.MinWidth.Set(415f, 0f); + mainPanel.MaxWidth.Set(884f, 0f); + mainPanel.Height.Set(350, 0f); + mainPanel.MinHeight.Set(263, 0f); + mainPanel.MaxHeight.Set(1000, 0f); + //mainPanel.BackgroundColor = Color.LightBlue; + + var config = ModContent.GetInstance(); + mainPanel.Left.Set(config.ItemChecklistPosition.X, 0f); + mainPanel.Top.Set(config.ItemChecklistPosition.Y, 0f); + mainPanel.Width.Set(config.ItemChecklistSize.X, 0f); + mainPanel.Height.Set(config.ItemChecklistSize.Y, 0f); int top = 0; int left = 0; + + checklistPanel = new UIPanel(); + checklistPanel.SetPadding(10); + checklistPanel.BackgroundColor = new Color(73, 94, 171);; + checklistPanel.Top.Set(0, 0f); + checklistPanel.Height.Set(0, 1f); + checklistPanel.Width.Set(0, 1f); + mainPanel.Append(checklistPanel); + mainPanel.AddDragTarget(checklistPanel); // Because OnInitialize Happens during load and because we need it to happen for OnEnterWorld, use dummy sprite. buttonsHaveDummyTextures = true; - foundFilterButton = new UIHoverImageButton(Main.magicPixel, "Cycle Found Filter: ??"); + foundFilterButton = new UIHoverImageButton(TextureAssets.MagicPixel.Value, "Cycle Found Filter: ??"); foundFilterButton.OnClick += (a, b) => ToggleFoundFilterButtonClicked(a, b, true); foundFilterButton.OnRightClick += (a, b) => ToggleFoundFilterButtonClicked(a, b, false); foundFilterButton.Top.Pixels = top; @@ -94,7 +118,7 @@ namespace ItemChecklist //sortButton.Top.Pixels = top; //checklistPanel.Append(sortButton); - modFilterButton = new UIHoverImageButton(Main.magicPixel, "Cycle Mod Filter: ??"); + modFilterButton = new UIHoverImageButton(TextureAssets.MagicPixel.Value, "Cycle Mod Filter: ??"); modFilterButton.OnClick += (a, b) => ToggleModFilterButtonClicked(a, b, true); modFilterButton.OnRightClick += (a, b) => ToggleModFilterButtonClicked(a, b, false); modFilterButton.Left.Pixels = left; @@ -102,21 +126,21 @@ namespace ItemChecklist checklistPanel.Append(modFilterButton); left += (int)spacing * 2 + 28; - muteButton = new UIToggleHoverImageButton(Main.magicPixel, ItemChecklist.instance.GetTexture("UIElements/closeButton"), "Toggle Messages", announce); + muteButton = new UIToggleHoverImageButton(TextureAssets.MagicPixel.Value, ItemChecklist.instance.Assets.Request("UIElements/closeButton", AssetRequestMode.ImmediateLoad).Value, "Toggle Messages", announce); muteButton.OnClick += ToggleMuteButtonClicked; muteButton.Left.Pixels = left; muteButton.Top.Pixels = top; checklistPanel.Append(muteButton); left += (int)spacing * 2 + 28; - collectChestItemsButton = new UIToggleHoverImageButton(Main.magicPixel, ItemChecklist.instance.GetTexture("UIElements/closeButton"), "Toggle Collect Chest Items", collectChestItems); + collectChestItemsButton = new UIToggleHoverImageButton(TextureAssets.MagicPixel.Value, ItemChecklist.instance.Assets.Request("UIElements/closeButton", AssetRequestMode.ImmediateLoad).Value, "Toggle Collect Chest Items", collectChestItems); collectChestItemsButton.OnClick += ToggleFindChestItemsButtonClicked; collectChestItemsButton.Left.Pixels = left; collectChestItemsButton.Top.Pixels = top; checklistPanel.Append(collectChestItemsButton); left += (int)spacing * 2 + 28; - showBadgeButton = new UIToggleHoverImageButton(Main.magicPixel, ItemChecklist.instance.GetTexture("UIElements/closeButton"), "Show Sort Value Text", showBadge); + showBadgeButton = new UIToggleHoverImageButton(TextureAssets.MagicPixel.Value, ItemChecklist.instance.Assets.Request("UIElements/closeButton", AssetRequestMode.ImmediateLoad).Value, "Show Sort Value Text", showBadge); showBadgeButton.OnClick += ToggleShowBadgeButtonClicked; showBadgeButton.Left.Pixels = left; showBadgeButton.Top.Pixels = top; @@ -157,7 +181,7 @@ namespace ItemChecklist top += 68; - checklistGrid = new UIGrid(5); + checklistGrid = new UIGrid(); checklistGrid.alternateSort = ItemGridSort; checklistGrid.Top.Pixels = top; checklistGrid.Width.Set(-25f, 1f); @@ -175,15 +199,19 @@ namespace ItemChecklist // Checklistlist populated when the panel is shown: UpdateCheckboxes() - Append(checklistPanel); + Append(mainPanel); // load time impact, do this on first show? itemSlots = new UIItemSlot[ItemLoader.ItemCount]; Item[] itemSlotItems = new Item[ItemLoader.ItemCount]; for (int i = 0; i < ItemLoader.ItemCount; i++) { - itemSlots[i] = new UIItemSlot(i); - itemSlotItems[i] = itemSlots[i].item; + Item item = new Item(); + item.SetDefaults(i, false); // 300 ms vs 30 ms + if (item.type == 0) + continue; + itemSlots[i] = new UIItemSlot(item, i); + itemSlotItems[i] = item; } FieldInfo inventoryGlowHue = typeof(Terraria.UI.ItemSlot).GetField("inventoryGlowHue", BindingFlags.Static | BindingFlags.NonPublic); @@ -194,11 +222,11 @@ namespace ItemChecklist inventoryGlowHue.SetValue(null, new float[ItemLoader.ItemCount]); inventoryGlowTime.SetValue(null, new int[ItemLoader.ItemCount]); - SortMethod.Invoke(null, parametersArray); + //SortMethod.Invoke(null, parametersArray); inventoryGlowHue.SetValue(null, new float[58]); inventoryGlowTime.SetValue(null, new int[58]); - int[] vanillaIDsInSortOrderTemp = itemSlotItems.Select((x) => x.type).ToArray(); + int[] vanillaIDsInSortOrderTemp = itemSlotItems.Where(x => x != null).Select((x) => x.type).ToArray(); vanillaIDsInSortOrder = new int[ItemLoader.ItemCount]; for (int i = 0; i < ItemLoader.ItemCount; i++) { @@ -206,7 +234,7 @@ namespace ItemChecklist } modnames = new List() { "All", "Vanilla" }; - modnames.AddRange(ModLoader.GetLoadedMods()/*.Where(x => x != "ModLoader")*/); + modnames.AddRange(ModLoader.Mods.Where(mod => mod.GetContent().Any()).Select(x => x.Name)/*.Where(x => x != "ModLoader")*/); updateNeeded = true; } @@ -222,7 +250,7 @@ namespace ItemChecklist private void ToggleFoundFilterButtonClicked(UIMouseEvent evt, UIElement listeningElement, bool left) { - Main.PlaySound(SoundID.MenuTick); + SoundEngine.PlaySound(SoundID.MenuTick); showCompleted = (3 + showCompleted + (left ? 1 : -1)) % 3; foundFilterButton.hoverText = "Cycle Found Filter: " + foundFilterStrings[showCompleted]; UpdateNeeded(); @@ -231,7 +259,7 @@ namespace ItemChecklist private void ToggleMuteButtonClicked(UIMouseEvent evt, UIElement listeningElement) { announce = !announce; - Main.PlaySound(announce ? SoundID.MenuOpen : SoundID.MenuClose); + SoundEngine.PlaySound(announce ? SoundID.MenuOpen : SoundID.MenuClose); muteButton.SetEnabled(announce); } @@ -245,7 +273,7 @@ namespace ItemChecklist private void ToggleModFilterButtonClicked(UIMouseEvent evt, UIElement listeningElement, bool left) { - Main.PlaySound(SoundID.MenuTick); + SoundEngine.PlaySound(SoundID.MenuTick); currentMod = (modnames.Count + currentMod + (left ? 1 : -1)) % modnames.Count; modFilterButton.hoverText = "Cycle Mod Filter: " + modnames[currentMod]; UpdateNeeded(); @@ -254,14 +282,14 @@ namespace ItemChecklist private void ToggleShowBadgeButtonClicked(UIMouseEvent evt, UIElement listeningElement) { showBadge = !showBadge; - Main.PlaySound(showBadge ? SoundID.MenuOpen : SoundID.MenuClose); + SoundEngine.PlaySound(showBadge ? SoundID.MenuOpen : SoundID.MenuClose); showBadgeButton.SetEnabled(showBadge); } private void ToggleFindChestItemsButtonClicked(UIMouseEvent evt, UIElement listeningElement) { collectChestItems = !collectChestItems; - Main.PlaySound(collectChestItems ? SoundID.MenuOpen : SoundID.MenuClose); + SoundEngine.PlaySound(collectChestItems ? SoundID.MenuOpen : SoundID.MenuClose); collectChestItemsButton.SetEnabled(collectChestItems); } @@ -295,12 +323,12 @@ namespace ItemChecklist if (buttonsHaveDummyTextures) { - Texture2D foundFilterTexture = Utilities.ResizeImage(ItemChecklist.instance.GetTexture("Images/filterFound"), 32, 32); - Texture2D muteButtonTexture = Utilities.ResizeImage(Main.itemTexture[ItemID.Megaphone], 32, 32); + Texture2D foundFilterTexture = Utilities.ResizeImage(ItemChecklist.instance.Assets.Request("Images/filterFound"), 32, 32); + Texture2D muteButtonTexture = Utilities.ResizeImage(TextureAssets.Item[ItemID.Megaphone].Value, 32, 32); //Texture2D sortButtonTexture = Utilities.ResizeImage(Main.itemTexture[ItemID.ToxicFlask], 32, 32); - Texture2D modFilterButtonTexture = Utilities.ResizeImage(ItemChecklist.instance.GetTexture("Images/filterMod"), 32, 32); - Texture2D collectChestItemsButtonTexture = Utilities.ResizeImage(Main.cursorTextures[8], 32, 32); - Texture2D showBadgeButtonTexture = Utilities.ResizeImage(Main.itemTexture[ItemID.Book], 32, 32); // Main.extraTexture[58] + Texture2D modFilterButtonTexture = Utilities.ResizeImage(ItemChecklist.instance.Assets.Request("Images/filterMod"), 32, 32); + Texture2D collectChestItemsButtonTexture = Utilities.ResizeImage(TextureAssets.Cursors[8].Value, 32, 32); + Texture2D showBadgeButtonTexture = Utilities.ResizeImage(TextureAssets.Item[ItemID.Book].Value, 32, 32); // Main.extraTexture[58] foundFilterButton.SetImage(foundFilterTexture); muteButton.SetImage(muteButtonTexture); @@ -311,12 +339,14 @@ namespace ItemChecklist buttonsHaveDummyTextures = false; } - var itemChecklistPlayer = Main.LocalPlayer.GetModPlayer(ItemChecklist.instance); + var itemChecklistPlayer = Main.LocalPlayer.GetModPlayer(); var temp = new List(); for (int i = 0; i < itemChecklistPlayer.findableItems.Length; i++) { if (itemChecklistPlayer.findableItems[i]) { + if (itemSlots[i] == null) continue; + // filters here if ((showCompleted != 1 && itemChecklistPlayer.foundItem[i]) || (showCompleted != 2 && !itemChecklistPlayer.foundItem[i])) { @@ -369,7 +399,7 @@ namespace ItemChecklist checklistGrid.Goto(delegate (UIElement element) { UIItemSlot itemSlot = element as UIItemSlot; - return itemSlot != null && itemSlot.id == lastfoundID; + return itemSlot != null && itemSlot.itemType == lastfoundID; }, true); } lastfoundID = -1; @@ -382,11 +412,11 @@ namespace ItemChecklist { return true; } - else if (currentMod == 1 && itemSlot.item.modItem == null) + else if (currentMod == 1 && itemSlot.item.ModItem == null) { return true; } - else if (itemSlot.item.modItem != null && itemSlot.item.modItem.mod.Name == modnames[currentMod]) + else if (itemSlot.item.ModItem != null && itemSlot.item.ModItem.Mod.Name == modnames[currentMod]) { return true; } @@ -400,6 +430,8 @@ namespace ItemChecklist bool found = false; foreach (var itemSlot in itemSlots) { + if (itemSlot == null) continue; + if (itemSlot.item.Name.IndexOf(itemNameFilter.currentString, StringComparison.OrdinalIgnoreCase) != -1) { found = true; @@ -423,7 +455,7 @@ namespace ItemChecklist { ItemChecklistUI.hoverText = ""; Vector2 MousePosition = new Vector2((float)Main.mouseX, (float)Main.mouseY); - if (checklistPanel.ContainsPoint(MousePosition)) + if (mainPanel.ContainsPoint(MousePosition)) { Main.player[Main.myPlayer].mouseInterface = true; } diff --git a/MagicStorageIntegration.cs b/MagicStorageIntegration.cs index ffbc491..ead2dfd 100644 --- a/MagicStorageIntegration.cs +++ b/MagicStorageIntegration.cs @@ -101,7 +101,7 @@ namespace ItemChecklist previousStorageAccess = storageAccess; if (!Main.playerInventory || storageAccess.X < 0 || storageAccess.Y < 0) return; - ModTile modTile = TileLoader.GetTile(Main.tile[storageAccess.X, storageAccess.Y].type); + ModTile modTile = TileLoader.GetTile(Main.tile[storageAccess.X, storageAccess.Y].TileType); if (modTile == null || !(modTile is StorageAccess)) { return; @@ -115,7 +115,10 @@ namespace ItemChecklist // Will 1000 items crash the chat? foreach (var item in items) { - ItemChecklist.instance.GetGlobalItem().ItemReceived(item); + foreach (ItemChecklistGlobalItem globalItem in ItemChecklist.instance.GetContent()) + { + globalItem.ItemReceived(item); + } } } } diff --git a/SharedUI.cs b/SharedUI.cs index a93b542..4137fa3 100644 --- a/SharedUI.cs +++ b/SharedUI.cs @@ -4,11 +4,14 @@ using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; using System.Linq; +using ReLogic.Content; using Terraria; +using Terraria.GameContent; using Terraria.GameContent.UI.Elements; using Terraria.GameContent.UI.States; using Terraria.ID; using static ItemChecklist.Utilities; +using Terraria.ModLoader; // Copied from my Recipe Browser mod. namespace ItemChecklist @@ -17,22 +20,18 @@ namespace ItemChecklist { internal static SharedUI instance; internal bool updateNeeded; - internal List modCategories = new List(); // TODO: copy over call? make it automatic somehow? - internal List modFilters = new List(); // TODO: copy over call? make it automatic somehow? internal UIPanel sortsAndFiltersPanel; internal UIHorizontalGrid categoriesGrid; + internal InvisibleFixedUIHorizontalScrollbar categoriesGridScrollbar; internal UIHorizontalGrid subCategorySortsFiltersGrid; internal InvisibleFixedUIHorizontalScrollbar lootGridScrollbar2; private Sort selectedSort; - internal Sort SelectedSort - { + internal Sort SelectedSort { get { return selectedSort; } - set - { - if (selectedSort != value) - { + set { + if (selectedSort != value) { updateNeeded = true; ItemChecklistUI.instance.UpdateNeeded(); } @@ -41,13 +40,10 @@ namespace ItemChecklist } private Category selectedCategory; - internal Category SelectedCategory - { + internal Category SelectedCategory { get { return selectedCategory; } - set - { - if (selectedCategory != value) - { + set { + if (selectedCategory != value) { updateNeeded = true; ItemChecklistUI.instance.UpdateNeeded(); } @@ -59,13 +55,11 @@ namespace ItemChecklist } } - public SharedUI() - { + public SharedUI() { instance = this; } - internal void Initialize() - { + internal void Initialize() { // Sorts // Filters: Categories? // Craft and Loot Badges as well! @@ -78,25 +72,23 @@ namespace ItemChecklist sortsAndFiltersPanel.Top.Set(0, 0f); sortsAndFiltersPanel.Width.Set(-275, 1); sortsAndFiltersPanel.Height.Set(60, 0f); - sortsAndFiltersPanel.BackgroundColor = new Color(73, 94, 221); + sortsAndFiltersPanel.BackgroundColor = Color.CornflowerBlue;//Color.LightSeaGreen; + //sortsAndFiltersPanel.SetPadding(4); //mainPanel.Append(sortsAndFiltersPanel); //additionalDragTargets.Add(sortsAndFiltersPanel); //SetupSortsAndCategories(); - //PopulateSortsAndFiltersPanel(); updateNeeded = true; } - internal void Update() - { + internal void Update() { if (!updateNeeded) { return; } updateNeeded = false; // Delay this so we can integrate mod categories. - if (sorts == null) - { + if (sorts == null) { SetupSortsAndCategories(); } @@ -104,36 +96,30 @@ namespace ItemChecklist } internal List availableFilters; - private void PopulateSortsAndFiltersPanel() - { + private void PopulateSortsAndFiltersPanel() { var availableSorts = new List(sorts); availableFilters = new List(filters); + //sortsAndFiltersPanel.RemoveAllChildren(); - if (subCategorySortsFiltersGrid != null) - { + if (subCategorySortsFiltersGrid != null) { sortsAndFiltersPanel.RemoveChild(subCategorySortsFiltersGrid); sortsAndFiltersPanel.RemoveChild(lootGridScrollbar2); } - bool doTopRow = false; - if (categoriesGrid == null) - { - doTopRow = true; - + if (categoriesGrid == null) { categoriesGrid = new UIHorizontalGrid(); categoriesGrid.Width.Set(0, 1f); categoriesGrid.Height.Set(26, 0f); categoriesGrid.ListPadding = 2f; - categoriesGrid.OnScrollWheel += ItemChecklistUI.OnScrollWheel_FixHotbarScroll; - sortsAndFiltersPanel.Append(categoriesGrid); categoriesGrid.drawArrows = true; - var lootGridScrollbar = new InvisibleFixedUIHorizontalScrollbar(ItemChecklist.ItemChecklistInterface); - lootGridScrollbar.SetView(100f, 1000f); - lootGridScrollbar.Width.Set(0, 1f); - lootGridScrollbar.Top.Set(0, 0f); - sortsAndFiltersPanel.Append(lootGridScrollbar); - categoriesGrid.SetScrollbar(lootGridScrollbar); + categoriesGridScrollbar = new InvisibleFixedUIHorizontalScrollbar(ItemChecklist.ItemChecklistInterface); + categoriesGridScrollbar.SetView(100f, 1000f); + categoriesGridScrollbar.Width.Set(0, 1f); + categoriesGridScrollbar.Top.Set(0, 0f); + sortsAndFiltersPanel.Append(categoriesGridScrollbar); + categoriesGrid.SetScrollbar(categoriesGridScrollbar); + sortsAndFiltersPanel.Append(categoriesGrid); // This is after so it gets the mouse events. } subCategorySortsFiltersGrid = new UIHorizontalGrid(); @@ -141,16 +127,16 @@ namespace ItemChecklist subCategorySortsFiltersGrid.Top.Set(26, 0f); subCategorySortsFiltersGrid.Height.Set(26, 0f); subCategorySortsFiltersGrid.ListPadding = 2f; - subCategorySortsFiltersGrid.OnScrollWheel += ItemChecklistUI.OnScrollWheel_FixHotbarScroll; - sortsAndFiltersPanel.Append(subCategorySortsFiltersGrid); subCategorySortsFiltersGrid.drawArrows = true; + float oldRow2ViewPosition = lootGridScrollbar2?.ViewPosition ?? 0f; lootGridScrollbar2 = new InvisibleFixedUIHorizontalScrollbar(ItemChecklist.ItemChecklistInterface); lootGridScrollbar2.SetView(100f, 1000f); lootGridScrollbar2.Width.Set(0, 1f); lootGridScrollbar2.Top.Set(28, 0f); sortsAndFiltersPanel.Append(lootGridScrollbar2); subCategorySortsFiltersGrid.SetScrollbar(lootGridScrollbar2); + sortsAndFiltersPanel.Append(subCategorySortsFiltersGrid); //sortsAndFiltersPanelGrid = new UIGrid(); //sortsAndFiltersPanelGrid.Width.Set(0, 1); @@ -167,45 +153,41 @@ namespace ItemChecklist var visibleCategories = new List(); var visibleSubCategories = new List(); int left = 0; - foreach (var category in categories) - { + foreach (var category in categories) { category.button.selected = false; visibleCategories.Add(category); bool meOrChildSelected = SelectedCategory == category; - foreach (var subcategory in category.subCategories) - { + foreach (var subcategory in category.subCategories) { subcategory.button.selected = false; meOrChildSelected |= subcategory == SelectedCategory; } - if (meOrChildSelected) - { + if (meOrChildSelected) { visibleSubCategories.AddRange(category.subCategories); category.button.selected = true; } } - if (doTopRow) - foreach (var category in visibleCategories) - { - var container = new UISortableElement(++count); - container.Width.Set(24, 0); - container.Height.Set(24, 0); - //category.button.Left.Pixels = left; - //if (category.parent != null) - // container.OrderIndex - // category.button.Top.Pixels = 12; - //sortsAndFiltersPanel.Append(category.button); - container.Append(category.button); - categoriesGrid.Add(container); - left += 26; - } + float oldTopRowViewPosition = categoriesGridScrollbar?.ViewPosition ?? 0f; + categoriesGrid.Clear(); + foreach (var category in visibleCategories) { + var container = new UISortableElement(++count); + container.Width.Set(24, 0); + container.Height.Set(24, 0); + //category.button.Left.Pixels = left; + //if (category.parent != null) + // container.OrderIndex + // category.button.Top.Pixels = 12; + //sortsAndFiltersPanel.Append(category.button); + container.Append(category.button); + categoriesGrid.Add(container); + left += 26; + } //UISortableElement spacer = new UISortableElement(++count); //spacer.Width.Set(0, 1); //sortsAndFiltersPanelGrid2.Add(spacer); - foreach (var category in visibleSubCategories) - { + foreach (var category in visibleSubCategories) { var container = new UISortableElement(++count); container.Width.Set(24, 0); container.Height.Set(24, 0); @@ -214,28 +196,26 @@ namespace ItemChecklist left += 26; } - if (visibleSubCategories.Count > 0) - { + if (visibleSubCategories.Count > 0) { var container2 = new UISortableElement(++count); container2.Width.Set(24, 0); container2.Height.Set(24, 0); - var image = new UIImage(ItemChecklist.instance.GetTexture("UIElements/spacer")); + var image = new UIImage(ItemChecklist.instance.Assets.Request("Images/spacer")); //image.Left.Set(6, 0); image.HAlign = 0.5f; container2.Append(image); subCategorySortsFiltersGrid.Add(container2); } - // add to sorts here - if (SelectedCategory != null) - { + // add to sorts and filters here + if (SelectedCategory != null) { SelectedCategory.button.selected = true; SelectedCategory.ParentAddToSorts(availableSorts); + SelectedCategory.ParentAddToFilters(availableFilters); } left = 0; - foreach (var sort in availableSorts) - { + foreach (var sort in availableSorts) { sort.button.selected = false; if (SelectedSort == sort) // TODO: SelectedSort no longwe valid sort.button.selected = true; @@ -251,25 +231,22 @@ namespace ItemChecklist //sortsAndFiltersPanel.Append(sort.button); left += 26; } - if (!availableSorts.Contains(SharedUI.instance.SelectedSort)) - { + if (!availableSorts.Contains(SharedUI.instance.SelectedSort)) { availableSorts[0].button.selected = true; SharedUI.instance.SelectedSort = availableSorts[0]; updateNeeded = false; } - if (SharedUI.instance.filters.Count > 0) - { + if (availableFilters.Count > 0) { var container2 = new UISortableElement(++count); container2.Width.Set(24, 0); container2.Height.Set(24, 0); - var image = new UIImage(ItemChecklist.instance.GetTexture("UIElements/spacer")); + var image = new UIImage(ItemChecklist.instance.Assets.Request("Images/spacer")); image.HAlign = 0.5f; container2.Append(image); subCategorySortsFiltersGrid.Add(container2); - foreach (var item in SharedUI.instance.filters) - { + foreach (var item in availableFilters) { var container = new UISortableElement(++count); container.Width.Set(24, 0); container.Height.Set(24, 0); @@ -277,41 +254,52 @@ namespace ItemChecklist subCategorySortsFiltersGrid.Add(container); } } + + // Restore view position after CycleFilter changes current filters. + subCategorySortsFiltersGrid.Recalculate(); + lootGridScrollbar2.ViewPosition = oldRow2ViewPosition; + categoriesGrid.Recalculate(); + //categoriesGridScrollbar.ViewPosition = oldTopRowViewPosition; // And after category disappears, not really needed since only 1 will disappear, unlike 2nd row. Test more if more special categories are added } internal List categories; internal List filters; internal List sorts; - internal List craftingTiles; - private void SetupSortsAndCategories() + + // Items whose textures are resized used during setup + // If they aren't loaded, some buttons doesn't have an icon + // TODO: A better way to do this? + private int[] itemTexturePreload = { - var tileUsageCounts = new Dictionary(); - int currentCount; - for (int i = 0; i < Recipe.numRecipes; i++) - { - for (int j = 0; j < 15; j++) - { - if (Main.recipe[i].requiredTile[j] == -1) - break; - tileUsageCounts.TryGetValue(Main.recipe[i].requiredTile[j], out currentCount); - tileUsageCounts[Main.recipe[i].requiredTile[j]] = currentCount + 1; - } - } - craftingTiles = tileUsageCounts.Select(x => x.Key).ToList(); + ItemID.MetalDetector, ItemID.SpellTome, ItemID.IronAnvil, ItemID.MythrilAnvil, ItemID.Blindfold, ItemID.GoldBroadsword, ItemID.GoldenShower, ItemID.FlintlockPistol, + ItemID.Shuriken, ItemID.SlimeStaff, ItemID.DD2LightningAuraT1Popper, ItemID.SilverHelmet, ItemID.SilverChainmail, ItemID.SilverGreaves, + ItemID.BunnyHood, ItemID.HerosHat, ItemID.GoldHelmet, ItemID.Sign, ItemID.IronAnvil, ItemID.PearlstoneBrickWall, ItemID.EoCShield, + ItemID.ZephyrFish, ItemID.FairyBell, ItemID.MechanicalSkull, ItemID.SlimySaddle, ItemID.AmethystHook, ItemID.OrangeDye, ItemID.BiomeHairDye, + ItemID.FallenStarfish, ItemID.HermesBoots, ItemID.LeafWings, ItemID.Minecart, ItemID.HealingPotion, ItemID.ManaPotion, ItemID.RagePotion, + ItemID.AlphabetStatueA, ItemID.GoldChest, ItemID.PaintingMartiaLisa, ItemID.HeartStatue, ItemID.Wire, ItemID.PurificationPowder, + ItemID.Extractinator, ItemID.UnicornonaStick, ItemID.SilverHelmet, ItemID.BunnyHood, ItemID.ZephyrFish, ItemID.Sign, ItemID.FallenStarfish, + ItemID.HealingPotion, ItemID.OrangeDye, ItemID.Candelabra, ItemID.WoodenDoor, ItemID.WoodenChair, ItemID.PalmWoodTable, ItemID.ChineseLantern, + ItemID.RainbowTorch, ItemID.GoldBunny, ItemID.WoodenDoor, ItemID.WoodenChair, ItemID.PalmWoodTable, ItemID.ChineseLantern, ItemID.RainbowTorch + }; - Texture2D terrariaSort = ResizeImage(Main.inventorySortTexture[1], 24, 24); - Texture2D rarity = ResizeImage(Main.itemTexture[ItemID.MetalDetector], 24, 24); + private void SetupSortsAndCategories() { + foreach (int type in itemTexturePreload) + Main.instance.LoadItem(type); + //Texture2D terrariaSort = ResizeImage(Main.inventorySortTexture[1], 24, 24); + Texture2D rarity = ResizeImage(TextureAssets.Item[ItemID.MetalDetector], 24, 24); + + // TODO: Implement Badge text as used in Item Checklist. sorts = new List() { new Sort("ItemID", "Images/sortItemID", (x,y)=>x.type.CompareTo(y.type), x=>x.type.ToString()), new Sort("Value", "Images/sortValue", (x,y)=>x.value.CompareTo(y.value), x=>x.value.ToString()), new Sort("Alphabetical", "Images/sortAZ", (x,y)=>x.Name.CompareTo(y.Name), x=>x.Name.ToString()), new Sort("Rarity", rarity, (x,y)=> x.rare==y.rare ? x.value.CompareTo(y.value) : Math.Abs(x.rare).CompareTo(Math.Abs(y.rare)), x=>x.rare.ToString()), - new Sort("Terraria Sort", terrariaSort, (x,y)=> -ItemChecklistUI.vanillaIDsInSortOrder[x.type].CompareTo(ItemChecklistUI.vanillaIDsInSortOrder[y.type]), x=>ItemChecklistUI.vanillaIDsInSortOrder[x.type].ToString()), + //new Sort("Terraria Sort", terrariaSort, (x,y)=> -ItemChecklistUI.vanillaIDsInSortOrder[x.type].CompareTo(ItemChecklistUI.vanillaIDsInSortOrder[y.type]), x=>ItemChecklistUI.vanillaIDsInSortOrder[x.type].ToString()), }; - Texture2D materialsIcon = Utilities.StackResizeImage(new Texture2D[] { Main.itemTexture[ItemID.SpellTome] }, 24, 24); + Texture2D materialsIcon = Utilities.StackResizeImage(new[] { TextureAssets.Item[ItemID.SpellTome] }, 24, 24); filters = new List() { new Filter("Materials", x=>ItemID.Sets.IsAMaterial[x.type], materialsIcon), @@ -320,60 +308,97 @@ namespace ItemChecklist // TODOS: Vanity armor, grapple, cart, potions buffs // 24x24 pixels - List yoyos = new List(); - for (int i = 0; i < ItemID.Sets.Yoyo.Length; ++i) - { - if (ItemID.Sets.Yoyo[i]) - { + var yoyos = new List(); + for (int i = 0; i < ItemID.Sets.Yoyo.Length; ++i) { + if (ItemID.Sets.Yoyo[i]) { + Main.instance.LoadItem(i); yoyos.Add(i); } } - Texture2D smallMelee = ResizeImage(Main.itemTexture[ItemID.GoldBroadsword], 24, 24); - Texture2D smallYoyo = ResizeImage(Main.itemTexture[Main.rand.Next(yoyos)], 24, 24); //Main.rand.Next(ItemID.Sets.Yoyo) ItemID.Yelets - Texture2D smallMagic = ResizeImage(Main.itemTexture[ItemID.GoldenShower], 24, 24); - Texture2D smallRanged = ResizeImage(Main.itemTexture[ItemID.FlintlockPistol], 24, 24); - Texture2D smallThrown = ResizeImage(Main.itemTexture[ItemID.Shuriken], 24, 24); - Texture2D smallSummon = ResizeImage(Main.itemTexture[ItemID.SlimeStaff], 24, 24); - Texture2D smallSentry = ResizeImage(Main.itemTexture[ItemID.DD2LightningAuraT1Popper], 24, 24); - Texture2D smallHead = ResizeImage(Main.itemTexture[ItemID.SilverHelmet], 24, 24); - Texture2D smallBody = ResizeImage(Main.itemTexture[ItemID.SilverChainmail], 24, 24); - Texture2D smallLegs = ResizeImage(Main.itemTexture[ItemID.SilverGreaves], 24, 24); - Texture2D smallTiles = ResizeImage(Main.itemTexture[ItemID.Sign], 24, 24); - Texture2D smallCraftingStation = ResizeImage(Main.itemTexture[ItemID.IronAnvil], 24, 24); - Texture2D smallWalls = ResizeImage(Main.itemTexture[ItemID.PearlstoneBrickWall], 24, 24); - Texture2D smallExpert = ResizeImage(Main.itemTexture[ItemID.EoCShield], 24, 24); - Texture2D smallPets = ResizeImage(Main.itemTexture[ItemID.ZephyrFish], 24, 24); - Texture2D smallLightPets = ResizeImage(Main.itemTexture[ItemID.FairyBell], 24, 24); - Texture2D smallBossSummon = ResizeImage(Main.itemTexture[ItemID.MechanicalSkull], 24, 24); - Texture2D smallMounts = ResizeImage(Main.itemTexture[ItemID.SlimySaddle], 24, 24); - Texture2D smallDyes = ResizeImage(Main.itemTexture[ItemID.OrangeDye], 24, 24); - Texture2D smallHairDye = ResizeImage(Main.itemTexture[ItemID.BiomeHairDye], 24, 24); - Texture2D smallQuestFish = ResizeImage(Main.itemTexture[ItemID.FallenStarfish], 24, 24); - Texture2D smallAccessories = ResizeImage(Main.itemTexture[ItemID.HermesBoots], 24, 24); - Texture2D smallWings = ResizeImage(Main.itemTexture[ItemID.LeafWings], 24, 24); - Texture2D smallCarts = ResizeImage(Main.itemTexture[ItemID.Minecart], 24, 24); - Texture2D smallHealth = ResizeImage(Main.itemTexture[ItemID.HealingPotion], 24, 24); - Texture2D smallMana = ResizeImage(Main.itemTexture[ItemID.ManaPotion], 24, 24); - Texture2D smallBuff = ResizeImage(Main.itemTexture[ItemID.RagePotion], 24, 24); - Texture2D smallAll = ResizeImage(Main.itemTexture[ItemID.AlphabetStatueA], 24, 24); - Texture2D smallContainer = ResizeImage(Main.itemTexture[ItemID.GoldChest], 24, 24); - Texture2D smallPaintings = ResizeImage(Main.itemTexture[ItemID.PaintingMartiaLisa], 24, 24); - Texture2D smallStatue = ResizeImage(Main.itemTexture[ItemID.HeartStatue], 24, 24); - Texture2D smallWiring = ResizeImage(Main.itemTexture[ItemID.Wire], 24, 24); - Texture2D smallConsumables = ResizeImage(Main.itemTexture[ItemID.PurificationPowder], 24, 24); - Texture2D smallExtractinator = ResizeImage(Main.itemTexture[ItemID.Extractinator], 24, 24); - Texture2D smallOther = ResizeImage(Main.itemTexture[ItemID.UnicornonaStick], 24, 24); + var useAmmoTypes = new Dictionary(); + var ammoTypes = new Dictionary(); + var testItem = new Item(); + for (int i = 0; i < ItemLoader.ItemCount; i++) { + testItem.SetDefaults(i); + if (testItem.useAmmo >= ItemLoader.ItemCount || testItem.ammo >= ItemLoader.ItemCount || testItem.useAmmo < 0 || testItem.ammo < 0) + continue; // Some mods misuse useAmmo + if (testItem.useAmmo > 0) { + useAmmoTypes.TryGetValue(testItem.useAmmo, out var currentCount); + useAmmoTypes[testItem.useAmmo] = currentCount + 1; + } + if (testItem.ammo > 0) { + ammoTypes.TryGetValue(testItem.ammo, out var currentCount); + ammoTypes[testItem.ammo] = currentCount + 1; + } + } + var sortedUseAmmoTypes = from pair in useAmmoTypes orderby pair.Value descending select pair.Key; + var sortedAmmoTypes = from pair in ammoTypes orderby pair.Value descending select pair.Key; - Texture2D smallArmor = StackResizeImage(new Texture2D[] { Main.itemTexture[ItemID.SilverHelmet], Main.itemTexture[ItemID.SilverChainmail], Main.itemTexture[ItemID.SilverGreaves] }, 24, 24); - Texture2D smallPetsLightPets = StackResizeImage(new Texture2D[] { Main.itemTexture[ItemID.ZephyrFish], Main.itemTexture[ItemID.FairyBell] }, 24, 24); - Texture2D smallPlaceables = StackResizeImage(new Texture2D[] { Main.itemTexture[ItemID.Sign], Main.itemTexture[ItemID.PearlstoneBrickWall] }, 24, 24); - Texture2D smallWeapons = StackResizeImage(new Texture2D[] { smallMelee, smallMagic, smallThrown }, 24, 24); - Texture2D smallTools = StackResizeImage(new Texture2D[] { ItemChecklist.instance.GetTexture("Images/sortPick"), ItemChecklist.instance.GetTexture("Images/sortAxe"), ItemChecklist.instance.GetTexture("Images/sortHammer") }, 24, 24); - Texture2D smallFishing = StackResizeImage(new Texture2D[] { ItemChecklist.instance.GetTexture("Images/sortFish"), ItemChecklist.instance.GetTexture("Images/sortBait"), Main.itemTexture[ItemID.FallenStarfish] }, 24, 24); - Texture2D smallPotions = StackResizeImage(new Texture2D[] { Main.itemTexture[ItemID.HealingPotion], Main.itemTexture[ItemID.ManaPotion], Main.itemTexture[ItemID.RagePotion] }, 24, 24); - Texture2D smallBothDyes = StackResizeImage(new Texture2D[] { Main.itemTexture[ItemID.OrangeDye], Main.itemTexture[ItemID.BiomeHairDye] }, 24, 24); - Texture2D smallSortTiles = StackResizeImage(new Texture2D[] { Main.itemTexture[ItemID.Candelabra], Main.itemTexture[ItemID.GrandfatherClock] }, 24, 24); + foreach (int type in sortedUseAmmoTypes) + Main.instance.LoadItem(type); + foreach (int type in sortedAmmoTypes) + Main.instance.LoadItem(type); + + var ammoFilters = sortedAmmoTypes.Select(ammoType => new Filter(Lang.GetItemNameValue(ammoType), x => x.ammo == ammoType, ResizeImage(TextureAssets.Item[ammoType], 24, 24))).ToList(); + var useAmmoFilters = sortedUseAmmoTypes.Select(ammoType => new Filter(Lang.GetItemNameValue(ammoType), x => x.useAmmo == ammoType, ResizeImage(TextureAssets.Item[ammoType], 24, 24))).ToList(); + + var ammoFilter = new CycleFilter("Cycle Ammo Types", "Images/sortAmmo", ammoFilters); + var useAmmoFilter = new CycleFilter("Cycle Used Ammo Types", "Images/sortAmmo", useAmmoFilters); + + Texture2D smallMelee = ResizeImage(TextureAssets.Item[ItemID.GoldBroadsword], 24, 24); + Texture2D smallYoyo = ResizeImage(TextureAssets.Item[Main.rand.Next(yoyos)], 24, 24); //Main.rand.Next(ItemID.Sets.Yoyo) ItemID.Yelets + Texture2D smallMagic = ResizeImage(TextureAssets.Item[ItemID.GoldenShower], 24, 24); + Texture2D smallRanged = ResizeImage(TextureAssets.Item[ItemID.FlintlockPistol], 24, 24); + Texture2D smallThrown = ResizeImage(TextureAssets.Item[ItemID.Shuriken], 24, 24); + Texture2D smallSummon = ResizeImage(TextureAssets.Item[ItemID.SlimeStaff], 24, 24); + Texture2D smallSentry = ResizeImage(TextureAssets.Item[ItemID.DD2LightningAuraT1Popper], 24, 24); + Texture2D smallHead = ResizeImage(TextureAssets.Item[ItemID.SilverHelmet], 24, 24); + Texture2D smallBody = ResizeImage(TextureAssets.Item[ItemID.SilverChainmail], 24, 24); + Texture2D smallLegs = ResizeImage(TextureAssets.Item[ItemID.SilverGreaves], 24, 24); + Texture2D smallVanity = ResizeImage(TextureAssets.Item[ItemID.BunnyHood], 24, 24); + //Texture2D smallVanity2 = ResizeImage(TextureAssets.Item[ItemID.HerosHat], 24, 24); + Texture2D smallNonVanity = ResizeImage(TextureAssets.Item[ItemID.GoldHelmet], 24, 24); + Texture2D smallTiles = ResizeImage(TextureAssets.Item[ItemID.Sign], 24, 24); + Texture2D smallCraftingStation = ResizeImage(TextureAssets.Item[ItemID.IronAnvil], 24, 24); + Texture2D smallWalls = ResizeImage(TextureAssets.Item[ItemID.PearlstoneBrickWall], 24, 24); + Texture2D smallExpert = ResizeImage(TextureAssets.Item[ItemID.EoCShield], 24, 24); + Texture2D smallPets = ResizeImage(TextureAssets.Item[ItemID.ZephyrFish], 24, 24); + Texture2D smallLightPets = ResizeImage(TextureAssets.Item[ItemID.FairyBell], 24, 24); + Texture2D smallBossSummon = ResizeImage(TextureAssets.Item[ItemID.MechanicalSkull], 24, 24); + Texture2D smallMounts = ResizeImage(TextureAssets.Item[ItemID.SlimySaddle], 24, 24); + Texture2D smallHooks = ResizeImage(TextureAssets.Item[ItemID.AmethystHook], 24, 24); + Texture2D smallDyes = ResizeImage(TextureAssets.Item[ItemID.OrangeDye], 24, 24); + Texture2D smallHairDye = ResizeImage(TextureAssets.Item[ItemID.BiomeHairDye], 24, 24); + Texture2D smallQuestFish = ResizeImage(TextureAssets.Item[ItemID.FallenStarfish], 24, 24); + Texture2D smallAccessories = ResizeImage(TextureAssets.Item[ItemID.HermesBoots], 24, 24); + Texture2D smallWings = ResizeImage(TextureAssets.Item[ItemID.LeafWings], 24, 24); + Texture2D smallCarts = ResizeImage(TextureAssets.Item[ItemID.Minecart], 24, 24); + Texture2D smallHealth = ResizeImage(TextureAssets.Item[ItemID.HealingPotion], 24, 24); + Texture2D smallMana = ResizeImage(TextureAssets.Item[ItemID.ManaPotion], 24, 24); + Texture2D smallBuff = ResizeImage(TextureAssets.Item[ItemID.RagePotion], 24, 24); + Texture2D smallAll = ResizeImage(TextureAssets.Item[ItemID.AlphabetStatueA], 24, 24); + Texture2D smallContainer = ResizeImage(TextureAssets.Item[ItemID.GoldChest], 24, 24); + Texture2D smallPaintings = ResizeImage(TextureAssets.Item[ItemID.PaintingMartiaLisa], 24, 24); + Texture2D smallStatue = ResizeImage(TextureAssets.Item[ItemID.HeartStatue], 24, 24); + Texture2D smallWiring = ResizeImage(TextureAssets.Item[ItemID.Wire], 24, 24); + Texture2D smallConsumables = ResizeImage(TextureAssets.Item[ItemID.PurificationPowder], 24, 24); + Texture2D smallExtractinator = ResizeImage(TextureAssets.Item[ItemID.Extractinator], 24, 24); + Texture2D smallOther = ResizeImage(TextureAssets.Item[ItemID.UnicornonaStick], 24, 24); + + Texture2D smallArmor = StackResizeImage(new[] { TextureAssets.Item[ItemID.SilverHelmet], TextureAssets.Item[ItemID.SilverChainmail], TextureAssets.Item[ItemID.SilverGreaves] }, 24, 24); + //Texture2D smallVanityFilterGroup = StackResizeImage2424(TextureAssets.Item[ItemID.BunnyHood], TextureAssets.Item[ItemID.GoldHelmet]); + Texture2D smallPetsLightPets = StackResizeImage(new[] { TextureAssets.Item[ItemID.ZephyrFish], TextureAssets.Item[ItemID.FairyBell] }, 24, 24); + Texture2D smallPlaceables = StackResizeImage(new[] { TextureAssets.Item[ItemID.Sign], TextureAssets.Item[ItemID.PearlstoneBrickWall] }, 24, 24); + Texture2D smallWeapons = StackResizeImage(new[] { smallMelee, smallMagic, smallThrown }, 24, 24); + Texture2D smallTools = StackResizeImage(new[] { ItemChecklist.instance.Assets.Request("Images/sortPick"), ItemChecklist.instance.Assets.Request("Images/sortAxe"), ItemChecklist.instance.Assets.Request("Images/sortHammer") }, 24, 24); + Texture2D smallFishing = StackResizeImage(new[] { ItemChecklist.instance.Assets.Request("Images/sortFish"), ItemChecklist.instance.Assets.Request("Images/sortBait"), TextureAssets.Item[ItemID.FallenStarfish] }, 24, 24); + Texture2D smallPotions = StackResizeImage(new[] { TextureAssets.Item[ItemID.HealingPotion], TextureAssets.Item[ItemID.ManaPotion], TextureAssets.Item[ItemID.RagePotion] }, 24, 24); + Texture2D smallBothDyes = StackResizeImage(new[] { TextureAssets.Item[ItemID.OrangeDye], TextureAssets.Item[ItemID.BiomeHairDye] }, 24, 24); + Texture2D smallSortTiles = StackResizeImage(new[] { TextureAssets.Item[ItemID.Candelabra], TextureAssets.Item[ItemID.GrandfatherClock] }, 24, 24); + + Texture2D StackResizeImage2424(params Asset[] textures) => StackResizeImage(textures, 24, 24); + Texture2D ResizeImage2424(Asset texture) => ResizeImage(texture, 24, 24); // Potions, other? // should inherit children? @@ -381,22 +406,29 @@ namespace ItemChecklist if (WorldGen.statueList == null) WorldGen.SetupStatueList(); + var vanity = new MutuallyExclusiveFilter("Vanity", x => x.vanity, smallVanity); + var armor = new MutuallyExclusiveFilter("Armor", x => !x.vanity, smallNonVanity); + vanity.SetExclusions(new List() { vanity, armor }); + armor.SetExclusions(new List() { vanity, armor }); + categories = new List() { new Category("All", x=> true, smallAll), + // TODO: Filter out tools from weapons. Separate belongs and doesn't belong predicates? How does inheriting work again? Other? new Category("Weapons"/*, x=>x.damage>0*/, x=> false, smallWeapons) { //"Images/sortDamage" subCategories = new List() { - new Category("Melee", x=>x.melee, smallMelee), + new Category("Melee", x=>x.CountsAsClass(DamageClass.Melee) && !(x.pick>0 || x.axe>0 || x.hammer>0), smallMelee), new Category("Yoyo", x=>ItemID.Sets.Yoyo[x.type], smallYoyo), - new Category("Magic", x=>x.magic, smallMagic), - new Category("Ranged", x=>x.ranged && x.ammo == 0, smallRanged) // TODO and ammo no + new Category("Magic", x=>x.CountsAsClass(DamageClass.Magic), smallMagic), + new Category("Ranged", x=>x.CountsAsClass(DamageClass.Ranged) && x.ammo == 0, smallRanged) // TODO and ammo no { - sorts = new List() { new Sort("Use Ammo Type", "Images/sortAmmo", (x,y)=>x.useAmmo.CompareTo(y.useAmmo), x => x.useAmmo.ToString()), } + sorts = new List() { new Sort("Use Ammo Type", "Images/sortAmmo", (x,y)=>x.useAmmo.CompareTo(y.useAmmo), x => x.useAmmo.ToString()), }, + filters = new List { useAmmoFilter } }, - new Category("Throwing", x=>x.thrown, smallThrown), - new Category("Summon", x=>x.summon && !x.sentry, smallSummon), - new Category("Sentry", x=>x.summon && x.sentry, smallSentry), + new Category("Throwing", x=>x.CountsAsClass(DamageClass.Throwing), smallThrown), + new Category("Summon", x=>x.CountsAsClass(DamageClass.Summon) && !x.sentry, smallSummon), + new Category("Sentry", x=>x.CountsAsClass(DamageClass.Summon) && x.sentry, smallSentry), }, - sorts = new List() { new Sort("Damage", "Images/sortDamage", (x,y)=>x.damage.CompareTo(y.damage), x => x.damage.ToString()), } // ascending + sorts = new List() { new Sort("Damage", "Images/sortDamage", (x,y)=>x.damage.CompareTo(y.damage), x => x.damage.ToString()), }, }, new Category("Tools"/*,x=>x.pick>0||x.axe>0||x.hammer>0*/, x=>false, smallTools) { subCategories = new List() { @@ -411,16 +443,33 @@ namespace ItemChecklist new Category("Body", x=>x.bodySlot!=-1, smallBody), new Category("Legs", x=>x.legSlot!=-1, smallLegs), }, - sorts = new List() { new Sort("Defense", "Images/sortDefense", (x,y)=>x.defense.CompareTo(y.defense), x => x.defense.ToString()), } + sorts = new List() { new Sort("Defense", "Images/sortDefense", (x,y)=>x.defense.CompareTo(y.defense), x => x.defense.ToString()), }, + filters = new List { + //new Filter("Vanity", x=>x.vanity, RecipeBrowser.instance.Assets.Request("Images/sortDefense")), + // Prefer MutuallyExclusiveFilter for this, rather than CycleFilter since there are only 2 options. + //new CycleFilter("Vanity/Armor", smallVanityFilterGroup, new List { + // new Filter("Vanity", x=>x.vanity, smallVanity), + // new Filter("Armor", x=>!x.vanity, smallNonVanity), + //}), + vanity, armor, + //new DoubleFilter("Vanity", "Armor", smallVanity2, x=>x.vanity), + } }, new Category("Tiles", x=>x.createTile!=-1, smallTiles) { subCategories = new List() { - new Category("Crafting Stations", x=>craftingTiles.Contains(x.createTile), smallCraftingStation), new Category("Containers", x=>x.createTile!=-1 && Main.tileContainer[x.createTile], smallContainer), new Category("Wiring", x=>ItemID.Sets.SortingPriorityWiring[x.type] > -1, smallWiring), - new Category("Statues", x=>WorldGen.statueList.Any(point => point.X == x.createTile && point.Y == x.placeStyle), smallStatue), + new Category("Statues", x=>WorldGen.statueList.Any(point => point.X == x.createTile && point.Y == x.placeStyle), smallStatue), + new Category("Doors", x=> x.createTile > 0 && TileID.Sets.RoomNeeds.CountsAsDoor.Contains(x.createTile), ResizeImage2424(TextureAssets.Item[ItemID.WoodenDoor])), + new Category("Chairs", x=> x.createTile > 0 && TileID.Sets.RoomNeeds.CountsAsChair.Contains(x.createTile), ResizeImage2424(TextureAssets.Item[ItemID.WoodenChair])), + new Category("Tables", x=> x.createTile > 0 && TileID.Sets.RoomNeeds.CountsAsTable.Contains(x.createTile), ResizeImage2424(TextureAssets.Item[ItemID.PalmWoodTable])), + new Category("Light Sources", x=> x.createTile > 0 && TileID.Sets.RoomNeeds.CountsAsTorch.Contains(x.createTile), ResizeImage2424(TextureAssets.Item[ItemID.ChineseLantern])), + new Category("Torches", x=> x.createTile > 0 && TileID.Sets.Torch[x.createTile], ResizeImage2424(TextureAssets.Item[ItemID.RainbowTorch])), + // Banners => Banner Bonanza mod integration + //TextureAssets.Item[Main.rand.Next(TileID.Sets.RoomNeeds.CountsAsTable)] doesn't work since those are tilesids. yoyo approach? + // todo: music box //new Category("Paintings", x=>ItemID.Sets.SortingPriorityPainting[x.type] > -1, smallPaintings), // oops, this is painting tools not painting tiles //new Category("5x4", x=>{ // if(x.createTile!=-1) @@ -431,9 +480,6 @@ namespace ItemChecklist // return false; //} , smallContainer), }, - // wires - - // Banners sorts = new List() { new Sort("Place Tile", smallSortTiles, (x,y)=> x.createTile == y.createTile ? x.placeStyle.CompareTo(y.placeStyle) : x.createTile.CompareTo(y.createTile), x=>$"{x.createTile},{x.placeStyle}"), } @@ -446,17 +492,21 @@ namespace ItemChecklist new Category("Wings", x=>x.wingSlot > 0, smallWings) } }, - new Category("Ammo", x=>x.ammo!=0, ItemChecklist.instance.GetTexture("Images/sortAmmo")) + new Category("Ammo", x=>x.ammo!=0, "Images/sortAmmo") { - sorts = new List() { new Sort("Ammo Type", "Images/sortAmmo", (x,y)=>x.ammo.CompareTo(y.ammo), x => $"{x.ammo}"), } - // TODO: Filters/Subcategories for all ammo types? + sorts = new List() { + new Sort("Ammo Type", "Images/sortAmmo", (x,y)=>x.ammo.CompareTo(y.ammo), x => $"{x.ammo}"), + new Sort("Damage", "Images/sortDamage", (x,y)=>x.damage.CompareTo(y.damage), x => $"{x.damage}"), + }, + filters = new List { ammoFilter } + // TODO: Filters/Subcategories for all ammo types? // each click cycles? }, - new Category("Potions", x=>(x.UseSound != null && x.UseSound.Style == 3), smallPotions) + new Category("Potions", x=> (x.UseSound?.IsTheSameAs(SoundID.Item3) == true), smallPotions) { subCategories = new List() { new Category("Health Potions", x=>x.healLife > 0, smallHealth) { sorts = new List() { new Sort("Heal Life", smallHealth, (x,y)=>x.healLife.CompareTo(y.healLife), x => $"{x.healLife}"), } }, new Category("Mana Potions", x=>x.healMana > 0, smallMana) { sorts = new List() { new Sort("Heal Mana", smallMana, (x,y)=>x.healMana.CompareTo(y.healMana), x => $"{x.healMana}"), }}, - new Category("Buff Potions", x=>(x.UseSound != null && x.UseSound.Style == 3) && x.buffType > 0, smallBuff), + new Category("Buff Potions", x=>(x.UseSound?.IsTheSameAs(SoundID.Item3) == true) && x.buffType > 0, smallBuff), // Todo: Automatic other category? } }, @@ -474,6 +524,11 @@ namespace ItemChecklist new Category("Carts", x=>x.mountType != -1 && MountID.Sets.Cart[x.mountType], smallCarts) // TODO: need mountType check? inherited parent logic or parent unions children? } }, + new Category("Hooks", x=> Main.projHook[x.shoot], smallHooks){ + sorts = new List() { + new Sort("Grapple Range", smallHooks, (x,y)=> GrappleRange(x.shoot).CompareTo(GrappleRange(y.shoot)), x => $"{GrappleRange(x.shoot)}"), + }, + }, new Category("Dyes", x=>false, smallBothDyes) { subCategories = new List() @@ -485,7 +540,11 @@ namespace ItemChecklist new Category("Boss Summons", x=>ItemID.Sets.SortingPriorityBossSpawns[x.type] != -1 && x.type != ItemID.LifeCrystal && x.type != ItemID.ManaCrystal && x.type != ItemID.CellPhone && x.type != ItemID.IceMirror && x.type != ItemID.MagicMirror && x.type != ItemID.LifeFruit && x.netID != ItemID.TreasureMap || x.netID == ItemID.PirateMap, smallBossSummon) { // vanilla bug. sorts = new List() { new Sort("Progression Order", "Images/sortDamage", (x,y)=>ItemID.Sets.SortingPriorityBossSpawns[x.type].CompareTo(ItemID.Sets.SortingPriorityBossSpawns[y.type]), x => $"{ItemID.Sets.SortingPriorityBossSpawns[x.type]}"), } }, - new Category("Consumables", x=>x.consumable, smallConsumables), + new Category("Consumables", x=> !(x.createWall > 0 || x.createTile > -1) && !(x.ammo > 0 && !x.notAmmo) && x.consumable, smallConsumables){ + subCategories = new List() { + new Category("Captured NPC", x=>x.makeNPC != 0, ResizeImage2424(TextureAssets.Item[ItemID.GoldBunny])), + } + }, new Category("Fishing"/*, x=> x.fishingPole > 0 || x.bait>0|| x.questItem*/, x=>false, smallFishing){ subCategories = new List() { new Category("Poles", x=>x.fishingPole > 0, "Images/sortFish") {sorts = new List() { new Sort("Pole Power", "Images/sortFish", (x,y)=>x.fishingPole.CompareTo(y.fishingPole), x => $"{x.fishingPole}"), } }, @@ -516,30 +575,65 @@ namespace ItemChecklist } } } - foreach (var modCategory in RecipeBrowser.instance.modFilters) { filters.Add(new Filter(modCategory.name, modCategory.belongs, modCategory.icon)); } */ - foreach (var parent in categories) - { - foreach (var child in parent.subCategories) - { + foreach (var parent in categories) { + foreach (var child in parent.subCategories) { child.parent = parent; // 3 levels? } } - SelectedSort = sorts[0]; SelectedCategory = categories[0]; } - private bool BelongsInOther(Item item) - { + // TODO: Update with new 1.4 values. + Dictionary vanillaGrappleRanges = new Dictionary() { + [13] = 300f, + [32] = 400f, + [73] = 440f, + [74] = 440f, + [165] = 250f, + [256] = 350f, + [315] = 500f, + [322] = 550f, + [13] = 300f, + [331] = 400f, + [332] = 550f, + [372] = 400f, + [396] = 300f, + [446] = 500f, + [652] = 600f, + [646] = 550f, + [647] = 550f, + [648] = 550f, + [649] = 550f, + [486] = 480f, + [487] = 480f, + [488] = 480f, + [489] = 480f, + [230] = 300f, + [231] = 330f, + [232] = 360f, + [233] = 390f, + [234] = 420f, + [235] = 450f, + }; + + private float GrappleRange(int type) { + if (vanillaGrappleRanges.ContainsKey(type)) + return vanillaGrappleRanges[type]; + if (type > ProjectileID.Count) + return ProjectileLoader.GetProjectile(type).GrappleRange(); + return 0; + } + + private bool BelongsInOther(Item item) { var cats = categories.Skip(1).Take(categories.Count - 2); - foreach (var category in cats) - { + foreach (var category in cats) { if (category.BelongsRecursive(item)) return false; } @@ -551,21 +645,21 @@ namespace ItemChecklist { internal string name; internal Predicate belongs; - internal List subCategories; // + internal List subCategories; internal List sorts; internal UISilentImageButton button; - internal Category parent; + internal Texture2D texture; + //internal Category parent; - public Filter(string name, Predicate belongs, Texture2D texture) - { + public Filter(string name, Predicate belongs, Texture2D texture) { this.name = name; + this.texture = texture; subCategories = new List(); sorts = new List(); this.belongs = belongs; this.button = new UISilentImageButton(texture, name); - button.OnClick += (a, b) => - { + button.OnClick += (a, b) => { button.selected = !button.selected; ItemChecklistUI.instance.UpdateNeeded(); //Main.NewText("clicked on " + button.hoverText); @@ -573,25 +667,114 @@ namespace ItemChecklist } } + internal class MutuallyExclusiveFilter : Filter + { + List exclusives; + + public MutuallyExclusiveFilter(string name, Predicate belongs, Texture2D texture) : base(name, belongs, texture) { + button.OnClick += (a, b) => { + if (button.selected) { + foreach (var item in exclusives) { + if (item != this) + item.button.selected = false; + } + } + }; + } + + internal void SetExclusions(List exclusives) { + this.exclusives = exclusives; + } + } + + // A bit confusing, don't use. + internal class DoubleFilter : Filter + { + bool right; + string other; + public DoubleFilter(string name, string other, Texture2D texture, Predicate belongs) : base(name, belongs, texture) { + this.other = other; + this.belongs = (item) => { + return belongs(item) ^ right; + }; + button = new UIBadgedSilentImageButton(texture, name + " (RMB)"); + button.OnClick += (a, b) => { + button.selected = !button.selected; + ItemChecklistUI.instance.UpdateNeeded(); + //Main.NewText("clicked on " + button.hoverText); + }; + button.OnRightClick += (a, b) => { + right = !right; + (button as UIBadgedSilentImageButton).drawX = right; + button.hoverText = (right ? other : name) + " (RMB)"; + ItemChecklistUI.instance.UpdateNeeded(); + }; + } + } + + internal class CycleFilter : Filter + { + int index = 0; // different images? different backgrounds? + List filters; + List buttons = new List(); + + public CycleFilter(string name, string textureFileName, List filters) : + this(name, ItemChecklist.instance.Assets.Request(textureFileName, AssetRequestMode.ImmediateLoad).Value, filters) { + } + + public CycleFilter(string name, Texture2D texture, List filters) : base(name, (item) => false, texture) { + this.filters = filters; + this.belongs = (item) => { + return index == 0 ? true : filters[index - 1].belongs(item); + }; + //CycleFilter needs SharedUI.instance.updateNeeded to update image, since each filter acts independently. + + var firstButton = new UISilentImageButton(texture, name); + firstButton.OnClick += (a, b) => ButtonBehavior(true); + firstButton.OnRightClick += (a, b) => ButtonBehavior(false); + + buttons.Add(firstButton); + + for (int i = 0; i < filters.Count; i++) { + var buttonOption = new UISilentImageButton(filters[i].texture, filters[i].name); + buttonOption.OnClick += (a, b) => ButtonBehavior(true); + buttonOption.OnRightClick += (a, b) => ButtonBehavior(false); + buttonOption.OnMiddleClick += (a, b) => ButtonBehavior(false, true); + buttons.Add(buttonOption); + } + + button = buttons[0]; + + void ButtonBehavior(bool increment, bool zero = false) { + button.selected = false; + + index = zero ? 0 : (increment ? (index + 1) % buttons.Count : (buttons.Count + index - 1) % buttons.Count); + button = buttons[index]; + if (index != 0) + button.selected = true; + ItemChecklistUI.instance.UpdateNeeded(); + SharedUI.instance.updateNeeded = true; + } + } + } + internal class Sort { internal Func sort; internal Func badge; internal UISilentImageButton button; - public Sort(string hoverText, Texture2D texture, Func sort, Func badge) - { + public Sort(string hoverText, Texture2D texture, Func sort, Func badge) { this.sort = sort; this.badge = badge; button = new UISilentImageButton(texture, hoverText); - button.OnClick += (a, b) => - { + button.OnClick += (a, b) => { SharedUI.instance.SelectedSort = this; }; } - public Sort(string hoverText, string textureFileName, Func sort, Func badge) : this(hoverText, ItemChecklist.instance.GetTexture(textureFileName), sort, badge) - { + public Sort(string hoverText, string textureFileName, Func sort, Func badge) : + this(hoverText, ItemChecklist.instance.Assets.Request(textureFileName, AssetRequestMode.ImmediateLoad).Value, sort, badge) { } } @@ -602,8 +785,7 @@ namespace ItemChecklist internal string parent; internal Texture2D icon; internal Predicate belongs; - public ModCategory(string name, string parent, Texture2D icon, Predicate belongs) - { + public ModCategory(string name, string parent, Texture2D icon, Predicate belongs) { this.name = name; this.parent = parent; this.icon = icon; @@ -620,42 +802,46 @@ namespace ItemChecklist internal Predicate belongs; internal List subCategories; internal List sorts; + internal List filters; internal UISilentImageButton button; internal Category parent; - public Category(string name, Predicate belongs, Texture2D texture = null) - { + public Category(string name, Predicate belongs, Texture2D texture = null) { if (texture == null) - texture = ItemChecklist.instance.GetTexture("Images/sortAmmo"); + texture = ItemChecklist.instance.Assets.Request("Images/sortAmmo", AssetRequestMode.ImmediateLoad).Value; this.name = name; subCategories = new List(); sorts = new List(); + filters = new List(); this.belongs = belongs; this.button = new UISilentImageButton(texture, name); - button.OnClick += (a, b) => - { + button.OnClick += (a, b) => { //Main.NewText("clicked on " + button.hoverText); SharedUI.instance.SelectedCategory = this; }; } - public Category(string name, Predicate belongs, string textureFileName) : this(name, belongs, ItemChecklist.instance.GetTexture(textureFileName)) - { + public Category(string name, Predicate belongs, string textureFileName) : + this(name, belongs, ItemChecklist.instance.Assets.Request(textureFileName, AssetRequestMode.ImmediateLoad).Value) { } - internal bool BelongsRecursive(Item item) - { + internal bool BelongsRecursive(Item item) { if (belongs(item)) return true; return subCategories.Any(x => x.belongs(item)); } - internal void ParentAddToSorts(List availableSorts) - { + internal void ParentAddToSorts(List availableSorts) { if (parent != null) parent.ParentAddToSorts(availableSorts); availableSorts.AddRange(sorts); } + + internal void ParentAddToFilters(List availableFilters) { + if (parent != null) + parent.ParentAddToFilters(availableFilters); + availableFilters.AddRange(filters); + } } } diff --git a/UIElements/NewUITextBox.cs b/UIElements/NewUITextBox.cs index 93b435e..7bb7d60 100644 --- a/UIElements/NewUITextBox.cs +++ b/UIElements/NewUITextBox.cs @@ -2,8 +2,10 @@ using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using ReLogic.Graphics; +using ReLogic.Content; using System; using Terraria; +using Terraria.GameContent; using Terraria.GameContent.UI.Elements; using Terraria.UI; @@ -47,7 +49,7 @@ namespace ItemChecklist.UIElements BorderColor = Color.White; // keyBoardInput.newKeyEvent += KeyboardInput_newKeyEvent; - Texture2D texture = ItemChecklist.instance.GetTexture("UIElements/closeButtonSmallWhite"); + Texture2D texture = ItemChecklist.instance.Assets.Request("UIElements/closeButtonSmallWhite", AssetRequestMode.ImmediateLoad).Value; var closeButton = new UIHoverImageButton(texture, ""); closeButton.OnClick += (a, b) => SetText(""); closeButton.Left.Set(-20f, 1f); @@ -260,12 +262,12 @@ namespace ItemChecklist.UIElements { color *= 0.5f; //Utils.DrawBorderString(spriteBatch, hintText, new Vector2(space.X, space.Y), Color.Gray, 1f); - spriteBatch.DrawString(Main.fontMouseText, hintText, drawPos, color); + spriteBatch.DrawString(FontAssets.MouseText.Value, hintText, drawPos, color); } else { //Utils.DrawBorderString(spriteBatch, displayString, drawPos, Color.White, 1f); - spriteBatch.DrawString(Main.fontMouseText, displayString, drawPos, color); + spriteBatch.DrawString(FontAssets.MouseText.Value, displayString, drawPos, color); } // CalculatedStyle innerDimensions2 = base.GetInnerDimensions(); diff --git a/UIElements/UIBottomlessPanel.cs b/UIElements/UIBottomlessPanel.cs new file mode 100644 index 0000000..9836add --- /dev/null +++ b/UIElements/UIBottomlessPanel.cs @@ -0,0 +1,60 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using ReLogic.Content; +using Terraria.Graphics; +using Terraria.UI; +using Terraria; +using Terraria.GameContent.UI.Elements; +using Terraria.ModLoader; + +namespace ItemChecklist.UIElements +{ + public class UIBottomlessPanel : UIPanel + { + private static int CORNER_SIZE = 12; + private static int BAR_SIZE = 4; + private static Asset _borderTexture; + private static Asset _backgroundTexture; + + public UIBottomlessPanel() + { + if (UIBottomlessPanel._borderTexture == null) + { + UIBottomlessPanel._borderTexture = ModContent.Request("Terraria/Images/UI/PanelBorder"); + } + if (UIBottomlessPanel._backgroundTexture == null) + { + UIBottomlessPanel._backgroundTexture = ModContent.Request("Terraria/Images/UI/PanelBackground"); + } + base.SetPadding((float)UIBottomlessPanel.CORNER_SIZE); + } + + private void DrawPanel(SpriteBatch spriteBatch, Texture2D texture, Color color) + { + CalculatedStyle dimensions = base.GetDimensions(); + Point point = new Point((int)dimensions.X, (int)dimensions.Y); + Point point2 = new Point(point.X + (int)dimensions.Width - UIBottomlessPanel.CORNER_SIZE, point.Y + (int)dimensions.Height); + int width = point2.X - point.X - UIBottomlessPanel.CORNER_SIZE; + int height = point2.Y - point.Y - UIBottomlessPanel.CORNER_SIZE; + spriteBatch.Draw(texture, new Rectangle(point.X, point.Y, UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.CORNER_SIZE), new Rectangle?(new Rectangle(0, 0, UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.CORNER_SIZE)), color); + spriteBatch.Draw(texture, new Rectangle(point2.X, point.Y, UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.CORNER_SIZE), new Rectangle?(new Rectangle(UIBottomlessPanel.CORNER_SIZE + UIBottomlessPanel.BAR_SIZE, 0, UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.CORNER_SIZE)), color); + // spriteBatch.Draw(texture, new Rectangle(point.X, point2.Y, UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.CORNER_SIZE), new Rectangle?(new Rectangle(0, UIBottomlessPanel.CORNER_SIZE + UIBottomlessPanel.BAR_SIZE, UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.CORNER_SIZE)), color); + // spriteBatch.Draw(texture, new Rectangle(point2.X, point2.Y, UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.CORNER_SIZE), new Rectangle?(new Rectangle(UIBottomlessPanel.CORNER_SIZE + UIBottomlessPanel.BAR_SIZE, UIBottomlessPanel.CORNER_SIZE + UIBottomlessPanel.BAR_SIZE, UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.CORNER_SIZE)), color); + spriteBatch.Draw(texture, new Rectangle(point.X + UIBottomlessPanel.CORNER_SIZE, point.Y, width, UIBottomlessPanel.CORNER_SIZE), new Rectangle?(new Rectangle(UIBottomlessPanel.CORNER_SIZE, 0, UIBottomlessPanel.BAR_SIZE, UIBottomlessPanel.CORNER_SIZE)), color); + // spriteBatch.Draw(texture, new Rectangle(point.X + UIBottomlessPanel.CORNER_SIZE, point2.Y, width, UIBottomlessPanel.CORNER_SIZE), new Rectangle?(new Rectangle(UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.CORNER_SIZE + UIBottomlessPanel.BAR_SIZE, UIBottomlessPanel.BAR_SIZE, UIBottomlessPanel.CORNER_SIZE)), color); + spriteBatch.Draw(texture, new Rectangle(point.X, point.Y + UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.CORNER_SIZE, height), new Rectangle?(new Rectangle(0, UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.BAR_SIZE)), color); + spriteBatch.Draw(texture, new Rectangle(point2.X, point.Y + UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.CORNER_SIZE, height), new Rectangle?(new Rectangle(UIBottomlessPanel.CORNER_SIZE + UIBottomlessPanel.BAR_SIZE, UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.BAR_SIZE)), color); + spriteBatch.Draw(texture, new Rectangle(point.X + UIBottomlessPanel.CORNER_SIZE, point.Y + UIBottomlessPanel.CORNER_SIZE, width, height), new Rectangle?(new Rectangle(UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.CORNER_SIZE, UIBottomlessPanel.BAR_SIZE, UIBottomlessPanel.BAR_SIZE)), color); + } + + protected override void DrawSelf(SpriteBatch spriteBatch) + { + this.DrawPanel(spriteBatch, UIBottomlessPanel._backgroundTexture.Value, this.BackgroundColor); + this.DrawPanel(spriteBatch, UIBottomlessPanel._borderTexture.Value, this.BorderColor); + + //Rectangle hitbox = GetInnerDimensions().ToRectangle(); + //Main.spriteBatch.Draw(Main.magicPixel, hitbox, Color.Red * 0.6f); + } + } +} \ No newline at end of file diff --git a/UIElements/UICheckbox.cs b/UIElements/UICheckbox.cs index 38fc4bc..d5e0c66 100644 --- a/UIElements/UICheckbox.cs +++ b/UIElements/UICheckbox.cs @@ -1,20 +1,24 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; +using ReLogic.Content; +using Terraria; using Terraria.GameContent.UI.Elements; -using Terraria.ModLoader; using Terraria.UI; namespace ItemChecklist.UIElements { - class UICheckbox : UIText + internal class UICheckbox : UIText { - public static Texture2D checkboxTexture; - public static Texture2D checkmarkTexture; - public event EventHandler SelectedChanged; - float order = 0; + public static Asset checkboxTexture; + public static Asset checkmarkTexture; + + public event EventHandler OnSelectedChanged; private bool selected = false; + private bool disabled = false; + internal string hoverText; + public bool Selected { get { return selected; } @@ -23,47 +27,60 @@ namespace ItemChecklist.UIElements if (value != selected) { selected = value; - SelectedChanged?.Invoke(this, EventArgs.Empty); + OnSelectedChanged?.Invoke(this, EventArgs.Empty); } } } - public UICheckbox(float order, string text, float textScale = 1, bool large = false) : base(text, textScale, large) + public UICheckbox(string text, string hoverText, float textScale = 1, bool large = false) : base(text, textScale, large) { - this.order = order; this.Left.Pixels += 20; //TextColor = Color.Blue; - //OnClick += UICheckbox_onLeftClick; + text = " " + text; + this.hoverText = hoverText; + SetText(text); + OnClick += UICheckbox_onLeftClick; Recalculate(); } - //private void UICheckbox_onLeftClick(UIMouseEvent evt, UIElement listeningElement) - //{ - // this.Selected = !Selected; - //} + private void UICheckbox_onLeftClick(UIMouseEvent evt, UIElement listeningElement) + { + if (disabled) return; + this.Selected = !Selected; + } + + public void SetDisabled(bool disabled = true) + { + this.disabled = disabled; + if (disabled) + { + Selected = false; + } + TextColor = disabled ? Color.Gray : Color.White; + } + public void SetHoverText(string hoverText) + { + this.hoverText = hoverText; + } protected override void DrawSelf(SpriteBatch spriteBatch) { - CalculatedStyle innerDimensions = base.GetInnerDimensions(); - Vector2 pos = new Vector2(innerDimensions.X - 20, innerDimensions.Y - 5); - - spriteBatch.Draw(checkboxTexture, pos, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); - if (Selected) - spriteBatch.Draw(checkmarkTexture, pos, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); - base.DrawSelf(spriteBatch); - } - public override int CompareTo(object obj) - { - UICheckbox other = obj as UICheckbox; - return order.CompareTo(other.order); + CalculatedStyle innerDimensions = base.GetInnerDimensions(); + Vector2 pos = new Vector2(innerDimensions.X, innerDimensions.Y - 5); + + //Rectangle hitbox = GetInnerDimensions().ToRectangle(); + //Main.spriteBatch.Draw(Main.magicPixel, hitbox, Color.Red * 0.6f); + + spriteBatch.Draw(checkboxTexture.Value, pos, null, disabled ? Color.Gray : Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); + if (Selected) + spriteBatch.Draw(checkmarkTexture.Value, pos, null, disabled ? Color.Gray : Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); + + if (IsMouseHovering) + { + Main.hoverItemName = hoverText; + } } } -} - -//public string Text -//{ -// get { return label.Text; } -// set { label.Text = value; } -//} +} \ No newline at end of file diff --git a/UIElements/UIDragableElement.cs b/UIElements/UIDragableElement.cs new file mode 100644 index 0000000..4c7fb3d --- /dev/null +++ b/UIElements/UIDragableElement.cs @@ -0,0 +1,162 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System.Collections.Generic; +using ReLogic.Content; +using Terraria; +using Terraria.Graphics; +using Terraria.ModLoader; +using Terraria.UI; + +namespace ItemChecklist +{ + internal class UIDragableElement : UIElement + { + private static Asset dragTexture; + private Vector2 offset; + private bool dragable; + private bool dragging; + private bool resizeableX; + private bool resizeableY; + private bool resizeable => resizeableX || resizeableY; + private bool resizeing; + + //private int minX, minY, maxX, maxY; + private List additionalDragTargets; + + // TODO, move panel back in if offscreen? prevent drag off screen? + public UIDragableElement(bool dragable = true, bool resizeableX = false, bool resizeableY = false) + { + this.dragable = dragable; + this.resizeableX = resizeableX; + this.resizeableY = resizeableY; + if (dragTexture == null) + { + dragTexture = ModContent.Request("Terraria/Images/UI/PanelBorder"); + } + additionalDragTargets = new List(); + } + + public void AddDragTarget(UIElement element) + { + additionalDragTargets.Add(element); + } + + //public void SetMinMaxWidth(int min, int max) + //{ + // this.minX = min; + // this.maxX = max; + //} + + //public void SetMinMaxHeight(int min, int max) + //{ + // this.minY = min; + // this.maxY = max; + //} + + public override void MouseDown(UIMouseEvent evt) + { + DragStart(evt); + base.MouseDown(evt); + } + + public override void MouseUp(UIMouseEvent evt) + { + DragEnd(evt); + base.MouseUp(evt); + } + + private void DragStart(UIMouseEvent evt) + { + CalculatedStyle innerDimensions = GetInnerDimensions(); + if (evt.Target == this || additionalDragTargets.Contains(evt.Target)) + { + if (resizeable && new Rectangle((int)(innerDimensions.X + innerDimensions.Width - 18), (int)(innerDimensions.Y + innerDimensions.Height - 18), 18, 18).Contains(evt.MousePosition.ToPoint())) + //if (resizeable && new Rectangle((int)(innerDimensions.X + innerDimensions.Width - 12), (int)(innerDimensions.Y + innerDimensions.Height - 12), 12 + 6, 12 + 6).Contains(evt.MousePosition.ToPoint())) + { + offset = new Vector2(evt.MousePosition.X - innerDimensions.X - innerDimensions.Width, evt.MousePosition.Y - innerDimensions.Y - innerDimensions.Height); + //offset = new Vector2(evt.MousePosition.X - innerDimensions.X - innerDimensions.Width - 6, evt.MousePosition.Y - innerDimensions.Y - innerDimensions.Height - 6); + resizeing = true; + } + else if (dragable) + { + offset = new Vector2(evt.MousePosition.X - Left.Pixels, evt.MousePosition.Y - Top.Pixels); + dragging = true; + } + } + } + + private void DragEnd(UIMouseEvent evt) + { + if (evt.Target == this || additionalDragTargets.Contains(evt.Target)) + { + dragging = false; + resizeing = false; + } + if(this == ItemChecklistUI.instance.mainPanel) { + ItemChecklistClientConfig config = ModContent.GetInstance(); + CalculatedStyle dimensions = GetOuterDimensions(); // Drag can go negative, need clamped by Min and Max values + config.ItemChecklistSize = new Vector2(dimensions.Width, dimensions.Height); + config.ItemChecklistPosition = new Vector2(Left.Pixels, Top.Pixels); + ItemChecklistClientConfig.SaveConfig(); + } + } + + protected override void DrawSelf(SpriteBatch spriteBatch) + { + //Rectangle hitbox = GetInnerDimensions().ToRectangle(); + //Main.spriteBatch.Draw(Main.magicPixel, hitbox, Color.Red * 0.6f); + + CalculatedStyle dimensions = base.GetOuterDimensions(); + if (ContainsPoint(Main.MouseScreen)) + { + Main.LocalPlayer.mouseInterface = true; + Main.LocalPlayer.cursorItemIconEnabled = false; + Main.ItemIconCacheUpdate(0); + } + if (dragging) + { + Left.Set(Main.MouseScreen.X - offset.X, 0f); + Top.Set(Main.MouseScreen.Y - offset.Y, 0f); + Recalculate(); + } + if (resizeing) + { + if (resizeableX) + { + //Width.Pixels = Utils.Clamp(Main.MouseScreen.X - dimensions.X - offset.X, minX, maxX); + Width.Pixels = Main.MouseScreen.X - dimensions.X - offset.X; + } + if (resizeableY) + { + //Height.Pixels = Utils.Clamp(Main.MouseScreen.Y - dimensions.Y - offset.Y, minY, maxY); + Height.Pixels = Main.MouseScreen.Y - dimensions.Y - offset.Y; + } + Recalculate(); + } + base.DrawSelf(spriteBatch); + } + + protected override void DrawChildren(SpriteBatch spriteBatch) + { + base.DrawChildren(spriteBatch); + if (resizeable) + { + DrawDragAnchor(spriteBatch, dragTexture.Value, Color.Black/*this.BorderColor*/); + } + } + + private void DrawDragAnchor(SpriteBatch spriteBatch, Texture2D texture, Color color) + { + CalculatedStyle dimensions = GetOuterDimensions(); + + //Rectangle hitbox = GetInnerDimensions().ToRectangle(); + //hitbox = new Rectangle((int)(innerDimensions.X + innerDimensions.Width - 18), (int)(innerDimensions.Y + innerDimensions.Height - 18), 18, 18); + //Main.spriteBatch.Draw(Main.magicPixel, hitbox, Color.LightBlue * 0.6f); + + Point point = new Point((int)(dimensions.X + dimensions.Width - 12), (int)(dimensions.Y + dimensions.Height - 12)); + spriteBatch.Draw(texture, new Rectangle(point.X - 2, point.Y - 2, 12 - 2, 12 - 2), new Rectangle(12 + 4, 12 + 4, 12, 12), color); + spriteBatch.Draw(texture, new Rectangle(point.X - 4, point.Y - 4, 12 - 4, 12 - 4), new Rectangle(12 + 4, 12 + 4, 12, 12), color); + spriteBatch.Draw(texture, new Rectangle(point.X - 6, point.Y - 6, 12 - 6, 12 - 6), new Rectangle(12 + 4, 12 + 4, 12, 12), color); + } + } +} \ No newline at end of file diff --git a/UIElements/UIGrid.cs b/UIElements/UIGrid.cs index c7be839..2bb945c 100644 --- a/UIElements/UIGrid.cs +++ b/UIElements/UIGrid.cs @@ -1,12 +1,13 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; using System; using System.Collections.Generic; using Terraria; using Terraria.GameContent.UI.Elements; using Terraria.UI; -namespace ItemChecklist.UIElements +namespace ItemChecklist { public class UIGrid : UIElement { @@ -41,6 +42,9 @@ namespace ItemChecklist.UIElements private float _innerListHeight; public float ListPadding = 5f; + public static Asset moreUpTexture; + public static Asset moreDownTexture; + public int Count { get @@ -49,11 +53,9 @@ namespace ItemChecklist.UIElements } } - int cols = 1; - - public UIGrid(int columns = 1) + // todo, vertical/horizontal orientation, left to right, etc? + public UIGrid() { - cols = columns; this._innerList.OverflowHidden = false; this._innerList.Width.Set(0f, 1f); this._innerList.Height.Set(0f, 1f); @@ -66,16 +68,23 @@ namespace ItemChecklist.UIElements return this._innerListHeight; } - public void Goto(UIGrid.ElementSearchMethod searchMethod, bool center = false) + public void Goto(UIGrid.ElementSearchMethod searchMethod, bool center = false, bool fuzzy = false) { + var innerDimensionHeight = GetInnerDimensions().Height; for (int i = 0; i < this._items.Count; i++) { - if (searchMethod(this._items[i])) + var item = this._items[i]; + if (searchMethod(item)) { - this._scrollbar.ViewPosition = this._items[i].Top.Pixels; + if (fuzzy) + { + if (item.Top.Pixels > _scrollbar.ViewPosition && item.Top.Pixels + item.GetOuterDimensions().Height < _scrollbar.ViewPosition + innerDimensionHeight) + return; + } + this._scrollbar.ViewPosition = item.Top.Pixels; if (center) { - this._scrollbar.ViewPosition = this._items[i].Top.Pixels - GetInnerDimensions().Height/2 + _items[i].GetOuterDimensions().Height/2; + this._scrollbar.ViewPosition = item.Top.Pixels - innerDimensionHeight / 2 + item.GetOuterDimensions().Height / 2; } return; } @@ -129,30 +138,28 @@ namespace ItemChecklist.UIElements public override void RecalculateChildren() { + float availableWidth = GetInnerDimensions().Width; base.RecalculateChildren(); float top = 0f; float left = 0f; + float maxRowHeight = 0f; for (int i = 0; i < this._items.Count; i++) { - this._items[i].Top.Set(top, 0f); - this._items[i].Left.Set(left, 0f); - this._items[i].Recalculate(); - if (i % cols == cols - 1) + var item = this._items[i]; + var outerDimensions = item.GetOuterDimensions(); + if (left + outerDimensions.Width > availableWidth && left > 0) { - top += this._items[i].GetOuterDimensions().Height + this.ListPadding; + top += maxRowHeight + this.ListPadding; left = 0; + maxRowHeight = 0; } - else - { - left += this._items[i].GetOuterDimensions().Width + this.ListPadding; - } - //num += this._items[i].GetOuterDimensions().Height + this.ListPadding; + maxRowHeight = Math.Max(maxRowHeight, outerDimensions.Height); + item.Left.Set(left, 0f); + left += outerDimensions.Width + this.ListPadding; + item.Top.Set(top, 0f); + item.Recalculate(); } - if (_items.Count > 0) - { - top += ListPadding + _items[0].GetOuterDimensions().Height; - } - this._innerListHeight = top; + this._innerListHeight = top + maxRowHeight; } private void UpdateScrollbar() @@ -170,6 +177,7 @@ namespace ItemChecklist.UIElements this.UpdateScrollbar(); } + //internal delegate int ElementSort(UIElement item1, UIElement item2); internal Comparison alternateSort; public void UpdateOrder() { @@ -206,7 +214,25 @@ namespace ItemChecklist.UIElements { this._innerList.Top.Set(-this._scrollbar.GetValue(), 0f); } + if (IsMouseHovering) + Terraria.GameInput.PlayerInput.LockVanillaMouseScroll("RecipeBrowser/UIHorizontalGrid"); this.Recalculate(); } + + public bool drawArrows; + protected override void DrawChildren(SpriteBatch spriteBatch) { + base.DrawChildren(spriteBatch); + if (drawArrows) { + var inner = GetInnerDimensions().ToRectangle(); + if (this._scrollbar.ViewPosition != 0) { + int centeredX = inner.X + inner.Width / 2 - moreUpTexture.Width() / 2; + spriteBatch.Draw(moreUpTexture.Value, new Vector2(centeredX, inner.Y), Color.White * .5f); + } + if (this._scrollbar.ViewPosition < _innerListHeight - inner.Height) { + int centeredX = inner.X + inner.Width / 2 - moreUpTexture.Width() / 2; + spriteBatch.Draw(moreDownTexture.Value, new Vector2(centeredX, inner.Bottom - moreDownTexture.Height()), Color.White * .5f); + } + } + } } -} +} \ No newline at end of file diff --git a/UIElements/UIHorizontalGrid.cs b/UIElements/UIHorizontalGrid.cs index 67d9986..3e17a02 100644 --- a/UIElements/UIHorizontalGrid.cs +++ b/UIElements/UIHorizontalGrid.cs @@ -1,9 +1,12 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using ItemChecklist.UIElements; using System; using System.Collections.Generic; +using ReLogic.Content; using Terraria; using Terraria.UI; +using Terraria.GameInput; namespace ItemChecklist.UIElements { @@ -40,8 +43,8 @@ namespace ItemChecklist.UIElements private float _innerListWidth; public float ListPadding = 5f; - public static Texture2D moreLeftTexture; - public static Texture2D moreRightTexture; + public static Asset moreLeftTexture; + public static Asset moreRightTexture; public int Count { @@ -203,6 +206,8 @@ namespace ItemChecklist.UIElements { this._innerList.Left.Set(-this._scrollbar.GetValue(), 0f); } + if(IsMouseHovering) + PlayerInput.LockVanillaMouseScroll("RecipeBrowser/UIHorizontalGrid"); this.Recalculate(); } @@ -215,11 +220,13 @@ namespace ItemChecklist.UIElements var inner = GetInnerDimensions().ToRectangle(); if (this._scrollbar.ViewPosition != 0) { - spriteBatch.Draw(moreLeftTexture, new Vector2(inner.X, inner.Y), Color.White * .5f); + int centeredY = inner.Y + inner.Height / 2 - moreLeftTexture.Height() / 2; + spriteBatch.Draw(moreLeftTexture.Value, new Vector2(inner.X, centeredY), Color.White * .5f); } - if (this._scrollbar.ViewPosition < _innerListWidth - inner.Width) + if (this._scrollbar.ViewPosition < _innerListWidth - inner.Width - 1) // -1 due to odd width leading to 0.5 view position offset. { - spriteBatch.Draw(moreRightTexture, new Vector2(inner.Right - moreRightTexture.Width, inner.Y), Color.White * .5f); + int centeredY = inner.Y + inner.Height / 2 - moreRightTexture.Height() / 2; + spriteBatch.Draw(moreRightTexture.Value, new Vector2(inner.Right - moreRightTexture.Width(), centeredY), Color.White * .5f); } } } diff --git a/UIElements/UIHorizontalScrollbar.cs b/UIElements/UIHorizontalScrollbar.cs index 97525e6..4817c8e 100644 --- a/UIElements/UIHorizontalScrollbar.cs +++ b/UIElements/UIHorizontalScrollbar.cs @@ -1,6 +1,9 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using ReLogic.Content; using Terraria; +using Terraria.Audio; +using Terraria.ID; using Terraria.UI; namespace ItemChecklist.UIElements @@ -32,8 +35,8 @@ namespace ItemChecklist.UIElements { this.Height.Set(20f, 0f); this.MaxHeight.Set(20f, 0f); - this._texture = ItemChecklist.instance.GetTexture("UIElements/ScrollbarHorizontal"); //TextureManager.Load("Images/UI/Scrollbar"); - this._innerTexture = ItemChecklist.instance.GetTexture("UIElements/ScrollbarInnerHorizontal"); //TextureManager.Load("Images/UI/ScrollbarInner"); + this._texture = ItemChecklist.instance.Assets.Request("UIElements/ScrollbarHorizontal", AssetRequestMode.ImmediateLoad).Value; //TextureManager.Load("Images/UI/Scrollbar"); + this._innerTexture = ItemChecklist.instance.Assets.Request("UIElements/ScrollbarInnerHorizontal", AssetRequestMode.ImmediateLoad).Value; //TextureManager.Load("Images/UI/ScrollbarInner"); this.PaddingLeft = 5f; this.PaddingRight = 5f; } @@ -88,7 +91,7 @@ namespace ItemChecklist.UIElements this._isHoveringOverHandle = handleRectangle.Contains(new Point((int)mousePosition.X, (int)mousePosition.Y)); if (!isHoveringOverHandle && this._isHoveringOverHandle && Main.hasFocus) { - Main.PlaySound(12, -1, -1, 1, 1f, 0f); + SoundEngine.PlaySound(SoundID.MenuTick); } this.DrawBar(spriteBatch, this._texture, dimensions.ToRectangle(), Color.White); this.DrawBar(spriteBatch, this._innerTexture, handleRectangle, Color.White * ((this._isDragging || this._isHoveringOverHandle) ? 1f : 0.85f)); diff --git a/UIElements/UIItemSlot.cs b/UIElements/UIItemSlot.cs index 17cffa0..d3c6a28 100644 --- a/UIElements/UIItemSlot.cs +++ b/UIElements/UIItemSlot.cs @@ -1,114 +1,227 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using ReLogic.Graphics; +using ReLogic.Content; using Terraria; -using Terraria.UI; +using Terraria.GameContent; +using Terraria.GameContent.UI.Elements; +using Terraria.ID; +using Terraria.ModLoader; +using Terraria.UI; +using Terraria.UI.Chat; namespace ItemChecklist.UIElements { internal class UIItemSlot : UIElement { - public static Texture2D backgroundTexture = Main.inventoryBack9Texture; - - private Texture2D _texture; - // private float _visibilityActive = 1f; - // private float _visibilityInactive = 0.4f; - private float scale = 0.75f; - internal int id; - internal Item item; + public static Asset defaultBackgroundTexture = TextureAssets.InventoryBack9; + public Asset backgroundTexture = defaultBackgroundTexture; + internal float scale = .75f; + public int itemType; + public Item item; + public int id; + public bool hideSlot = false; + internal static Item hoveredItem; public string badge; - public UIItemSlot(int id) + public UIItemSlot(Item item, int id, float scale = .75f) { - this._texture = Main.itemTexture[id]; + this.scale = scale; + this.item = item; this.id = id; - this.item = new Item(); - item.SetDefaults(id, true); - - this.Width.Set(backgroundTexture.Width * scale, 0f); - this.Height.Set(backgroundTexture.Height * scale, 0f); + this.itemType = item.type; + this.Width.Set(defaultBackgroundTexture.Width() * scale, 0f); + this.Height.Set(defaultBackgroundTexture.Height() * scale, 0f); } - //public override int CompareTo(object obj) - //{ - // UIItemSlot other = obj as UIItemSlot; - // int result; - // switch (ItemChecklistUI.sortMode) - // { - // case SortModes.ID: - // return id.CompareTo(other.id); - // case SortModes.AZ: - // return item.Name.CompareTo(other.item.Name); - // case SortModes.Value: - // result = item.value.CompareTo(other.item.value); - // if (result == 0) - // result = item.Name.CompareTo(other.item.Name); - // return result; - // case SortModes.Rare: - // result = item.rare.CompareTo(other.item.rare); - // if (result == 0) - // result = item.Name.CompareTo(other.item.Name); - // return result; - // case SortModes.TerrariaSort: - // return ItemChecklistUI.vanillaIDsInSortOrder[id].CompareTo(ItemChecklistUI.vanillaIDsInSortOrder[other.id]); - // } - - // return id.CompareTo(other.id); - //} + internal int frameCounter = 0; + internal int frameTimer = 0; + private const int frameDelay = 7; protected override void DrawSelf(SpriteBatch spriteBatch) { - CalculatedStyle dimensions = base.GetDimensions(); - //spriteBatch.Draw(this._texture, dimensions.Position(), Color.White * (base.IsMouseHovering ? this._visibilityActive : this._visibilityInactive)); - - spriteBatch.Draw(backgroundTexture, dimensions.Position(), null, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f); - //Texture2D texture2D = Main.itemTexture[this.item.type]; - Rectangle rectangle2; - if (Main.itemAnimations[id] != null) + if (item != null) { - rectangle2 = Main.itemAnimations[id].GetFrame(_texture); - } - else - { - rectangle2 = _texture.Frame(1, 1, 0, 0); - } - float num = 1f; - float num2 = (float)backgroundTexture.Width * scale; - if ((float)rectangle2.Width > num2 || (float)rectangle2.Height > num2) - { - if (rectangle2.Width > rectangle2.Height) + CalculatedStyle dimensions = base.GetInnerDimensions(); + Rectangle rectangle = dimensions.ToRectangle(); + if (!hideSlot) { - num = num2 / (float)rectangle2.Width; + spriteBatch.Draw(backgroundTexture.Value, dimensions.Position(), null, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f); + DrawAdditionalOverlays(spriteBatch, dimensions.Position(), scale); + } + if (!item.IsAir) + { + Main.instance.LoadItem(this.item.type); + Texture2D itemTexture = TextureAssets.Item[this.item.type].Value; + Rectangle rectangle2 = Main.itemAnimations[item.type]?.GetFrame(itemTexture) ?? itemTexture.Frame(); + Color newColor = Color.White; + float pulseScale = 1f; + ItemSlot.GetItemLight(ref newColor, ref pulseScale, item, false); + int height = rectangle2.Height; + int width = rectangle2.Width; + float drawScale = 1f; + float availableWidth = (float)defaultBackgroundTexture.Width() * scale; + if (width > availableWidth || height > availableWidth) + { + if (width > height) + { + drawScale = availableWidth / width; + } + else + { + drawScale = availableWidth / height; + } + } + drawScale *= scale; + Vector2 vector = backgroundTexture.Size() * scale; + Vector2 position2 = dimensions.Position() + vector / 2f - rectangle2.Size() * drawScale / 2f; + Vector2 origin = rectangle2.Size() * (pulseScale / 2f - 0.5f); + //Vector2 drawPosition = dimensions.Position(); + //drawPosition.X += defaultBackgroundTexture.Width * scale / 2f - (float)width * drawScale / 2f; + //drawPosition.Y += defaultBackgroundTexture.Height * scale / 2f - (float)height * drawScale / 2f; + + Color alphaColor = Main.LocalPlayer.GetModPlayer().foundItem[id] ? item.GetAlpha(newColor) : Color.Black; + Color colorColor = Main.LocalPlayer.GetModPlayer().foundItem[id] ? item.GetColor(Color.White) : Color.Black; + + if (ItemLoader.PreDrawInInventory(item, spriteBatch, position2, rectangle2, alphaColor, + colorColor, origin, drawScale * pulseScale)) + { + spriteBatch.Draw(itemTexture, position2, new Rectangle?(rectangle2), alphaColor, 0f, origin, drawScale * pulseScale, SpriteEffects.None, 0f); + if (item.color != Color.Transparent) + { + spriteBatch.Draw(itemTexture, position2, new Rectangle?(rectangle2), colorColor, 0f, origin, drawScale * pulseScale, SpriteEffects.None, 0f); + } + } + ItemLoader.PostDrawInInventory(item, spriteBatch, position2, rectangle2, alphaColor, + colorColor, origin, drawScale * pulseScale); + if (ItemID.Sets.TrapSigned[item.type]) + { + spriteBatch.Draw(TextureAssets.Wire.Value, dimensions.Position() + new Vector2(40f, 40f) * scale, new Rectangle?(new Rectangle(4, 58, 8, 8)), Color.White, 0f, new Vector2(4f), 1f, SpriteEffects.None, 0f); + } + DrawAdditionalBadges(spriteBatch, dimensions.Position(), scale); + if (item.stack > 1) + { + ChatManager.DrawColorCodedStringWithShadow(spriteBatch, FontAssets.ItemStack.Value, item.stack.ToString(), dimensions.Position() + new Vector2(10f, 26f) * scale, Color.White, 0f, Vector2.Zero, new Vector2(scale), -1f, scale); + } + + //this.item.GetColor(Color.White); + //spriteBatch.Draw(itemTexture, drawPosition, rectangle2, this.item.GetAlpha(Color.White), 0f, Vector2.Zero, drawScale, SpriteEffects.None, 0f); + //if (this.item.color != default(Color)) + //{ + // spriteBatch.Draw(itemTexture, drawPosition, new Rectangle?(rectangle2), this.item.GetColor(Color.White), 0f, Vector2.Zero, drawScale, SpriteEffects.None, 0f); + //} + //if (this.item.stack > 1) + //{ + // spriteBatch.DrawString(Main.fontItemStack, this.item.stack.ToString(), new Vector2(drawPosition.X + 10f * scale, drawPosition.Y + 26f * scale), Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f); + //} + + if (ItemChecklistUI.showBadge && !string.IsNullOrEmpty(badge)) + { + spriteBatch.DrawString(FontAssets.ItemStack.Value, badge, new Vector2(dimensions.Position().X + 10f * scale, dimensions.Position().Y + 26f * scale), Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f); + } + + if (IsMouseHovering) + { + // TODO, should only need 2 of these 3 I think + Main.HoverItem = item.Clone(); + Main.hoverItemName = Main.HoverItem.Name + (Main.HoverItem.ModItem != null && ModContent.GetInstance().ShowItemModSource ? " [" + Main.HoverItem.ModItem.Mod.DisplayName + "]" : ""); + + // Main.hoverItemName = this.item.name; + // Main.toolTip = item.Clone(); + Main.HoverItem.SetNameOverride(Main.HoverItem.Name + (Main.HoverItem.ModItem != null && ModContent.GetInstance().ShowItemModSource ? " [" + Main.HoverItem.ModItem.Mod.DisplayName + "]" : "")); + + hoveredItem = Main.HoverItem; + } + } + } + } + + internal virtual void DrawAdditionalOverlays(SpriteBatch spriteBatch, Vector2 vector2, float scale) + { + } + + internal virtual void DrawAdditionalBadges(SpriteBatch spriteBatch, Vector2 vector2, float scale) + { + } + } + + internal class UIItemNoSlot : UIElement + { + internal float scale = .75f; + public int itemType; + public Item item; + public UIItemNoSlot(Item item, float scale = .75f) + { + this.scale = scale; + this.item = item; + this.itemType = item.type; + this.Width.Set(32f * scale * 0.65f, 0f); + this.Height.Set(32f * scale * 0.65f, 0f); + } + + public override void Draw(SpriteBatch spriteBatch) + { + base.Draw(spriteBatch); + + Vector2 position = GetInnerDimensions().Position(); + float num = 1f; + float num2 = 1f; + if (Main.netMode != NetmodeID.Server && !Main.dedServ) + { + Texture2D texture2D = TextureAssets.Item[item.type].Value; + Rectangle rectangle; + if (Main.itemAnimations[item.type] != null) + { + rectangle = Main.itemAnimations[item.type].GetFrame(texture2D); } else { - num = num2 / (float)rectangle2.Height; + rectangle = texture2D.Frame(1, 1, 0, 0); + } + if (rectangle.Height > 32) + { + num2 = 32f / (float)rectangle.Height; } } - Vector2 drawPosition = dimensions.Position(); - drawPosition.X += (float)backgroundTexture.Width * scale / 2f - (float)rectangle2.Width * num / 2f; - drawPosition.Y += (float)backgroundTexture.Height * scale / 2f - (float)rectangle2.Height * num / 2f; - - item.GetColor(Color.White); - Color alphaColor = Main.LocalPlayer.GetModPlayer(ItemChecklist.instance).foundItem[id] ? this.item.GetAlpha(Color.White) : Color.Black; - Color colorColor = Main.LocalPlayer.GetModPlayer(ItemChecklist.instance).foundItem[id] ? this.item.GetColor(Color.White) : Color.Black; - //spriteBatch.Draw(_texture, drawPosition, new Rectangle?(rectangle2), this.item.GetAlpha(Color.White), 0f, Vector2.Zero, num, SpriteEffects.None, 0f); - spriteBatch.Draw(_texture, drawPosition, new Rectangle?(rectangle2), alphaColor, 0f, Vector2.Zero, num, SpriteEffects.None, 0f); - if (this.item.color != Color.Transparent) + num2 *= scale; + num *= num2; + if (num > 0.75f) { - spriteBatch.Draw(_texture, drawPosition, new Rectangle?(rectangle2), colorColor, 0f, Vector2.Zero, num, SpriteEffects.None, 0f); + num = 0.75f; } - if (ItemChecklistUI.showBadge && !string.IsNullOrEmpty(badge)) { - spriteBatch.DrawString(Main.fontItemStack, badge, new Vector2(dimensions.Position().X + 10f * scale, dimensions.Position().Y + 26f * scale), Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f); + float inventoryScale = Main.inventoryScale; + Main.inventoryScale = scale * num; + ItemSlot.Draw(spriteBatch, ref item, 14, position - new Vector2(10f) * scale * num, Color.White); + Main.inventoryScale = inventoryScale; } if (IsMouseHovering) { - ItemChecklistUI.hoverText = item.Name + (item.modItem != null ? " [" + item.modItem.mod.Name + "]" : ""); + //Main.HoverItem = item.Clone(); + //Main.instance.MouseText(item.Name, item.rare, 0, -1, -1, -1, -1); - Main.HoverItem = item.Clone(); + Main.hoverItemName = item.Name; } } } -} + + //internal class UIHoverText : UIText + //{ + // string hover; + // public UIHoverText(string hover, string text, float textScale = 1f, bool large = false) : base(text, textScale, large) + // { + // this.hover = hover; + // } + + // protected override void DrawSelf(SpriteBatch spriteBatch) + // { + // base.DrawSelf(spriteBatch); + + // if (IsMouseHovering) + // { + // Main.hoverItemName = hover; + // } + // } + //} +} \ No newline at end of file diff --git a/UIElements/UISilentImageButton.cs b/UIElements/UISilentImageButton.cs index e98708c..e126899 100644 --- a/UIElements/UISilentImageButton.cs +++ b/UIElements/UISilentImageButton.cs @@ -1,10 +1,32 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using ReLogic.Graphics; using Terraria; +using Terraria.GameContent; using Terraria.UI; +using Terraria.UI.Chat; namespace ItemChecklist.UIElements { + // A bit confusing, don't use. + class UIBadgedSilentImageButton : UISilentImageButton + { + internal bool drawX = false; + public UIBadgedSilentImageButton(Texture2D texture, string hoverText) : base(texture, hoverText) { + } + + protected override void DrawSelf(SpriteBatch spriteBatch) { + base.DrawSelf(spriteBatch); + if (drawX) { + CalculatedStyle dimensions = base.GetDimensions(); + //ChatManager.DrawColorCodedStringWithShadow(spriteBatch, Main.fontItemStack, "X", dimensions.Position() + new Vector2(14f, 10f), Color.LightSalmon, 0f, Vector2.Zero, new Vector2(0.7f)); + var r = dimensions.ToRectangle(); + r.Inflate(-2, -2); + spriteBatch.Draw(TextureAssets.Cd.Value, r, null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 0); + } + } + } + class UISilentImageButton : UIElement { private Texture2D _texture; @@ -15,41 +37,39 @@ namespace ItemChecklist.UIElements public bool selected; internal string hoverText; - public UISilentImageButton(Texture2D texture, string hoverText) - { + public UISilentImageButton(Texture2D texture, string hoverText) { this._texture = texture; this.Width.Set((float)this._texture.Width, 0f); this.Height.Set((float)this._texture.Height, 0f); this.hoverText = hoverText; + + base.Recalculate(); } - public void SetImage(Texture2D texture) - { + public void SetImage(Texture2D texture) { this._texture = texture; this.Width.Set((float)this._texture.Width, 0f); this.Height.Set((float)this._texture.Height, 0f); + + base.Recalculate(); } - protected override void DrawSelf(SpriteBatch spriteBatch) - { - if (selected) - { + protected override void DrawSelf(SpriteBatch spriteBatch) { + if (selected) { var r = GetDimensions().ToRectangle(); - r.Inflate(0,0); + r.Inflate(0, 0); //spriteBatch.Draw(UIElements.UIRecipeSlot.selectedBackgroundTexture, r, Color.White); - spriteBatch.Draw( Main.inventoryBack14Texture, r, Color.White); + spriteBatch.Draw(TextureAssets.InventoryBack14.Value, r, Color.White); } CalculatedStyle dimensions = base.GetDimensions(); - spriteBatch.Draw(this._texture, dimensions.Position(), Color.White * (selected ? _visibilityActive : ( IsMouseHovering ? _visibilityHovered : this._visibilityInactive))); - if (IsMouseHovering) - { + spriteBatch.Draw(this._texture, dimensions.Position(), Color.White * (selected ? _visibilityActive : (IsMouseHovering ? _visibilityHovered : this._visibilityInactive))); + if (IsMouseHovering) { Main.hoverItemName = hoverText; } } - public override void MouseOver(UIMouseEvent evt) - { + public override void MouseOver(UIMouseEvent evt) { base.MouseOver(evt); //Main.PlaySound(12, -1, -1, 1, 1f, 0f); } @@ -60,4 +80,4 @@ namespace ItemChecklist.UIElements // this._visibilityInactive = MathHelper.Clamp(whenInactive, 0f, 1f); //} } -} +} \ No newline at end of file diff --git a/UIElements/UIToggleHoverImageButton.cs b/UIElements/UIToggleHoverImageButton.cs index b18de9b..d78eb77 100644 --- a/UIElements/UIToggleHoverImageButton.cs +++ b/UIElements/UIToggleHoverImageButton.cs @@ -1,6 +1,8 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Terraria; +using Terraria.Audio; +using Terraria.ID; using Terraria.UI; namespace ItemChecklist.UIElements @@ -47,7 +49,7 @@ namespace ItemChecklist.UIElements public override void MouseOver(UIMouseEvent evt) { base.MouseOver(evt); - Main.PlaySound(12, -1, -1, 1, 1f, 0f); + SoundEngine.PlaySound(SoundID.MenuTick); } } @@ -80,7 +82,7 @@ namespace ItemChecklist.UIElements public override void MouseOver(UIMouseEvent evt) { base.MouseOver(evt); - Main.PlaySound(12, -1, -1, 1, 1f, 0f); + SoundEngine.PlaySound(SoundID.MenuTick); } public void SetVisibility(float whenActive, float whenInactive) diff --git a/Utilities.cs b/Utilities.cs index 61f3cf3..241e721 100644 --- a/Utilities.cs +++ b/Utilities.cs @@ -1,11 +1,36 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using ReLogic.Content; using Terraria; +using Terraria.GameContent; +using Terraria.ID; +using Terraria.Map; +using Terraria.ObjectData; +using Terraria.ModLoader; namespace ItemChecklist { static class Utilities { + //public static Asset ToAsset(this Texture2D texture) + //{ + // using MemoryStream stream = new(); + // texture.SaveAsPng(stream, texture.Width, texture.Height); + // stream.Position = 0; + // return RecipeBrowser.instance.Assets.CreateUntracked(stream, "any.png"); + //} + + internal static Texture2D StackResizeImage(Asset[] texture2D, int desiredWidth, int desiredHeight) + { + foreach (Asset asset in texture2D) + asset.Wait?.Invoke(); + + return StackResizeImage(texture2D.Select(asset => asset.Value).ToArray(), desiredWidth, desiredHeight); + } + internal static Texture2D StackResizeImage(Texture2D[] texture2D, int desiredWidth, int desiredHeight) { float overlap = .5f; @@ -43,9 +68,16 @@ namespace ItemChecklist Color[] content = new Color[desiredWidth * desiredHeight]; renderTarget.GetData(content); mergedTexture.SetData(content); + return mergedTexture; } + internal static Texture2D ResizeImage(Asset asset, int desiredWidth, int desiredHeight) + { + asset.Wait?.Invoke(); + return ResizeImage(asset.Value, desiredWidth, desiredHeight); + } + internal static Texture2D ResizeImage(Texture2D texture2D, int desiredWidth, int desiredHeight) { RenderTarget2D renderTarget = new RenderTarget2D(Main.graphics.GraphicsDevice, desiredWidth, desiredHeight); @@ -70,10 +102,103 @@ namespace ItemChecklist Texture2D mergedTexture = new Texture2D(Main.instance.GraphicsDevice, desiredWidth, desiredHeight); Color[] content = new Color[desiredWidth * desiredHeight]; - renderTarget.GetData(content); + renderTarget.GetData(content); mergedTexture.SetData(content); + return mergedTexture; } - } -} + internal static Dictionary tileTextures; + + internal static void GenerateTileTexture(int tile) + { + Texture2D texture; + Main.instance.LoadTiles(tile); + + var tileObjectData = TileObjectData.GetTileData(tile, 0, 0); + if (tileObjectData == null) + { + tileTextures[tile] = TextureAssets.MagicPixel.Value; + return; + } + + int width = tileObjectData.Width; + int height = tileObjectData.Height; + int padding = tileObjectData.CoordinatePadding; + + //Main.spriteBatch.End(); + RenderTarget2D renderTarget = new RenderTarget2D(Main.graphics.GraphicsDevice, width * 16, height * 16); + Main.instance.GraphicsDevice.SetRenderTarget(renderTarget); + Main.instance.GraphicsDevice.Clear(Color.Transparent); + Main.spriteBatch.Begin(); + + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + Main.spriteBatch.Draw(TextureAssets.Tile[tile].Value, new Vector2(i * 16, j * 16), new Rectangle(i * 16 + i * padding, j * 16 + j * padding, 16, 16), Color.White, 0f, Vector2.Zero, 1, SpriteEffects.None, 0f); + } + } + + Main.spriteBatch.End(); + Main.instance.GraphicsDevice.SetRenderTarget(null); + + texture = new Texture2D(Main.instance.GraphicsDevice, width * 16, height * 16); + Color[] content = new Color[width * 16 * height * 16]; + renderTarget.GetData(content); + texture.SetData(content); + tileTextures[tile] = texture; + } + + internal static string GetTileName(int tile) + { + int requiredTileStyle = Recipe.GetRequiredTileStyle(tile); + string tileName = Lang.GetMapObjectName(MapHelper.TileToLookup(tile, requiredTileStyle)); + if (tileName == "") + { + if (tile < TileID.Count) + tileName = TileID.Search.GetName(tile);// $"Tile {tile}"; + else + tileName = Terraria.ModLoader.TileLoader.GetTile(tile).Name + " (err no entry)"; + } + return tileName; + } + + internal static List PopulateAdjTilesForTile(int Tile) { + List adjTiles = new List(); + adjTiles.Add(Tile); + + ModTile modTile = TileLoader.GetTile(Tile); + if (modTile != null) { + adjTiles.AddRange(modTile.AdjTiles); + } + if (Tile == 302) + adjTiles.Add(17); + if (Tile == 77) + adjTiles.Add(17); + if (Tile == 133) { + adjTiles.Add(17); + adjTiles.Add(77); + } + if (Tile == 134) + adjTiles.Add(16); + if (Tile == 354) + adjTiles.Add(14); + if (Tile == 469) + adjTiles.Add(14); + if (Tile == 487) + adjTiles.Add(14); + if (Tile == 355) { + adjTiles.Add(13); + adjTiles.Add(14); + } + // TODO: GlobalTile.AdjTiles support (no player object, reflection needed since private) + return adjTiles; + } + + internal static Color textColor = Color.White; // new Color(Main.mouseTextColor, Main.mouseTextColor, Main.mouseTextColor); + internal static Color noColor = Color.LightSalmon; // OrangeRed Red + internal static Color yesColor = Color.LightGreen; // Green + internal static Color maybeColor = Color.Yellow; // LightYellow LightGoldenrodYellow Yellow Goldenrod + } +} \ No newline at end of file