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 Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using Terraria;
using Terraria.DataStructures;
using Terraria.ID;
using Terraria.ModLoader;

namespace SoulHarvest.Projectiles;


/// <summary>
/// Assigns a server-local monotonic presentation action token to each Void slash.
/// A multi-cut special uses one strike projectile per visible cut, so each cut can
/// create its own impact rift without relying on reusable projectile identities.
/// </summary>
internal sealed class ReaperVoidHitActionTokenGlobalProjectile : GlobalProjectile
{
    private static int nextToken;

    public override bool InstancePerEntity => true;

    // This token is presentation-only. Restrict the per-entity global to the two
    // direct-hit projectile types so unrelated projectiles do not pay an
    // allocation or spawn hook.
    public override bool AppliesToEntity(Projectile entity, bool lateInstantiation)
        => lateInstantiation && entity.ModProjectile is SickleSwingProjectile
            or ReaperStrikeProjectile;

    internal int ActionToken { get; private set; }

    public override void OnSpawn(Projectile projectile, IEntitySource source)
    {
        if (Main.netMode == NetmodeID.MultiplayerClient)
            return;
        ActionToken = NextToken();
    }

    internal static int Resolve(Projectile projectile, int fallback)
    {
        if (Main.netMode == NetmodeID.MultiplayerClient)
            return fallback;
        return GetOrAssign(projectile);
    }

    private static int GetOrAssign(Projectile projectile)
    {
        ReaperVoidHitActionTokenGlobalProjectile data =
            projectile.GetGlobalProjectile<ReaperVoidHitActionTokenGlobalProjectile>();
        if (data.ActionToken == 0)
            data.ActionToken = NextToken();
        return data.ActionToken;
    }

    private static int NextToken()
    {
        unchecked
        {
            nextToken++;
            if (nextToken == 0)
                nextToken++;
        }
        return nextToken;
    }
}