XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

DeathMod

【Terraria】DeathMod (now aka Soul Harvest)

公开
关注 0 Fork 0 Star 0
UTF-8
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<GameInterfaceLayer> 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<MyPlayer>();
        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);
    }
}