using SoulHarvest.Common; using SoulHarvest.Items; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; using Terraria; using Terraria.GameContent; using Terraria.Localization; using Terraria.ModLoader; using Terraria.UI; namespace SoulHarvest.UI; [Autoload(Side = ModSide.Client)] public class SickleCooldownUISystem : ModSystem { public override void ModifyInterfaceLayers(List layers) { int mouseTextIndex = layers.FindIndex(layer => layer.Name == "Vanilla: Mouse Text"); if (mouseTextIndex < 0) return; layers.Insert(mouseTextIndex, new LegacyGameInterfaceLayer( "SoulHarvest: Sickle Alternate Cooldown", DrawCooldown, InterfaceScaleType.UI)); } private static bool DrawCooldown() { Player player = Main.LocalPlayer; if (Main.gameMenu || !player.active || player.dead || player.HeldItem.ModItem is not NormalSickle) return true; MyPlayer modPlayer = player.GetModPlayer(); ReaperProgressionState progression = modPlayer.ReaperProgression; ReaperFormId form = progression.CurrentForm; Color primary = ReaperUIData.GetPrimaryColor(form); Color secondary = ReaperUIData.GetSecondaryColor(form); int specialRemaining = Math.Max(0, modPlayer.ReaperSpecialCooldown); int specialMaximum = Math.Max(1, modPlayer.ReaperSpecialCooldownMax); float specialReadyRatio = 1f - MathHelper.Clamp(specialRemaining / (float)specialMaximum, 0f, 1f); int ultimateRemaining = Math.Max(0, modPlayer.GetReaperUltimateCooldown(form)); float energyValue = MathHelper.Clamp(modPlayer.GetReaperEnergy(form), 0f, 100f); int energy = (int)MathF.Floor(energyValue); int exhaustion = Math.Max(0, modPlayer.ReaperExhaustionCooldown); bool ultimateUnlocked = form == ReaperFormId.Death ? progression.DeathFormUnlocked : progression.GetStage(form) >= ReaperStage.StageIII; int width = Math.Clamp((int)(Main.screenWidth * 0.24f), 236, 336); int height = 12; Vector2 center = new(Main.screenWidth * 0.5f, Main.screenHeight - 145f); Texture2D pixel = TextureAssets.MagicPixel.Value; string formName = ReaperUIData.GetFormName(form); string stageText = form switch { ReaperFormId.Base => Language.GetTextValue("Mods.SoulHarvest.UI.ReaperHUD.BaseStage"), ReaperFormId.Death => Language.GetTextValue("Mods.SoulHarvest.UI.ReaperHUD.DeathStage"), _ => Language.GetTextValue("Mods.SoulHarvest.UI.ReaperHUD.Stage", (int)progression.GetStage(form)) }; string specialText = specialRemaining <= 0 ? Language.GetTextValue("Mods.SoulHarvest.UI.ReaperHUD.SpecialReady") : Language.GetTextValue("Mods.SoulHarvest.UI.ReaperHUD.SpecialCooldown", specialRemaining / 60f); string ultimateText = !ultimateUnlocked ? Language.GetTextValue("Mods.SoulHarvest.UI.ReaperHUD.UltimateLocked") : ultimateRemaining > 0 ? Language.GetTextValue("Mods.SoulHarvest.UI.ReaperHUD.UltimateCooldown", ultimateRemaining / 60f) : Language.GetTextValue("Mods.SoulHarvest.UI.ReaperHUD.Energy", ReaperUIData.GetEnergyName(form), energy); DrawBar(Main.spriteBatch, pixel, center, width, height, specialReadyRatio, primary, secondary, specialText, 0.62f); DrawBar(Main.spriteBatch, pixel, center + new Vector2(0f, 27f), width, height, ultimateUnlocked ? energyValue / 100f : 0f, Color.Lerp(primary, new Color(238, 62, 171), 0.38f), secondary, ultimateText, 0.58f); float nameScale = 0.69f; Vector2 nameSize = FontAssets.MouseText.Value.MeasureString(formName) * nameScale; Utils.DrawBorderString(Main.spriteBatch, formName, new Vector2(center.X - nameSize.X * 0.5f, center.Y - 49f), secondary, nameScale); float stageScale = 0.54f; Vector2 stageSize = FontAssets.MouseText.Value.MeasureString(stageText) * stageScale; Utils.DrawBorderString(Main.spriteBatch, stageText, new Vector2(center.X - stageSize.X * 0.5f, center.Y - 27f), new Color(191, 181, 210), stageScale); if (exhaustion > 0) { string exhaustionText = Language.GetTextValue("Mods.SoulHarvest.UI.ReaperHUD.Exhaustion", exhaustion / 60f); float exhaustionScale = 0.59f; Vector2 exhaustionSize = FontAssets.MouseText.Value.MeasureString(exhaustionText) * exhaustionScale; Utils.DrawBorderString(Main.spriteBatch, exhaustionText, new Vector2(center.X - exhaustionSize.X * 0.5f, center.Y + 47f), new Color(255, 94, 133), exhaustionScale); } return true; } private static void DrawBar(SpriteBatch spriteBatch, Texture2D pixel, Vector2 center, int width, int height, float ratio, Color primary, Color secondary, string text, float textScale) { ratio = MathHelper.Clamp(ratio, 0f, 1f); Rectangle outer = new((int)center.X - width / 2 - 3, (int)center.Y - 3, width + 6, height + 6); Rectangle inner = new((int)center.X - width / 2, (int)center.Y, width, height); Rectangle fill = new(inner.X, inner.Y, (int)Math.Round(inner.Width * ratio), inner.Height); spriteBatch.Draw(pixel, outer, new Color(22, 10, 38, 230)); spriteBatch.Draw(pixel, new Rectangle(outer.X + 1, outer.Y + 1, outer.Width - 2, outer.Height - 2), primary * 0.54f); spriteBatch.Draw(pixel, inner, new Color(8, 8, 20, 240)); if (fill.Width > 0) { spriteBatch.Draw(pixel, fill, Color.Lerp(primary, secondary, ratio * 0.72f)); spriteBatch.Draw(pixel, new Rectangle(fill.X, fill.Y, fill.Width, Math.Max(1, height / 4)), Color.White * 0.25f); } for (int index = 1; index < 4; index++) { int x = inner.X + inner.Width * index / 4; spriteBatch.Draw(pixel, new Rectangle(x, inner.Y - 1, 1, inner.Height + 2), secondary * 0.32f); } Vector2 textSize = FontAssets.MouseText.Value.MeasureString(text) * textScale; Utils.DrawBorderString(spriteBatch, text, new Vector2(center.X - textSize.X * 0.5f, center.Y - 2f), Color.White, textScale); } }