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

DeathMod

【Terraria】DeathMod (now aka Soul Harvest)

公开
关注 0 Fork 0 Star 0
UTF-8
using SoulHarvest.Projectiles;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using Terraria;
using Terraria.Audio;
using Terraria.GameContent;
using Terraria.ID;
using Terraria.ModLoader;

namespace SoulHarvest.Common;


/// <summary>
/// Observes already-networked gameplay projectiles for the few skill activations
/// which do not own an NPC status transition (echo, refraction, residual cut and
/// zero-degree follow-up).  The per-projectile flag guarantees one local report.
/// </summary>
[Autoload(Side = ModSide.Client)]
internal sealed class ReaperSkillProjectileObserver : GlobalProjectile
{
    public override bool InstancePerEntity => true;

    private bool reported;

    public override void PostAI(Projectile projectile)
    {
        if (reported || Main.dedServ || projectile.owner < 0 || projectile.owner >= Main.maxPlayers)
            return;

        MyGlobalProjectile data = projectile.GetGlobalProjectile<MyGlobalProjectile>();
        if (!data.HasReaperSnapshot)
            return;

        SickleCombatSnapshot snapshot = data.ReaperSnapshot;
        int skill = -1;
        int level = 0;
        if (projectile.ModProjectile is ReaperFrostShardProjectile or FrostShardProjectile && snapshot.Skill2 > 0)
        {
            skill = 1;
            level = snapshot.Skill2;
        }
        else if (projectile.ModProjectile is ReaperStrikeProjectile
            && data.ReaperHitKind == ReaperHitKind.PrimaryDerived)
        {
            int lastPhase = ReaperCombatRegistry.GetPrimaryPhaseCount(snapshot.Form, snapshot.Stage) - 1;
            switch (snapshot.Form)
            {
                case ReaperFormId.Soul when snapshot.Skill1 > 0:
                    skill = 0;
                    level = snapshot.Skill1;
                    break;
                case ReaperFormId.Frost when data.ReaperPhase == 2 && snapshot.Skill3 > 0:
                    skill = 2;
                    level = snapshot.Skill3;
                    break;
                case ReaperFormId.Void when data.ReaperPhase == lastPhase && snapshot.Skill2 > 0:
                    skill = 1;
                    level = snapshot.Skill2;
                    break;
                case ReaperFormId.Infernal when snapshot.Stage >= ReaperStage.StageIII
                    && data.ReaperPhase == 2 && snapshot.Skill3 > 0:
                    skill = 2;
                    level = snapshot.Skill3;
                    break;
            }
        }

        if (skill < 0 || level <= 0)
            return;
        reported = true;
        int seed = ReaperSkillCueProjectile.StableSeed(
            projectile.owner, projectile.identity, data.ReaperActionId, skill);
        ReaperSkillVisualSystem.ReportSkill(projectile.owner, snapshot.Form, snapshot.Stage,
            skill, Math.Clamp(level, 1, 3), 0, projectile.Center,
            data.AttackAngle.ToRotationVector2(), data.ReaperActionId, seed);
    }
}