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 System;
using Terraria;
using Terraria.GameContent;
using Terraria.ID;
using Terraria.ModLoader;

namespace SoulHarvest.Projectiles;

public class DomainSoulBladeProjectile : ModProjectile
{
    public override string Texture => "Terraria/Images/Projectile_0";

    public override void SetStaticDefaults()
    {
        ProjectileID.Sets.TrailCacheLength[Type] = 12;
        ProjectileID.Sets.TrailingMode[Type] = 2;
    }

    public override void SetDefaults()
    {
        Projectile.width = 30;
        Projectile.height = 30;
        Projectile.friendly = true;
        Projectile.hostile = false;
        Projectile.tileCollide = false;
        Projectile.ignoreWater = true;
        Projectile.penetrate = 3;
        Projectile.timeLeft = 150;
        Projectile.usesLocalNPCImmunity = true;
        Projectile.localNPCHitCooldown = 15;
    }

    public override void AI()
    {
        Projectile.rotation = Projectile.velocity.ToRotation() + MathHelper.PiOver4;
        NPC? target = FindTarget(700f);
        if (target is not null)
        {
            float speed = Math.Max(8f, Projectile.velocity.Length());
            Vector2 desired = (target.Center - Projectile.Center).SafeNormalize(Vector2.UnitX) * speed;
            Projectile.velocity = Vector2.Lerp(Projectile.velocity, desired, 0.075f);
        }

        if (Main.rand.NextBool(2))
        {
            Dust dust = Dust.NewDustPerfect(Projectile.Center, DustID.DungeonSpirit, -Projectile.velocity * 0.08f, 80, new Color(105, 225, 245), 0.65f);
            dust.noGravity = true;
        }
    }

    public override bool PreDraw(ref Color lightColor)
    {
        int itemType = (int)Projectile.ai[0];
        if (itemType <= ItemID.None || itemType >= ItemLoader.ItemCount)
            return false;
        Main.instance.LoadItem(itemType);
        Texture2D texture = TextureAssets.Item[itemType].Value;
        Rectangle frame = Main.itemAnimations[itemType]?.GetFrame(texture) ?? texture.Frame();
        float scale = Math.Min(0.7f, 42f / Math.Max(frame.Width, frame.Height));
        Vector2 origin = frame.Size() * 0.5f;
        for (int index = Projectile.oldPos.Length - 1; index >= 0; index--)
        {
            if (Projectile.oldPos[index] == Vector2.Zero)
                continue;
            float progress = 1f - index / (float)Projectile.oldPos.Length;
            Color color = Color.Lerp(new Color(210, 25, 75), new Color(75, 225, 245), progress) * (progress * 0.5f);
            Vector2 position = Projectile.oldPos[index] + Projectile.Size * 0.5f - Main.screenPosition;
            Main.EntitySpriteDraw(texture, position, frame, color, Projectile.oldRot[index], origin, scale * (0.75f + progress * 0.25f), SpriteEffects.None);
        }
        Main.EntitySpriteDraw(texture, Projectile.Center - Main.screenPosition, frame, Color.White, Projectile.rotation, origin, scale, SpriteEffects.None);
        return false;
    }

    private NPC? FindTarget(float maximumDistance)
    {
        NPC? result = null;
        foreach (NPC npc in Main.ActiveNPCs)
        {
            if (!npc.CanBeChasedBy(Projectile))
                continue;
            float distance = Vector2.Distance(npc.Center, Projectile.Center);
            if (distance < maximumDistance)
            {
                maximumDistance = distance;
                result = npc;
            }
        }
        return result;
    }
}