using System.Collections.Generic;
using UnityEngine;
using Platformer.Mechanics;
using Platformer.Gameplay;
using static Platformer.Core.Simulation;
namespace EerieVillage.Skills.Effectors
{
///
/// 투사체 기본 컴포넌트. Line 궤적 직선 이동·단일 적 타격 후 소멸.
/// BT12-Dev Phase 2-B §4-2.
/// 파생: (A15 추적 화염구).
///
public class Projectile : MonoBehaviour
{
protected ActiveSkillData _data;
protected ActiveSkillRuntime _runtime;
protected PlayerSkillInventory _inventory;
protected Vector2 _direction;
protected float _speed = 12f;
protected float _lifetime = 3f;
// 동일 투사체로 동일 Collider 중복 타격 방지
protected readonly HashSet _hitTargets = new HashSet();
///
/// ProjectileSpawner.Trigger 에서 Instantiate 직후 호출.
///
public virtual void Initialize(ActiveSkillRuntime runtime, PlayerSkillInventory inventory, Vector2 direction)
{
_runtime = runtime;
_data = runtime.ActiveData;
_inventory = inventory;
_direction = direction.normalized;
_hitTargets.Clear();
// Phase 2-B: 풀링 미도입 — Invoke 기반 자동 소멸
Invoke(nameof(SelfDestruct), _lifetime);
}
protected virtual void Update()
{
transform.position += (Vector3)(_direction * _speed * Time.deltaTime);
}
protected virtual void OnTriggerEnter2D(Collider2D other)
{
if (_hitTargets.Contains(other)) return;
// PD 지시 2026-05-09 후속 방어 — 자기(Player) hit·자기 자신·hit 방어.
if (other.GetComponent() != null) return;
// Enemy 레이어 한정.
// Phase 2-D fallback (2026-05-09): TagManager에 "Enemy" 레이어 미등재 시 LayerMask.NameToLayer 반환값 = -1.
// 레이어 매칭 실패 시 EnemyController 컴포넌트 존재 여부로 대체 판정.
int enemyLayer = LayerMask.NameToLayer("Enemy");
bool isEnemy = (enemyLayer != -1 && other.gameObject.layer == enemyLayer)
|| other.GetComponent() != null;
if (!isEnemy) return;
var health = other.GetComponent();
if (health == null || !health.IsAlive) return;
_hitTargets.Add(other);
// 유효 대미지 산출 (balance/01 v0.2 §3 공식 — ActiveSkillRuntime.CalculateEffectiveDamage())
// BT12-Dev 2026-05-10 임시 (PD 지시): 기본 공격력 5 하한 강제. balance-designer 정식 수치 영역 임시 영역.
int damage = Mathf.Max(_runtime.CalculateEffectiveDamage(), 5);
// 피해 적용
health.Decrement(damage);
// 부가 효과 (DoT·Stun·Slow·DebuffStack) — StatusApplier 위임
var enemy = other.GetComponent();
if (enemy != null)
{
StatusApplier.Apply(_data, enemy);
}
// BT12-Dev 2026-05-10 근본 fix — Enemy 즉사 시 EnemyDeath 체인 발동 (AttackHitbox.cs:70~76 패턴 정합).
// 누락 시 Enemy hp 0 도달 영역 시각 사망 X·Destroy X·ExperienceSystem.OnEnemyKilled X (경험치 X·레벨업 X).
if (!health.IsAlive && enemy != null)
{
Schedule().enemy = enemy;
}
// 단일 적 타격 후 소멸 (관통 미지원 — Phase 2 범위 내)
SelfDestruct();
}
protected void SelfDestruct()
{
CancelInvoke(nameof(SelfDestruct));
Destroy(gameObject);
}
}
}