using System.Collections.Generic; using UnityEngine; using Colosseum.Combat; using Colosseum.Enemy; namespace Colosseum.Skills.Effects { /// /// 주변 적의 위협 수치를 높여 주 대상을 자신에게 돌리는 도발 효과입니다. /// 필요 시 시전자에게 임시 위협 생성 배율도 함께 부여합니다. /// [CreateAssetMenu(fileName = "TauntEffect", menuName = "Colosseum/Skills/Effects/Taunt")] public class TauntEffect : SkillEffect { [Header("Taunt Settings")] [Tooltip("도발 시 추가할 기본 위협 수치")] [Min(0f)] [SerializeField] private float flatThreatAmount = 50f; [Tooltip("현재 최고 위협보다 이 값만큼 더 높게 설정합니다.")] [Min(0f)] [SerializeField] private float threatLeadBonus = 10f; [Tooltip("도발과 함께 시전자에게 부여할 위협 생성 배율")] [Min(0f)] [SerializeField] private float selfThreatMultiplier = 1.5f; [Tooltip("위협 생성 배율 지속 시간")] [Min(0f)] [SerializeField] private float selfThreatMultiplierDuration = 5f; private readonly Collider[] overlapBuffer = new Collider[16]; private readonly HashSet processedEnemies = new HashSet(); protected override void ApplyEffect(GameObject caster, GameObject target) { if (caster == null) return; ApplySelfThreatMultiplier(caster); processedEnemies.Clear(); int hitCount = Physics.OverlapSphereNonAlloc(caster.transform.position, areaRadius, overlapBuffer, targetLayers); 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 (!IsValidTarget(caster, enemy.gameObject)) continue; processedEnemies.Add(enemy); ApplyTauntThreat(enemy, caster); } } private void ApplySelfThreatMultiplier(GameObject caster) { if (selfThreatMultiplier <= 0f || selfThreatMultiplierDuration <= 0f) return; ThreatController threatController = caster.GetComponent(); if (threatController == null) { threatController = caster.AddComponent(); } threatController.ApplyThreatMultiplier(selfThreatMultiplier, selfThreatMultiplierDuration); } private void ApplyTauntThreat(EnemyBase enemy, GameObject caster) { if (enemy == null || caster == null || !enemy.UseThreatSystem) return; GameObject highestThreatTarget = enemy.GetHighestThreatTarget(); float highestThreat = highestThreatTarget != null ? enemy.GetThreat(highestThreatTarget) : 0f; float currentCasterThreat = enemy.GetThreat(caster); float desiredThreat = Mathf.Max(currentCasterThreat + flatThreatAmount, highestThreat + threatLeadBonus + flatThreatAmount); enemy.SetThreat(caster, desiredThreat); } } }