From 7f037576dcbdec1b90d076b28e527006c1c8dc13 Mon Sep 17 00:00:00 2001 From: JavidPack Date: Sat, 17 Dec 2016 23:03:34 -0700 Subject: [PATCH] 0.1 initial release. --- .gitignore | 4 + ItemChecklist.cs | 98 ++++++++++++++ ItemChecklist.csproj | 94 ++++++++++++++ ItemChecklistGlobalItem.cs | 42 ++++++ ItemChecklistPlayer.cs | 100 ++++++++++++++ ItemChecklistUI.cs | 258 +++++++++++++++++++++++++++++++++++++ ItemSlot.cs | 113 ++++++++++++++++ UICheckbox.cs | 69 ++++++++++ UIGrid.cs | 191 +++++++++++++++++++++++++++ UIHoverImageButton.cs | 43 +++++++ build.txt | 11 ++ checkBox.png | Bin 0 -> 3089 bytes checkMark.png | Bin 0 -> 3225 bytes description.txt | 3 + 14 files changed, 1026 insertions(+) create mode 100644 .gitignore create mode 100644 ItemChecklist.cs create mode 100644 ItemChecklist.csproj create mode 100644 ItemChecklistGlobalItem.cs create mode 100644 ItemChecklistPlayer.cs create mode 100644 ItemChecklistUI.cs create mode 100644 ItemSlot.cs create mode 100644 UICheckbox.cs create mode 100644 UIGrid.cs create mode 100644 UIHoverImageButton.cs create mode 100644 build.txt create mode 100644 checkBox.png create mode 100644 checkMark.png create mode 100644 description.txt 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 0000000000000000000000000000000000000000..a8aa3fcee0c665948625a8a0e17c12ce2e67e7a0 GIT binary patch literal 3089 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