205 lines
10 KiB
C#
205 lines
10 KiB
C#
// ─────────────────────────────────────────────────────────────────────────────
|
|
// WLSurvivalUiBridge.cs — 813tj 가 열어 둔 6줄을 813i API 에 연결한다 (WL-813y §1-1 · #813)
|
|
//
|
|
// 813tj 완료보고 §4 ②:
|
|
// "813i 병합 시 PotionButton.CountProvider/CooldownRemainProvider/CooldownTotalProvider/UseHandler 4줄 +
|
|
// ReviveDialog.NotifyDeath()/ReviveRequested 2줄만 연결하면 끝(UI 수정 0)"
|
|
//
|
|
// ■ 왜 Gameplay 가 아니라 여기인가
|
|
// 813i(`Assets/WL/Combat/Survival/**`)는 **Gameplay 소유**라 이 세션이 손대지 못한다(발주서 §2 금지).
|
|
// UI 쪽에서 813i 의 **public API 만 호출**하는 얇은 브리지를 두면 소유 경계를 넘지 않고 6줄이 붙는다.
|
|
//
|
|
// ■ 연결 6줄 (813i 완료보고 §4 · 전부 `WL.Combat.Survival`)
|
|
// ① PotionButton.CountProvider ← PotionUse.Remaining
|
|
// ② PotionButton.CooldownRemainProvider ← PotionUse.CooldownRemaining
|
|
// ③ PotionButton.CooldownTotalProvider ← PotionUse.CooldownTotal
|
|
// ④ PotionButton.UseHandler ← PotionUse.TryUse() == PotionResult.Used
|
|
// ⑤ ReviveDialog.NotifyDeath() ← DeathFlow.Died / DeathFlow.ReviveRequested 구독
|
|
// ⑥ ReviveDialog.ReviveRequested ← DeathFlow.Revive()
|
|
//
|
|
// ■ 스위치 = 813i 소유 `WLSurvivalSettings.Enabled`(에셋 `enabled` · **Lead 가 병합 시 켠다**)
|
|
// 꺼져 있으면 물약 표시는 813tj 의 표시용 기본값으로 떨어지고, 사망/부활 이벤트는 애초에 안 온다
|
|
// → 병합 전후 어느 쪽이든 화면이 깨지지 않는다(C8).
|
|
//
|
|
// 🔴 어셈블리 주의: Assets/WL/UI/ 에 .asmdef 를 만들지 말 것(Assembly-CSharp 단일).
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
using System.Text;
|
|
using UnityEngine;
|
|
using WL.Combat.Survival;
|
|
|
|
namespace WL.UI
|
|
{
|
|
public static class WLSurvivalUiBridge
|
|
{
|
|
public static bool Installed { get; private set; }
|
|
|
|
// 진단(프로브가 읽는다 · 실측만)
|
|
public static int DiedSeen, ReviveRequestedSeen, RevivedSeen, PotionChangedSeen;
|
|
public static int ReviveCalls, PotionUseCalls, PotionUseOk;
|
|
public static string LastEvent = "";
|
|
public static float LastEventTime;
|
|
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
|
private static void Boot() { Install(); }
|
|
|
|
/// <summary>6줄을 연결한다(중복 호출 안전). 프로브도 이 경로를 쓴다.</summary>
|
|
public static string Install()
|
|
{
|
|
if (Installed) return "이미 연결됨";
|
|
|
|
// ── 물약 4줄 ──────────────────────────────────────────────────────
|
|
// 스위치가 꺼져 있으면 813tj 의 표시용 기본값으로 떨어진다(연결 전 화면과 동일).
|
|
PotionButton.CountProvider = ReadCount;
|
|
PotionButton.CooldownRemainProvider = ReadCooldownRemain;
|
|
PotionButton.CooldownTotalProvider = ReadCooldownTotal;
|
|
PotionButton.UseHandler = Use;
|
|
|
|
// ── 부활 2줄 ──────────────────────────────────────────────────────
|
|
ReviveDialog.ReviveRequested = RequestRevive;
|
|
DeathFlow.Died.Add(OnDied);
|
|
DeathFlow.ReviveRequested.Add(OnReviveRequested);
|
|
DeathFlow.Revived.Add(OnRevived);
|
|
PotionUse.Changed.Add(OnPotionChanged);
|
|
|
|
Installed = true;
|
|
return "연결 6줄 완료 · survivalEnabled=" + WLSurvivalSettings.Enabled;
|
|
}
|
|
|
|
/// <summary>연결을 끊는다(프로브 종료 · 813tj 원래 상태로 복귀).</summary>
|
|
public static string Uninstall()
|
|
{
|
|
if (!Installed) return "연결 안 돼 있음";
|
|
PotionButton.ClearProvider();
|
|
ReviveDialog.ReviveRequested = null;
|
|
DeathFlow.Died.Remove(OnDied);
|
|
DeathFlow.ReviveRequested.Remove(OnReviveRequested);
|
|
DeathFlow.Revived.Remove(OnRevived);
|
|
PotionUse.Changed.Remove(OnPotionChanged);
|
|
Installed = false;
|
|
return "연결 해제(813tj 미연결 상태로 복귀)";
|
|
}
|
|
|
|
// ── 물약 (813i PotionUse) ─────────────────────────────────────────────
|
|
private static int ReadCount()
|
|
{
|
|
if (!WLSurvivalSettings.Enabled) return FallbackCount();
|
|
return PotionUse.Remaining;
|
|
}
|
|
|
|
private static float ReadCooldownRemain()
|
|
{
|
|
return WLSurvivalSettings.Enabled ? PotionUse.CooldownRemaining : 0f;
|
|
}
|
|
|
|
private static float ReadCooldownTotal()
|
|
{
|
|
if (!WLSurvivalSettings.Enabled) return FallbackCooldown();
|
|
float t = PotionUse.CooldownTotal;
|
|
return t > 0f ? t : FallbackCooldown();
|
|
}
|
|
|
|
private static bool Use()
|
|
{
|
|
PotionUseCalls++;
|
|
if (!WLSurvivalSettings.Enabled) { Note("potion:disabled"); return false; }
|
|
var r = PotionUse.TryUse();
|
|
bool ok = r == PotionResult.Used;
|
|
if (ok) PotionUseOk++;
|
|
Note("potion:" + r);
|
|
return ok;
|
|
}
|
|
|
|
private static int FallbackCount()
|
|
{
|
|
var s = WLSurvivalUiSettings.Instance;
|
|
return s != null ? s.potionFallbackCount : 0;
|
|
}
|
|
|
|
private static float FallbackCooldown()
|
|
{
|
|
var s = WLSurvivalUiSettings.Instance;
|
|
return s != null ? s.potionFallbackCooldownSeconds : 0f;
|
|
}
|
|
|
|
private static void OnPotionChanged(in PotionEvent e)
|
|
{
|
|
PotionChangedSeen++;
|
|
Note("changed:" + e.change + "(" + e.remaining + "/" + e.max + ")");
|
|
}
|
|
|
|
// ── 사망 · 부활 (813i DeathFlow) ──────────────────────────────────────
|
|
/// <summary>사망 = 팝업 예약(813tj 는 자체 지연으로 사망 연출 시간을 기다린다).</summary>
|
|
private static void OnDied(in DeathEvent e)
|
|
{
|
|
DiedSeen++;
|
|
Note("died#" + e.deathCount + " display=" + e.displaySeconds.ToString("F2") + "s · " + ReviveDialog.NotifyDeath());
|
|
}
|
|
|
|
/// <summary>
|
|
/// 813i 가 사망 연출을 끝내고 부활 대기에 들어간 시점 — 지연 없이 지금 연다.
|
|
/// **이 구독자가 있어야** 813i 의 `autoReviveWhenNoListener`(구독 0 이면 자동 부활)가 꺼진다.
|
|
/// </summary>
|
|
private static void OnReviveRequested(in ReviveRequestEvent e)
|
|
{
|
|
ReviveRequestedSeen++;
|
|
Note("reviveRequested#" + e.deathCount + " worldHeld=" + e.worldHeld + " · " + ReviveDialog.NotifyReviveRequested());
|
|
}
|
|
|
|
private static void OnRevived(in RevivedEvent e)
|
|
{
|
|
RevivedSeen++;
|
|
Note("revived#" + e.deathCount + " external=" + e.external + " auto=" + e.auto + " · " + ReviveDialog.NotifyRevived());
|
|
}
|
|
|
|
/// <summary>팝업 "존 시작점에서 부활" 버튼 → 813i.</summary>
|
|
private static void RequestRevive()
|
|
{
|
|
ReviveCalls++;
|
|
bool ok = false;
|
|
if (WLSurvivalSettings.Enabled) ok = DeathFlow.Revive();
|
|
Note("revive() → " + ok);
|
|
}
|
|
|
|
private static void Note(string s)
|
|
{
|
|
LastEvent = s;
|
|
LastEventTime = Time.unscaledTime;
|
|
}
|
|
|
|
// ── 진단 ──────────────────────────────────────────────────────────────
|
|
public static void ResetDiagnostics()
|
|
{
|
|
DiedSeen = ReviveRequestedSeen = RevivedSeen = PotionChangedSeen = 0;
|
|
ReviveCalls = PotionUseCalls = PotionUseOk = 0;
|
|
LastEvent = ""; LastEventTime = 0f;
|
|
}
|
|
|
|
public static string Dump()
|
|
{
|
|
var sb = new StringBuilder();
|
|
sb.AppendLine("[WLSurvivalUiBridge] installed=" + Installed +
|
|
" survivalEnabled=" + WLSurvivalSettings.Enabled +
|
|
" · died=" + DiedSeen + " reviveReq=" + ReviveRequestedSeen + " revived=" + RevivedSeen +
|
|
" potionChanged=" + PotionChangedSeen +
|
|
" reviveCalls=" + ReviveCalls + " potionUse=" + PotionUseOk + "/" + PotionUseCalls +
|
|
" last=\"" + LastEvent + "\"");
|
|
sb.AppendLine(" 연결 6줄 = count:" + (PotionButton.CountProvider != null) +
|
|
" cdRemain:" + (PotionButton.CooldownRemainProvider != null) +
|
|
" cdTotal:" + (PotionButton.CooldownTotalProvider != null) +
|
|
" use:" + (PotionButton.UseHandler != null) +
|
|
" reviveReq:" + (ReviveDialog.ReviveRequested != null) +
|
|
" deathFlow구독(Died/ReviveRequested/Revived)=" +
|
|
DeathFlow.Died.Count + "/" + DeathFlow.ReviveRequested.Count + "/" + DeathFlow.Revived.Count);
|
|
sb.AppendLine(" 813i 현재값 = remaining " + PotionUse.Remaining + "/" + PotionUse.Max +
|
|
" cd " + PotionUse.CooldownRemaining.ToString("F2") + "/" + PotionUse.CooldownTotal.ToString("F2") + "s" +
|
|
" ready=" + PotionUse.IsReady +
|
|
" · DeathFlow state=" + DeathFlow.State + " deaths=" + DeathFlow.DeathCount +
|
|
" revives=" + DeathFlow.ReviveCount + " auto=" + DeathFlow.AutoReviveCount);
|
|
sb.AppendLine(" UI 가 읽는 값 = count " + ReadCount() + " cdRemain " + ReadCooldownRemain().ToString("F2") +
|
|
"s cdTotal " + ReadCooldownTotal().ToString("F2") + "s");
|
|
return sb.ToString();
|
|
}
|
|
}
|
|
}
|