diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c07de7e --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +bin +obj +*.user +App.config \ No newline at end of file diff --git a/ItemChecklist.cs b/ItemChecklist.cs new file mode 100644 index 0000000..75f1938 --- /dev/null +++ b/ItemChecklist.cs @@ -0,0 +1,98 @@ +using System; +using Terraria; +using Terraria.ModLoader; +using System.Collections.Generic; +using Terraria.UI; +using Terraria.DataStructures; +using ItemChecklist.UI; +using Microsoft.Xna.Framework; + +namespace ItemChecklist +{ + public class ItemChecklist : Mod + { + static internal ItemChecklist instance; + internal static ModHotKey ToggleChecklistHotKey; + internal static UserInterface ItemChecklistInterface; + internal ItemChecklistUI ItemChecklistUI; + + public ItemChecklist() + { + Properties = new ModProperties() + { + Autoload = true, + }; + } + + public override void Load() + { + instance = this; + ToggleChecklistHotKey = RegisterHotKey("Toggle Item Checklist", "I"); + //if (!Main.dedServ) + //{ + // ItemChecklistUI = new ItemChecklistUI(); + // ItemChecklistUI.Activate(); + // ItemChecklistInterface = new UserInterface(); + // ItemChecklistInterface.SetState(ItemChecklistUI); + //} + } + + public override void PostSetupContent() + { + if (!Main.dedServ) + { + ItemChecklistUI = new ItemChecklistUI(); + ItemChecklistUI.Activate(); + ItemChecklistInterface = new UserInterface(); + ItemChecklistInterface.SetState(ItemChecklistUI); + } + } + + int lastSeenScreenWidth; + int lastSeenScreenHeight; + public override void ModifyInterfaceLayers(List layers) + { + int MouseTextIndex = layers.FindIndex(layer => layer.Name.Equals("Vanilla: Mouse Text")); + if (MouseTextIndex != -1) + { + layers.Insert(MouseTextIndex, new MethodSequenceListItem( + "ItemChecklist: Item Checklist", + delegate + { + if (ItemChecklistUI.visible) + { + if (lastSeenScreenWidth != Main.screenWidth || lastSeenScreenHeight != Main.screenHeight) + { + ItemChecklistInterface.Recalculate(); + lastSeenScreenWidth = Main.screenWidth; + lastSeenScreenHeight = Main.screenHeight; + } + + ItemChecklistInterface.Update(Main._drawInterfaceGameTime); + ItemChecklistUI.Draw(Main.spriteBatch); + + if (ItemChecklistUI.hoverText != "") + { + float x = Main.fontMouseText.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)) + { + vector.Y = (float)(Main.screenHeight - 30); + } + if (vector.X > (float)(Main.screenWidth - x - 30)) + { + 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); + } + + } + return true; + }, + null) + ); + } + } + } +} + diff --git a/ItemChecklist.csproj b/ItemChecklist.csproj new file mode 100644 index 0000000..d283424 --- /dev/null +++ b/ItemChecklist.csproj @@ -0,0 +1,94 @@ + + + + + Debug + AnyCPU + {F067608B-12F3-49DA-9CF6-6CC5199923CE} + Library + Properties + ItemChecklist + ItemChecklist + v4.6 + 512 + true + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + + + + ..\..\solutiondlls\Microsoft.Xna.Framework.dll + + + ..\..\solutiondlls\Microsoft.Xna.Framework.Game.dll + + + ..\..\solutiondlls\Microsoft.Xna.Framework.Graphics.dll + + + ..\..\solutiondlls\Microsoft.Xna.Framework.Xact.dll + + + + + + + + + + + C:\Program Files (x86)\Steam\steamapps\common\Terraria\tModLoader.exe + + + + + + + + + + + + + + + + + + + + + + "C:\Program Files (x86)\Steam\steamapps\common\terraria\tModLoaderDebug.exe" -build "$(ProjectDir)\" -eac "$(TargetPath)" + + + \ No newline at end of file diff --git a/ItemChecklistGlobalItem.cs b/ItemChecklistGlobalItem.cs new file mode 100644 index 0000000..8ce009b --- /dev/null +++ b/ItemChecklistGlobalItem.cs @@ -0,0 +1,42 @@ +using ItemChecklist.UI; +using System.Linq; +using Terraria; +using Terraria.GameInput; +using Terraria.ModLoader; +using Terraria.ModLoader.IO; + +namespace ItemChecklist +{ + class ItemChecklistGlobalItem : GlobalItem + { + // OnPIckup only called on LocalPlayer: I think + public override void OnCraft(Item item, Recipe recipe) + { + ItemReceived(item); + } + + // OnPIckup only called on LocalPlayer: i == Main.myPlayer + public override bool OnPickup(Item item, Player player) + { + ItemReceived(item); + return true; + } + + // TODO, unloaded items, check against?? + internal void ItemReceived(Item item) + { + var itemChecklistPlayer = Main.LocalPlayer.GetModPlayer(mod); + if (!itemChecklistPlayer.foundItem[item.type] && itemChecklistPlayer.findableItems[item.type]) + { + Item newItem = new Item(); + newItem.SetDefaults(item.type); + itemChecklistPlayer.foundItems.Add(newItem); + itemChecklistPlayer.totalItemsFound++; + itemChecklistPlayer.foundItem[item.type] = true; + //ItemChecklist.instance.ItemChecklistUI.UpdateCheckboxes(); + ItemChecklist.instance.ItemChecklistUI.UpdateNeeded(); + Main.NewText($"Congrats: You found your first {item.name}. Total Progress: {itemChecklistPlayer.totalItemsFound}/{itemChecklistPlayer.totalItemsToFind}"); + } + } + } +} diff --git a/ItemChecklistPlayer.cs b/ItemChecklistPlayer.cs new file mode 100644 index 0000000..9c56022 --- /dev/null +++ b/ItemChecklistPlayer.cs @@ -0,0 +1,100 @@ +using ItemChecklist.UI; +using System.Collections.Generic; +using System.Linq; +using Terraria; +using Terraria.GameInput; +using Terraria.ID; +using Terraria.ModLoader; +using Terraria.ModLoader.IO; + +namespace ItemChecklist +{ + class ItemChecklistPlayer : ModPlayer + { + // internal static ItemChecklistPlayer localInstance; + + // This is a list of items...Holds clean versions of unloaded mystery and loaded real items. + internal List foundItems; + // + internal bool[] foundItem; + internal bool[] findableItems; + //Skipping: + // Main.itemName 0 is empty + // Mysteryitem is to skip --> ItemID.Count + // Deprecated if (this.type > 0 && ItemID.Sets.Deprecated[this.type]) + + internal int totalItemsToFind; + internal int totalItemsFound; // eh, property? dunno. + + public override void ProcessTriggers(TriggersSet triggersSet) + { + if (ItemChecklist.ToggleChecklistHotKey.JustPressed) + { + if (!ItemChecklistUI.visible) + { + ItemChecklist.instance.ItemChecklistUI.UpdateNeeded(); + } + ItemChecklistUI.visible = !ItemChecklistUI.visible; + } + } + + public override void OnEnterWorld(Player player) + { + var itemChecklistPlayer = Main.LocalPlayer.GetModPlayer(mod); + ItemChecklistUI.visible = false; + ItemChecklist.instance.ItemChecklistUI.UpdateNeeded(); + } + + // Do I need to use Initialize? I think so because of cloning. + public override void Initialize() + { + foundItems = new List(); + foundItem = new bool[Main.itemName.Length]; + findableItems = new bool[Main.itemName.Length]; + for (int i = 0; i < Main.itemName.Length; i++) + { + if (i > 0 && !ItemID.Sets.Deprecated[i] && i != ItemID.Count) // TODO, is this guaranteed? + { + totalItemsToFind++; + findableItems[i] = true; + } + } + // localInstance = this; + } + + public override void PreUpdate() + { + var itemChecklistPlayer = Main.LocalPlayer.GetModPlayer(mod); + for (int i = 0; i < 59; i++) + { + if (!player.inventory[i].IsAir && !itemChecklistPlayer.foundItem[player.inventory[i].type] && itemChecklistPlayer.findableItems[player.inventory[i].type]) + { + ((ItemChecklistGlobalItem)mod.GetGlobalItem("ItemChecklistGlobalItem")).ItemReceived(player.inventory[i]); + } + } + } + + public override TagCompound Save() + { + // sanitize? should be possible to add item already seen. + return new TagCompound + { + ["FoundItems"] = foundItems.Select(ItemIO.Save).ToList(), + }; + } + + public override void Load(TagCompound tag) + { + foundItems = tag.GetList("FoundItems").Select(ItemIO.Load).ToList(); + + foreach (var item in foundItems) + { + if (item.name != "Unloaded Item") + { + foundItem[item.type] = true; + totalItemsFound++; + } + } + } + } +} diff --git a/ItemChecklistUI.cs b/ItemChecklistUI.cs new file mode 100644 index 0000000..edb9671 --- /dev/null +++ b/ItemChecklistUI.cs @@ -0,0 +1,258 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.ModLoader; +using Terraria.GameContent.UI.Elements; +using Terraria.UI; +using System; +using System.Collections.Generic; +using Terraria.ID; +using Terraria.ModLoader.UI; +using System.Reflection; +using Terraria.Graphics; + +namespace ItemChecklist.UI +{ + class ItemChecklistUI : UIState + { + public UIHoverImageButton toggleButton; + public UIPanel checklistPanel; + //public UIList checklistList; + public UIGrid checklistList; + // private FieldInfo uilistinnerlist; + + float spacing = 8f; + public static bool visible = false; + public static bool showCompleted = true; + public static string hoverText = ""; + + ItemSlot[] itemSlots; + + public override void OnInitialize() + { + // Is initialize called? (Yes it is called on reload) I want to reset nicely with new character or new loaded mods: visible = false; + + // uilistinnerlist = typeof(UIList).GetField("_innerList", BindingFlags.Instance | BindingFlags.NonPublic); + + checklistPanel = new UIPanel(); + checklistPanel.SetPadding(10); + checklistPanel.Left.Pixels = 0; + checklistPanel.HAlign = 1f; + checklistPanel.Top.Set(50f, 0f); + checklistPanel.Width.Set(250f, 0f); + checklistPanel.Height.Set(-100, 1f); + checklistPanel.BackgroundColor = new Color(73, 94, 171); + + toggleButton = new UIHoverImageButton(Main.itemTexture[ItemID.Book], "Toggle Found"); + toggleButton.OnClick += ToggleButtonClicked; + //toggleButton.Left.Pixels = spacing; + //toggleButton.Top.Pixels = spacing; + checklistPanel.Append(toggleButton); + + checklistList = new UIGrid(5); + checklistList.Top.Pixels = 32f + spacing; + checklistList.Width.Set(-25f, 1f); + checklistList.Height.Set(-32f, 1f); + checklistList.ListPadding = 12f; + checklistPanel.Append(checklistList); + + FixedUIScrollbar checklistListScrollbar = new FixedUIScrollbar(); + checklistListScrollbar.SetView(100f, 1000f); + checklistListScrollbar.Top.Pixels = 32f + spacing; + checklistListScrollbar.Height.Set(-32f - spacing, 1f); + checklistListScrollbar.HAlign = 1f; + checklistPanel.Append(checklistListScrollbar); + checklistList.SetScrollbar(checklistListScrollbar); + + // Checklistlist populated when the panel is shown: UpdateCheckboxes() + + Append(checklistPanel); + + // load time impact, do this on first show? + itemSlots = new ItemSlot[Main.itemName.Length]; + for (int i = 0; i < Main.itemName.Length; i++) + { + itemSlots[i] = new ItemSlot(i); + } + updateneeded = true; + // TODO, game window resize issue --> UserInterface.ActiveInstance.Recalculate(); on resize? new hook? + // TODO, Scrollbar can't click + } + + private void ToggleButtonClicked(UIMouseEvent evt, UIElement listeningElement) + { + Main.PlaySound(10, -1, -1, 1); + showCompleted = !showCompleted; + UpdateNeeded(); + } + + private bool updateneeded; + internal void UpdateNeeded() + { + updateneeded = true; + } + + // todo, items on load. + internal void UpdateCheckboxes() + { + if (!updateneeded) { return; } + updateneeded = false; + checklistList.Clear(); + // var uilistinner = (UIElement)uilistinnerlist.GetValue(checklistList); + + var itemChecklistPlayer = Main.LocalPlayer.GetModPlayer(ItemChecklist.instance); + //var itemChecklistPlayer = ItemChecklistPlayer.localInstance; + + UIElement element = new UIElement(); + int count = 0; + for (int i = 0; i < itemChecklistPlayer.findableItems.Length; i++) + { + if (itemChecklistPlayer.findableItems[i]) + { + if (showCompleted || !itemChecklistPlayer.foundItem[i]) + { + + //ItemSlot box = new ItemSlot(i); + ItemSlot box = itemSlots[i]; + //keyImage.Left.Set(xOffset, 1f); + //element.Append(keyImage); + //count++; + //if(count == 4) + //{ + // count = 0; + // element = new UIElement(); + //} + //UIHoverImageButton box = new UIHoverImageButton(Main.itemTexture[i], Main.itemName[i]); + + //UICheckbox box = new UICheckbox(i, Main.itemName[i], 1f, false); + //box.Selected = itemChecklistPlayer.foundItem[i]; + //checklistList.Add(box); n squared + + + checklistList._items.Add(box); + checklistList._innerList.Append(box); + // uilistinner.Append(box); + } + } + } + checklistList.UpdateOrder(); + checklistList._innerList.Recalculate(); +// uilistinner.Recalculate(); + } + + protected override void DrawSelf(SpriteBatch spriteBatch) + { + UpdateCheckboxes(); + ItemChecklistUI.hoverText = ""; + Vector2 MousePosition = new Vector2((float)Main.mouseX, (float)Main.mouseY); + if (checklistPanel.ContainsPoint(MousePosition)) + { + Main.player[Main.myPlayer].mouseInterface = true; + } + } + } + + //public class FixedUIScrollbar : UIElement + public class FixedUIScrollbar : UIScrollbar + { + //private float _viewPosition; + //private float _viewSize = 1f; + //private float _maxViewSize = 20f; + //private bool _isDragging; + //private bool _isHoveringOverHandle; + //private float _dragYOffset; + //private Texture2D _texture; + //private Texture2D _innerTexture; + + //public float ViewPosition + //{ + // get + // { + // return this._viewPosition; + // } + // set + // { + // this._viewPosition = MathHelper.Clamp(value, 0f, this._maxViewSize - this._viewSize); + // } + //} + + //public FixedUIScrollbar() + //{ + // this.Width.Set(20f, 0f); + // this.MaxWidth.Set(20f, 0f); + // this._texture = TextureManager.Load("Images/UI/Scrollbar"); + // this._innerTexture = TextureManager.Load("Images/UI/ScrollbarInner"); + // this.PaddingTop = 5f; + // this.PaddingBottom = 5f; + //} + + //public void SetView(float viewSize, float maxViewSize) + //{ + // viewSize = MathHelper.Clamp(viewSize, 0f, maxViewSize); + // this._viewPosition = MathHelper.Clamp(this._viewPosition, 0f, maxViewSize - viewSize); + // this._viewSize = viewSize; + // this._maxViewSize = maxViewSize; + //} + + //public float GetValue() + //{ + // return this._viewPosition; + //} + + //private Rectangle GetHandleRectangle() + //{ + // CalculatedStyle innerDimensions = base.GetInnerDimensions(); + // if (this._maxViewSize == 0f && this._viewSize == 0f) + // { + // this._viewSize = 1f; + // this._maxViewSize = 1f; + // } + // return new Rectangle((int)innerDimensions.X, (int)(innerDimensions.Y + innerDimensions.Height * (this._viewPosition / this._maxViewSize)) - 3, 20, (int)(innerDimensions.Height * (this._viewSize / this._maxViewSize)) + 7); + //} + + //private void DrawBar(SpriteBatch spriteBatch, Texture2D texture, Rectangle dimensions, Color color) + //{ + // spriteBatch.Draw(texture, new Rectangle(dimensions.X, dimensions.Y - 6, dimensions.Width, 6), new Rectangle?(new Rectangle(0, 0, texture.Width, 6)), color); + // spriteBatch.Draw(texture, new Rectangle(dimensions.X, dimensions.Y, dimensions.Width, dimensions.Height), new Rectangle?(new Rectangle(0, 9, texture.Width, 2)), color); + // spriteBatch.Draw(texture, new Rectangle(dimensions.X, dimensions.Y + dimensions.Height, dimensions.Width, 6), new Rectangle?(new Rectangle(0, texture.Height - 6, texture.Width, 6)), color); + //} + + protected override void DrawSelf(SpriteBatch spriteBatch) + { + UserInterface temp = UserInterface.ActiveInstance; + UserInterface.ActiveInstance = ItemChecklist.ItemChecklistInterface; + base.DrawSelf(spriteBatch); + UserInterface.ActiveInstance = temp; + } + + public override void MouseDown(UIMouseEvent evt) + { + UserInterface temp = UserInterface.ActiveInstance; + UserInterface.ActiveInstance = ItemChecklist.ItemChecklistInterface; + base.MouseDown(evt); + UserInterface.ActiveInstance = temp; + } + + //public override void MouseUp(UIMouseEvent evt) + //{ + // base.MouseUp(evt); + // this._isDragging = false; + //} + } + + //public class BossInfo + //{ + // internal Func available; + // internal Func downed; + // internal string name; + // internal float progression; + + // public BossInfo(string name, float progression, Func available, Func downed) + // { + // this.name = name; + // this.progression = progression; + // this.available = available; + // this.downed = downed; + // } + //} +} diff --git a/ItemSlot.cs b/ItemSlot.cs new file mode 100644 index 0000000..97c714e --- /dev/null +++ b/ItemSlot.cs @@ -0,0 +1,113 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using Terraria.UI; +using Terraria; +using ItemChecklist.UI; + +namespace ItemChecklist +{ + internal class ItemSlot : UIElement + { + public static Texture2D backgroundTexture = Main.inventoryBack9Texture; + + private Texture2D _texture; + // private float _visibilityActive = 1f; + // private float _visibilityInactive = 0.4f; + private float scale = 0.6f; + private int id; + private Item item; + + public ItemSlot(int id) + { + this._texture = Main.itemTexture[id]; + this.id = id; + this.item = new Item(); + item.SetDefaults(id); + + this.Width.Set(backgroundTexture.Width * scale, 0f); + this.Height.Set(backgroundTexture.Height * scale, 0f); + } + + public override int CompareTo(object obj) + { + ItemSlot other = obj as ItemSlot; + return id.CompareTo(other.id); + } + + 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) + { + 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) + { + num = num2 / (float)rectangle2.Width; + } + else + { + num = num2 / (float)rectangle2.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) + { + spriteBatch.Draw(_texture, drawPosition, new Rectangle?(rectangle2), colorColor, 0f, Vector2.Zero, num, SpriteEffects.None, 0f); + } + //if (this.item.stack > 1) + //{ + // spriteBatch.DrawString(Main.fontItemStack, this.item.stack.ToString(), new Vector2(dimensions.Position().X + 10f * scale, dimensions.Position().Y + 26f * scale), Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f); + //} + + + if (IsMouseHovering) + { + ItemChecklistUI.hoverText = item.name + (item.modItem != null ? " [" + item.modItem.mod.Name + "]" : ""); + } + //if (IsMouseHovering) + //{ + // string hoverText = item.name + " " + item.type; + // float x = Main.fontMouseText.MeasureString(hoverText).X; + // Vector2 vector = new Vector2((float)Main.mouseX, (float)Main.mouseY) + new Vector2(16f, 0f); + // if (vector.Y > (float)(Main.screenHeight - 30)) + // { + // vector.Y = (float)(Main.screenHeight - 30); + // } + // if (vector.X > (float)(Parent.GetDimensions().Width + Parent.GetDimensions().X - x - 16)) + // { + // vector.X = (float)(Parent.GetDimensions().Width + Parent.GetDimensions().X - x - 16); + // } + // Utils.DrawBorderStringFourWay(spriteBatch, Main.fontMouseText, hoverText, vector.X, vector.Y, new Color((int)Main.mouseTextColor, (int)Main.mouseTextColor, (int)Main.mouseTextColor, (int)Main.mouseTextColor), Color.Black, Vector2.Zero, 1f); + //} + } + + //public override void MouseOver(UIMouseEvent evt) + //{ + // base.MouseOver(evt); + // Main.PlaySound(12, -1, -1, 1, 1f, 0f); + //} + } +} diff --git a/UICheckbox.cs b/UICheckbox.cs new file mode 100644 index 0000000..f05b8f8 --- /dev/null +++ b/UICheckbox.cs @@ -0,0 +1,69 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria.ModLoader; +using Terraria.GameContent.UI.Elements; +using Terraria.UI; +using System; + +namespace ItemChecklist.UI +{ + class UICheckbox : UIText + { + static Texture2D checkboxTexture = ((ItemChecklist)ModLoader.GetMod("ItemChecklist")).GetTexture("checkBox"); + static Texture2D checkmarkTexture = ((ItemChecklist)ModLoader.GetMod("ItemChecklist")).GetTexture("checkMark"); + public event EventHandler SelectedChanged; + float order = 0; + + private bool selected = false; + public bool Selected + { + get { return selected; } + set + { + if (value != selected) + { + selected = value; + SelectedChanged?.Invoke(this, EventArgs.Empty); + } + } + } + + public UICheckbox(float order, string text, float textScale = 1, bool large = false) : base(text, textScale, large) + { + this.order = order; + this.Left.Pixels += 20; + //TextColor = Color.Blue; + //OnClick += UICheckbox_onLeftClick; + Recalculate(); + } + + //private void UICheckbox_onLeftClick(UIMouseEvent evt, UIElement listeningElement) + //{ + // this.Selected = !Selected; + //} + + 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); + } + } +} + +//public string Text +//{ +// get { return label.Text; } +// set { label.Text = value; } +//} diff --git a/UIGrid.cs b/UIGrid.cs new file mode 100644 index 0000000..42b75ec --- /dev/null +++ b/UIGrid.cs @@ -0,0 +1,191 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using Terraria; +using Terraria.GameContent.UI.Elements; +using Terraria.UI; + +namespace ItemChecklist +{ + public class UIGrid : UIElement + { + public delegate bool ElementSearchMethod(UIElement element); + + private class UIInnerList : UIElement + { + public override bool ContainsPoint(Vector2 point) + { + return true; + } + + protected override void DrawChildren(SpriteBatch spriteBatch) + { + Vector2 position = this.Parent.GetDimensions().Position(); + Vector2 dimensions = new Vector2(this.Parent.GetDimensions().Width, this.Parent.GetDimensions().Height); + foreach (UIElement current in this.Elements) + { + Vector2 position2 = current.GetDimensions().Position(); + Vector2 dimensions2 = new Vector2(current.GetDimensions().Width, current.GetDimensions().Height); + if (Collision.CheckAABBvAABBCollision(position, dimensions, position2, dimensions2)) + { + current.Draw(spriteBatch); + } + } + } + } + + public List _items = new List(); + protected UIScrollbar _scrollbar; + internal UIElement _innerList = new UIGrid.UIInnerList(); + private float _innerListHeight; + public float ListPadding = 5f; + + public int Count + { + get + { + return this._items.Count; + } + } + + int cols = 1; + + public UIGrid(int columns = 1) + { + cols = columns; + this._innerList.OverflowHidden = false; + this._innerList.Width.Set(0f, 1f); + this._innerList.Height.Set(0f, 1f); + this.OverflowHidden = true; + base.Append(this._innerList); + } + + public float GetTotalHeight() + { + return this._innerListHeight; + } + + public void Goto(UIGrid.ElementSearchMethod searchMethod) + { + for (int i = 0; i < this._items.Count; i++) + { + if (searchMethod(this._items[i])) + { + this._scrollbar.ViewPosition = this._items[i].Top.Pixels; + return; + } + } + } + + public virtual void Add(UIElement item) + { + this._items.Add(item); + this._innerList.Append(item); + this.UpdateOrder(); + this._innerList.Recalculate(); + } + + public virtual bool Remove(UIElement item) + { + this._innerList.RemoveChild(item); + this.UpdateOrder(); + return this._items.Remove(item); + } + + public virtual void Clear() + { + this._innerList.RemoveAllChildren(); + this._items.Clear(); + } + + public override void Recalculate() + { + base.Recalculate(); + this.UpdateScrollbar(); + } + + public override void ScrollWheel(UIScrollWheelEvent evt) + { + base.ScrollWheel(evt); + if (this._scrollbar != null) + { + this._scrollbar.ViewPosition -= (float)evt.ScrollWheelValue; + } + } + + public override void RecalculateChildren() + { + base.RecalculateChildren(); + float top = 0f; + float left = 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) + { + top += this._items[i].GetOuterDimensions().Height + this.ListPadding; + left = 0; + } + else + { + left += this._items[i].GetOuterDimensions().Width + this.ListPadding; + } + //num += this._items[i].GetOuterDimensions().Height + this.ListPadding; + } + this._innerListHeight = top; + } + + private void UpdateScrollbar() + { + if (this._scrollbar == null) + { + return; + } + this._scrollbar.SetView(base.GetInnerDimensions().Height, this._innerListHeight); + } + + public void SetScrollbar(UIScrollbar scrollbar) + { + this._scrollbar = scrollbar; + this.UpdateScrollbar(); + } + + public void UpdateOrder() + { + this._items.Sort(new Comparison(this.SortMethod)); + this.UpdateScrollbar(); + } + + public int SortMethod(UIElement item1, UIElement item2) + { + return item1.CompareTo(item2); + } + + public override List GetSnapPoints() + { + List list = new List(); + SnapPoint item; + if (base.GetSnapPoint(out item)) + { + list.Add(item); + } + foreach (UIElement current in this._items) + { + list.AddRange(current.GetSnapPoints()); + } + return list; + } + + protected override void DrawSelf(SpriteBatch spriteBatch) + { + if (this._scrollbar != null) + { + this._innerList.Top.Set(-this._scrollbar.GetValue(), 0f); + } + this.Recalculate(); + } + } +} diff --git a/UIHoverImageButton.cs b/UIHoverImageButton.cs new file mode 100644 index 0000000..c7ba16c --- /dev/null +++ b/UIHoverImageButton.cs @@ -0,0 +1,43 @@ +using ItemChecklist.UI; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Terraria; +using Terraria.GameContent.UI.Elements; + +namespace ItemChecklist +{ + internal class UIHoverImageButton : UIImageButton + { + internal string hoverText; + + public UIHoverImageButton(Texture2D texture, string hoverText) : base(texture) + { + this.hoverText = hoverText; + } + + protected override void DrawSelf(SpriteBatch spriteBatch) + { + base.DrawSelf(spriteBatch); + if (IsMouseHovering) + { + ItemChecklistUI.hoverText = hoverText; + //float x = Main.fontMouseText.MeasureString(hoverText).X; + //Vector2 vector = new Vector2((float)Main.mouseX, (float)Main.mouseY) + new Vector2(16f, 0f); + //if (vector.Y > (float)(Main.screenHeight - 30)) + //{ + // vector.Y = (float)(Main.screenHeight - 30); + //} + //if (vector.X > (float)(Parent.GetDimensions().Width + Parent.GetDimensions().X - x - 16)) + //{ + // vector.X = (float)(Parent.GetDimensions().Width + Parent.GetDimensions().X - x - 16); + //} + //Utils.DrawBorderStringFourWay(spriteBatch, Main.fontMouseText, 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/build.txt b/build.txt new file mode 100644 index 0000000..67690d9 --- /dev/null +++ b/build.txt @@ -0,0 +1,11 @@ +author = jopojelly +version = 0.1 +displayName = Item Checklist +homepage = https://forums.terraria.org/index.php?threads/item-checklist-in-game-100-item-collection-checklist.52786/ +hideCode = false +hideResources = false +includeSource = true +languageVersion = 6 +includePDB = true +notworkingside = Client +buildIgnore = .vs\*, Properties\*, *.csproj, *.user, obj\*, bin\*, *.config, lib\*, .gitignore, .git\*, diff --git a/checkBox.png b/checkBox.png new file mode 100644 index 0000000..a8aa3fc Binary files /dev/null and b/checkBox.png differ diff --git a/checkMark.png b/checkMark.png new file mode 100644 index 0000000..767e85f Binary files /dev/null and b/checkMark.png differ diff --git a/description.txt b/description.txt new file mode 100644 index 0000000..8fa1f69 --- /dev/null +++ b/description.txt @@ -0,0 +1,3 @@ +Item Checklist lets you view a checklist for picking up or crafting 100% of the items in the game + +Toggle the checklist with the hotkey assigned to it in the settings.