105 lines
6.0 KiB
C#
105 lines
6.0 KiB
C#
// ─────────────────────────────────────────────────────────────────────────────
|
|
// BossEvents.cs — WL 전투 액션 · 보스 페이즈 통지 허브(정적)
|
|
//
|
|
// PD 지시 #813 · 발주서 WL-813h §1-1 (2026-09-09)
|
|
//
|
|
// ■ 왜 별도 파일인가
|
|
// 코어 허브 `Assets/WL/Combat/Core/CombatEvents.cs` 는 811d~j 가 동시에 물고 있어 수정 금지다.
|
|
// 보스 페이즈(BossPhase)는 811 12종 이벤트에 없던 새 축이므로 같은 규약으로 이 파일에 따로 둔다.
|
|
// · 정적 클래스(새 Manager/Singleton 0) · 구조체 페이로드를 `in` 으로 전달(복사·박싱 0)
|
|
// · 구독자 = 사전 할당 배열(코어의 CombatEventList<T> 재사용 — Assembly-CSharp 단일 어셈블리)
|
|
// · 구독자 예외는 try/catch 로 격리(코어 CombatEventList.Dispatch 안) → 원본 전투 흐름을 끊지 않는다
|
|
// · WLCombatCoreSettings.enabled / RuntimeDisabled 를 그대로 준수(C8 롤백 1순위 스위치 공유)
|
|
//
|
|
// ■ 발생 지점 (원본 훅은 BossMobActor.cs 1줄뿐 — 실제 판정은 BossPatternTable 안)
|
|
// BossMobActor.On_Regen ─ BossPatternTable.Apply → 페이즈 1 진입 통지(스폰)
|
|
// BossMobActor.Get_Damage ─ BossPatternTable.UpdatePhase → HP% 가 임계를 내려갈 때만 통지
|
|
// 페이즈는 단조 증가(회복해도 되돌아가지 않는다) — 연출·UI 가 페이즈를 왕복하지 않게 한다.
|
|
//
|
|
// ■ 임계값의 출처 (C45)
|
|
// 코드 상수 0. 임계는 `Assets/WL/Combat/Settings/Resources/WL/WL813h_BossPattern.json`
|
|
// (보스별 phaseThresholds · 없으면 테이블 기본 [1.0, 0.7, 0.4]).
|
|
// JSON 이 없거나 코어가 꺼져 있으면 Raise 자체가 일어나지 않는다 = 원본 100%.
|
|
//
|
|
// 🔴 어셈블리 주의: Assets/WL/Combat/ 에 .asmdef 를 만들지 말 것(BossMobActor 가 Assembly-CSharp 에 있다).
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
using UnityEngine;
|
|
using WL.Combat.Core;
|
|
|
|
namespace WL.Combat.Boss
|
|
{
|
|
/// <summary>보스 페이즈 전환 페이로드(발생 시점 스냅샷 · struct · GC 0).</summary>
|
|
public struct BossPhaseEvent
|
|
{
|
|
/// <summary>페이즈가 바뀐 보스(에디트 모드 프로브에서는 프리팹 인스턴스일 수 있다).</summary>
|
|
public BossMobActor boss;
|
|
/// <summary>MonsterList 의 n_MonsterID (Anubis = 10006).</summary>
|
|
public int monsterId;
|
|
/// <summary>이전 페이즈(스폰 통지는 0) · 새 페이즈(1부터).</summary>
|
|
public int prevPhase, phase;
|
|
/// <summary>이 보스의 총 페이즈 수(임계 배열 길이).</summary>
|
|
public int phaseCount;
|
|
/// <summary>전환 시점의 HP 비율(0~1) · 이 페이즈에 들어오게 한 임계값.</summary>
|
|
public float hpPercent, threshold;
|
|
/// <summary>스폰(페이즈 1 진입) 통지면 true — 피해로 인한 전환과 구분한다.</summary>
|
|
public bool isSpawn;
|
|
public float time;
|
|
public int frame;
|
|
}
|
|
|
|
/// <summary>보스 이벤트 허브. 정적 · GC 0 · 구독은 BossPhase.Add / Remove.</summary>
|
|
public static class BossEvents
|
|
{
|
|
/// <summary>페이즈 전환 구독자 목록(코어와 같은 구현 · 예외 격리 · Raised/Dispatched 카운터).</summary>
|
|
public static readonly CombatEventList<BossPhaseEvent> BossPhase = new CombatEventList<BossPhaseEvent>(4);
|
|
|
|
/// <summary>코어 활성 여부 = WLCombatCoreSettings.Enabled(에셋 · enabled · RuntimeDisabled).</summary>
|
|
public static bool Enabled { get { return WLCombatCoreSettings.Enabled; } }
|
|
|
|
// ── 진단(프로브가 읽는다)
|
|
public static int TotalRaised;
|
|
public static string LastEvent = "";
|
|
public static float LastEventTime;
|
|
public static int LastPhase, LastPrevPhase, LastMonsterId;
|
|
public static float LastHpPercent, LastThreshold;
|
|
|
|
/// <summary>
|
|
/// 페이즈 전환 통지. 호출측(BossPatternTable)이 이미 "바뀌었다"를 판정한 뒤에만 부른다.
|
|
/// 코어가 꺼져 있으면 즉시 반환(C8) — 구독자도 카운터도 움직이지 않는다.
|
|
/// </summary>
|
|
public static void RaiseBossPhase(BossMobActor boss, int monsterId, int prevPhase, int phase,
|
|
int phaseCount, float hpPercent, float threshold, bool isSpawn)
|
|
{
|
|
if (!Enabled) return;
|
|
var e = new BossPhaseEvent
|
|
{
|
|
boss = boss, monsterId = monsterId,
|
|
prevPhase = prevPhase, phase = phase, phaseCount = phaseCount,
|
|
hpPercent = hpPercent, threshold = threshold, isSpawn = isSpawn,
|
|
time = Time.unscaledTime, frame = Time.frameCount
|
|
};
|
|
TotalRaised++;
|
|
LastEvent = "BossPhase";
|
|
LastEventTime = e.time;
|
|
LastPrevPhase = prevPhase; LastPhase = phase; LastMonsterId = monsterId;
|
|
LastHpPercent = hpPercent; LastThreshold = threshold;
|
|
BossPhase.Dispatch(in e);
|
|
|
|
var c = WLCombatCoreSettings.Instance;
|
|
if (c != null && c.verboseLog)
|
|
Debug.Log("[BossEvents] Phase " + prevPhase + "→" + phase + " id=" + monsterId +
|
|
" hp=" + hpPercent.ToString("F3") + " th=" + threshold.ToString("F3"));
|
|
}
|
|
|
|
/// <summary>프로브용: 카운터 초기화(구독은 유지).</summary>
|
|
public static void ResetDiagnostics()
|
|
{
|
|
TotalRaised = 0; LastEvent = ""; LastEventTime = 0f;
|
|
LastPhase = LastPrevPhase = LastMonsterId = 0;
|
|
LastHpPercent = LastThreshold = 0f;
|
|
BossPhase.Raised = BossPhase.Dispatched = 0;
|
|
}
|
|
}
|
|
}
|