using UnityEngine; using Platformer.Mechanics; namespace EerieVillage.Skills.Effectors { /// /// 상태 효과 일괄 적용기. /// Projectile.OnTriggerEnter2D 등 타격 판정 후 ActiveSkillData 필드를 읽어 /// DoT·Stun·Slow·Knockback·DebuffStack 을 EnemyController 에 적용한다. /// BT12-Dev Phase 2-B §4-5. /// public static class StatusApplier { public static void Apply(ActiveSkillData data, EnemyController enemy) { if (data == null || enemy == null) return; // DoT (화염·독 등) — DotInterval > 0 영역만 발화 (DotDuration 영역 OnDotFxPrefab.ParticleSystem.main.duration 영역 자동 영역) // BT12-Dev 2026-05-13 — damage = BaseDamage × DotDamageMultiplier (PD 영역: 25%) + OnDotFxPrefab 자식 spawn if ((data.DotDuration > 0f || data.OnDotFxPrefab != null) && data.DotInterval > 0f) { int dotDamage = Mathf.Max(1, Mathf.RoundToInt(data.BaseDamage * data.DotDamageMultiplier)); ApplyDoT(enemy, dotDamage, data.DotDuration, data.DotInterval, data.OnDotFxPrefab, data.DotFxScale); } // 기절 (스턴) if (data.StunDuration > 0f) { ApplyStun(enemy, data.StunDuration); } // 감속 (슬로우) if (data.SlowDuration > 0f && data.SlowMultiplier < 1.0f) { ApplySlow(enemy, data.SlowDuration, data.SlowMultiplier); } // 넉백 if (data.KnockbackForce > 0f) { ApplyKnockback(enemy, data.KnockbackForce); } // 저주 스택 (A08 저주의 화살) if (data.DebuffStackLimit > 0) { DebuffStack.AddStack(enemy, data.DebuffStackLimit, data.BaseDamage); } } // ------------------------------------------------------------------- // 내부 헬퍼 // ------------------------------------------------------------------- private static void ApplyDoT(EnemyController enemy, int damagePerTick, float duration, float interval, GameObject fxPrefab = null, float fxScale = 1f) { var existing = enemy.GetComponent(); if (existing == null) existing = enemy.gameObject.AddComponent(); existing.AddDoT(damagePerTick, duration, interval, fxPrefab, fxScale); } private static void ApplyStun(EnemyController enemy, float duration) { var existing = enemy.GetComponent(); if (existing == null) existing = enemy.gameObject.AddComponent(); existing.ApplyStun(duration); } private static void ApplySlow(EnemyController enemy, float duration, float multiplier) { var existing = enemy.GetComponent(); if (existing == null) existing = enemy.gameObject.AddComponent(); existing.ApplySlow(duration, multiplier); } private static void ApplyKnockback(EnemyController enemy, float force) { var rb = enemy.GetComponent(); if (rb != null) { // facing 반대 방향 넉백 — 단순 +x 방향 (Phase 2 범위, Phase 2-C에서 방향 정합 예정) rb.AddForce(Vector2.right * force, ForceMode2D.Impulse); } } } }