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

DeathMod

【Terraria】DeathMod (now aka Soul Harvest)

公开
关注 0 Fork 0 Star 0
UTF-8
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.GameContent;
using Terraria.ModLoader;

namespace SoulHarvest.Common;

[Autoload(Side = ModSide.Client)]
internal class DeathWingTrailSystem : ModSystem
{
    public override void PostDrawTiles()
    {
        bool hasVisibleTrail = false;
        for (int playerIndex = 0; playerIndex < Main.maxPlayers; playerIndex++)
        {
            Player player = Main.player[playerIndex];
            if (player.active
                && !player.dead
                && player.GetModPlayer<MyPlayer>().DeathWingTrailCount >= 2)
            {
                hasVisibleTrail = true;
                break;
            }
        }

        if (!hasVisibleTrail)
            return;

        SpriteBatch spriteBatch = Main.spriteBatch;
        spriteBatch.Begin(
            SpriteSortMode.Deferred,
            BlendState.AlphaBlend,
            SamplerState.PointClamp,
            DepthStencilState.None,
            RasterizerState.CullNone,
            null,
            Main.GameViewMatrix.TransformationMatrix);

        Texture2D pixel = TextureAssets.MagicPixel.Value;
        for (int playerIndex = 0; playerIndex < Main.maxPlayers; playerIndex++)
        {
            Player player = Main.player[playerIndex];
            if (!player.active || player.dead)
                continue;

            MyPlayer modPlayer = player.GetModPlayer<MyPlayer>();
            if (modPlayer.DeathWingTrailCount < 2 || modPlayer.DeathWingTrailOpacity <= 0f)
                continue;

            DrawTrail(spriteBatch, pixel, modPlayer.DeathWingUpperTrail, modPlayer);
            DrawTrail(spriteBatch, pixel, modPlayer.DeathWingLowerTrail, modPlayer);
        }

        spriteBatch.End();
    }

    private static void DrawTrail(SpriteBatch spriteBatch, Texture2D pixel, Vector2[] positions, MyPlayer modPlayer)
    {
        float mastery = modPlayer.DeathWingTrailMastery;
        int maximumPoints = 11 + (int)(mastery * 15f);
        int pointCount = System.Math.Min(modPlayer.DeathWingTrailCount, maximumPoints);
        float opacity = modPlayer.DeathWingTrailOpacity;
        Color outerColor = Color.Lerp(new Color(105, 0, 22), new Color(225, 20, 100), mastery) with { A = 0 };
        Color coreColor = Color.Lerp(new Color(235, 18, 42), new Color(255, 125, 195), mastery) with { A = 0 };

        for (int index = pointCount - 1; index >= 1; index--)
        {
            Vector2 older = positions[index];
            Vector2 newer = positions[index - 1];
            if (older == Vector2.Zero || newer == Vector2.Zero)
                continue;

            Vector2 segment = newer - older;
            float length = segment.Length();
            if (length is < 0.35f or > 72f)
                continue;

            float strength = 1f - index / (float)pointCount;
            float taper = (float)System.Math.Pow(strength, 0.72f);
            float outerWidth = (2.35f + mastery * 2.1f) * taper;
            float coreWidth = (0.68f + mastery * 0.82f) * taper;
            DrawSegment(spriteBatch, pixel, older, segment, outerColor * opacity * strength * 0.38f, outerWidth);
            DrawSegment(spriteBatch, pixel, older, segment, coreColor * opacity * strength * 0.88f, coreWidth);
        }
    }

    private static void DrawSegment(SpriteBatch spriteBatch, Texture2D pixel, Vector2 start, Vector2 segment, Color color, float width)
    {
        DeathDomainPrimitiveTextureSystem.DrawSmoothLine(spriteBatch,
            start - Main.screenPosition, start + segment - Main.screenPosition, color, width);
    }
}