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; /// /// 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. /// [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(); 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); } }