From 728fe401d8e6002a4b46d4a0eec2d2085b8ede44 Mon Sep 17 00:00:00 2001 From: gorateron Date: Wed, 29 Mar 2017 20:11:57 +0200 Subject: [PATCH] Final things for v0.2 --- DeconstructorGUI.cs | 272 ++-------------------------------- Items/Cube.cs | 25 +++- Items/LunarCube.cs | 13 +- Items/QueerLunarCube.cs | 14 +- SoundHelper.cs | 40 +++++ Sounds/Custom/DeconSounds.cs | 21 ++- TheDeconstructor.cs | 51 ++----- TheDeconstructor.csproj | 3 + Tiles/Deconstructor.cs | 14 +- Tools.cs | 2 + UI/ItemPanel.cs | 136 +++++++++++++++++ UI/UIInteractableItemPanel.cs | 148 ++++++++++++++++++ changelog.txt | 35 +++-- 13 files changed, 430 insertions(+), 344 deletions(-) create mode 100644 SoundHelper.cs create mode 100644 UI/ItemPanel.cs create mode 100644 UI/UIInteractableItemPanel.cs diff --git a/DeconstructorGUI.cs b/DeconstructorGUI.cs index 4539a16..825c5a2 100644 --- a/DeconstructorGUI.cs +++ b/DeconstructorGUI.cs @@ -11,7 +11,7 @@ using Terraria.UI; using TheDeconstructor.Items; using TheDeconstructor.Tiles; - +using TheDeconstructor.UI; namespace TheDeconstructor { @@ -45,9 +45,8 @@ internal sealed class DeconstructorGUI : UIState //internal Dictionary TEInstances = new Dictionary(); //internal int? currentInstance = null; internal Point16? currentTEPosition = null; - internal bool hoveringChild = false; internal bool visible = false; - internal bool dragging = false; + private bool dragging = false; private Vector2 offset; internal const float vpadding = 10; @@ -116,7 +115,7 @@ public override void OnInitialize() closeButton = new UIImageButton(TheDeconstructor.instance.GetTexture("closeButton")); closeButton.OnClick += (s, e) => { - TheDeconstructor.instance.TryToggleGUI(false, TileEntity.ByPosition[currentTEPosition.Value] as DeconstructorTE); + TheDeconstructor.instance.TryToggleGUI(false); }; closeButton.Width.Set(20f, 0f); closeButton.Height.Set(20f, 0f); @@ -219,8 +218,6 @@ public void ToggleUI(bool on = true) { if (!on) { - if (currentTEPosition.HasValue) - (TileEntity.ByPosition[currentTEPosition.Value] as DeconstructorTE).isActive = false; recipeList.Clear(); TryGetCube(); TryGetSource(); @@ -270,9 +267,11 @@ public override void Update(GameTime gameTime) if ( Math.Abs(TE.playerDistances[Main.myPlayer].X) > 12f * 16f || Math.Abs(TE.playerDistances[Main.myPlayer].Y) > 12f * 16f - || Main.inputTextEscape || Main.LocalPlayer.dead || Main.gameMenu) + || Main.LocalPlayer.dead || Main.gameMenu) { - TheDeconstructor.instance.TryToggleGUI(false, TE); + TE.isCurrentlyActive = false; + TE.player = -1; + TheDeconstructor.instance.TryToggleGUI(false); } } @@ -351,6 +350,10 @@ public override void Update(GameTime gameTime) } } + + /// + /// Clickable, to deconstruct selected recipe + /// internal class UIRecipeBag : UIImageButton { public UIRecipeBag(Texture2D texture) : base(texture) @@ -490,263 +493,10 @@ internal void DoUpdate() } // Allows user to put in / take out item - internal class UIInteractableItemPanel : UIItemPanel - { - public UIInteractableItemPanel(int netID = 0, int stack = 0, Texture2D hintTexture = null, string hintText = null) - : base(netID, stack, hintTexture, hintText) - { - base.OnClick += UIInteractableItemPanel_OnClick; - } - - public override void Update(GameTime gameTime) - { - base.Update(gameTime); - if (base.IsMouseHovering - && Main.mouseRight) - { - // Slot has an item - if (!item.IsAir) - { - // Open inventory - Main.playerInventory = true; - - // Mouseitem has to be the same as slot - if (Main.stackSplit <= 1 && - (Main.mouseItem.type == item.type - || Main.mouseItem.IsAir)) - { - int num2 = Main.superFastStack + 1; - for (int j = 0; j < num2; j++) - { - // Mouseitem is air, or stack is smaller than maxstack, and slot has stack - if (Main.mouseItem.IsAir - || (Main.mouseItem.stack < Main.mouseItem.maxStack) - && item.stack > 0) - { - // Play sound - if (j == 0) - { - Main.PlaySound(18, -1, -1, 1); - } - // Mouseitem is air, clone item - if (Main.mouseItem.IsAir) - { - Main.mouseItem = item.Clone(); - // If it has prefix, copy it - if (item.prefix != 0) - { - Main.mouseItem.Prefix((int)item.prefix); - } - Main.mouseItem.stack = 0; - } - // Add to mouseitem stack - Main.mouseItem.stack++; - // Take from slot stack - item.stack--; - Main.stackSplit = Main.stackSplit == 0 ? 15 : Main.stackDelay; - - // Reset item - if (item.stack <= 0) - { - item.TurnToAir(); - } - } - } - } - } - - PostOnRightClick(); - } - } - - public virtual bool CanTakeItem(Item item) => true; - public virtual void PostOnRightClick() { } - public virtual void PostOnClick(UIMouseEvent evt, UIElement e) { } - - private void UIInteractableItemPanel_OnClick(UIMouseEvent evt, UIElement e) - { - // Slot has an item - if (!item.IsAir) - { - // Only slot has an item - if (Main.mouseItem.IsAir) - { - Main.playerInventory = true; - Main.mouseItem = item.Clone(); - item.TurnToAir(); - } - // Mouse has an item - // Can take mouse item - else if (CanTakeItem(Main.mouseItem)) - { - Main.playerInventory = true; - // Items are the same type - if (item.type == Main.mouseItem.type) - { - // Attempt increment stack - var newStack = item.stack + Main.mouseItem.stack; - // Mouse item stack fits, increment - if (item.maxStack >= newStack) - { - item.stack = newStack; - Main.mouseItem.TurnToAir(); - } - // Doesn't fit, set item to maxstack, set mouse item stack to difference - else - { - var stackDiff = newStack - item.maxStack; - item.stack = item.maxStack; - Main.mouseItem.stack = stackDiff; - } - } - // Items are not the same type - else - { - // Swap mouse item and slot item - var tmp = item.Clone(); - var tmp2 = Main.mouseItem.Clone(); - Main.mouseItem = tmp; - item = tmp2; - } - } - } - // Slot has no item - // Slot can take mouse item - else if (CanTakeItem(Main.mouseItem)) - { - Main.playerInventory = true; - item = Main.mouseItem.Clone(); - Main.mouseItem.TurnToAir(); - } - - // PostClick - PostOnClick(evt, e); - } - } // Item panel which can display an item - internal class UIItemPanel : UIPanel - { - internal const float panelwidth = 50f; - internal const float panelheight = 50f; - internal const float panelpadding = 0f; - public string HintText { get; set; } - public Texture2D HintTexture { get; set; } - public Item item; - - public UIItemPanel(int netID = 0, int stack = 0, Texture2D hintTexture = null, string hintText = null) - { - base.Width.Set(panelwidth, 0f); - base.Height.Set(panelheight, 0f); - base.SetPadding(panelpadding); - this.item = new Item(); - this.item.netDefaults(netID); - this.item.stack = stack; - this.HintTexture = hintTexture; - this.HintText = hintText; - } - - //public virtual void BindItem(DeconEntityInstance instance) { } - - protected override void DrawSelf(SpriteBatch spriteBatch) - { - base.DrawSelf(spriteBatch); - - Texture2D texture2D; - CalculatedStyle innerDimensions = base.GetInnerDimensions(); - Color drawColor; - - if (HintTexture != null - && item.IsAir) - { - texture2D = HintTexture; - drawColor = Color.LightGray * 0.5f; - if (base.IsMouseHovering) - { - Main.hoverItemName = HintText ?? string.Empty; - } - } - else if (item.IsAir) - return; - else - { - texture2D = Main.itemTexture[item.type]; - drawColor = this.item.GetAlpha(Color.White); - if (base.IsMouseHovering) - { - Main.hoverItemName = item.name; - Main.toolTip = item.Clone(); - Main.toolTip.GetModInfo(TheDeconstructor.instance).addValueTooltip = true; - //ItemValue value = new ItemValue().SetFromCopperValue(item.value*item.stack); - Main.toolTip.name = - $"{Main.toolTip.name}{Main.toolTip.modItem?.mod.Name.Insert((int)Main.toolTip.modItem?.mod.Name.Length, "]").Insert(0, " [")}"; - } - } - - var frame = - !item.IsAir && Main.itemAnimations[item.type] != null - ? Main.itemAnimations[item.type].GetFrame(texture2D) - : texture2D.Frame(1, 1, 0, 0); - - float drawScale = 1f; - if ((float)frame.Width > innerDimensions.Width - || (float)frame.Height > innerDimensions.Width) - { - if (frame.Width > frame.Height) - { - drawScale = innerDimensions.Width / (float)frame.Width; - } - else - { - drawScale = innerDimensions.Width / (float)frame.Height; - } - } - - var unreflectedScale = drawScale; - var tmpcolor = Color.White; - // 'Breathing' effect - ItemSlot.GetItemLight(ref tmpcolor, ref drawScale, item.type); - - Vector2 drawPosition = new Vector2(innerDimensions.X, innerDimensions.Y); - - drawPosition.X += (float)innerDimensions.Width * 1f / 2f - (float)frame.Width * drawScale / 2f; - drawPosition.Y += (float)innerDimensions.Height * 1f / 2f - (float)frame.Height * drawScale / 2f; - - //todo: globalitem? - if (item.modItem == null - || item.modItem.PreDrawInInventory(spriteBatch, drawPosition, frame, drawColor, drawColor, Vector2.Zero, drawScale)) - { - spriteBatch.Draw(texture2D, drawPosition, new Rectangle?(frame), drawColor, 0f, - Vector2.Zero, drawScale, SpriteEffects.None, 0f); - - if (this.item?.color != default(Color)) - { - spriteBatch.Draw(texture2D, drawPosition, new Rectangle?(frame), drawColor, 0f, - Vector2.Zero, drawScale, SpriteEffects.None, 0f); - } - } - - item.modItem?.PostDrawInInventory(spriteBatch, drawPosition, frame, drawColor, drawColor, Vector2.Zero, drawScale); - - // Draw stack count - if (this.item?.stack > 1) - { - Utils.DrawBorderStringFourWay( - spriteBatch, - Main.fontItemStack, - Math.Min(9999, item.stack).ToString(), - innerDimensions.Position().X + 10f, - innerDimensions.Position().Y + 26f, - Color.White, - Color.Black, - Vector2.Zero, - unreflectedScale * 0.8f); - } - } - - } internal sealed class DogePanel : UIPanel { diff --git a/Items/Cube.cs b/Items/Cube.cs index cd30a18..2ebae50 100644 --- a/Items/Cube.cs +++ b/Items/Cube.cs @@ -190,7 +190,7 @@ public override void RightClick(Player player) public virtual void NotifyLoss(int type, int stack) { - string str = $"[i/s1:{type}] (x{stack}) was lost while unsealing!"; + string str = $"[i/s1:{type}] (x{stack}) was lost!"; Main.NewText(str, 255); if (Main.netMode == NetmodeID.MultiplayerClient) NetMessage.SendData(MessageID.ChatText, -1, -1, str, 255); @@ -247,6 +247,11 @@ public override void ModifyTooltips(List tooltips) } + /// + /// How our cube item is cloned + /// + /// + /// public virtual Cube CubeClone() where T : Cube, new() { Cube clone = new T @@ -259,12 +264,20 @@ public override void ModifyTooltips(List tooltips) return clone; } - public override void PostUpdate() + public virtual Color CubeColor() where T : Cube, new() { - Color useColor = - item.type == mod.ItemType() - ? Tools.DiscoColor() - : Color.White; + var inst = new T(); + return + inst is LunarCube + ? Color.White + : inst is QueerLunarCube + ? Tools.DiscoColor() + : Color.White; + } + + public virtual void CubeLighting() where T : Cube, new() + { + Color useColor = CubeColor(); var sine = (float)Math.Sin(Main.essScale * 0.50f); var r = 0.05f + 0.35f * sine * useColor.R * 0.01f; var g = 0.05f + 0.35f * sine * useColor.G * 0.01f; diff --git a/Items/LunarCube.cs b/Items/LunarCube.cs index 2210f8e..2ea205e 100644 --- a/Items/LunarCube.cs +++ b/Items/LunarCube.cs @@ -1,4 +1,5 @@ -using Terraria.ID; +using Microsoft.Xna.Framework; +using Terraria.ID; using Terraria.ModLoader; namespace TheDeconstructor.Items @@ -11,8 +12,14 @@ public override void SetDefaults() item.name = "Lunar Cube"; } - public override ModItem Clone() - => CubeClone() as ModItem; + public override ModItem Clone() => + CubeClone(); + + public override Color? GetAlpha(Color lightColor) => + CubeColor(); + + public override void PostUpdate() => + CubeLighting(); public override void AddRecipes() { diff --git a/Items/QueerLunarCube.cs b/Items/QueerLunarCube.cs index 20e01b6..c7e8de5 100644 --- a/Items/QueerLunarCube.cs +++ b/Items/QueerLunarCube.cs @@ -21,14 +21,13 @@ public override void SetDefaults() } public override ModItem Clone() - => CubeClone() as ModItem; + => CubeClone(); - public override Color? GetAlpha(Color lightColor) - { - var c = Tools.DiscoColor(); - c.A = lightColor.A; - return c; - } + public override Color? GetAlpha(Color lightColor) => + CubeColor(); + + public override void PostUpdate() => + CubeLighting(); public override void AddRecipes() { @@ -40,5 +39,4 @@ public override void AddRecipes() recipe.AddRecipe(); } } - } diff --git a/SoundHelper.cs b/SoundHelper.cs new file mode 100644 index 0000000..f418d47 --- /dev/null +++ b/SoundHelper.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Terraria; +using Terraria.ModLoader; + + +namespace TheDeconstructor +{ + internal static class SoundHelper + { + internal static string[] Sounds = + { + "CloseUI", + "Decline", + "Notif", + "OpenUI", + "Receive", + "Redeem" + }; + + internal enum SoundType + { + CloseUI, + Decline, + Notif, + OpenUI, + Receive, + Redeem + } + + internal static void PlaySound(SoundType type) + { + Main.PlaySound(SoundLoader.customSoundType, -1, -1, + TheDeconstructor.instance.GetSoundSlot(Terraria.ModLoader.SoundType.Custom, "Sounds/Custom/" + Sounds[(int)type])); + } + } +} diff --git a/Sounds/Custom/DeconSounds.cs b/Sounds/Custom/DeconSounds.cs index c93109e..0e7771f 100644 --- a/Sounds/Custom/DeconSounds.cs +++ b/Sounds/Custom/DeconSounds.cs @@ -4,11 +4,20 @@ namespace TheDeconstructor.Sounds.Custom { + static class SoundMaker + { + public static SoundEffectInstance MakeSoundInstance(ref SoundEffectInstance instance, float volume, float level) + { + instance.Volume = volume * level; + return instance; + } + } + internal class CloseUI : ModSound { public override SoundEffectInstance PlaySound(ref SoundEffectInstance soundInstance, float volume, float pan, SoundType type) { - return soundInstance; + return SoundMaker.MakeSoundInstance(ref soundInstance, volume, 0.5f); } } @@ -16,7 +25,7 @@ internal class Decline : ModSound { public override SoundEffectInstance PlaySound(ref SoundEffectInstance soundInstance, float volume, float pan, SoundType type) { - return soundInstance; + return SoundMaker.MakeSoundInstance(ref soundInstance, volume, 0.5f); } } @@ -24,7 +33,7 @@ internal class Notif : ModSound { public override SoundEffectInstance PlaySound(ref SoundEffectInstance soundInstance, float volume, float pan, SoundType type) { - return soundInstance; + return SoundMaker.MakeSoundInstance(ref soundInstance, volume, 0.5f); } } @@ -32,7 +41,7 @@ internal class OpenUI : ModSound { public override SoundEffectInstance PlaySound(ref SoundEffectInstance soundInstance, float volume, float pan, SoundType type) { - return soundInstance; + return SoundMaker.MakeSoundInstance(ref soundInstance, volume, 0.5f); } } @@ -40,7 +49,7 @@ internal class Receive : ModSound { public override SoundEffectInstance PlaySound(ref SoundEffectInstance soundInstance, float volume, float pan, SoundType type) { - return soundInstance; + return SoundMaker.MakeSoundInstance(ref soundInstance, volume, 0.5f); } } @@ -48,7 +57,7 @@ internal class Redeem : ModSound { public override SoundEffectInstance PlaySound(ref SoundEffectInstance soundInstance, float volume, float pan, SoundType type) { - return soundInstance; + return SoundMaker.MakeSoundInstance(ref soundInstance, volume, 0.5f); } } } diff --git a/TheDeconstructor.cs b/TheDeconstructor.cs index ba0dd4d..93513be 100644 --- a/TheDeconstructor.cs +++ b/TheDeconstructor.cs @@ -8,35 +8,6 @@ namespace TheDeconstructor { - internal static class SoundHelper - { - internal static string[] Sounds = - { - "CloseUI", - "Decline", - "Notif", - "OpenUI", - "Receive", - "Redeem" - }; - - internal enum SoundType - { - CloseUI, - Decline, - Notif, - OpenUI, - Receive, - Redeem - } - - internal static void PlaySound(SoundType type) - { - Main.PlaySound(SoundLoader.customSoundType, -1, -1, - TheDeconstructor.instance.GetSoundSlot(Terraria.ModLoader.SoundType.Custom, "Sounds/Custom/" + Sounds[(int)type])); - } - } - public class TheDeconstructor : Mod { internal UserInterface deconUI; @@ -56,16 +27,21 @@ public TheDeconstructor() public override void Load() { instance = this as TheDeconstructor; - if (Main.dedServ) return; + DogeTexture = GetTexture("EmptyDoge"); DogeTexture.MultiplyColorsByAlpha(); + deconUI = new UserInterface(); deconGUI = new DeconstructorGUI(); deconGUI.Activate(); deconUI.SetState(deconGUI); } + /// + /// Insert our UI layer between vanilla layers + /// + /// public override void ModifyInterfaceLayers(List layers) { int insertLayer = layers.FindIndex(layer => layer.Name.Equals("Vanilla: Mouse Text")); @@ -88,7 +64,11 @@ public override void ModifyInterfaceLayers(List layers) layers[insertLayer].Skip = insertLayer != -1 && deconGUI.IsMouseHovering; } - internal void TryToggleGUI(bool? state = null, DeconstructorTE TE = null) + /// + /// Try toggling our UI + /// + /// + internal void TryToggleGUI(bool? state = null) { bool visible = state ?? !deconGUI.visible; @@ -100,15 +80,6 @@ internal void TryToggleGUI(bool? state = null, DeconstructorTE TE = null) deconGUI.visible = visible; deconGUI.ToggleUI(visible); - - if (TE != null) - { - TE.isActive = visible; - TE.isActiveSource = - TE.isActive - ? Main.myPlayer - : 0; - } } } } diff --git a/TheDeconstructor.csproj b/TheDeconstructor.csproj index 4797558..c1d8258 100644 --- a/TheDeconstructor.csproj +++ b/TheDeconstructor.csproj @@ -67,11 +67,14 @@ + + + diff --git a/Tiles/Deconstructor.cs b/Tiles/Deconstructor.cs index d6a5bcb..01619db 100644 --- a/Tiles/Deconstructor.cs +++ b/Tiles/Deconstructor.cs @@ -15,9 +15,9 @@ namespace TheDeconstructor.Tiles internal sealed class DeconstructorTE : ModTileEntity { //public DeconEntityInstance instance; + public bool isCurrentlyActive = false; // if someone is in UI + public int player = -1; // active player public int frame = 0; - public bool isActive = false; - public int isActiveSource = 0; public Vector2[] playerDistances = new Vector2[Main.maxPlayers]; public override bool ValidTile(int i, int j) @@ -105,11 +105,13 @@ public override void RightClick(int i, int j) var instance = TheDeconstructor.instance.deconGUI; var TEPos = tile.GetTopLeftFrame(i, j, s, p); var TE = (TileEntity.ByPosition[TEPos] as DeconstructorTE); - if (TE != null && (!TE.isActive || Main.myPlayer == TE.isActiveSource)) + if (!TE.isCurrentlyActive + || TE.player == Main.myPlayer) { + TE.isCurrentlyActive = !TE.isCurrentlyActive; + TE.player = Main.myPlayer; instance.currentTEPosition = TEPos; - //instance.currentInstance = TE?.instance.ID; - TheDeconstructor.instance.TryToggleGUI(null, TE); + TheDeconstructor.instance.TryToggleGUI(); } } } @@ -159,7 +161,7 @@ public override void PostDraw(int i, int j, SpriteBatch spriteBatch) if (inst.deconGUI.visible && !inst.deconGUI.cubeItemPanel.item.IsAir && inst.deconGUI.currentTEPosition.HasValue - && inst.deconGUI.currentTEPosition.Value == new Point16(i,j)) + && inst.deconGUI.currentTEPosition.Value == new Point16(i, j)) { var TE = TileEntity.ByPosition[inst.deconGUI.currentTEPosition.Value] as DeconstructorTE; Color useColor = diff --git a/Tools.cs b/Tools.cs index d10957c..aa69e35 100644 --- a/Tools.cs +++ b/Tools.cs @@ -10,6 +10,7 @@ namespace TheDeconstructor { public static class Tools { + // Can be removed upon tML update public static int GiveClonedItem(this Player player, Item item, int stack) { int index = Item.NewItem((int)player.position.X, (int)player.position.Y, player.width, player.height, item.type, stack, false, -1, false, false); @@ -49,6 +50,7 @@ public static string ToHexString(this Color c) => public static string ToRgbString(this Color c) => $"RGB({c.R}, {c.G}, {c.B})"; + // Can be removed upon tML update public static Color DiscoColor() => new Color(Main.DiscoR, Main.DiscoG, Main.DiscoB); diff --git a/UI/ItemPanel.cs b/UI/ItemPanel.cs new file mode 100644 index 0000000..10fd892 --- /dev/null +++ b/UI/ItemPanel.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.GameContent.UI.Elements; +using Terraria.UI; + + +namespace TheDeconstructor.UI +{ + internal class UIItemPanel : UIPanel + { + internal const float panelwidth = 50f; + internal const float panelheight = 50f; + internal const float panelpadding = 0f; + + public string HintText { get; set; } + public Texture2D HintTexture { get; set; } + public Item item; + + public UIItemPanel(int netID = 0, int stack = 0, Texture2D hintTexture = null, string hintText = null) + { + base.Width.Set(panelwidth, 0f); + base.Height.Set(panelheight, 0f); + base.SetPadding(panelpadding); + this.item = new Item(); + this.item.netDefaults(netID); + this.item.stack = stack; + this.HintTexture = hintTexture; + this.HintText = hintText; + } + + //public virtual void BindItem(DeconEntityInstance instance) { } + + protected override void DrawSelf(SpriteBatch spriteBatch) + { + base.DrawSelf(spriteBatch); + + Texture2D texture2D; + CalculatedStyle innerDimensions = base.GetInnerDimensions(); + Color drawColor; + + if (HintTexture != null + && item.IsAir) + { + texture2D = HintTexture; + drawColor = Color.LightGray * 0.5f; + if (base.IsMouseHovering) + { + Main.hoverItemName = HintText ?? string.Empty; + } + } + else if (item.IsAir) + return; + else + { + texture2D = Main.itemTexture[item.type]; + drawColor = this.item.GetAlpha(Color.White); + if (base.IsMouseHovering) + { + Main.hoverItemName = item.name; + Main.toolTip = item.Clone(); + Main.toolTip.GetModInfo(TheDeconstructor.instance).addValueTooltip = true; + //ItemValue value = new ItemValue().SetFromCopperValue(item.value*item.stack); + Main.toolTip.name = + $"{Main.toolTip.name}{Main.toolTip.modItem?.mod.Name.Insert((int)Main.toolTip.modItem?.mod.Name.Length, "]").Insert(0, " [")}"; + } + } + + var frame = + !item.IsAir && Main.itemAnimations[item.type] != null + ? Main.itemAnimations[item.type].GetFrame(texture2D) + : texture2D.Frame(1, 1, 0, 0); + + float drawScale = 1f; + if ((float)frame.Width > innerDimensions.Width + || (float)frame.Height > innerDimensions.Width) + { + if (frame.Width > frame.Height) + { + drawScale = innerDimensions.Width / (float)frame.Width; + } + else + { + drawScale = innerDimensions.Width / (float)frame.Height; + } + } + + var unreflectedScale = drawScale; + var tmpcolor = Color.White; + // 'Breathing' effect + ItemSlot.GetItemLight(ref tmpcolor, ref drawScale, item.type); + + Vector2 drawPosition = new Vector2(innerDimensions.X, innerDimensions.Y); + + drawPosition.X += (float)innerDimensions.Width * 1f / 2f - (float)frame.Width * drawScale / 2f; + drawPosition.Y += (float)innerDimensions.Height * 1f / 2f - (float)frame.Height * drawScale / 2f; + + //todo: globalitem? + if (item.modItem == null + || item.modItem.PreDrawInInventory(spriteBatch, drawPosition, frame, drawColor, drawColor, Vector2.Zero, drawScale)) + { + spriteBatch.Draw(texture2D, drawPosition, new Rectangle?(frame), drawColor, 0f, + Vector2.Zero, drawScale, SpriteEffects.None, 0f); + + if (this.item?.color != default(Color)) + { + spriteBatch.Draw(texture2D, drawPosition, new Rectangle?(frame), drawColor, 0f, + Vector2.Zero, drawScale, SpriteEffects.None, 0f); + } + } + + item.modItem?.PostDrawInInventory(spriteBatch, drawPosition, frame, drawColor, drawColor, Vector2.Zero, drawScale); + + // Draw stack count + if (this.item?.stack > 1) + { + Utils.DrawBorderStringFourWay( + spriteBatch, + Main.fontItemStack, + Math.Min(9999, item.stack).ToString(), + innerDimensions.Position().X + 10f, + innerDimensions.Position().Y + 26f, + Color.White, + Color.Black, + Vector2.Zero, + unreflectedScale * 0.8f); + } + } + + } +} diff --git a/UI/UIInteractableItemPanel.cs b/UI/UIInteractableItemPanel.cs new file mode 100644 index 0000000..6c97f3b --- /dev/null +++ b/UI/UIInteractableItemPanel.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.UI; + + +namespace TheDeconstructor.UI +{ + internal class UIInteractableItemPanel : UIItemPanel + { + public UIInteractableItemPanel(int netID = 0, int stack = 0, Texture2D hintTexture = null, string hintText = null) + : base(netID, stack, hintTexture, hintText) + { + base.OnClick += UIInteractableItemPanel_OnClick; + } + + public override void Update(GameTime gameTime) + { + base.Update(gameTime); + if (base.IsMouseHovering + && Main.mouseRight) + { + // Slot has an item + if (!item.IsAir) + { + // Open inventory + Main.playerInventory = true; + + // Mouseitem has to be the same as slot + if (Main.stackSplit <= 1 && + (Main.mouseItem.type == item.type + || Main.mouseItem.IsAir)) + { + int num2 = Main.superFastStack + 1; + for (int j = 0; j < num2; j++) + { + // Mouseitem is air, or stack is smaller than maxstack, and slot has stack + if (Main.mouseItem.IsAir + || (Main.mouseItem.stack < Main.mouseItem.maxStack) + && item.stack > 0) + { + // Play sound + if (j == 0) + { + Main.PlaySound(18, -1, -1, 1); + } + // Mouseitem is air, clone item + if (Main.mouseItem.IsAir) + { + Main.mouseItem = item.Clone(); + // If it has prefix, copy it + if (item.prefix != 0) + { + Main.mouseItem.Prefix((int)item.prefix); + } + Main.mouseItem.stack = 0; + } + // Add to mouseitem stack + Main.mouseItem.stack++; + // Take from slot stack + item.stack--; + Main.stackSplit = Main.stackSplit == 0 ? 15 : Main.stackDelay; + + // Reset item + if (item.stack <= 0) + { + item.TurnToAir(); + } + } + } + } + } + + PostOnRightClick(); + } + } + + public virtual bool CanTakeItem(Item item) => true; + public virtual void PostOnRightClick() { } + public virtual void PostOnClick(UIMouseEvent evt, UIElement e) { } + + private void UIInteractableItemPanel_OnClick(UIMouseEvent evt, UIElement e) + { + // Slot has an item + if (!item.IsAir) + { + // Only slot has an item + if (Main.mouseItem.IsAir) + { + Main.playerInventory = true; + Main.mouseItem = item.Clone(); + item.TurnToAir(); + } + // Mouse has an item + // Can take mouse item + else if (CanTakeItem(Main.mouseItem)) + { + Main.playerInventory = true; + // Items are the same type + if (item.type == Main.mouseItem.type) + { + // Attempt increment stack + var newStack = item.stack + Main.mouseItem.stack; + // Mouse item stack fits, increment + if (item.maxStack >= newStack) + { + item.stack = newStack; + Main.mouseItem.TurnToAir(); + } + // Doesn't fit, set item to maxstack, set mouse item stack to difference + else + { + var stackDiff = newStack - item.maxStack; + item.stack = item.maxStack; + Main.mouseItem.stack = stackDiff; + } + } + // Items are not the same type + else + { + // Swap mouse item and slot item + var tmp = item.Clone(); + var tmp2 = Main.mouseItem.Clone(); + Main.mouseItem = tmp; + item = tmp2; + } + + } + } + // Slot has no item + // Slot can take mouse item + else if (CanTakeItem(Main.mouseItem)) + { + Main.playerInventory = true; + item = Main.mouseItem.Clone(); + Main.mouseItem.TurnToAir(); + } + + // PostClick + PostOnClick(evt, e); + } + } +} diff --git a/changelog.txt b/changelog.txt index 5b5a068..9fae458 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,39 +2,46 @@ General 'Deconstructor' renamed to 'Lunar Deconstructor' - Goodie bag is gone, now 'Lunar Cube', upgraded version is 'Queer Lunar Cube'. - You can craft a Lunar Cube at the Lunar Deconstructor with 1 of any Lunar Fragment and 1 Lunar Bar. - A 'Queer' Lunar Cube is crafted with 1 Lunar Cube and 1 of any Lunar Fragment at the Lunar Deconstructor. - A Queer Lunar Cube can be sealed and unsealed without being destroyed, a Lunar Cube can be unsealed once before being destroyed. - Queer Lunar Cubes are recognizable by their morphing colors. - The cubes also have a overhauled tooltips and tooltip ordering (compared to the old goodie bag) - While deconstruction UI is open, rightclicking a cube will not unseal it to prevent accidental openings. + Goodie bag is gone, now 'Lunar Cube', upgraded version is 'Queer Lunar Cube' + You can craft a Lunar Cube at the Lunar Deconstructor with 1 of any Lunar Fragment and 1 Lunar Bar + A 'Queer' Lunar Cube is crafted with 1 Lunar Cube and 1 of any Lunar Fragment at the Lunar Deconstructor + A Queer Lunar Cube can be unsealed without being destroyed, a Lunar Cube is destroyed itself upon unsealing + A Queer Lunar Cube is recognizable by its morphing colors + The cubes also have a overhauled tooltips and tooltip ordering + While deconstruction UI is open, right clicking a cube will not unseal it to prevent accidental openings. Item loss chance changed to 30% (from 20%) + Tile itself no longer draws cube all the time, instead it will draw the cube that's currently it its UI + All SFX volume lowered by 50%, no more earrape guys. + Lunar Deconstructor now counts as a table for rooms. + Changed tile origin for easier placement. UI Changes There's now a new slot (top slot) which will take an unsealed cube, contents will be sealed into this cube - The bottom slot is for the item you want to seal + The bottom slot is for the item you want to seal. Tooltips will show on mouse hover to help you. UI will now show reddit's 'Wow, such empty' doge when the list is empty, because the initial preview was posted on reddit - UI item slots now supports ModItem Pre/Post DrawInInventory, along with a 'breathing' effect (such as lunar fragments) + UI item slots now supports ModItem Pre/Post DrawInInventory, along with a 'breathing' effect (lunar fragments 'breathe', for example) UI item slots stack drawing improved: now draws with black border (FourWay) Bugfixes Fixed several bugs, including but not limited to: - 1) Not receiving items when UI is forcefully closed + 1) Not receiving items when UI is forcefully closed in certain circumstances 2) Distance from tile to player not being managed properly - This is fixed by shifting the logic completely to a TileEntity + This is fixed by shifting the logic completely to the TileEntity 3) Right click not functioning properly on UI ItemSlots This includes loss of ItemInfos + 4) Infos for cubes (previously goodie bags) not being synced in multiplayer + Fixed using Netsend/Netreceive Sprite improvements Tile sprite was improved. Cube sprite was improved. - Both cubes share the same sprite, but the Queer version morphs colors. + Queer cube morphs in colors. Other Massive improvements/reworks in code, check github - Vanilla 'flask' are now also seen as potions, and thus will have a failure rate in place. - By changing the code to use ItemRarity.GetColor, the rarity for level 4 should now be properly displayed + Vanilla 'flask' are now also seen as potions, and thus will have a failure rate in place + Lunar fragments (solar, vortex, stardust, nebula) now also have a failure rate in place + By changing the code to use ItemRarity.GetColor, the rarity color for level 4 should now be correct Added 2 more 'errors' in UI: 1) When trying to seal an already sealed cube 2) When trying to seal with no cube in the UI