- 보호막을 단일 수치에서 타입별 독립 인스턴스 구조로 리팩터링하고 같은 타입만 갱신되도록 정리 - 플레이어/보스 보호막 상태를 이상상태와 연동해 HUD 및 보스 UI에서 타입별로 식별 가능하게 보강 - 드로그 집행 개시 전조를 집행 준비 이상상태 기반으로 재구성하고 관련 데이터와 보스 컨텍스트를 정리 - 전투 밸런스 계측기와 디버그 메뉴를 추가해 피해, 치유, 보호막, 위협, 패턴 사용량 측정 경로를 마련 - 테스트용 보호막 A/B와 시그니처 전조 자산을 추가하고 기본 포트 7777 원복 후 빌드 및 런타임 검증을 완료
141 lines
4.6 KiB
C#
141 lines
4.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Colosseum.Stats;
|
|
|
|
namespace Colosseum.Abnormalities
|
|
{
|
|
/// <summary>
|
|
/// 제어 효과 타입
|
|
/// </summary>
|
|
public enum ControlType
|
|
{
|
|
None, // 제어 효과 없음
|
|
Stun, // 기절 (이동, 스킬 사용 불가)
|
|
Silence, // 침묵 (스킬 사용 불가)
|
|
Slow, // 둔화 (이동 속도 감소)
|
|
Invincible // 무적 (대미지 무시)
|
|
}
|
|
|
|
/// <summary>
|
|
/// 스탯 수정자 엔트리
|
|
/// </summary>
|
|
[Serializable]
|
|
public class AbnormalityStatModifier
|
|
{
|
|
[Tooltip("수정할 스탯 타입")]
|
|
public StatType statType;
|
|
|
|
[Tooltip("수정값")]
|
|
public float value;
|
|
|
|
[Tooltip("수정 타입 (Flat: 고정값, PercentAdd: 퍼센트 합산, PercentMult: 퍼센트 곱셈)")]
|
|
public StatModType modType;
|
|
|
|
public AbnormalityStatModifier() { }
|
|
|
|
public AbnormalityStatModifier(StatType statType, float value, StatModType modType)
|
|
{
|
|
this.statType = statType;
|
|
this.value = value;
|
|
this.modType = modType;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 이상 상태 정의 ScriptableObject
|
|
/// 버프/디버프의 데이터를 정의합니다.
|
|
/// </summary>
|
|
[CreateAssetMenu(fileName = "AbnormalityData", menuName = "Colosseum/Abnormalities/Abnormality")]
|
|
public class AbnormalityData : ScriptableObject
|
|
{
|
|
[Header("기본 정보")]
|
|
[Tooltip("이상 상태 이름")]
|
|
public string abnormalityName = "Abnormality";
|
|
|
|
[Tooltip("아이콘")]
|
|
public Sprite icon;
|
|
|
|
[Tooltip("지속 시간 (초, 0 이하면 영구)")]
|
|
public float duration = 5f;
|
|
|
|
[Tooltip("효과 레벨 (중복 처리용, 높으면 우선)")]
|
|
public int level = 1;
|
|
|
|
[Tooltip("디버프 여부")]
|
|
public bool isDebuff = false;
|
|
|
|
[Tooltip("플레이어 HUD의 이상상태 UI에 표시할지 여부")]
|
|
public bool showInUI = true;
|
|
|
|
[Tooltip("보호막 계열 상태인지 여부 (보호막 인스턴스 동기화용)")]
|
|
public bool isShieldState = false;
|
|
|
|
[Tooltip("활성 중에는 일반 피격 반응(경직, 넉백, 다운)을 무시할지 여부")]
|
|
public bool ignoreHitReaction = false;
|
|
|
|
[Header("시각 효과")]
|
|
[Tooltip("이상 상태가 유지되는 동안 대상에 붙일 루핑 VFX 프리팹")]
|
|
public GameObject loopingVfxPrefab;
|
|
|
|
[Tooltip("루핑 VFX 위치 보정값")]
|
|
public Vector3 loopingVfxOffset = Vector3.zero;
|
|
|
|
[Tooltip("루핑 VFX 스케일 배율")]
|
|
[Min(0.01f)]
|
|
public float loopingVfxScaleMultiplier = 1f;
|
|
|
|
[Tooltip("루핑 VFX를 대상의 자식으로 붙일지 여부")]
|
|
public bool parentLoopingVfxToTarget = true;
|
|
|
|
[Header("스탯 수정자")]
|
|
[Tooltip("스탯에 적용할 수정자 목록")]
|
|
public List<AbnormalityStatModifier> statModifiers = new List<AbnormalityStatModifier>();
|
|
|
|
[Header("주기적 효과 (DoT/HoT)")]
|
|
[Tooltip("주기적 효과 간격 (초, 0이면 비활성)")]
|
|
public float periodicInterval = 0f;
|
|
|
|
[Tooltip("주기적 효과값 (양수=힐, 음수=데미지)")]
|
|
public float periodicValue = 0f;
|
|
|
|
[Header("제어 효과 (CC)")]
|
|
[Tooltip("제어 효과 타입")]
|
|
public ControlType controlType = ControlType.None;
|
|
|
|
[Tooltip("둔화 배율 (Slow일 때, 0.5 = 50% 감소)")]
|
|
[Range(0f, 1f)]
|
|
public float slowMultiplier = 0.5f;
|
|
|
|
[Header("피해 배율")]
|
|
[Tooltip("이상 상태가 적용된 동안 받는 피해 배율 (1 = 기본, 1.1 = 10% 증가)")]
|
|
[Min(0f)]
|
|
public float incomingDamageMultiplier = 1f;
|
|
|
|
/// <summary>
|
|
/// 영구 효과인지 확인
|
|
/// </summary>
|
|
public bool IsPermanent => duration <= 0f;
|
|
|
|
/// <summary>
|
|
/// 주기적 효과가 있는지 확인
|
|
/// </summary>
|
|
public bool HasPeriodicEffect => periodicInterval > 0f && periodicValue != 0f;
|
|
|
|
/// <summary>
|
|
/// 제어 효과가 있는지 확인
|
|
/// </summary>
|
|
public bool HasControlEffect => controlType != ControlType.None;
|
|
|
|
/// <summary>
|
|
/// 유지형 루핑 VFX가 있는지 확인
|
|
/// </summary>
|
|
public bool HasLoopingVfx => loopingVfxPrefab != null;
|
|
|
|
/// <summary>
|
|
/// 받는 피해 배율 변경 여부
|
|
/// </summary>
|
|
public bool HasIncomingDamageModifier => !Mathf.Approximately(incomingDamageMultiplier, 1f);
|
|
}
|
|
}
|