using UnityEngine; using System.Collections.Generic; using Colosseum.Abnormalities; using Colosseum.Skills; namespace Colosseum.AI { /// /// 패턴의 대분류. grace period 판단에 사용됩니다. /// public enum PatternCategory { /// 기본 패턴 — grace period 제한 없음 Basic, /// 대형 패턴 — basicLoopCount 이후 사용 가능 Big, /// 징벌 패턴 — 항상 허용, bigPattern 카운터 리셋 Punish, } /// /// 패턴의 타겟 해석 방식 /// public enum TargetResolveMode { /// 타겟 해석 불필요 (시그니처 등 내부 처리) None, /// 가장 위협도가 높은 근접 대상 HighestThreat, /// 기동 패턴 전용 타겟 Mobility, /// 유틸리티 패턴 전용 타겟 Utility, } public enum PatternStepType { Skill, Wait, ChargeWait } /// /// ChargeWait 스텝의 차단 관련 설정 데이터입니다. /// 충전 대기 중 플레이어가 누적 피해를 충족하면 차단 성공으로 처리됩니다. /// [System.Serializable] public class ChargeStepData { [Header("차단 조건")] [Tooltip("차단에 필요한 누적 피해 비율 (보스 최대 체력 기준)")] [Range(0f, 1f)] [SerializeField] private float requiredDamageRatio = 0.1f; [Header("전조 효과")] [Tooltip("충전 중 부여할 전조 이상상태 (루핑 VFX 등)")] [SerializeField] private AbnormalityData telegraphAbnormality; [Header("차단 성공 효과")] [Tooltip("차단 성공 시 보스 경직 시간")] [Min(0f)] [SerializeField] private float staggerDuration = 2f; public float RequiredDamageRatio => requiredDamageRatio; public AbnormalityData TelegraphAbnormality => telegraphAbnormality; public float StaggerDuration => staggerDuration; } [System.Serializable] public class PatternStep { public PatternStepType Type = PatternStepType.Skill; public SkillData Skill; [Min(0f)] public float Duration = 0.5f; [Tooltip("ChargeWait 타입 전용 차단 설정")] public ChargeStepData ChargeData; } /// /// 보스 패턴 데이터. 순서대로 실행할 스텝(스킬 또는 대기) 목록과 쿨타임을 정의합니다. /// [CreateAssetMenu(fileName = "NewBossPattern", menuName = "Colosseum/Boss Pattern")] public class BossPatternData : ScriptableObject { [Header("패턴 정보")] [SerializeField] private string patternName; [Header("패턴 특성")] [Tooltip("패턴 분류 — grace period 판단에 사용")] [SerializeField] private PatternCategory category = PatternCategory.Basic; [Tooltip("시그니처 패턴 여부 — 현재 사용되지 않음 (ChargeWait 스텝으로 대체)")] [SerializeField] private bool isSignature; [Tooltip("근접 패턴 여부 — meleePatternCounter 갱신")] [SerializeField] private bool isMelee; [Tooltip("타겟 해석 방식")] [SerializeField] private TargetResolveMode targetMode = TargetResolveMode.HighestThreat; [Header("스텝 순서")] [SerializeField] private List steps = new List(); [Header("쿨타임")] [Min(0f)] [Tooltip("패턴 완료 후 다시 사용 가능해지기까지의 시간")] [SerializeField] private float cooldown = 5f; [Header("페이즈 제한")] [Min(1)] [Tooltip("이 패턴을 사용하기 시작하는 최소 페이즈 (1=Phase 1부터)")] [SerializeField] private int minPhase = 1; [Header("조건부 점프")] [Tooltip("점프 스텝에서 대상을 찾지 못하면 해당 스텝을 스킵하고 패턴을 종료합니다 (조합 패턴용)")] [SerializeField] private bool skipJumpStepOnNoTarget = false; public string PatternName => patternName; public PatternCategory Category => category; public bool IsSignature => isSignature; public bool IsMelee => isMelee; public TargetResolveMode TargetMode => targetMode; public IReadOnlyList Steps => steps; public float Cooldown => cooldown; public int MinPhase => minPhase; public bool SkipJumpStepOnNoTarget => skipJumpStepOnNoTarget; /// /// Big 패턴인지 반환합니다 (grace period 대상). /// public bool IsBigPattern => category == PatternCategory.Big; } }