using System.Collections.Generic;
using UnityEngine;
using Colosseum.Enemy;
using Colosseum.Passives;
using Colosseum.Skills;
namespace Colosseum.Combat
{
///
/// 힐, 보호막, 버프 등 비공격 스킬에서 위협을 생성할 때 사용하는 공통 유틸리티입니다.
/// 시전자 주변의 적을 탐색하고, 위협 배율 체인을 적용하여 위협을 누적합니다.
///
public static class ThreatUtility
{
private const float DefaultThreatRadius = 50f;
private static readonly Collider[] overlapBuffer = new Collider[256];
private static readonly HashSet processedEnemies = new HashSet();
///
/// 시전자 주변의 적들에게 위협을 분배합니다.
/// 위협 공식: baseThreat × (Gem 배율 × ThreatController 배율 × Passive 배율)
///
/// 시전자 (위협을 얻을 주체)
/// 배율 적용 전 기본 위협 수치
/// 위협을 생성할 반경 (기본 50m)
public static void GenerateThreatOnNearbyEnemies(GameObject caster, float baseThreat, float radius = DefaultThreatRadius)
{
if (caster == null || baseThreat <= 0f)
return;
float multiplier = ResolveThreatMultiplier(caster);
float finalThreat = baseThreat * multiplier;
processedEnemies.Clear();
int hitCount = Physics.OverlapSphereNonAlloc(
caster.transform.position,
Mathf.Max(radius, 1f),
overlapBuffer);
for (int i = 0; i < hitCount; i++)
{
Collider hit = overlapBuffer[i];
if (hit == null)
continue;
EnemyBase enemy = hit.GetComponentInParent();
if (enemy == null || processedEnemies.Contains(enemy))
continue;
if (!enemy.UseThreatSystem || enemy.IsDead)
continue;
// 같은 팀(적이 아님)은 제외
if (Colosseum.Team.IsSameTeam(caster, enemy.gameObject))
continue;
processedEnemies.Add(enemy);
enemy.AddThreat(caster, finalThreat);
}
if (processedEnemies.Count > 0)
{
CombatBalanceTracker.RecordThreat(caster, finalThreat);
}
}
///
/// 시전자의 전체 위협 배율을 계산합니다.
/// 체인: SkillGem 배율 × ThreatController 배율 × Passive 배율
///
public static float ResolveThreatMultiplier(GameObject source)
{
if (source == null)
return 1f;
float gemMultiplier = SkillRuntimeModifierUtility.GetThreatMultiplier(source);
ThreatController threatController = source.GetComponent();
float runtimeMultiplier = threatController != null
? Mathf.Max(0f, threatController.CurrentThreatMultiplier)
: 1f;
float passiveMultiplier = PassiveRuntimeModifierUtility.GetThreatGeneratedMultiplier(source);
return gemMultiplier * runtimeMultiplier * passiveMultiplier;
}
}
}