Merge branch 'wl/ui/WL-813q3-result-bosshp'
This commit is contained in:
commit
ef6797a54f
|
|
@ -0,0 +1,98 @@
|
|||
== WL-813q3 프로브 — 결과창 보스 HP = RunEnded 페이로드 스냅샷 ==
|
||||
2026-09-09 19:17:53 · Unity 6000.3.23f1 · isPlaying=False · project=E:\NerdNavis\WL_wt\ui
|
||||
|
||||
── ⓪ 설정 실측 — 신규 값 2개 · 신규 행 1개
|
||||
에셋 = Assets/WL/UI/Settings/Resources/WL/WLRunUiSettings.asset (4688 B · 2026-09-09 10:12:11 UTC)
|
||||
resultBossHpFromPayload=True · resultBossHpFromUi=True · resultCountCardPicksInUi=True · resultCountElitesInUi=True
|
||||
문구 = "미처치 (HP 남음 {0} %)" / "미처치" · 카드 행 이름 = "카드 선택"
|
||||
[PASS] resultBossHpFromPayload 기본 on(813w6 페이로드 우선)
|
||||
[PASS] resultCountCardPicksInUi 기본 on
|
||||
[PASS] rowCardPicksLabel 값 있음
|
||||
resultRows(11) = TotalTime · BossClear · Kills · EliteKills · MaxChain · MaxDamage · Level · CardPicks · LootByGrade · Gold · DeathsPotions
|
||||
[PASS] BossClear 행 있음
|
||||
[PASS] EliteKills 행 있음(813q2)
|
||||
[PASS] CardPicks 행 있음(813q3 신설)
|
||||
배치 = 제목영역 120px + 행 11×56=616px → 본문 끝 736px · 버튼 상단 940px · 상자 1080px
|
||||
[PASS] 행이 버튼을 안 침범(736 ≤ 940) = 잘림 0(산술)
|
||||
|
||||
── ① 813w6 페이로드 계약 — RunResult 에 보스 HP 3필드
|
||||
합성 RunResult · bossHpRatio=0.2439 bossHp=439 bossHpMax=1800
|
||||
[PASS] RunResult.bossHpRatio 필드 존재·대입(컴파일이 곧 증거)
|
||||
[PASS] RunResult.bossHp / bossHpMax 필드 존재·대입
|
||||
구독자 수 RunEnded=0 RunStarted=0
|
||||
|
||||
── ② 가짜 RunEnded(bossHpRatio 0.2439) → 「미처치 (HP 남음 24 %)」
|
||||
BuildBody → 행 11개
|
||||
보스 처치 행 = "미처치 (HP 남음 24 %)" · 원천 = 페이로드 · 스냅샷 = 24.39% (439/1800)
|
||||
[PASS] 문구 = "미처치 (HP 남음 24 %)" (0.2439 → 24)
|
||||
[PASS] 원천 = 페이로드(BossHpBar 를 안 읽었다)
|
||||
[PASS] BossHpRatioAtEnd = 0.2439(구조체째 복사)
|
||||
[PASS] BossHp/BossHpMax 스냅샷도 함께 복사
|
||||
|
||||
── ③ 🔴 부활 미룸(늦은 그리기) — Park 로 만피가 되어도 값 불변
|
||||
Park 실행 DeferredParkCount 0 → 0 · BossHpBar.RunBossHpRatio = 1.00 · BossArena.LastBossHpRatio = -1.00
|
||||
늦은 Show() → 노드 미조립 — Bind 먼저
|
||||
보스 처치 행(늦게) = "미처치 (HP 남음 24 %)" · 원천 = 페이로드
|
||||
[PASS] 🔴 늦게 그려도 24 % 그대로(813w6 §6-1 잔여 해소)
|
||||
[PASS] 스냅샷 버퍼가 만피에 안 덮인다
|
||||
|
||||
── ③-B C8 — resultBossHpFromPayload = 0 이면 같은 자리에서 100 %(D-44 재현)
|
||||
행 = "미처치 (HP 남음 100 %)" · 원천 = UI바
|
||||
[PASS] 스위치 off → 813q2 동작(만피 100 %) = D-44 재현
|
||||
[PASS] off 일 때 원천 = UI바(BossHpBar)
|
||||
[PASS] 스위치 복구 → 다시 24 %
|
||||
|
||||
── ④ 진짜 발행 경로 — RunDirector.StartRun → EndRun(Timeout)
|
||||
StartRun 후 phase=Zones running=True (EndedSeen=0)
|
||||
EndRun 후 EndedSeen 0 → 1 · LastResult.bossHpRatio=0.2439 · 결과창 스냅샷=0.2439
|
||||
보스 처치 행(진짜 발행) = "미처치 (HP 남음 24 %)" · 원천 = 페이로드
|
||||
[PASS] 결과창이 RunEnded 를 실제로 받았다
|
||||
[PASS] 결과창 스냅샷 = RunDirector.LastResult.bossHpRatio (같은 값)
|
||||
[PASS] 진짜 발행에서도 24 %
|
||||
[PASS] 진짜 발행 + Park 뒤 늦은 그리기도 24 %
|
||||
|
||||
── ⑤ 처치 케이스(MM:SS) · 페이로드 −1 폴백 · 둘 다 없음
|
||||
처치 런(bossClearSec 154) = "02:34"
|
||||
[PASS] 처치면 「02:34」(HP 는 안 본다)
|
||||
페이로드 −1 + 바 43.6 % = "미처치 (HP 남음 44 %)" · 원천 = UI바
|
||||
[PASS] 페이로드가 −1 이면 813q2 폴백(44 %)
|
||||
[PASS] 폴백 원천 표시 = UI바
|
||||
둘 다 없음 = "미처치" · 원천 = 없음
|
||||
[PASS] 둘 다 없으면 퍼센트 없이 「미처치」
|
||||
[PASS] 원천 = 없음
|
||||
|
||||
── ⑥ 결과창 행 실측 — 엘리트 · 카드 선택 · 사망/물약 · 본문 전체
|
||||
813o ZonePickup.PicksThisRun(현재) = 0 · PickCount=0
|
||||
카드 선택 종료스냅 = 0 · 엘리트 종료스냅 = 0
|
||||
카드 선택 행 = "0" · 엘리트 행 = "0" · 사망/물약 행 = "1 / 2"
|
||||
[PASS] 카드 선택 행 = 종료 스냅샷 값
|
||||
[PASS] 엘리트 행 = 종료 스냅샷 값(813q2 그대로)
|
||||
[PASS] 사망/물약 행 = 「1 / 2」(RunResult 값 그대로)
|
||||
[PASS] 본문 행 수 = resultRows 길이 (11)
|
||||
본문 = 시간 종료 | 총 시간 : 04:01 | 보스 처치 : 미처치 (HP 남음 24 %) | 처치 수 : 29 (보스 0) | 엘리트 처치 : 0 | 최대 연쇄 : 7 | 최대 피해 : 8889 | 레벨 : 11 → 12 | 카드 선택 : 0 | 획득 : <color=#F2F5FA>5</color> <color=#cd835e>2</color> | 골드 : 777 | 사망 / 물약 : 1 / 2 |
|
||||
(카드 카운터는 813o 소유 · 프로브는 읽기만 — 스냅샷 시점만 확인한다)
|
||||
|
||||
── ⑦ GC — 매 프레임 경로 0 B · 이번에 늘어난 줄 0 B
|
||||
[PASS] Tick ×100(매 프레임 경로) Δ = 0 B
|
||||
[PASS] 이번에 늘어난 읽기(PicksThisRun + BossHpRatioAtEnd) ×100 Δ = 0 B (sink 0/24.4)
|
||||
[PASS] LastBossHpSource 대입(리터럴) ×100 Δ = 0 B
|
||||
참고 — BuildBody ×100 Δ = 49152 B (런 종료 1회 경로 · 813q 부터 본문 문자열을 만든다 · 매 프레임 아님)
|
||||
|
||||
── ⑧ C8 롤백 — 값 하나씩
|
||||
[PASS] resultCountCardPicksInUi=0 → 카드 선택 행 「0」
|
||||
[PASS] resultRows 에서 CardPicks 를 빼면 행이 사라진다
|
||||
[PASS] 행 배열 복구 = 11행
|
||||
[PASS] 둘 다 off → 퍼센트 없이 「미처치」
|
||||
RuntimeDisabled Tick → off — 무동작
|
||||
[PASS] RuntimeDisabled=1 → Tick 무동작
|
||||
[PASS] 복구 → tick ok
|
||||
[PASS] resultEnabled=0 → 무동작
|
||||
|
||||
── ⑨ 뒷정리 — 에셋 저장 0 · 구독·주입 원복
|
||||
BossArena 주입 해제 · BossHpBar.RunBossHpRatio=-1 · 결과창 구독=False(시작 시 False)
|
||||
BossArena.BossHpSnapshots=1 DeferredParkCount=0
|
||||
에셋 후 = 4688 B · 2026-09-09 10:12:11 UTC
|
||||
[PASS] 에셋 파일 무변동 = 저장 0(SaveAssets/SetDirty 호출 0)
|
||||
SO 값 원복 = payload:True fromUi:True cards:True elites:True enabled_:True result:True 행수:11
|
||||
|
||||
== 합계 PASS 42 / FAIL 0 / NOTE 0 ==
|
||||
|
|
@ -0,0 +1,384 @@
|
|||
// WL-813q3 프로브 — 결과창 「보스 처치 : 미처치 (HP 남음 N %)」 가 813w6 `RunEnded` 페이로드
|
||||
// `bossHpRatio` 를 쓰는지 실측(에디트 모드 · Play 0 · 로그인 0 · #813).
|
||||
// unity command run_script --file AgentScripts/WL813q3_Probe.cs --entry WL813q3_Probe.RunAll
|
||||
// 산출물: <worktree>/AgentScripts/WL813q3_PROBE.txt
|
||||
//
|
||||
// 🔴 에셋 저장 0 — WLRunUiSettings 값은 **메모리에서만** 바꾸고 finally 에서 원복한다.
|
||||
// AssetDatabase.SaveAssets / EditorUtility.SetDirty 호출 **0**. 파일 크기·수정시각을 전후로 찍어 증거로 남긴다.
|
||||
// 🔴 Gameplay 는 읽기·공개 API 호출만(파일 수정 0). Play 진입 0.
|
||||
// 🔴 핵심 계측 = **「늦게 그려도 값이 안 바뀐다」**.
|
||||
// RunEnded 를 받은 뒤 BossArena 가 미뤄 둔 Park(만피 복구)을 실제로 돌리고, 보스 HP 바 미러까지
|
||||
// 100 % 로 만든 다음 결과창을 **다시 그려서** 문구가 그대로 24 % 인지 본다.
|
||||
// 스위치를 끄면(813q2 동작) 같은 자리에서 100 % 가 나온다 = D-44 재현.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using WL.UI;
|
||||
using WL.Combat.Run;
|
||||
using WL.Combat.Boss;
|
||||
|
||||
public static class WL813q3_Probe
|
||||
{
|
||||
const string kAsset = "Assets/WL/UI/Settings/Resources/WL/WLRunUiSettings.asset";
|
||||
|
||||
static StringBuilder _o;
|
||||
static int _pass, _fail, _note;
|
||||
|
||||
static void H(string s) { _o.AppendLine(); _o.AppendLine("── " + s); }
|
||||
static void N(string s) { _o.AppendLine(" " + s); }
|
||||
static void Note(string s) { _note++; _o.AppendLine(" [NOTE] " + s); }
|
||||
static bool Chk(bool ok, string what)
|
||||
{
|
||||
if (ok) { _pass++; _o.AppendLine(" [PASS] " + what); }
|
||||
else { _fail++; _o.AppendLine(" [FAIL] " + what); }
|
||||
return ok;
|
||||
}
|
||||
|
||||
static string Root { get { return Directory.GetParent(Application.dataPath).FullName; } }
|
||||
static string OutPath(string n) { return Path.Combine(Path.Combine(Root, "AgentScripts"), n); }
|
||||
|
||||
/// <summary>본문에서 한 행의 값 문자열을 뽑는다(노드 없이도 되는 유일한 경로 = BodyText).</summary>
|
||||
static string BodyRow(string label)
|
||||
{
|
||||
string body = RunResultUI.BodyText;
|
||||
if (string.IsNullOrEmpty(body)) return "";
|
||||
var lines = body.Split('\n');
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
int k = lines[i].IndexOf(" : ", StringComparison.Ordinal);
|
||||
if (k < 0) continue;
|
||||
if (lines[i].Substring(0, k) == label) return lines[i].Substring(k + 3);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/// <summary>합성 RunResult — 배열 3종은 813p 계약대로 길이만 맞춘다.</summary>
|
||||
static RunResult Fake(RunOutcome outcome, float bossClearSec, float ratio, double hp, double maxHp)
|
||||
{
|
||||
return new RunResult
|
||||
{
|
||||
outcome = outcome,
|
||||
runIndex = 1,
|
||||
totalSec = 241f,
|
||||
runSeconds = 270f,
|
||||
zoneClearSec = new float[] { 61.5f, -1f },
|
||||
zoneKills = new int[] { 17, 12 },
|
||||
zoneCount = 2,
|
||||
zonesCleared = 1,
|
||||
bossGateSec = 170f,
|
||||
bossStartSec = 173f,
|
||||
bossClearSec = bossClearSec,
|
||||
bossHpRatio = ratio,
|
||||
bossHp = hp,
|
||||
bossHpMax = maxHp,
|
||||
kills = 29,
|
||||
bossKills = bossClearSec >= 0f ? 1 : 0,
|
||||
maxChain = 7,
|
||||
maxDamage = 4321d,
|
||||
maxDamageBurst = 8888.5d,
|
||||
levelFrom = 11,
|
||||
levelTo = 12,
|
||||
lootByGrade = new int[] { 0, 5, 2, 0, 0, 0, 0, 0, 0, 0 },
|
||||
lootTotal = 7,
|
||||
gold = 777,
|
||||
deaths = 1,
|
||||
potionsUsed = 2,
|
||||
skillCasts = 40,
|
||||
time = 0f,
|
||||
frame = 0,
|
||||
};
|
||||
}
|
||||
|
||||
public static string RunAll()
|
||||
{
|
||||
_o = new StringBuilder(16000);
|
||||
_o.AppendLine("== WL-813q3 프로브 — 결과창 보스 HP = RunEnded 페이로드 스냅샷 ==");
|
||||
_o.AppendLine(" " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " · Unity " + Application.unityVersion +
|
||||
" · isPlaying=" + Application.isPlaying + " · project=" + Root);
|
||||
|
||||
WLRunUiSettings.ClearCache();
|
||||
var s = WLRunUiSettings.Instance;
|
||||
if (s == null) { _o.AppendLine(" [FAIL] WLRunUiSettings 에셋 없음 — 중단"); return Flush(); }
|
||||
|
||||
string abs = Path.Combine(Root, kAsset.Replace('/', Path.DirectorySeparatorChar));
|
||||
var fi0 = new FileInfo(abs); fi0.Refresh();
|
||||
long len0 = fi0.Length; DateTime mt0 = fi0.LastWriteTimeUtc;
|
||||
|
||||
// ── 원복용 스냅샷 ────────────────────────────────────────────────────
|
||||
bool o_payload = s.resultBossHpFromPayload, o_fromUi = s.resultBossHpFromUi;
|
||||
bool o_cards = s.resultCountCardPicksInUi, o_elites = s.resultCountElitesInUi;
|
||||
bool o_enabled = s.enabled_, o_result = s.resultEnabled;
|
||||
var o_rows = s.resultRows;
|
||||
float o_barRatio = BossHpBar.RunBossHpRatio;
|
||||
bool o_subscribed = RunResultUI.Subscribed;
|
||||
|
||||
try
|
||||
{
|
||||
// ── ⓪ 설정·행 배열 실측 ─────────────────────────────────────────
|
||||
H("⓪ 설정 실측 — 신규 값 2개 · 신규 행 1개");
|
||||
N("에셋 = " + kAsset + " (" + len0 + " B · " + mt0.ToString("yyyy-MM-dd HH:mm:ss") + " UTC)");
|
||||
N("resultBossHpFromPayload=" + s.resultBossHpFromPayload + " · resultBossHpFromUi=" + s.resultBossHpFromUi +
|
||||
" · resultCountCardPicksInUi=" + s.resultCountCardPicksInUi + " · resultCountElitesInUi=" + s.resultCountElitesInUi);
|
||||
N("문구 = \"" + s.resultBossNotClearedHpFormat + "\" / \"" + s.resultBossNotClearedText + "\" · 카드 행 이름 = \"" + s.rowCardPicksLabel + "\"");
|
||||
Chk(s.resultBossHpFromPayload, "resultBossHpFromPayload 기본 on(813w6 페이로드 우선)");
|
||||
Chk(s.resultCountCardPicksInUi, "resultCountCardPicksInUi 기본 on");
|
||||
Chk(!string.IsNullOrEmpty(s.rowCardPicksLabel), "rowCardPicksLabel 값 있음");
|
||||
|
||||
var sbRows = new StringBuilder();
|
||||
bool hasCard = false, hasElite = false, hasBoss = false;
|
||||
for (int i = 0; i < s.resultRows.Length; i++)
|
||||
{
|
||||
if (i > 0) sbRows.Append(" · ");
|
||||
sbRows.Append(s.resultRows[i]);
|
||||
if (s.resultRows[i] == WLRunResultRow.CardPicks) hasCard = true;
|
||||
if (s.resultRows[i] == WLRunResultRow.EliteKills) hasElite = true;
|
||||
if (s.resultRows[i] == WLRunResultRow.BossClear) hasBoss = true;
|
||||
}
|
||||
N("resultRows(" + s.resultRows.Length + ") = " + sbRows);
|
||||
Chk(hasBoss, "BossClear 행 있음");
|
||||
Chk(hasElite, "EliteKills 행 있음(813q2)");
|
||||
Chk(hasCard, "CardPicks 행 있음(813q3 신설)");
|
||||
|
||||
// 상자 안에 11행이 들어가는지 산술 실측(제목 + 행 + 버튼)
|
||||
float top = s.resultPadTopPx + s.resultTitleFontPx + s.resultTitleGapPx;
|
||||
float rowsH = s.resultRowHeightPx * s.resultRows.Length;
|
||||
float btnTop = s.resultBoxSizePx.y - (s.resultButtonBottomPx + s.resultButtonSizePx.y);
|
||||
N("배치 = 제목영역 " + top + "px + 행 " + s.resultRows.Length + "×" + s.resultRowHeightPx + "=" + rowsH +
|
||||
"px → 본문 끝 " + (top + rowsH) + "px · 버튼 상단 " + btnTop + "px · 상자 " + s.resultBoxSizePx.y + "px");
|
||||
Chk(top + rowsH <= btnTop, "행이 버튼을 안 침범(" + (top + rowsH) + " ≤ " + btnTop + ") = 잘림 0(산술)");
|
||||
|
||||
// ── ① 813w6 계약 확인 ────────────────────────────────────────────
|
||||
H("① 813w6 페이로드 계약 — RunResult 에 보스 HP 3필드");
|
||||
var probe = Fake(RunOutcome.Timeout, -1f, 0.2439f, 439d, 1800d);
|
||||
N("합성 RunResult · bossHpRatio=" + probe.bossHpRatio.ToString("F4") + " bossHp=" + probe.bossHp + " bossHpMax=" + probe.bossHpMax);
|
||||
Chk(Math.Abs(probe.bossHpRatio - 0.2439f) < 1e-5f, "RunResult.bossHpRatio 필드 존재·대입(컴파일이 곧 증거)");
|
||||
Chk(probe.bossHp == 439d && probe.bossHpMax == 1800d, "RunResult.bossHp / bossHpMax 필드 존재·대입");
|
||||
N("구독자 수 RunEnded=" + RunEvents.RunEnded.Count + " RunStarted=" + RunEvents.RunStarted.Count);
|
||||
|
||||
// ── ② 가짜 RunEnded(0.2439) → 「HP 남음 24 %」 ────────────────────
|
||||
H("② 가짜 RunEnded(bossHpRatio 0.2439) → 「미처치 (HP 남음 24 %)」");
|
||||
if (!RunResultUI.Subscribed) RunResultUI.Subscribe(true);
|
||||
RunResultUI.ResetState();
|
||||
BossHpBar.RunBossHpRatio = -1f; // 바는 아무것도 안 물었다 = 폴백이 못 쓰는 상태
|
||||
RunResultUI.CopyResult(in probe); // = OnRunEnded 가 즉시 하는 그 복사
|
||||
N("BuildBody → " + RunResultUI.BuildBody(s));
|
||||
string v2 = BodyRow(s.rowBossClearLabel);
|
||||
N("보스 처치 행 = \"" + v2 + "\" · 원천 = " + RunResultUI.LastBossHpSource +
|
||||
" · 스냅샷 = " + (RunResultUI.BossHpRatioAtEnd * 100f).ToString("F2") + "% (" +
|
||||
RunResultUI.BossHpAtEnd + "/" + RunResultUI.BossHpMaxAtEnd + ")");
|
||||
Chk(v2 == "미처치 (HP 남음 24 %)", "문구 = \"미처치 (HP 남음 24 %)\" (0.2439 → 24)");
|
||||
Chk(RunResultUI.LastBossHpSource == "페이로드", "원천 = 페이로드(BossHpBar 를 안 읽었다)");
|
||||
Chk(Math.Abs(RunResultUI.BossHpRatioAtEnd - 0.2439f) < 1e-5f, "BossHpRatioAtEnd = 0.2439(구조체째 복사)");
|
||||
Chk(RunResultUI.BossHpAtEnd == 439d && RunResultUI.BossHpMaxAtEnd == 1800d, "BossHp/BossHpMax 스냅샷도 함께 복사");
|
||||
|
||||
// ── ③ 🔴 부활 미룸 = 늦게 그려도 스냅샷 유지 ───────────────────────
|
||||
H("③ 🔴 부활 미룸(늦은 그리기) — Park 로 만피가 되어도 값 불변");
|
||||
BossArena.SetBossHpForProbe(1f, 1800d, 1800d); // Park → On_Regen 만피
|
||||
BossHpBar.RunBossHpRatio = 1f; // 813q2 가 읽던 UI 미러도 만피
|
||||
int deferBefore = BossArena.DeferredParkCount;
|
||||
BossArena.PumpDeferredPark(); // 813w6 이 발행 뒤로 미뤄 둔 고정을 실제로 실행
|
||||
N("Park 실행 DeferredParkCount " + deferBefore + " → " + BossArena.DeferredParkCount +
|
||||
" · BossHpBar.RunBossHpRatio = " + BossHpBar.RunBossHpRatio.ToString("F2") +
|
||||
" · BossArena.LastBossHpRatio = " + BossArena.LastBossHpRatio.ToString("F2"));
|
||||
string show3 = RunResultUI.Show(); // ← 부활 팝업이 닫힌 뒤의 「늦은 그리기」
|
||||
N("늦은 Show() → " + show3);
|
||||
string v3 = BodyRow(s.rowBossClearLabel);
|
||||
N("보스 처치 행(늦게) = \"" + v3 + "\" · 원천 = " + RunResultUI.LastBossHpSource);
|
||||
Chk(v3 == "미처치 (HP 남음 24 %)", "🔴 늦게 그려도 24 % 그대로(813w6 §6-1 잔여 해소)");
|
||||
Chk(Math.Abs(RunResultUI.BossHpRatioAtEnd - 0.2439f) < 1e-5f, "스냅샷 버퍼가 만피에 안 덮인다");
|
||||
|
||||
H("③-B C8 — resultBossHpFromPayload = 0 이면 같은 자리에서 100 %(D-44 재현)");
|
||||
s.resultBossHpFromPayload = false;
|
||||
RunResultUI.BuildBody(s);
|
||||
string v3b = BodyRow(s.rowBossClearLabel);
|
||||
N("행 = \"" + v3b + "\" · 원천 = " + RunResultUI.LastBossHpSource);
|
||||
Chk(v3b == "미처치 (HP 남음 100 %)", "스위치 off → 813q2 동작(만피 100 %) = D-44 재현");
|
||||
Chk(RunResultUI.LastBossHpSource == "UI바", "off 일 때 원천 = UI바(BossHpBar)");
|
||||
s.resultBossHpFromPayload = true;
|
||||
RunResultUI.BuildBody(s);
|
||||
Chk(BodyRow(s.rowBossClearLabel) == "미처치 (HP 남음 24 %)", "스위치 복구 → 다시 24 %");
|
||||
|
||||
// ── ④ 진짜 RunDirector.EndRun 경로 ─────────────────────────────────
|
||||
H("④ 진짜 발행 경로 — RunDirector.StartRun → EndRun(Timeout)");
|
||||
BossArena.SetBossHpForProbe(0.2439f, 439d, 1800d);
|
||||
BossHpBar.RunBossHpRatio = -1f;
|
||||
RunResultUI.ResetState();
|
||||
RunDirector.StartRun("WL813q3 프로브");
|
||||
int endedBefore = RunResultUI.EndedSeen; // StartRun 이 앞 런을 Abandon 으로 닫을 수 있다
|
||||
N("StartRun 후 phase=" + RunDirector.Phase + " running=" + RunDirector.IsRunning +
|
||||
" (EndedSeen=" + endedBefore + ")");
|
||||
if (RunDirector.IsRunning)
|
||||
{
|
||||
RunDirector.EndRun(RunOutcome.Timeout);
|
||||
N("EndRun 후 EndedSeen " + endedBefore + " → " + RunResultUI.EndedSeen +
|
||||
" · LastResult.bossHpRatio=" + RunDirector.LastResult.bossHpRatio.ToString("F4") +
|
||||
" · 결과창 스냅샷=" + RunResultUI.BossHpRatioAtEnd.ToString("F4"));
|
||||
string v4 = BodyRow(s.rowBossClearLabel);
|
||||
N("보스 처치 행(진짜 발행) = \"" + v4 + "\" · 원천 = " + RunResultUI.LastBossHpSource);
|
||||
Chk(RunResultUI.EndedSeen == endedBefore + 1, "결과창이 RunEnded 를 실제로 받았다");
|
||||
Chk(Math.Abs(RunResultUI.BossHpRatioAtEnd - RunDirector.LastResult.bossHpRatio) < 1e-6f,
|
||||
"결과창 스냅샷 = RunDirector.LastResult.bossHpRatio (같은 값)");
|
||||
if (RunDirector.LastResult.bossHpRatio >= 0f)
|
||||
{
|
||||
Chk(v4 == "미처치 (HP 남음 24 %)", "진짜 발행에서도 24 %");
|
||||
// 발행 뒤 Park → 다시 그려도 그대로
|
||||
BossArena.SetBossHpForProbe(1f, 1800d, 1800d);
|
||||
BossHpBar.RunBossHpRatio = 1f;
|
||||
BossArena.PumpDeferredPark();
|
||||
RunResultUI.BuildBody(s);
|
||||
Chk(BodyRow(s.rowBossClearLabel) == "미처치 (HP 남음 24 %)", "진짜 발행 + Park 뒤 늦은 그리기도 24 %");
|
||||
}
|
||||
else
|
||||
{
|
||||
Note("BossArena 가 에디트 모드에서 비활성(snapshotBossHpOnRunEnd/Active) — 페이로드 −1 · " +
|
||||
"값 경로는 ②③ 합성으로만 실측(진짜 발행의 값은 「미확인」)");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Note("RunDirector 가 에디트 모드에서 안 돈다(WLRunSettings/Cfg) — 진짜 발행 경로는 「미확인」");
|
||||
}
|
||||
|
||||
// ── ⑤ 처치 케이스 · 값 없음 폴백 ───────────────────────────────────
|
||||
H("⑤ 처치 케이스(MM:SS) · 페이로드 −1 폴백 · 둘 다 없음");
|
||||
RunResultUI.CopyResult(Fake(RunOutcome.Win, 154f, 0f, 0d, 1800d));
|
||||
RunResultUI.BuildBody(s);
|
||||
string v5a = BodyRow(s.rowBossClearLabel);
|
||||
N("처치 런(bossClearSec 154) = \"" + v5a + "\"");
|
||||
Chk(v5a == "02:34", "처치면 「02:34」(HP 는 안 본다)");
|
||||
|
||||
BossHpBar.RunBossHpRatio = 0.436f; // 813q2 가 읽던 값이 살아 있는 상태
|
||||
RunResultUI.CopyResult(Fake(RunOutcome.Timeout, -1f, -1f, 0d, 0d));
|
||||
RunResultUI.BuildBody(s);
|
||||
string v5b = BodyRow(s.rowBossClearLabel);
|
||||
N("페이로드 −1 + 바 43.6 % = \"" + v5b + "\" · 원천 = " + RunResultUI.LastBossHpSource);
|
||||
Chk(v5b == "미처치 (HP 남음 44 %)", "페이로드가 −1 이면 813q2 폴백(44 %)");
|
||||
Chk(RunResultUI.LastBossHpSource == "UI바", "폴백 원천 표시 = UI바");
|
||||
|
||||
BossHpBar.RunBossHpRatio = -1f;
|
||||
RunResultUI.BuildBody(s);
|
||||
string v5c = BodyRow(s.rowBossClearLabel);
|
||||
N("둘 다 없음 = \"" + v5c + "\" · 원천 = " + RunResultUI.LastBossHpSource);
|
||||
Chk(v5c == s.resultBossNotClearedText, "둘 다 없으면 퍼센트 없이 「미처치」");
|
||||
Chk(RunResultUI.LastBossHpSource == "없음", "원천 = 없음");
|
||||
|
||||
// ── ⑥ 결과창 행 실측 ───────────────────────────────────────────────
|
||||
H("⑥ 결과창 행 실측 — 엘리트 · 카드 선택 · 사망/물약 · 본문 전체");
|
||||
N("813o ZonePickup.PicksThisRun(현재) = " + ZonePickup.PicksThisRun + " · PickCount=" + ZonePickup.PickCount);
|
||||
RunResultUI.CopyResult(Fake(RunOutcome.Timeout, -1f, 0.2439f, 439d, 1800d));
|
||||
RunResultUI.BuildBody(s);
|
||||
N("카드 선택 종료스냅 = " + RunResultUI.CardPicksAtEnd + " · 엘리트 종료스냅 = " + RunResultUI.EliteKillsAtEnd);
|
||||
N("카드 선택 행 = \"" + BodyRow(s.rowCardPicksLabel) + "\" · 엘리트 행 = \"" + BodyRow(s.rowEliteKillsLabel) +
|
||||
"\" · 사망/물약 행 = \"" + BodyRow(s.rowDeathsLabel) + "\"");
|
||||
Chk(BodyRow(s.rowCardPicksLabel) == RunResultUI.CardPicksAtEnd.ToString(), "카드 선택 행 = 종료 스냅샷 값");
|
||||
Chk(BodyRow(s.rowEliteKillsLabel) == RunResultUI.EliteKillsAtEnd.ToString(), "엘리트 행 = 종료 스냅샷 값(813q2 그대로)");
|
||||
Chk(BodyRow(s.rowDeathsLabel) == "1 / 2", "사망/물약 행 = 「1 / 2」(RunResult 값 그대로)");
|
||||
Chk(RunResultUI.VisibleRows == s.resultRows.Length, "본문 행 수 = resultRows 길이 (" + RunResultUI.VisibleRows + ")");
|
||||
N("본문 = " + RunResultUI.BodyText.Replace("\n", " | "));
|
||||
|
||||
// 카드 선택 스냅샷이 「런 종료 순간」인지 — 뒤에 카운터가 늘어도 화면은 안 바뀐다
|
||||
N("(카드 카운터는 813o 소유 · 프로브는 읽기만 — 스냅샷 시점만 확인한다)");
|
||||
|
||||
// ── ⑦ GC ───────────────────────────────────────────────────────────
|
||||
H("⑦ GC — 매 프레임 경로 0 B · 이번에 늘어난 줄 0 B");
|
||||
RunResultUI.Tick(0f); RunResultUI.BuildBody(s); // 워밍업(첫 회 버퍼)
|
||||
long g0 = GC.GetTotalMemory(false);
|
||||
for (int i = 0; i < 100; i++) RunResultUI.Tick(i);
|
||||
long g1 = GC.GetTotalMemory(false);
|
||||
Chk(g1 - g0 == 0, "Tick ×100(매 프레임 경로) Δ = " + (g1 - g0) + " B");
|
||||
|
||||
int sink = 0; float fsink = 0f;
|
||||
g0 = GC.GetTotalMemory(false);
|
||||
for (int i = 0; i < 100; i++) { sink += ZonePickup.PicksThisRun; fsink += RunResultUI.BossHpRatioAtEnd; }
|
||||
g1 = GC.GetTotalMemory(false);
|
||||
Chk(g1 - g0 == 0, "이번에 늘어난 읽기(PicksThisRun + BossHpRatioAtEnd) ×100 Δ = " + (g1 - g0) + " B (sink " + sink + "/" + fsink.ToString("F1") + ")");
|
||||
|
||||
g0 = GC.GetTotalMemory(false);
|
||||
for (int i = 0; i < 100; i++) RunResultUI.LastBossHpSource = "페이로드";
|
||||
g1 = GC.GetTotalMemory(false);
|
||||
Chk(g1 - g0 == 0, "LastBossHpSource 대입(리터럴) ×100 Δ = " + (g1 - g0) + " B");
|
||||
|
||||
g0 = GC.GetTotalMemory(false);
|
||||
for (int i = 0; i < 100; i++) RunResultUI.BuildBody(s);
|
||||
g1 = GC.GetTotalMemory(false);
|
||||
N("참고 — BuildBody ×100 Δ = " + (g1 - g0) + " B (런 종료 1회 경로 · 813q 부터 본문 문자열을 만든다 · 매 프레임 아님)");
|
||||
|
||||
// ── ⑧ C8 롤백 ──────────────────────────────────────────────────────
|
||||
H("⑧ C8 롤백 — 값 하나씩");
|
||||
s.resultCountCardPicksInUi = false;
|
||||
RunResultUI.BuildBody(s);
|
||||
Chk(BodyRow(s.rowCardPicksLabel) == "0", "resultCountCardPicksInUi=0 → 카드 선택 행 「0」");
|
||||
s.resultCountCardPicksInUi = true;
|
||||
|
||||
s.resultRows = new WLRunResultRow[] { WLRunResultRow.TotalTime, WLRunResultRow.BossClear };
|
||||
RunResultUI.BuildBody(s);
|
||||
Chk(RunResultUI.VisibleRows == 2 && BodyRow(s.rowCardPicksLabel) == "", "resultRows 에서 CardPicks 를 빼면 행이 사라진다");
|
||||
s.resultRows = o_rows;
|
||||
RunResultUI.BuildBody(s);
|
||||
Chk(RunResultUI.VisibleRows == o_rows.Length, "행 배열 복구 = " + RunResultUI.VisibleRows + "행");
|
||||
|
||||
s.resultBossHpFromPayload = false; s.resultBossHpFromUi = false;
|
||||
RunResultUI.BuildBody(s);
|
||||
Chk(BodyRow(s.rowBossClearLabel) == s.resultBossNotClearedText, "둘 다 off → 퍼센트 없이 「미처치」");
|
||||
s.resultBossHpFromPayload = o_payload; s.resultBossHpFromUi = o_fromUi;
|
||||
|
||||
WLRunUiSettings.RuntimeDisabled = true;
|
||||
string tickOff = RunResultUI.Tick(0f);
|
||||
N("RuntimeDisabled Tick → " + tickOff);
|
||||
Chk(tickOff.StartsWith("off"), "RuntimeDisabled=1 → Tick 무동작");
|
||||
WLRunUiSettings.RuntimeDisabled = false;
|
||||
Chk(RunResultUI.Tick(0f) == "tick ok", "복구 → tick ok");
|
||||
|
||||
s.resultEnabled = false;
|
||||
Chk(RunResultUI.Tick(0f).StartsWith("off"), "resultEnabled=0 → 무동작");
|
||||
s.resultEnabled = o_result;
|
||||
|
||||
// ── ⑨ 뒷정리 확인 ──────────────────────────────────────────────────
|
||||
H("⑨ 뒷정리 — 에셋 저장 0 · 구독·주입 원복");
|
||||
BossArena.SetBossHpForProbe(-2f, 0d, 0d); // 주입 해제
|
||||
BossHpBar.RunBossHpRatio = o_barRatio;
|
||||
RunResultUI.ResetState();
|
||||
if (!o_subscribed) RunResultUI.Subscribe(false);
|
||||
N("BossArena 주입 해제 · BossHpBar.RunBossHpRatio=" + BossHpBar.RunBossHpRatio +
|
||||
" · 결과창 구독=" + RunResultUI.Subscribed + "(시작 시 " + o_subscribed + ")");
|
||||
N("BossArena.BossHpSnapshots=" + BossArena.BossHpSnapshots + " DeferredParkCount=" + BossArena.DeferredParkCount);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_fail++;
|
||||
_o.AppendLine(" [FAIL] 예외 — " + ex.GetType().Name + " : " + ex.Message);
|
||||
_o.AppendLine(ex.StackTrace);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 🔴 SO 원복(메모리만 · 저장 0)
|
||||
s.resultBossHpFromPayload = o_payload; s.resultBossHpFromUi = o_fromUi;
|
||||
s.resultCountCardPicksInUi = o_cards; s.resultCountElitesInUi = o_elites;
|
||||
s.enabled_ = o_enabled; s.resultEnabled = o_result; s.resultRows = o_rows;
|
||||
WLRunUiSettings.RuntimeDisabled = false;
|
||||
try { BossArena.SetBossHpForProbe(-2f, 0d, 0d); } catch { }
|
||||
BossHpBar.RunBossHpRatio = o_barRatio;
|
||||
}
|
||||
|
||||
var fi1 = new FileInfo(abs); fi1.Refresh();
|
||||
N("에셋 후 = " + fi1.Length + " B · " + fi1.LastWriteTimeUtc.ToString("yyyy-MM-dd HH:mm:ss") + " UTC");
|
||||
Chk(fi1.Length == len0 && fi1.LastWriteTimeUtc == mt0, "에셋 파일 무변동 = 저장 0(SaveAssets/SetDirty 호출 0)");
|
||||
N("SO 값 원복 = payload:" + s.resultBossHpFromPayload + " fromUi:" + s.resultBossHpFromUi +
|
||||
" cards:" + s.resultCountCardPicksInUi + " elites:" + s.resultCountElitesInUi +
|
||||
" enabled_:" + s.enabled_ + " result:" + s.resultEnabled + " 행수:" + s.resultRows.Length);
|
||||
|
||||
return Flush();
|
||||
}
|
||||
|
||||
static string Flush()
|
||||
{
|
||||
_o.AppendLine();
|
||||
_o.AppendLine("== 합계 PASS " + _pass + " / FAIL " + _fail + " / NOTE " + _note + " ==");
|
||||
string p = OutPath("WL813q3_PROBE.txt");
|
||||
try { File.WriteAllText(p, _o.ToString(), new UTF8Encoding(true)); } catch { }
|
||||
return _o.ToString() + "\n(파일: " + p + ")";
|
||||
}
|
||||
}
|
||||
|
|
@ -35,6 +35,16 @@
|
|||
// (전용 Canvas `sortingOrder` 40 → 20 · `SetAsFirstSibling`), 부활이 끝나면 되돌린다.
|
||||
// 🔴 Gameplay 는 **읽기·구독·공개 API 호출만** 한다(파일 수정 0).
|
||||
//
|
||||
// ■ WL-813q3(D-44) — 「보스 처치 : 미처치 (HP 남음 N %)」 의 원천을 바꿨다.
|
||||
// 813w6 이 `RunEnded` 페이로드에 **`bossHpRatio`/`bossHp`/`bossHpMax`** 를 실었다(`RunEvents.cs` 실측 ·
|
||||
// 순서 = HP 스냅샷 → `RunEnded` 발행 → `BossArena.ParkBoss`(만피 복구)). 813q2 는 이 필드가 없어
|
||||
// **표시 시점**에 `BossHpBar.RunBossHpRatio` 를 읽었고, 부활 미룸(D-18)으로 결과가 늦게 그려지면
|
||||
// 그 사이 Park 이 돌아 **만피 100 %** 가 찍혔다(813w6 보고 §6-1 「잔여」).
|
||||
// 이제 `CopyResult` 가 런 종료 순간에 구조체째 복사한 **`s_result.bossHpRatio`** 를 쓴다
|
||||
// → 늦게 그려도 스냅샷 값 그대로. 페이로드가 −1(보스 미등장·못 읽음)이면 813q2 폴백으로 간다.
|
||||
// C8 = `resultBossHpFromPayload = 0` → 813q2 동작(만피 재현). 원천은 `LastBossHpSource` 로 읽는다.
|
||||
// 같은 발주로 「카드 선택」 행(813o `ZonePickup.PicksThisRun` · 읽기만)을 추가했다.
|
||||
//
|
||||
// ■ 프리팹 diff 0 — 노드는 전부 런타임 생성(`HideFlags.DontSave`) · 1회 만들고 재사용.
|
||||
// ■ C8 롤백 — `WLRunUiSettings.enabled_ = 0`(또는 `resultEnabled = 0`) → 구독 0 · 노드 0 · 표시 0.
|
||||
// 🔴 어셈블리 주의: Assets/WL/UI/ 에 .asmdef 를 만들지 말 것(Assembly-CSharp 단일).
|
||||
|
|
@ -86,6 +96,7 @@ namespace WL.UI
|
|||
private static bool s_lowered; // WL-813q2 — 부활 뒤로 재정렬해 둔 상태인가
|
||||
private static int s_eliteKills; // WL-813q2 — 런 중 엘리트 처치(UI 자체 집계)
|
||||
private static int s_eliteKillsAtEnd; // RunEnded 순간의 스냅샷(결과 화면이 쓰는 값)
|
||||
private static int s_cardPicksAtEnd; // WL-813q3 — RunEnded 순간의 813o 카드 선택 수 스냅샷
|
||||
private static readonly StringBuilder s_sb = new StringBuilder(128);
|
||||
private static readonly char[] s_timeBuf = new char[8];
|
||||
|
||||
|
|
@ -100,6 +111,15 @@ namespace WL.UI
|
|||
public static int LowerCount, RaiseCount; // 결과 화면을 부활 뒤로 내린/되돌린 횟수
|
||||
public static int EliteKilledSeen; // 런 중 본 엘리트 처치(UI 자체 집계)
|
||||
public static string LastDeathLog = "";
|
||||
// ── WL-813q3(D-44) 진단 ──────────────────────────────────────────────
|
||||
/// <summary>마지막 「보스 처치」 행이 남은 HP 를 어디서 읽었나 — "페이로드"(813w6) / "UI바"(813q2) / "없음".</summary>
|
||||
public static string LastBossHpSource = "없음";
|
||||
/// <summary>런 종료 순간의 보스 HP 스냅샷(813w6 페이로드 · −1 = 미발생) — 늦게 그려도 안 바뀐다.</summary>
|
||||
public static float BossHpRatioAtEnd { get { return s_result.bossHpRatio; } }
|
||||
public static double BossHpAtEnd { get { return s_result.bossHp; } }
|
||||
public static double BossHpMaxAtEnd { get { return s_result.bossHpMax; } }
|
||||
/// <summary>런 종료 순간의 813o 카드 선택 수 스냅샷.</summary>
|
||||
public static int CardPicksAtEnd { get { return s_cardPicksAtEnd; } }
|
||||
public static bool Subscribed { get { return s_subscribed; } }
|
||||
public static bool Bound { get { return s_root != null; } }
|
||||
public static bool IsOpen { get { return s_open; } }
|
||||
|
|
@ -221,7 +241,10 @@ namespace WL.UI
|
|||
{
|
||||
EndedSeen++;
|
||||
s_eliteKillsAtEnd = s_eliteKills; // WL-813q2 — 결과 화면이 쓰는 값은 이 순간의 스냅샷
|
||||
CopyResult(in e); // 🔴 배열 3종을 즉시 자기 버퍼로 복사
|
||||
s_cardPicksAtEnd = ZonePickup.PicksThisRun; // WL-813q3 — 813o 카운터도 이 순간에 뜬다(읽기만)
|
||||
// 🔴 WL-813q3 — 배열 3종 + **보스 HP 스냅샷(813w6 `e.bossHpRatio`)** 을 즉시 자기 버퍼로 복사.
|
||||
// 이 뒤에 BossArena 가 미뤄 둔 Park(만피 복구)을 돌려도 결과창 값은 안 바뀐다.
|
||||
CopyResult(in e);
|
||||
var s = St;
|
||||
if (s == null || !WLRunUiSettings.Enabled || !s.resultEnabled) return;
|
||||
if (e.outcome == RunOutcome.Abandon && !s.resultShowOnAbandon)
|
||||
|
|
@ -537,6 +560,7 @@ namespace WL.UI
|
|||
case WLRunResultRow.LootByGrade: return s.rowLootLabel;
|
||||
case WLRunResultRow.Gold: return s.rowGoldLabel;
|
||||
case WLRunResultRow.EliteKills: return s.rowEliteKillsLabel;
|
||||
case WLRunResultRow.CardPicks: return s.rowCardPicksLabel;
|
||||
default: return s.rowDeathsLabel;
|
||||
}
|
||||
}
|
||||
|
|
@ -575,6 +599,9 @@ namespace WL.UI
|
|||
case WLRunResultRow.EliteKills:
|
||||
sb.Append(s.resultCountElitesInUi ? s_eliteKillsAtEnd : 0);
|
||||
break;
|
||||
case WLRunResultRow.CardPicks:
|
||||
sb.Append(s.resultCountCardPicksInUi ? s_cardPicksAtEnd : 0);
|
||||
break;
|
||||
default:
|
||||
AppendFormat2(sb, s.rowDeathsFormat, s_result.deaths, s_result.potionsUsed);
|
||||
break;
|
||||
|
|
@ -582,16 +609,31 @@ namespace WL.UI
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// WL-813q2 §1-3 — 보스 처치 행. 처치했으면 mm:ss, 아니면 "미처치".
|
||||
/// 🔴 813p `RunResult` 에는 **보스 HP 필드가 없다**(구조체 실측) → 남은 HP 는 813c `BossHpBar` 가
|
||||
/// 이번 런에 실제로 물고 있던 마지막 비율(UI 자체 실측)을 쓴다(`resultBossHpFromUi`).
|
||||
/// 바가 보스를 한 번도 물지 못했으면 퍼센트 없이 "미처치"만 쓴다.
|
||||
/// WL-813q3 §1-1 — 보스 처치 행. 처치했으면 mm:ss, 아니면 "미처치 (HP 남음 N %)".
|
||||
/// 🔴 남은 HP 의 원천이 바뀌었다: **`RunEnded` 페이로드 `bossHpRatio`**(813w6 D-44 스냅샷 · 0~1 · −1 = 미발생).
|
||||
/// `CopyResult` 가 런 종료 순간에 구조체째 복사해 두므로 **부활 미룸(813q2 D-18)으로 결과가 늦게 그려져도**
|
||||
/// 그 사이 `BossArena.ParkBoss` 가 보스를 만피로 되돌린 것과 무관하게 스냅샷 값 그대로다.
|
||||
/// 페이로드가 −1(보스 미등장 · 못 읽음)이면 813q2 폴백(`BossHpBar.RunBossHpRatio` · UI 자체 실측)으로 간다.
|
||||
/// 둘 다 없으면 퍼센트 없이 "미처치"만 쓴다. 원천은 `LastBossHpSource` 로 실측한다.
|
||||
/// </summary>
|
||||
private static void AppendBossClear(StringBuilder sb, WLRunUiSettings s)
|
||||
{
|
||||
if (s_result.bossClearSec >= 0f) { AppendTime(sb, s_result.bossClearSec, s); return; }
|
||||
|
||||
float ratio = s.resultBossHpFromUi ? BossHpBar.RunBossHpRatio : -1f;
|
||||
// ① 813w6 페이로드 스냅샷(Park 이전 값) → ② 813q2 UI 실측 폴백 → ③ 없음
|
||||
float ratio = -1f;
|
||||
LastBossHpSource = "없음";
|
||||
if (s.resultBossHpFromPayload && s_result.bossHpRatio >= 0f)
|
||||
{
|
||||
ratio = s_result.bossHpRatio;
|
||||
LastBossHpSource = "페이로드"; // RunEnded.bossHpRatio (813w6)
|
||||
}
|
||||
else if (s.resultBossHpFromUi)
|
||||
{
|
||||
ratio = BossHpBar.RunBossHpRatio;
|
||||
if (ratio >= 0f) LastBossHpSource = "UI바"; // BossHpBar.RunBossHpRatio (813q2)
|
||||
}
|
||||
|
||||
if (ratio >= 0f && !string.IsNullOrEmpty(s.resultBossNotClearedHpFormat))
|
||||
{
|
||||
// 0 % 는 "죽었는데 처치 기록이 없는" 경우라 올림하지 않는다(살아 있으면 최소 1 %).
|
||||
|
|
@ -852,6 +894,7 @@ namespace WL.UI
|
|||
DiedSeen = ReviveRequestSeen = RevivedSeen = SkipPopupReviveCount = 0;
|
||||
LowerCount = RaiseCount = EliteKilledSeen = 0;
|
||||
s_eliteKills = s_eliteKillsAtEnd = 0;
|
||||
s_cardPicksAtEnd = 0; LastBossHpSource = "없음"; // WL-813q3
|
||||
s_lowered = false; LastDeathLog = "";
|
||||
s_pending = false; UsedCommonPopup = false; LastShowLog = "";
|
||||
Hide();
|
||||
|
|
@ -894,6 +937,10 @@ namespace WL.UI
|
|||
" 전체본것=" + EliteKilledSeen + " · 보스HP(UI 실측)=" +
|
||||
(BossHpBar.RunBossHpRatio >= 0f ? (BossHpBar.RunBossHpRatio * 100f).ToString("F1") + "%" : "없음") +
|
||||
" · 마지막 사망 로그 = " + LastDeathLog);
|
||||
sb.AppendLine(" [813q3] 보스HP 원천=" + LastBossHpSource + " · 페이로드 스냅샷 ratio=" +
|
||||
(BossHpRatioAtEnd >= 0f ? (BossHpRatioAtEnd * 100f).ToString("F1") + "%" : "없음(−1)") +
|
||||
" hp=" + BossHpAtEnd.ToString("F0") + "/" + BossHpMaxAtEnd.ToString("F0") +
|
||||
" · 카드 선택 종료스냅=" + s_cardPicksAtEnd + "(현재 " + ZonePickup.PicksThisRun + ")");
|
||||
if (s != null && s.resultRows != null)
|
||||
for (int i = 0; i < s.resultRows.Length; i++)
|
||||
{
|
||||
|
|
@ -921,7 +968,9 @@ namespace WL.UI
|
|||
" · [813q2] 사망중미룸=" + s.resultDeferWhileDying + " 런밖즉시부활=" + s.skipRevivePopupAfterRunEnd +
|
||||
" 전용캔버스=" + s.resultOwnCanvas + "(" + s.resultSortingOrder + "→" + s.resultSortingOrderWhileRevive + ")" +
|
||||
" 재정렬=" + s.resultLowerWhileRevive + "/" + s.resultRaiseAfterRevive +
|
||||
" 엘리트UI집계=" + s.resultCountElitesInUi + " 보스HP UI=" + s.resultBossHpFromUi);
|
||||
" 엘리트UI집계=" + s.resultCountElitesInUi + " 보스HP UI=" + s.resultBossHpFromUi +
|
||||
" · [813q3] 보스HP 페이로드=" + s.resultBossHpFromPayload +
|
||||
" 카드선택UI집계=" + s.resultCountCardPicksInUi);
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ MonoBehaviour:
|
|||
- 3
|
||||
- 4
|
||||
- 5
|
||||
- 10
|
||||
- 6
|
||||
- 7
|
||||
- 8
|
||||
|
|
@ -115,6 +116,7 @@ MonoBehaviour:
|
|||
rowGoldLabel: "\uACE8\uB4DC"
|
||||
rowDeathsLabel: "\uC0AC\uB9DD / \uBB3C\uC57D"
|
||||
rowEliteKillsLabel: "\uC5D8\uB9AC\uD2B8 \uCC98\uCE58"
|
||||
rowCardPicksLabel: "\uCE74\uB4DC \uC120\uD0DD"
|
||||
rowKillsFormat: "{0} (\uBCF4\uC2A4 {1})"
|
||||
rowLevelFormat: "{0} \u2192 {1}"
|
||||
rowDeathsFormat: '{0} / {1}'
|
||||
|
|
@ -126,7 +128,9 @@ MonoBehaviour:
|
|||
resultBossNotClearedText: "미처치"
|
||||
resultBossNotClearedHpFormat: "미처치 (HP 남음 {0} %)"
|
||||
resultBossHpFromUi: 1
|
||||
resultBossHpFromPayload: 1
|
||||
resultCountElitesInUi: 1
|
||||
resultCountCardPicksInUi: 1
|
||||
resultNextRunText: "\uB2E4\uC74C \uB7F0"
|
||||
resultCloseText: "\uB2EB\uAE30"
|
||||
resultButtonSizePx: {x: 340, y: 104}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ namespace WL.UI
|
|||
DeathsPotions = 8,
|
||||
/// <summary>엘리트 처치 수(WL-813q2 · 813p RunResult 에 없어 UI 가 직접 센다).</summary>
|
||||
EliteKills = 9,
|
||||
/// <summary>카드 선택 수(WL-813q3 · 813o `ZonePickup.PicksThisRun` · 런 종료 순간 스냅샷).</summary>
|
||||
CardPicks = 10,
|
||||
}
|
||||
|
||||
[CreateAssetMenu(fileName = "WLRunUiSettings", menuName = "WL/Run UI Settings", order = 33)]
|
||||
|
|
@ -346,6 +348,7 @@ namespace WL.UI
|
|||
public string rowGoldLabel = "골드";
|
||||
public string rowDeathsLabel = "사망 / 물약";
|
||||
public string rowEliteKillsLabel = "엘리트 처치";
|
||||
public string rowCardPicksLabel = "카드 선택";
|
||||
|
||||
[Tooltip("처치 수 값 문구 — {0} = 전체 처치, {1} = 그중 보스.")]
|
||||
public string rowKillsFormat = "{0} (보스 {1})";
|
||||
|
|
@ -380,13 +383,25 @@ namespace WL.UI
|
|||
public string resultBossNotClearedHpFormat = "미처치 (HP 남음 {0} %)";
|
||||
|
||||
[Tooltip("🔴 813p RunResult 에는 보스 HP 필드가 없다(실측). 켜면 813c 보스 HP 바가 이번 런에 " +
|
||||
"실제로 물었던 마지막 비율을 쓴다(UI 자체 실측). 끄면 남은 HP 를 쓰지 않는다.")]
|
||||
"실제로 물었던 마지막 비율을 쓴다(UI 자체 실측). 끄면 남은 HP 를 쓰지 않는다.\n" +
|
||||
"WL-813q3 부터는 resultBossHpFromPayload 가 먼저이고 이 값은 폴백이다.")]
|
||||
public bool resultBossHpFromUi = true;
|
||||
|
||||
// ── 보스 HP 원천 (WL-813q3 · 813w6 D-44) ──────────────────────────────
|
||||
[Tooltip("🔴 WL-813q3 — 813w6 이 RunResult 에 bossHpRatio/bossHp/bossHpMax 를 실었다(실측). " +
|
||||
"켜면 결과창은 RunEnded 페이로드의 스냅샷(= BossArena.ParkBoss 만피 복구 **이전** 값)을 쓴다. " +
|
||||
"런 종료 순간에 복사해 두므로 부활 미룸(813q2 D-18)으로 늦게 그려도 값이 안 바뀐다. " +
|
||||
"끄면 813q2 동작(= BossHpBar.RunBossHpRatio · 늦게 그리면 만피 100 %)으로 돌아간다.")]
|
||||
public bool resultBossHpFromPayload = true;
|
||||
|
||||
[Tooltip("🔴 813p RunResult 에는 엘리트 집계가 없다(실측). 켜면 UI 가 CombatEvents.Killed 의 " +
|
||||
"subRole==Elite 를 런 중에 직접 센다. 끄면 엘리트 행은 0 으로 나온다.")]
|
||||
public bool resultCountElitesInUi = true;
|
||||
|
||||
[Tooltip("🔴 WL-813q3 — 813p RunResult 에는 카드 선택 집계도 없다(실측). 켜면 813o " +
|
||||
"ZonePickup.PicksThisRun(런 시작에 0) 을 런 종료 순간에 스냅샷해서 쓴다. 끄면 0.")]
|
||||
public bool resultCountCardPicksInUi = true;
|
||||
|
||||
[Header("결과 화면 — 버튼")]
|
||||
[Tooltip("\"다음 런\" 버튼 문구 — 누르면 RunDirector.Restart() 하나만 부른다(813p 공개 API).")]
|
||||
public string resultNextRunText = "다음 런";
|
||||
|
|
|
|||
Loading…
Reference in New Issue