2026-11-09 09:03:43 +00:00
using System.Collections.Generic ;
2026-11-05 12:11:10 +00:00
using System.Text ;
using UnityEngine ;
using UnityEngine.UI ;
namespace TKS.OutGame
{
/// <summary>
2026-11-09 09:03:43 +00:00
/// 전투 결과 패널(기획서 §6 · 비주얼 = Fable 제안서 §4-2 #1104) — 별 3(받침 원 + 등장 튀김) · 조건 행 3 · 보상 타일(골드 · 경험 · 보옥 · 장비 · 상자) ·
/// 버튼 = 「다시」(Tertiary · 같은 스테이지 재도전) + 「확인」(Primary 노랑) · 승리면 리본 뒤 금빛.
/// 전투 HUD 의 승리/패배 판(sortingOrder 100) 위에 덮는다 · 화면 아무 데나 탭 = 기존 그대로(SlingshotInput → 월드맵 복귀 · 「다시」 위만 제외).
2026-11-05 12:11:10 +00:00
/// </summary>
public class BattleResultPanel
{
2026-11-09 09:03:43 +00:00
// 패널 배치(UI px · 패널 왼쪽 위 기준)
const float PW = 920f ;
2026-11-09 09:19:06 +00:00
const float PH = 1080f ;
2026-11-09 09:03:43 +00:00
const float Side = 60f ;
const float RowW = PW - Side * 2f ;
const float RowH = 64f ;
const float Tile = 132f ;
const float BtnY = PH - 40f - 110f ;
2026-11-05 12:11:10 +00:00
readonly OutGameRoot root ;
readonly GameObject go ;
readonly Text title ;
2026-11-06 14:20:57 +00:00
readonly Image ribbon ;
2026-11-09 09:03:43 +00:00
readonly Image glow ;
2026-11-06 14:20:57 +00:00
readonly RectTransform starRow ;
readonly Image [ ] starImg = new Image [ 3 ] ;
2026-11-09 09:03:43 +00:00
readonly RectTransform body ;
readonly Text plain ;
readonly Button retry ;
readonly Button ok ;
2026-11-09 09:19:06 +00:00
readonly Text retryCost ;
2026-11-09 09:03:43 +00:00
string rewardsText = "" ;
2026-11-05 12:11:10 +00:00
public bool Visible
{
get { return go . activeSelf ; }
}
public string RewardsText
{
2026-11-09 09:03:43 +00:00
get { return rewardsText ; }
2026-11-05 12:11:10 +00:00
}
public BattleResultPanel ( OutGameRoot r , RectTransform canvas )
{
root = r ;
var dim = UiKit . Fill ( "Result" , canvas ) ;
2026-11-06 14:20:57 +00:00
UiKit . Paint ( dim , UISkin . Col ( "dim" , new Color ( 0f , 0f , 0f , 0.55f ) ) , false ) ;
2026-11-05 12:11:10 +00:00
go = dim . gameObject ;
2026-11-09 09:19:06 +00:00
Image panel = null ;
if ( UISkin . Has ( "popup" ) & & UISkin . Has ( "panel_frame" ) )
2026-11-06 14:20:57 +00:00
{
2026-11-09 09:03:43 +00:00
// 리본 뒤 금빛(승리만 · 팩 Glow_Circle01 · 호흡) → 팩 팝업 틀 → 제목 리본(승리 붉은 · 패배 회색)
if ( UISkin . Has ( "glow_circle" ) )
{
glow = UiKit . Skin ( UiKit . Rect ( "Glow" , dim , new Vector2 ( 0.5f , 0.5f ) , new Vector2 ( 0.5f , 0.5f ) , new Vector2 ( 0f , 20f + PH * 0.5f + 90f ) , new Vector2 ( 1240f , 1240f ) ) , "glow_circle" , UiKit . Col ( "ribbon_glow" , Color . clear ) ) ;
var pulse = glow . gameObject . AddComponent < UiPulse > ( ) ;
pulse . min = 0.65f ;
pulse . period = 1.6f ;
2026-11-09 09:23:18 +00:00
// 안쪽 한 겹 더(그림 가운데 α 0.5 라 한 장으로는 후광이 약함 · 검수2 보충)
var core = UiKit . Skin ( UiKit . Rect ( "Core" , glow . transform , new Vector2 ( 0.5f , 0.5f ) , new Vector2 ( 0.5f , 0.5f ) , Vector2 . zero , new Vector2 ( 720f , 720f ) ) , "glow_circle" , UiKit . Col ( "ribbon_glow" , Color . clear ) ) ;
core . raycastTarget = false ;
2026-11-09 09:03:43 +00:00
}
2026-11-09 09:19:06 +00:00
// 패널 = 섹션 패널 층(그림자 · 밝은 프레임 #3F4262 · 필드 #262840 · 윗면 광택 · 검수 결함 10)
var holder = UiKit . Rect ( "Panel" , dim , new Vector2 ( 0.5f , 0.5f ) , new Vector2 ( 0.5f , 0.5f ) , new Vector2 ( 0f , 20f ) , new Vector2 ( PW , PH ) ) ;
RectTransform froot ;
UiKit . SectionPanel ( holder , "Frame" , 0f , 0f , PW , PH , false , false , out froot ) ;
var pt = ( Transform ) holder ;
var rib = UiKit . Rect ( "Ribbon" , pt , new Vector2 ( 0.5f , 1f ) , new Vector2 ( 0.5f , 0.5f ) , new Vector2 ( 0f , 10f ) , new Vector2 ( 1000f , 200f ) ) ;
2026-11-06 14:20:57 +00:00
ribbon = UiKit . Skin ( rib , "ribbon" , Color . white ) ;
title = UiKit . Title ( UiKit . FillLabel ( rib , "" , 88 , UiKit . White , TextAnchor . MiddleCenter , true , 150f ) , true ) ;
title . rectTransform . offsetMin = new Vector2 ( 150f , 34f ) ;
2026-11-09 09:03:43 +00:00
// 별 3 = 받침 원(Circle78 chip_dark) + 별(가운데 크게 · 위로) · 0.15 s 간격 튀김
2026-11-09 09:19:06 +00:00
starRow = UiKit . At ( pt , "StarRow" , 0f , 120f , PW , 190f ) ;
2026-11-09 16:05:47 +00:00
UiLayer . Nest ( starRow . gameObject , UiRate . Frame , false ) ; // 별 3 튀김 = 한 Frame 층(별마다 캔버스를 만들지 않음 · PD 2026-11-10)
2026-11-06 14:20:57 +00:00
for ( int i = 0 ; i < 3 ; i + + )
{
2026-11-09 09:03:43 +00:00
bool mid = i = = 1 ;
float plate = mid ? 150f : 120f ;
var pos = new Vector2 ( ( i - 1 ) * 190f , mid ? 12f : - 14f ) ;
UiKit . Skin ( UiKit . Rect ( "Plate" + i , starRow , new Vector2 ( 0.5f , 0.5f ) , new Vector2 ( 0.5f , 0.5f ) , pos , new Vector2 ( plate , plate ) ) , "circle_frame" , UiKit . Col ( "chip_dark" , UiKit . Dark ) ) ;
starImg [ i ] = UiKit . Icon ( starRow , "star_on_l" , new Vector2 ( 0.5f , 0.5f ) , new Vector2 ( 0.5f , 0.5f ) , pos + new Vector2 ( 0f , 4f ) , mid ? 132f : 106f ) ;
if ( starImg [ i ] = = null ) continue ;
UiKit . DropShadow ( starImg [ i ] , 5f ) ;
starImg [ i ] . gameObject . AddComponent < UiPop > ( ) . delay = 0.15f * i ;
2026-11-06 14:20:57 +00:00
}
2026-11-09 09:19:06 +00:00
body = UiKit . Fill ( "Body" , pt ) ;
retry = UiKit . SkinBtn ( pt , "Retry" , "round08" , UiKit . Col ( "menu_btn" , UiKit . Dark ) , "다시" , 34 , UiKit . White , Side , BtnY , 260f , 110f , ( ) = > root . RetryStage ( ) ) ;
retryCost = UiKit . BtnCost ( retry , "cur_stamina" , "" , 36f , 28 ) ; // 재도전 = 군량 소모 표시(검수 결함 2)
ok = UiKit . SkinBtn ( pt , "Ok" , UISkin . Has ( "btn_l_yellow" ) ? "btn_l_yellow" : "button" , UISkin . Has ( "btn_l_yellow" ) ? UiKit . White : UiKit . Coin , "확인" , 46 , UiKit . Col ( "text_on_yellow" , UiKit . Ink ) , PW - Side - 520f , BtnY , 520f , 110f , null ) ;
2026-11-06 14:20:57 +00:00
}
else
{
2026-11-09 09:03:43 +00:00
panel = UiKit . Box ( "Panel" , dim , new Vector2 ( 0.5f , 0.5f ) , new Vector2 ( 0.5f , 0.5f ) , new Vector2 ( 0f , 40f ) , new Vector2 ( PW , PH ) , UiKit . Paper ) ;
2026-11-06 14:20:57 +00:00
UiKit . Border ( panel , UiKit . Line , 4f ) ;
var head = UiKit . TopBand ( "Head" , panel . transform , 0f , 170f ) ;
UiKit . Paint ( head , UiKit . Dark ) ;
title = UiKit . FillLabel ( head , "" , 96 , UiKit . White ) ;
2026-11-09 09:03:43 +00:00
plain = UiKit . Label ( panel . transform , "" , 36 , UiKit . Ink , TextAnchor . UpperLeft , new Vector2 ( 0.5f , 1f ) , new Vector2 ( 0.5f , 1f ) , new Vector2 ( 0f , - 200f ) , new Vector2 ( 760f , 860f ) , false ) ;
plain . lineSpacing = 1.15f ;
UiKit . Label ( panel . transform , "화면을 탭하면 계속" , 34 , UiKit . InkSoft , TextAnchor . MiddleCenter , new Vector2 ( 0.5f , 0f ) , new Vector2 ( 0.5f , 0f ) , new Vector2 ( 0f , 36f ) , new Vector2 ( 800f , 60f ) , false ) ;
2026-11-06 14:20:57 +00:00
}
2026-11-05 12:11:10 +00:00
go . SetActive ( false ) ;
}
public void SetVisible ( bool on )
{
if ( go . activeSelf ! = on ) go . SetActive ( on ) ;
}
2026-11-09 09:03:43 +00:00
/// <summary>화면 좌표가 「다시」 버튼 위인가 — 화면 탭(월드맵 복귀)을 이 버튼에서는 건너뛴다.</summary>
public bool PointerOnRetry ( Vector2 screen )
{
if ( retry = = null | | ! go . activeInHierarchy | | ! retry . gameObject . activeSelf ) return false ;
var c = go . GetComponentInParent < Canvas > ( ) ;
return RectTransformUtility . RectangleContainsScreenPoint ( ( RectTransform ) retry . transform , screen , c ! = null ? c . worldCamera : null ) ;
}
2026-11-05 12:11:10 +00:00
public void Fill ( StageReward r )
{
var s = root . Session ;
2026-11-09 09:03:43 +00:00
rewardsText = r . win ? RewardText ( s , r ) : "보상 없음" ;
2026-11-05 12:11:10 +00:00
title . text = ( r . win ? "승리" : "패배" ) + " <size=44>" + r . chapter + "-" + r . stage + ( r . boss ? " 보스" : "" ) + "</size>" ;
2026-11-06 14:20:57 +00:00
ShowStars ( r . win ? r . stars : 0 , r . win ) ;
2026-11-09 09:03:43 +00:00
SetButtons ( true ) ;
2026-11-09 09:19:06 +00:00
if ( retryCost ! = null & & root . Battle ! = null & & root . Battle . Config ! = null & & root . Battle . StageIndex > = 0 & & root . Battle . StageIndex < root . Battle . Config . stages . Length )
{
int cost = EconomyRules . StageCost ( s . Db , s . Save , root . Battle . Config . stages [ root . Battle . StageIndex ] ) ;
retryCost . text = cost . ToString ( ) ;
retry . GetComponent < Image > ( ) . color = s . Save . stamina > = cost ? UiKit . Col ( "menu_btn" , UiKit . Dark ) : UiKit . Col ( "disabled" , UiKit . Disabled ) ;
}
2026-11-09 09:03:43 +00:00
if ( body = = null )
{
plain . text = ( r . win ? "별 " + UiKit . Stars ( r . stars , 3 ) + "\n\n" : "아군이 전멸했습니다\n\n" ) + rewardsText ;
return ;
}
UiKit . Clear ( body ) ;
float y = 330f ;
2026-11-05 12:11:10 +00:00
if ( r . win )
{
2026-11-09 09:03:43 +00:00
string [ ] cond = { "스테이지 클리어" , "아군 전원 생존" , r . starTurns + "턴 이내 클리어 <size=26>(" + r . turns + "턴)</size>" } ;
for ( int i = 0 ; i < 3 ; i + + )
UiKit . CondRow ( body , "Cond" + i , Side , y + i * ( RowH + 8f ) , RowW , RowH , r . conds [ i ] ? "check" : "x_small" , r . conds [ i ] , cond [ i ] , 30 ) ;
2026-11-05 12:11:10 +00:00
}
else
{
2026-11-09 09:03:43 +00:00
UiKit . CondRow ( body , "Cond0" , Side , y , RowW , RowH , "x_small" , false , "아군이 전멸했습니다" , 30 ) ;
UiKit . CondRow ( body , "Cond1" , Side , y + RowH + 8f , RowW , RowH , "cur_stamina" , false , "군량 " + r . stamina + " 소모 · 별 없음" , 30 , false ) ;
}
y = 566f ;
UiKit . SubTitle ( body , "보상" , Side , y , RowW ) ;
y + = 64f ;
if ( ! r . win )
{
var none = UiKit . Title ( UiKit . Label ( body , "보상 없음" , 40 , UiKit . Col ( "text_soft" , UiKit . InkSoft ) , TextAnchor . MiddleCenter , new Vector2 ( 0f , 1f ) , new Vector2 ( 0f , 1f ) , new Vector2 ( Side , - y - 10f ) , new Vector2 ( RowW , 70f ) ) ) ;
none . horizontalOverflow = HorizontalWrapMode . Overflow ;
UiKit . Label ( body , "영웅 레벨업 · 승급 · 편성을 바꿔 다시 도전" , 30 , UiKit . Col ( "text_soft" , UiKit . InkSoft ) , TextAnchor . MiddleCenter , new Vector2 ( 0f , 1f ) , new Vector2 ( 0f , 1f ) , new Vector2 ( Side , - y - 90f ) , new Vector2 ( RowW , 50f ) , false ) ;
return ;
}
Tiles ( s , r , y ) ;
2026-11-09 09:19:06 +00:00
Notes ( s , r , y + Tile + 62f ) ;
2026-11-09 09:03:43 +00:00
}
/// <summary>보상 타일 행(가운데 정렬 · 칸 아래 이름) — 골드 · 경험 · 보옥(있을 때) · 장비(등급 칸 · 있을 때) · 상자(있을 때).</summary>
void Tiles ( OutGameSession s , StageReward r , float y )
{
var list = new List < string [ ] > ( ) ; // 아이콘 · 수량 · 칸 색 접두 · 이름
2026-11-09 09:19:06 +00:00
list . Add ( new [ ] { "cur_gold" , r . gold . ToString ( "N0" ) , "gear_white_" , r . first ? "골드" : "골드 × " + s . Db . Economy . RepeatRewardMult } ) ;
2026-11-09 09:03:43 +00:00
list . Add ( new [ ] { "cur_exp" , r . exp . ToString ( "N0" ) , "gear_white_" , "경험 · " + r . expTo . Count + "명" } ) ;
if ( r . gem > 0 ) list . Add ( new [ ] { "cur_gem" , r . gem . ToString ( "N0" ) , "gear_blue_" , "보옥" } ) ;
if ( ! string . IsNullOrEmpty ( r . gearId ) )
{
var g = s . Db . Gear . Get ( r . gearId ) ;
string grade = g ! = null & & ! string . IsNullOrEmpty ( g . grade ) ? g . grade : "white" ;
list . Add ( new [ ] { g ! = null ? "gear_" + g . kind : "cur_gear" , "" , "gear_" + grade + "_" , g ! = null ? g . nameKo : r . gearId } ) ;
}
if ( ! string . IsNullOrEmpty ( r . chest ) & & s . Db . Chests ! = null & & s . Db . Chests . Get ( r . chest ) ! = null )
list . Add ( new [ ] { "chest_" + r . chest , "" , "gear_purple_" , s . Db . Chests . Get ( r . chest ) . nameKo } ) ;
float gap = list . Count > = 5 ? 22f : 30f ;
float x = ( PW - list . Count * Tile - ( list . Count - 1 ) * gap ) * 0.5f ;
for ( int i = 0 ; i < list . Count ; i + + )
{
var e = list [ i ] ;
float tx = x + i * ( Tile + gap ) ;
2026-11-09 09:19:06 +00:00
var cell = UiKit . RewardTile ( body , "Tile" + i , tx , y , Tile , e [ 2 ] , e [ 0 ] , e [ 1 ] , e [ 2 ] ! = "gear_white_" ) ;
if ( r . first & & ( e [ 0 ] = = "cur_gold" | | e [ 0 ] = = "cur_gem" ) ) FirstBadge ( cell ) ; // 첫 클리어 = 뱃지(스테이지 팝업과 같은 표현 · 검수 결함 8)
2026-11-09 09:03:43 +00:00
var n = UiKit . Label ( body , e [ 3 ] , 26 , UiKit . Col ( "text_soft" , UiKit . InkSoft ) , TextAnchor . UpperCenter , new Vector2 ( 0f , 1f ) , new Vector2 ( 0.5f , 1f ) , new Vector2 ( tx + Tile * 0.5f , - y - Tile - 12f ) , new Vector2 ( Tile + gap , 36f ) , false ) ;
n . horizontalOverflow = HorizontalWrapMode . Overflow ;
2026-11-05 12:11:10 +00:00
}
}
2026-11-09 09:19:06 +00:00
/// <summary>「첫」 뱃지(Label_Badge01_Yellow · 칸 오른쪽 위).</summary>
public static void FirstBadge ( Transform cell )
{
var b = UiKit . Icon ( cell , "badge_first" , new Vector2 ( 1f , 1f ) , new Vector2 ( 0.5f , 0.5f ) , new Vector2 ( - 8f , - 6f ) , 58f ) ;
if ( b ! = null ) UiKit . Title ( UiKit . FillLabel ( b . transform , "첫" , 24 , UiKit . White ) , true ) ;
}
/// <summary>타일 아래 = 레벨업 가능 칩(위 화살표 + 노란 글자 · 검수 결함 8) · 없으면 비움.</summary>
2026-11-09 09:03:43 +00:00
void Notes ( OutGameSession s , StageReward r , float y )
{
var ready = ReadyNames ( s , r ) ;
2026-11-09 09:19:06 +00:00
if ( ready . Length = = 0 ) return ;
string text = "레벨업 가능 " + ready ;
var t = UiKit . InfoChip ( body , "LevelUp" , Side , y , RowW , 56f , "up_green" , text , 28 ) ;
t . color = UiKit . Col ( "select_line" , UiKit . Coin ) ;
float w = Mathf . Min ( RowW , Mathf . Ceil ( t . preferredWidth ) + 110f ) ;
var c = ( RectTransform ) t . transform . parent ;
c . anchoredPosition = new Vector2 ( ( PW - w ) * 0.5f , - y ) ;
c . sizeDelta = new Vector2 ( w , 56f ) ;
t . rectTransform . sizeDelta = new Vector2 ( w - 80f , 56f ) ;
2026-11-09 09:03:43 +00:00
}
/// <summary>연무장 결과(탑 · 던전 · 투기장 · 적장 토벌 · PD #1093 C) — 별 없음 · 결과 행 · 탭 = 연무장.</summary>
2026-11-05 15:22:54 +00:00
public void FillMode ( ModeResult r )
{
2026-11-09 09:03:43 +00:00
SetButtons ( false ) ;
rewardsText = r ! = null ? string . Join ( "\n" , r . lines . ToArray ( ) ) : "" ;
2026-11-05 15:22:54 +00:00
if ( r = = null )
{
title . text = "연무장" ;
2026-11-09 09:03:43 +00:00
ShowStars ( - 1 , true ) ;
if ( body ! = null ) UiKit . Clear ( body ) ;
else plain . text = "" ;
2026-11-05 15:22:54 +00:00
return ;
}
2026-11-09 09:03:43 +00:00
bool win = r . win | | r . kind = = ArenaRules . Raid ;
2026-11-05 15:22:54 +00:00
title . text = r . kind = = ArenaRules . Raid ? "토벌 종료" : r . win ? "승리" : "패배" ;
2026-11-09 09:03:43 +00:00
ShowStars ( - 1 , win ) ;
if ( body = = null )
{
plain . text = "<size=44>" + r . title + "</size>\n\n" + rewardsText ;
return ;
}
UiKit . Clear ( body ) ;
var head = UiKit . Title ( UiKit . Label ( body , r . title , 44 , UiKit . White , TextAnchor . MiddleCenter , new Vector2 ( 0f , 1f ) , new Vector2 ( 0f , 1f ) , new Vector2 ( Side , - 150f ) , new Vector2 ( RowW , 110f ) ) , true ) ;
head . horizontalOverflow = HorizontalWrapMode . Overflow ;
UiKit . SubTitle ( body , "결과" , Side , 290f , RowW ) ;
float y = 354f ;
for ( int i = 0 ; i < r . lines . Count & & y + RowH < = BtnY - 20f ; i + + , y + = RowH + 8f )
UiKit . CondRow ( body , "Line" + i , Side , y , RowW , RowH , null , true , r . lines [ i ] , 30 ) ;
}
/// <summary>스테이지 = 「다시」 + 「확인」 · 연무장 = 「확인」 가운데.</summary>
void SetButtons ( bool stage )
{
if ( retry = = null ) return ;
retry . gameObject . SetActive ( stage ) ;
( ( RectTransform ) ok . transform ) . anchoredPosition = new Vector2 ( stage ? PW - Side - 520f : ( PW - 520f ) * 0.5f , - BtnY ) ;
2026-11-05 15:22:54 +00:00
}
2026-11-09 09:03:43 +00:00
/// <summary>별 아이콘(n < 0 = 숨김) · 리본 색(승리 붉은 · 패배 회색) · 금빛 = 승리만.</summary>
2026-11-06 14:20:57 +00:00
void ShowStars ( int n , bool win )
{
2026-11-09 09:03:43 +00:00
if ( glow ! = null ) glow . gameObject . SetActive ( win ) ;
2026-11-06 14:20:57 +00:00
if ( starRow = = null ) return ;
starRow . gameObject . SetActive ( n > = 0 ) ;
for ( int i = 0 ; i < 3 ; i + + )
2026-11-09 09:03:43 +00:00
if ( starImg [ i ] ! = null ) starImg [ i ] . sprite = UISkin . Icon ( i < n ? "star_on_l" : "star_off" ) ? ? starImg [ i ] . sprite ;
2026-11-06 14:20:57 +00:00
if ( ribbon ! = null & & ! UISkin . Apply ( ribbon , win ? "ribbon" : "ribbon_gray" ) ) ribbon . color = win ? Color . white : UiKit . Disabled ;
}
2026-11-09 09:03:43 +00:00
static string ReadyNames ( OutGameSession s , StageReward r )
2026-11-05 12:11:10 +00:00
{
2026-11-09 09:03:43 +00:00
var ready = new StringBuilder ( ) ;
foreach ( var id in r . expTo )
{
var lv = s . Save . Level ( id ) ;
if ( HeroRules . CanLevelUp ( s . Db , s . Save , lv ) ! = null ) continue ;
if ( ready . Length > 0 ) ready . Append ( " · " ) ;
ready . Append ( s . Def ( id ) . nameKo ) ;
}
return ready . ToString ( ) ;
2026-11-05 12:11:10 +00:00
}
2026-11-09 09:03:43 +00:00
/// <summary>보상 줄(소탕 팝업 · 테마 없을 때 결과 화면 공용).</summary>
2026-11-05 12:11:10 +00:00
public static string RewardText ( OutGameSession s , StageReward r )
{
var e = s . Db . Economy ;
var sb = new StringBuilder ( ) ;
sb . Append ( "골드 +" ) . Append ( r . gold . ToString ( "N0" ) ) . Append ( r . first ? " <size=28>(첫 클리어)</size>" : " <size=28>(반복 × " + e . RepeatRewardMult + ")</size>" ) ;
sb . Append ( "\n경험 +" ) . Append ( r . exp ) . Append ( " <size=28>출전 " ) . Append ( r . expTo . Count ) . Append ( "명</size>" ) ;
if ( r . gem > 0 ) sb . Append ( "\n보옥 +" ) . Append ( r . gem ) . Append ( r . boss ? " <size=28>(첫 클리어 + 보스)</size>" : " <size=28>(첫 클리어)</size>" ) ;
if ( ! string . IsNullOrEmpty ( r . gearId ) )
{
var g = s . Db . Gear . Get ( r . gearId ) ;
sb . Append ( "\n장비 " ) . Append ( g ! = null ? g . nameKo + " (" + UiKit . GradeKo ( g . grade ) + ")" : r . gearId ) . Append ( " 획득" ) ;
}
else sb . Append ( "\n<size=30>장비 드랍 없음</size>" ) ;
2026-11-05 15:22:54 +00:00
if ( ! string . IsNullOrEmpty ( r . chest ) & & s . Db . Chests ! = null & & s . Db . Chests . Get ( r . chest ) ! = null ) sb . Append ( "\n" ) . Append ( s . Db . Chests . Get ( r . chest ) . nameKo ) . Append ( " 획득 <size=28>(보물 > 상자)</size>" ) ;
2026-11-05 12:11:10 +00:00
if ( r . sweep ) sb . Append ( "\n<size=30>군량 " ) . Append ( r . stamina ) . Append ( " 소모 · 소탕(전투 없음)</size>" ) ;
2026-11-09 09:03:43 +00:00
var ready = ReadyNames ( s , r ) ;
2026-11-05 12:11:10 +00:00
if ( ready . Length > 0 ) sb . Append ( "\n<color=#a03a22><size=30>레벨업 가능: " ) . Append ( ready ) . Append ( "</size></color>" ) ;
return sb . ToString ( ) ;
}
}
}