전투 결과 · 공용 팝업 · 거래 비주얼 개선 = Fable 제안서 §4-2~§4-4 구현(#1104 · PD 2026-11-09)
- 전투 결과: 별 받침 원 + 큰 별(Icon_Star_On/Off 한 벌) 0.15 s 튀김(UiPop) · 조건 행 3(체크/엑스) · 보상 타일(ItemFrame 5층 + 수량 칩 · 장비 = 등급 칸 · 상자) · 「다시」(같은 노드 재출전 · 군량 확인 · WorldMapScreen.RetryLast · 화면 탭은 이 버튼 위만 제외 = SlingshotInput.HoldResultTap) + 「확인」 Primary 노랑 · 리본 뒤 금빛(호흡) - 군량 팝업: 필드 인셋 · 현재 군량 블록 · 교환 행 2(비용 → 군량 · 오늘 횟수 · Secondary 하늘/녹 · 다 쓰면 회색) · 닫기 = X 만 - 스테이지 팝업: 필드 인셋 · 적 구성 병종 원 ×n + 장수 칩 · 보상 타일 4(첫 클리어 뱃지) · 별 조건 행 3 · 출정 = 붉은 Primary + 군량 비용 · 소탕 = 녹 Secondary · 닫기 버튼 삭제(PopupFill · CostOf 훅) - 거래(뽑기): 목록 바탕 · 서브탭 Round10 · 배너 아래 문양 띠 + 「픽업」 뱃지 · 천장 = 레벨형 게이지 + 노랑 배지 · 확률 = 섹션 패널 + 제목 띠 + 행 3(별 · 바 · %) · 1회 Secondary 하늘 + 보옥 비용 · 10연 Primary 노랑 + 「첫 무료」 꼬리 칩 · 각주 → ⓘ 팝업 - UiKit 공용 부품 ②: At · SkinBtn · BtnCost · SubTab/SetSubTab · Gauge/SetGauge · InfoChip · QtyChip · RewardTile · CondRow · SubTitle - 테마 행 추가(ui_theme.csv): 버튼 btn_l_yellow·btn_l_red · 소제목 선 · 큰 별 · 뱃지 · 배너 문양 · 상자 색(구 TreasureScreen.ChestColor 상수 이관 준비) 등 - 테스트 117/117 · console error 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
9a05b9a0ca
commit
ca8b4cc5e0
|
|
@ -428,3 +428,59 @@ color,alert_red,,,,,,#FF243E,알림 원(수량)
|
||||||
skin,btn_s_gray,Button/Button01_s_Gray.png,,2.1,,,,Secondary 회색 h56(비활성 · 검수 결함 3)
|
skin,btn_s_gray,Button/Button01_s_Gray.png,,2.1,,,,Secondary 회색 h56(비활성 · 검수 결함 3)
|
||||||
color,row_label_strip,,,,,,#FFFFFF0A,편성 라벨 칸 세로 띠(흰 4 %)
|
color,row_label_strip,,,,,,#FFFFFF0A,편성 라벨 칸 세로 띠(흰 4 %)
|
||||||
font,title,Assets/UI/GUIPro/ResourcesData/Fonts/Sen-ExtraBold.ttf,,,,,,제목·숫자(라틴 Sen · 한글 = 폴백 Malgun Gothic · PD 결정 전)
|
font,title,Assets/UI/GUIPro/ResourcesData/Fonts/Sen-ExtraBold.ttf,,,,,,제목·숫자(라틴 Sen · 한글 = 폴백 Malgun Gothic · PD 결정 전)
|
||||||
|
color,text_on_yellow,,,,,,#1E1E2A,노랑 Primary 위 글자(Fable §5-8)
|
||||||
|
color,ribbon_glow,,,,,,#F3B72EB3,결과 리본 뒤 금빛(α 0.7 · Fable §4-2 α 0.35 는 어두운 덮개 위에서 안 보여 올림)
|
||||||
|
color,row_on_field,,,,,,#3F4262,필드 위 행 판(필드보다 밝게 · 팝업 교환 행)
|
||||||
|
skin,btn_l_yellow,Button/Button01_l_Yellow.png,,1.3,,,,Primary 노랑 h110(확인·10연·열기 · Fable §5-5)
|
||||||
|
skin,btn_l_red,Button/Button01_l_White_Bg.png,Button/Button01_l_White_Light1.png,1.35,5;5;5;18,0.35,,Primary 붉은 h104(출정 · 틴트 red)
|
||||||
|
skin,title_divider_l,Label/Title_Line01_Divider_Left.png,,1,,,,소제목 왼쪽 선(Fable §5-2)
|
||||||
|
skin,title_divider_r,Label/Title_Line01_Divider_Right.png,,1,,,,소제목 오른쪽 선
|
||||||
|
icon,star_on_l,IconMisc/Icon_Star_On.png,,,,,,큰 별 켜짐(결과 · star_off 와 한 벌 289 px)
|
||||||
|
icon,x_small,IconMisc/Icon_Close02.png,,,,,,미달 표시(틴트 disabled)
|
||||||
|
icon,badge_first,Label/Label_Badge01_Yellow.png,,,,,,첫 클리어 뱃지
|
||||||
|
icon,badge_hot,Label/Label_Badge01_Red.png,,,,,,픽업·×2 뱃지
|
||||||
|
icon,ad,IconMisc/Icon_Going.png,,,,,,광고 보기 글리프(임시)
|
||||||
|
skin,banner_pattern,Frame/BannerFrame00_01~02_Pattern.png,,1,,,,배너 아래 문양 띠(Tiled · Fable §4-4)
|
||||||
|
color,banner_pattern,,,,,,#FFFFFF14,배너 아래 문양(흰 8 %)
|
||||||
|
icon,lv_badge_y,Slider/Slider_Level02_Icon_Badge_Yellow.png,,,,,,천장 게이지 배지(노랑)
|
||||||
|
color,chest_bronze,,,,,,#B0784D,청동 상자 카드 틴트(구 TreasureScreen.ChestColor 상수 → 테마 · C45)
|
||||||
|
color,chest_bronze_bg,,,,,,#FF8A1E,청동 상자 칸 bg(= gear_orange_bg)
|
||||||
|
color,chest_bronze_deco,,,,,,#FFA43CE6,청동 상자 칸 deco(= gear_orange_deco)
|
||||||
|
color,chest_bronze_light,,,,,,#FFD36BD9,청동 상자 칸 light(= gear_orange_light)
|
||||||
|
color,chest_bronze_glow,,,,,,#FFD98A59,청동 상자 칸 glow(= gear_orange_glow)
|
||||||
|
color,chest_silver,,,,,,#A8ADB8,은 상자 카드 틴트(구 TreasureScreen.ChestColor 상수 → 테마 · C45)
|
||||||
|
color,chest_silver_bg,,,,,,#617E8A,은 상자 칸 bg(= gear_white_bg)
|
||||||
|
color,chest_silver_deco,,,,,,#718E99E6,은 상자 칸 deco(= gear_white_deco)
|
||||||
|
color,chest_silver_light,,,,,,#82A0ABD9,은 상자 칸 light(= gear_white_light)
|
||||||
|
color,chest_silver_glow,,,,,,#FFFFFF59,은 상자 칸 glow(= gear_white_glow)
|
||||||
|
color,chest_gold,,,,,,#E0B338,금 상자 카드 틴트(구 TreasureScreen.ChestColor 상수 → 테마 · C45)
|
||||||
|
color,chest_gold_bg,,,,,,#FFC900,금 상자 칸 bg(= gear_gold_bg)
|
||||||
|
color,chest_gold_deco,,,,,,#FFDE00E6,금 상자 칸 deco(= gear_gold_deco)
|
||||||
|
color,chest_gold_light,,,,,,#FEFD4ED9,금 상자 칸 light(= gear_gold_light)
|
||||||
|
color,chest_gold_glow,,,,,,#F3FF3159,금 상자 칸 glow(= gear_gold_glow)
|
||||||
|
color,chest_general,,,,,,#9E4038,명장 상자 카드 틴트(구 TreasureScreen.ChestColor 상수 → 테마 · C45)
|
||||||
|
color,chest_general_bg,,,,,,#DF2F38,명장 상자 칸 bg(= tre_myth_bg)
|
||||||
|
color,chest_general_deco,,,,,,#FD474BE6,명장 상자 칸 deco(= tre_myth_deco)
|
||||||
|
color,chest_general_light,,,,,,#FF8F9CD9,명장 상자 칸 light(= tre_myth_light)
|
||||||
|
color,chest_general_glow,,,,,,#FF9DA459,명장 상자 칸 glow(= tre_myth_glow)
|
||||||
|
color,chest_gem,,,,,,#4DA691,보옥 상자 카드 틴트(구 TreasureScreen.ChestColor 상수 → 테마 · C45)
|
||||||
|
color,chest_gem_bg,,,,,,#1DC056,보옥 상자 칸 bg(= gear_green_bg)
|
||||||
|
color,chest_gem_deco,,,,,,#34D934E6,보옥 상자 칸 deco(= gear_green_deco)
|
||||||
|
color,chest_gem_light,,,,,,#B2F11FD9,보옥 상자 칸 light(= gear_green_light)
|
||||||
|
color,chest_gem_glow,,,,,,#C0FF5159,보옥 상자 칸 glow(= gear_green_glow)
|
||||||
|
skin,card3_bg,Frame/CardFrame03_n_Bg.png,,1,,,,상자 카드 바탕(틴트 · Fable §4-5)
|
||||||
|
skin,card3_inner,Frame/CardFrame03_n_InnerBg.png,,1,,,,상자 카드 안쪽
|
||||||
|
skin,card3_light,Frame/CardFrame03_n_Light.png,,1,,,,상자 카드 광택
|
||||||
|
color,card3_inner,,,,,,#00000040,상자 카드 안쪽(검정 25 %)
|
||||||
|
color,card3_light,,,,,,#FFFFFF80,상자 카드 광택(흰 50 %)
|
||||||
|
color,chest_glow,,,,,,#F3B72E73,상자 뒤 빛(α 0.45)
|
||||||
|
skin,banner_point,Frame/BannerFrame05_Single.png,,3,,,,상자 포인트 띠(h90 · 장식 비율 유지)
|
||||||
|
color,banner_point,,,,,,#2C2F4A,상자 포인트 띠 틴트
|
||||||
|
skin,bar4_bg,Slider/Slider_Basic04_Bg.png,,1.5,,,,가는 진행 바 바탕
|
||||||
|
skin,bar4_fill,Slider/Slider_Basic04_Fill_Orange.png,,1.5,,,,가는 진행 바 채움
|
||||||
|
icon,tre_stat_hp,Icon_ItemIcons/128/ItemIcon_Heart_Red.Png,,,,,,보물 임시 아이콘 체력(최종 = 보물 그림 N3)
|
||||||
|
icon,tre_stat_atk,Icon_ItemIcons/128/ItemIcon_Gear_Sword.Png,,,,,,보물 임시 아이콘 공격
|
||||||
|
icon,tre_stat_def,Icon_ItemIcons/128/ItemIcon_Gear_Armor_Top.Png,,,,,,보물 임시 아이콘 방어
|
||||||
|
icon,tre_stat_crit,Icon_ItemIcons/128/ItemIcon_Damage.Png,,,,,,보물 임시 아이콘 치명
|
||||||
|
icon,tre_stat_range,Icon_ItemIcons/128/ItemIcon_Gear_Boots.Png,,,,,,보물 임시 아이콘 사거리
|
||||||
|
icon,tre_stat_splash,Icon_ItemIcons/128/ItemIcon_Battle.Png,,,,,,보물 임시 아이콘 광역
|
||||||
|
|
|
||||||
|
|
|
@ -499,6 +499,72 @@ MonoBehaviour:
|
||||||
color: {r: 1, g: 0.14117648, b: 0.24313726, a: 1}
|
color: {r: 1, g: 0.14117648, b: 0.24313726, a: 1}
|
||||||
- id: row_label_strip
|
- id: row_label_strip
|
||||||
color: {r: 1, g: 1, b: 1, a: 0.039215688}
|
color: {r: 1, g: 1, b: 1, a: 0.039215688}
|
||||||
|
- id: text_on_yellow
|
||||||
|
color: {r: 0.11764706, g: 0.11764706, b: 0.16470589, a: 1}
|
||||||
|
- id: ribbon_glow
|
||||||
|
color: {r: 0.9529412, g: 0.7176471, b: 0.18039216, a: 0.7019608}
|
||||||
|
- id: row_on_field
|
||||||
|
color: {r: 0.24705882, g: 0.25882354, b: 0.38431373, a: 1}
|
||||||
|
- id: banner_pattern
|
||||||
|
color: {r: 1, g: 1, b: 1, a: 0.078431375}
|
||||||
|
- id: chest_bronze
|
||||||
|
color: {r: 0.6901961, g: 0.47058824, b: 0.3019608, a: 1}
|
||||||
|
- id: chest_bronze_bg
|
||||||
|
color: {r: 1, g: 0.5411765, b: 0.11764706, a: 1}
|
||||||
|
- id: chest_bronze_deco
|
||||||
|
color: {r: 1, g: 0.6431373, b: 0.23529412, a: 0.9019608}
|
||||||
|
- id: chest_bronze_light
|
||||||
|
color: {r: 1, g: 0.827451, b: 0.41960785, a: 0.8509804}
|
||||||
|
- id: chest_bronze_glow
|
||||||
|
color: {r: 1, g: 0.8509804, b: 0.5411765, a: 0.34901962}
|
||||||
|
- id: chest_silver
|
||||||
|
color: {r: 0.65882355, g: 0.6784314, b: 0.72156864, a: 1}
|
||||||
|
- id: chest_silver_bg
|
||||||
|
color: {r: 0.38039216, g: 0.49411765, b: 0.5411765, a: 1}
|
||||||
|
- id: chest_silver_deco
|
||||||
|
color: {r: 0.44313726, g: 0.5568628, b: 0.6, a: 0.9019608}
|
||||||
|
- id: chest_silver_light
|
||||||
|
color: {r: 0.50980395, g: 0.627451, b: 0.67058825, a: 0.8509804}
|
||||||
|
- id: chest_silver_glow
|
||||||
|
color: {r: 1, g: 1, b: 1, a: 0.34901962}
|
||||||
|
- id: chest_gold
|
||||||
|
color: {r: 0.8784314, g: 0.7019608, b: 0.21960784, a: 1}
|
||||||
|
- id: chest_gold_bg
|
||||||
|
color: {r: 1, g: 0.7882353, b: 0, a: 1}
|
||||||
|
- id: chest_gold_deco
|
||||||
|
color: {r: 1, g: 0.87058824, b: 0, a: 0.9019608}
|
||||||
|
- id: chest_gold_light
|
||||||
|
color: {r: 0.99607843, g: 0.99215686, b: 0.30588236, a: 0.8509804}
|
||||||
|
- id: chest_gold_glow
|
||||||
|
color: {r: 0.9529412, g: 1, b: 0.19215687, a: 0.34901962}
|
||||||
|
- id: chest_general
|
||||||
|
color: {r: 0.61960787, g: 0.2509804, b: 0.21960784, a: 1}
|
||||||
|
- id: chest_general_bg
|
||||||
|
color: {r: 0.8745098, g: 0.18431373, b: 0.21960784, a: 1}
|
||||||
|
- id: chest_general_deco
|
||||||
|
color: {r: 0.99215686, g: 0.2784314, b: 0.29411766, a: 0.9019608}
|
||||||
|
- id: chest_general_light
|
||||||
|
color: {r: 1, g: 0.56078434, b: 0.6117647, a: 0.8509804}
|
||||||
|
- id: chest_general_glow
|
||||||
|
color: {r: 1, g: 0.6156863, b: 0.6431373, a: 0.34901962}
|
||||||
|
- id: chest_gem
|
||||||
|
color: {r: 0.3019608, g: 0.6509804, b: 0.5686275, a: 1}
|
||||||
|
- id: chest_gem_bg
|
||||||
|
color: {r: 0.11372549, g: 0.7529412, b: 0.3372549, a: 1}
|
||||||
|
- id: chest_gem_deco
|
||||||
|
color: {r: 0.20392157, g: 0.8509804, b: 0.20392157, a: 0.9019608}
|
||||||
|
- id: chest_gem_light
|
||||||
|
color: {r: 0.69803923, g: 0.94509804, b: 0.12156863, a: 0.8509804}
|
||||||
|
- id: chest_gem_glow
|
||||||
|
color: {r: 0.7529412, g: 1, b: 0.31764707, a: 0.34901962}
|
||||||
|
- id: card3_inner
|
||||||
|
color: {r: 0, g: 0, b: 0, a: 0.2509804}
|
||||||
|
- id: card3_light
|
||||||
|
color: {r: 1, g: 1, b: 1, a: 0.5019608}
|
||||||
|
- id: chest_glow
|
||||||
|
color: {r: 0.9529412, g: 0.7176471, b: 0.18039216, a: 0.4509804}
|
||||||
|
- id: banner_point
|
||||||
|
color: {r: 0.17254902, g: 0.18431373, b: 0.2901961, a: 1}
|
||||||
skins:
|
skins:
|
||||||
- id: card
|
- id: card
|
||||||
pack: {fileID: 21300000, guid: 3070a6f23e6ca4273897acf1b7e8c5ce, type: 3}
|
pack: {fileID: 21300000, guid: 3070a6f23e6ca4273897acf1b7e8c5ce, type: 3}
|
||||||
|
|
@ -1193,6 +1259,83 @@ MonoBehaviour:
|
||||||
ppu: 2.1
|
ppu: 2.1
|
||||||
inset: {x: 0, y: 0, z: 0, w: 0}
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
overlayAlpha: 1
|
overlayAlpha: 1
|
||||||
|
- id: btn_l_yellow
|
||||||
|
pack: {fileID: 21300000, guid: 6cdadcc1a39954748abf7d3d4351e1e6, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1.3
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: btn_l_red
|
||||||
|
pack: {fileID: 21300000, guid: 3eba92f7629b145ae9366b196000a3f3, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 21300000, guid: b802653e90c694dd0966490b86866a22, type: 3}
|
||||||
|
ppu: 1.35
|
||||||
|
inset: {x: 5, y: 5, z: 5, w: 18}
|
||||||
|
overlayAlpha: 0.35
|
||||||
|
- id: title_divider_l
|
||||||
|
pack: {fileID: 21300000, guid: 878668f672fc94e3b92df41daa6fb966, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: title_divider_r
|
||||||
|
pack: {fileID: 21300000, guid: 6c3ea799aad7c48919b36b752f77ead4, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: banner_pattern
|
||||||
|
pack: {fileID: 21300000, guid: b75949b3a23a049fb814d9cb21aa2c39, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: card3_bg
|
||||||
|
pack: {fileID: 21300000, guid: 12e2f59e45c9e4f6280b38d49ef68605, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: card3_inner
|
||||||
|
pack: {fileID: 21300000, guid: 74ae39be6091048c7a16b3cd8712ce2c, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: card3_light
|
||||||
|
pack: {fileID: 21300000, guid: 6cd33b9fcf759447fa159757f293591b, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: banner_point
|
||||||
|
pack: {fileID: 21300000, guid: 0311dcd69620e47f4b965eb345ef9b35, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 3
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: bar4_bg
|
||||||
|
pack: {fileID: 21300000, guid: 3c166fa4e3ee74616b471b7c2332ab9b, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1.5
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: bar4_fill
|
||||||
|
pack: {fileID: 21300000, guid: 26d89dd2d7ae148e4acefd7fb973eb82, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1.5
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
icons:
|
icons:
|
||||||
- id: cur_gold
|
- id: cur_gold
|
||||||
pack: {fileID: 21300000, guid: 6d5687fb0dd3a428d9cd26a6f36c6d78, type: 3}
|
pack: {fileID: 21300000, guid: 6d5687fb0dd3a428d9cd26a6f36c6d78, type: 3}
|
||||||
|
|
@ -1538,6 +1681,54 @@ MonoBehaviour:
|
||||||
pack: {fileID: 21300000, guid: c0c390b014f3f4b0781cfca1e2ebe6f0, type: 3}
|
pack: {fileID: 21300000, guid: c0c390b014f3f4b0781cfca1e2ebe6f0, type: 3}
|
||||||
samguk: {fileID: 0}
|
samguk: {fileID: 0}
|
||||||
tint: {r: 1, g: 1, b: 1, a: 1}
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- id: star_on_l
|
||||||
|
pack: {fileID: 21300000, guid: 9fdf2423376c44500a69de40dd83ef49, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- id: x_small
|
||||||
|
pack: {fileID: 21300000, guid: f1a76f95358d94ca080a3e48691f8e5f, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- id: badge_first
|
||||||
|
pack: {fileID: 21300000, guid: 77ef9d3b0b12a4a4d954bfce8b142152, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- id: badge_hot
|
||||||
|
pack: {fileID: 21300000, guid: e9be1374ca9ae47fdb7208668217021c, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- id: ad
|
||||||
|
pack: {fileID: 21300000, guid: 23684c39a5232480abc423f4c39c550d, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- id: lv_badge_y
|
||||||
|
pack: {fileID: 21300000, guid: 9fa652a2cd39b4cfcaf06285cfff1483, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- id: tre_stat_hp
|
||||||
|
pack: {fileID: 21300000, guid: ae898e04b74ec47d8bb33582fcf24b12, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- id: tre_stat_atk
|
||||||
|
pack: {fileID: 21300000, guid: 41bc376691e7a4aef8398c3f84ee249f, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- id: tre_stat_def
|
||||||
|
pack: {fileID: 21300000, guid: 3a3a5d970e2d94998818421e4e0e384b, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- id: tre_stat_crit
|
||||||
|
pack: {fileID: 21300000, guid: 5864b32a142be4809ab2ccc225cae6bf, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- id: tre_stat_range
|
||||||
|
pack: {fileID: 21300000, guid: e07c16cced13542f59c7400aff52d8a7, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- id: tre_stat_splash
|
||||||
|
pack: {fileID: 21300000, guid: d031f4b21493c4841914d4257119a4e3, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
- id: tile_bridge
|
- id: tile_bridge
|
||||||
pack: {fileID: 0}
|
pack: {fileID: 0}
|
||||||
samguk: {fileID: 21300000, guid: 8e5bf7eb1e300474785ff2781eeb5093, type: 3}
|
samguk: {fileID: 21300000, guid: 8e5bf7eb1e300474785ff2781eeb5093, type: 3}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
@ -5,21 +6,33 @@ using UnityEngine.UI;
|
||||||
namespace TKS.OutGame
|
namespace TKS.OutGame
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 전투 결과 패널(기획서 §6) — 별 3(클리어 · 전원 생존 · n턴 이내) · 골드 · 경험(출전 전원) · 보옥(첫 클리어 · 보스) · 장비 드랍.
|
/// 전투 결과 패널(기획서 §6 · 비주얼 = Fable 제안서 §4-2 #1104) — 별 3(받침 원 + 등장 튀김) · 조건 행 3 · 보상 타일(골드 · 경험 · 보옥 · 장비 · 상자) ·
|
||||||
/// 전투 HUD 의 승리/패배 판(sortingOrder 100) 위에 덮는다 · 탭 처리는 기존 그대로(SlingshotInput → 월드맵 복귀).
|
/// 버튼 = 「다시」(Tertiary · 같은 스테이지 재도전) + 「확인」(Primary 노랑) · 승리면 리본 뒤 금빛.
|
||||||
|
/// 전투 HUD 의 승리/패배 판(sortingOrder 100) 위에 덮는다 · 화면 아무 데나 탭 = 기존 그대로(SlingshotInput → 월드맵 복귀 · 「다시」 위만 제외).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BattleResultPanel
|
public class BattleResultPanel
|
||||||
{
|
{
|
||||||
|
// 패널 배치(UI px · 패널 왼쪽 위 기준)
|
||||||
|
const float PW = 920f;
|
||||||
|
const float PH = 1180f;
|
||||||
|
const float Side = 60f;
|
||||||
|
const float RowW = PW - Side * 2f;
|
||||||
|
const float RowH = 64f;
|
||||||
|
const float Tile = 132f;
|
||||||
|
const float BtnY = PH - 40f - 110f;
|
||||||
|
|
||||||
readonly OutGameRoot root;
|
readonly OutGameRoot root;
|
||||||
readonly GameObject go;
|
readonly GameObject go;
|
||||||
readonly Text title;
|
readonly Text title;
|
||||||
readonly Text stars;
|
|
||||||
readonly Text conds;
|
|
||||||
readonly Text rewards;
|
|
||||||
readonly Text hint;
|
|
||||||
readonly Image ribbon;
|
readonly Image ribbon;
|
||||||
|
readonly Image glow;
|
||||||
readonly RectTransform starRow;
|
readonly RectTransform starRow;
|
||||||
readonly Image[] starImg = new Image[3];
|
readonly Image[] starImg = new Image[3];
|
||||||
|
readonly RectTransform body;
|
||||||
|
readonly Text plain;
|
||||||
|
readonly Button retry;
|
||||||
|
readonly Button ok;
|
||||||
|
string rewardsText = "";
|
||||||
|
|
||||||
public bool Visible
|
public bool Visible
|
||||||
{
|
{
|
||||||
|
|
@ -28,7 +41,7 @@ namespace TKS.OutGame
|
||||||
|
|
||||||
public string RewardsText
|
public string RewardsText
|
||||||
{
|
{
|
||||||
get { return rewards.text; }
|
get { return rewardsText; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public BattleResultPanel(OutGameRoot r, RectTransform canvas)
|
public BattleResultPanel(OutGameRoot r, RectTransform canvas)
|
||||||
|
|
@ -40,35 +53,47 @@ namespace TKS.OutGame
|
||||||
Image panel;
|
Image panel;
|
||||||
if (UISkin.Has("popup"))
|
if (UISkin.Has("popup"))
|
||||||
{
|
{
|
||||||
// 팩 팝업 틀 + 제목 리본(승리 = 붉은 · 패배 = 회색) + 별 아이콘 3
|
// 리본 뒤 금빛(승리만 · 팩 Glow_Circle01 · 호흡) → 팩 팝업 틀 → 제목 리본(승리 붉은 · 패배 회색)
|
||||||
panel = UiKit.Skin(UiKit.Rect("Panel", dim, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 20f), new Vector2(920f, 1180f)), "popup", UiKit.Paper);
|
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;
|
||||||
|
}
|
||||||
|
panel = UiKit.Skin(UiKit.Rect("Panel", dim, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 20f), new Vector2(PW, PH)), "popup", UiKit.Paper);
|
||||||
var rib = UiKit.Rect("Ribbon", panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 0.5f), new Vector2(0f, 10f), new Vector2(1000f, 200f));
|
var rib = UiKit.Rect("Ribbon", panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 0.5f), new Vector2(0f, 10f), new Vector2(1000f, 200f));
|
||||||
ribbon = UiKit.Skin(rib, "ribbon", Color.white);
|
ribbon = UiKit.Skin(rib, "ribbon", Color.white);
|
||||||
title = UiKit.Title(UiKit.FillLabel(rib, "", 88, UiKit.White, TextAnchor.MiddleCenter, true, 150f), true);
|
title = UiKit.Title(UiKit.FillLabel(rib, "", 88, UiKit.White, TextAnchor.MiddleCenter, true, 150f), true);
|
||||||
title.rectTransform.offsetMin = new Vector2(150f, 34f);
|
title.rectTransform.offsetMin = new Vector2(150f, 34f);
|
||||||
starRow = UiKit.Rect("StarRow", panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -150f), new Vector2(600f, 190f));
|
// 별 3 = 받침 원(Circle78 chip_dark) + 별(가운데 크게 · 위로) · 0.15 s 간격 튀김
|
||||||
|
starRow = UiKit.At(panel.transform, "StarRow", 0f, 120f, PW, 190f);
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
float s = i == 1 ? 190f : 150f;
|
bool mid = i == 1;
|
||||||
starImg[i] = UiKit.Icon(starRow, "star_on", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2((i - 1) * 180f, i == 1 ? 14f : -10f), s);
|
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;
|
||||||
}
|
}
|
||||||
|
body = UiKit.Fill("Body", panel.transform);
|
||||||
|
retry = UiKit.SkinBtn(panel.transform, "Retry", "round08", UiKit.Col("menu_btn", UiKit.Dark), "다시", 40, UiKit.White, Side, BtnY, 260f, 110f, () => root.RetryStage());
|
||||||
|
ok = UiKit.SkinBtn(panel.transform, "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);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
panel = UiKit.Box("Panel", dim, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 40f), new Vector2(920f, 1180f), UiKit.Paper);
|
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);
|
||||||
UiKit.Border(panel, UiKit.Line, 4f);
|
UiKit.Border(panel, UiKit.Line, 4f);
|
||||||
var head = UiKit.TopBand("Head", panel.transform, 0f, 170f);
|
var head = UiKit.TopBand("Head", panel.transform, 0f, 170f);
|
||||||
UiKit.Paint(head, UiKit.Dark);
|
UiKit.Paint(head, UiKit.Dark);
|
||||||
title = UiKit.FillLabel(head, "", 96, UiKit.White);
|
title = UiKit.FillLabel(head, "", 96, UiKit.White);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
stars = UiKit.Label(panel.transform, "", 120, UiKit.Star, TextAnchor.MiddleCenter, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -190f), new Vector2(800f, 150f));
|
|
||||||
conds = UiKit.Label(panel.transform, "", 34, UiKit.Ink, TextAnchor.UpperLeft, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -350f), new Vector2(760f, 180f), false);
|
|
||||||
conds.lineSpacing = 1.15f;
|
|
||||||
var line = UiKit.Box("Line", panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -540f), new Vector2(800f, 4f), UiKit.Slot, false);
|
|
||||||
line.raycastTarget = false;
|
|
||||||
rewards = UiKit.Label(panel.transform, "", 38, UiKit.Ink, TextAnchor.UpperLeft, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -566f), new Vector2(760f, 460f), false);
|
|
||||||
rewards.lineSpacing = 1.15f;
|
|
||||||
hint = 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);
|
|
||||||
go.SetActive(false);
|
go.SetActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,61 +102,155 @@ namespace TKS.OutGame
|
||||||
if (go.activeSelf != on) go.SetActive(on);
|
if (go.activeSelf != on) go.SetActive(on);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <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);
|
||||||
|
}
|
||||||
|
|
||||||
public void Fill(StageReward r)
|
public void Fill(StageReward r)
|
||||||
{
|
{
|
||||||
var s = root.Session;
|
var s = root.Session;
|
||||||
hint.text = "화면을 탭하면 월드맵으로";
|
rewardsText = r.win ? RewardText(s, r) : "보상 없음";
|
||||||
title.text = (r.win ? "승리" : "패배") + " <size=44>" + r.chapter + "-" + r.stage + (r.boss ? " 보스" : "") + "</size>";
|
title.text = (r.win ? "승리" : "패배") + " <size=44>" + r.chapter + "-" + r.stage + (r.boss ? " 보스" : "") + "</size>";
|
||||||
stars.text = r.win ? UiKit.Stars(r.stars, 3) : UiKit.Stars(0, 3);
|
|
||||||
ShowStars(r.win ? r.stars : 0, r.win);
|
ShowStars(r.win ? r.stars : 0, r.win);
|
||||||
|
SetButtons(true);
|
||||||
|
if (body == null)
|
||||||
|
{
|
||||||
|
plain.text = (r.win ? "별 " + UiKit.Stars(r.stars, 3) + "\n\n" : "아군이 전멸했습니다\n\n") + rewardsText;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UiKit.Clear(body);
|
||||||
|
float y = 330f;
|
||||||
if (r.win)
|
if (r.win)
|
||||||
{
|
{
|
||||||
conds.text = Mark(r.conds[0]) + " 클리어\n" +
|
string[] cond = { "스테이지 클리어", "아군 전원 생존", r.starTurns + "턴 이내 클리어 <size=26>(" + r.turns + "턴)</size>" };
|
||||||
Mark(r.conds[1]) + " 아군 전원 생존\n" +
|
for (int i = 0; i < 3; i++)
|
||||||
Mark(r.conds[2]) + " " + r.starTurns + "턴 이내 클리어 (" + r.turns + "턴)";
|
UiKit.CondRow(body, "Cond" + i, Side, y + i * (RowH + 8f), RowW, RowH, r.conds[i] ? "check" : "x_small", r.conds[i], cond[i], 30);
|
||||||
rewards.text = RewardText(s, r);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
conds.text = "아군이 전멸했습니다\n군량 " + r.stamina + " 소모 · 별 없음";
|
UiKit.CondRow(body, "Cond0", Side, y, RowW, RowH, "x_small", false, "아군이 전멸했습니다", 30);
|
||||||
rewards.text = "보상 없음\n<size=32>영웅 레벨업 · 승급 · 편성을 바꿔 다시 도전</size>";
|
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);
|
||||||
|
Notes(s, r, y + Tile + 60f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>보상 타일 행(가운데 정렬 · 칸 아래 이름) — 골드 · 경험 · 보옥(있을 때) · 장비(등급 칸 · 있을 때) · 상자(있을 때).</summary>
|
||||||
|
void Tiles(OutGameSession s, StageReward r, float y)
|
||||||
|
{
|
||||||
|
var list = new List<string[]>(); // 아이콘 · 수량 · 칸 색 접두 · 이름
|
||||||
|
list.Add(new[] { "cur_gold", r.gold.ToString("N0"), "gear_white_", "골드" });
|
||||||
|
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);
|
||||||
|
UiKit.RewardTile(body, "Tile" + i, tx, y, Tile, e[2], e[0], e[1], e[2] != "gear_white_");
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>연무장 결과(탑 · 던전 · 투기장 · 적장 토벌 · PD #1093 C) — 별 없음 · 결과 줄 · 탭 = 연무장.</summary>
|
/// <summary>타일 아래 한두 줄 — 첫 클리어/반복 배율 · 레벨업 가능 영웅 · 소탕.</summary>
|
||||||
|
void Notes(OutGameSession s, StageReward r, float y)
|
||||||
|
{
|
||||||
|
var e = s.Db.Economy;
|
||||||
|
var sb = new StringBuilder(r.first ? "첫 클리어 보상" + (r.boss ? " + 보스" : "") : "반복 보상 ×" + e.RepeatRewardMult);
|
||||||
|
if (r.sweep) sb.Append(" · 소탕(군량 ").Append(r.stamina).Append(")");
|
||||||
|
var ready = ReadyNames(s, r);
|
||||||
|
if (ready.Length > 0) sb.Append("\n<color=#").Append(ColorUtility.ToHtmlStringRGB(UiKit.Col("alert_red", UiKit.Red))).Append(">레벨업 가능 ").Append(ready).Append("</color>");
|
||||||
|
var t = UiKit.Label(body, sb.ToString(), 30, UiKit.White, TextAnchor.UpperCenter, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(Side, -y), new Vector2(RowW, 100f), false);
|
||||||
|
t.lineSpacing = 1.2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>연무장 결과(탑 · 던전 · 투기장 · 적장 토벌 · PD #1093 C) — 별 없음 · 결과 행 · 탭 = 연무장.</summary>
|
||||||
public void FillMode(ModeResult r)
|
public void FillMode(ModeResult r)
|
||||||
{
|
{
|
||||||
hint.text = "화면을 탭하면 연무장으로";
|
SetButtons(false);
|
||||||
|
rewardsText = r != null ? string.Join("\n", r.lines.ToArray()) : "";
|
||||||
if (r == null)
|
if (r == null)
|
||||||
{
|
{
|
||||||
title.text = "연무장";
|
title.text = "연무장";
|
||||||
stars.text = conds.text = rewards.text = "";
|
ShowStars(-1, true);
|
||||||
|
if (body != null) UiKit.Clear(body);
|
||||||
|
else plain.text = "";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
bool win = r.win || r.kind == ArenaRules.Raid;
|
||||||
title.text = r.kind == ArenaRules.Raid ? "토벌 종료" : r.win ? "승리" : "패배";
|
title.text = r.kind == ArenaRules.Raid ? "토벌 종료" : r.win ? "승리" : "패배";
|
||||||
stars.text = "";
|
ShowStars(-1, win);
|
||||||
ShowStars(-1, r.win || r.kind == ArenaRules.Raid);
|
if (body == null)
|
||||||
conds.text = "<size=44>" + r.title + "</size>";
|
{
|
||||||
rewards.text = string.Join("\n", r.lines.ToArray());
|
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>별 아이콘(n < 0 = 숨김) · 리본 색(승리 붉은 · 패배 회색) · 테마가 없으면 글자 별만.</summary>
|
/// <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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>별 아이콘(n < 0 = 숨김) · 리본 색(승리 붉은 · 패배 회색) · 금빛 = 승리만.</summary>
|
||||||
void ShowStars(int n, bool win)
|
void ShowStars(int n, bool win)
|
||||||
{
|
{
|
||||||
|
if (glow != null) glow.gameObject.SetActive(win);
|
||||||
if (starRow == null) return;
|
if (starRow == null) return;
|
||||||
stars.gameObject.SetActive(false);
|
|
||||||
starRow.gameObject.SetActive(n >= 0);
|
starRow.gameObject.SetActive(n >= 0);
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
if (starImg[i] != null) starImg[i].sprite = UISkin.Icon(i < n ? "star_on" : "star_off") ?? starImg[i].sprite;
|
if (starImg[i] != null) starImg[i].sprite = UISkin.Icon(i < n ? "star_on_l" : "star_off") ?? starImg[i].sprite;
|
||||||
if (ribbon != null && !UISkin.Apply(ribbon, win ? "ribbon" : "ribbon_gray")) ribbon.color = win ? Color.white : UiKit.Disabled;
|
if (ribbon != null && !UISkin.Apply(ribbon, win ? "ribbon" : "ribbon_gray")) ribbon.color = win ? Color.white : UiKit.Disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
static string Mark(bool ok)
|
static string ReadyNames(OutGameSession s, StageReward r)
|
||||||
{
|
{
|
||||||
return ok ? "<color=#3a6a30>○</color>" : "<color=#a03a22>×</color>";
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>보상 줄(결과 화면 · 소탕 팝업 공용).</summary>
|
/// <summary>보상 줄(소탕 팝업 · 테마 없을 때 결과 화면 공용).</summary>
|
||||||
public static string RewardText(OutGameSession s, StageReward r)
|
public static string RewardText(OutGameSession s, StageReward r)
|
||||||
{
|
{
|
||||||
var e = s.Db.Economy;
|
var e = s.Db.Economy;
|
||||||
|
|
@ -147,14 +266,7 @@ namespace TKS.OutGame
|
||||||
else sb.Append("\n<size=30>장비 드랍 없음</size>");
|
else sb.Append("\n<size=30>장비 드랍 없음</size>");
|
||||||
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>");
|
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>");
|
||||||
if (r.sweep) sb.Append("\n<size=30>군량 ").Append(r.stamina).Append(" 소모 · 소탕(전투 없음)</size>");
|
if (r.sweep) sb.Append("\n<size=30>군량 ").Append(r.stamina).Append(" 소모 · 소탕(전투 없음)</size>");
|
||||||
var ready = new StringBuilder();
|
var ready = ReadyNames(s, r);
|
||||||
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);
|
|
||||||
}
|
|
||||||
if (ready.Length > 0) sb.Append("\n<color=#a03a22><size=30>레벨업 가능: ").Append(ready).Append("</size></color>");
|
if (ready.Length > 0) sb.Append("\n<color=#a03a22><size=30>레벨업 가능: ").Append(ready).Append("</size></color>");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,8 @@ namespace TKS.OutGame
|
||||||
{
|
{
|
||||||
wm.TopInset = TopBarH;
|
wm.TopInset = TopBarH;
|
||||||
wm.PopupInfo = PopupInfo;
|
wm.PopupInfo = PopupInfo;
|
||||||
|
wm.PopupFill = PopupFill;
|
||||||
|
wm.CostOf = si => EconomyRules.StageCost(Session.Db, Session.Save, b.Config.stages[si]);
|
||||||
wm.TryEnter = TryEnter;
|
wm.TryEnter = TryEnter;
|
||||||
wm.StarsOf = si => EconomyRules.StarsOf(Session.Save, b.Config.stages[si]);
|
wm.StarsOf = si => EconomyRules.StarsOf(Session.Save, b.Config.stages[si]);
|
||||||
wm.CanSweep = si => EconomyRules.CanSweep(Session.Save, b.Config.stages[si]);
|
wm.CanSweep = si => EconomyRules.CanSweep(Session.Save, b.Config.stages[si]);
|
||||||
|
|
@ -221,6 +223,7 @@ namespace TKS.OutGame
|
||||||
BuildTabBar();
|
BuildTabBar();
|
||||||
BuildCurrencyBar();
|
BuildCurrencyBar();
|
||||||
result = new BattleResultPanel(this, (RectTransform)resultCanvas.transform);
|
result = new BattleResultPanel(this, (RectTransform)resultCanvas.transform);
|
||||||
|
if (s != null) s.HoldResultTap = p => result.PointerOnRetry(p);
|
||||||
mainCanvas.gameObject.SetActive(false);
|
mainCanvas.gameObject.SetActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -625,11 +628,16 @@ namespace TKS.OutGame
|
||||||
StaminaModal(null);
|
StaminaModal(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaminaModal(string why)
|
void StaminaModal(string why, bool good = false)
|
||||||
{
|
{
|
||||||
var e = Session.Db.Economy;
|
var e = Session.Db.Economy;
|
||||||
var d = Session.Save;
|
var d = Session.Save;
|
||||||
EconomyRules.RollDaily(d, Session.Now);
|
EconomyRules.RollDaily(d, Session.Now);
|
||||||
|
if (UISkin.Has("popup") && UISkin.Has("panel_field"))
|
||||||
|
{
|
||||||
|
StaminaPopup(why, good);
|
||||||
|
return;
|
||||||
|
}
|
||||||
string body = (why != null ? why + "\n\n" : "") +
|
string body = (why != null ? why + "\n\n" : "") +
|
||||||
"군량 " + d.stamina + " / " + EconomyRules.StaminaMax(Session.Db, d) + " · " + (EconomyRules.RegenSec(Session.Db, d) / 60f).ToString("0.#") + "분마다 1 회복(오프라인 포함)\n" +
|
"군량 " + d.stamina + " / " + EconomyRules.StaminaMax(Session.Db, d) + " · " + (EconomyRules.RegenSec(Session.Db, d) / 60f).ToString("0.#") + "분마다 1 회복(오프라인 포함)\n" +
|
||||||
"스테이지 " + e.StageCost + " · 보스 " + e.BossCost + " 소모";
|
"스테이지 " + e.StageCost + " · 보스 " + e.BossCost + " 소모";
|
||||||
|
|
@ -649,6 +657,73 @@ namespace TKS.OutGame
|
||||||
new ModalButton("닫기", UiKit.Dark, null));
|
new ModalButton("닫기", UiKit.Dark, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 군량 충전 팝업(Fable 제안서 §4-3 · #1104) — 팝업 안 필드(panel_field 인셋 20) · 현재 군량 블록 · 교환 행 2(보옥 → 군량 · 광고 → 군량)
|
||||||
|
/// = 비용 아이콘 + 숫자 → 화살표 → 군량 아이콘 + 「+n」 · 행 오른쪽 Secondary 버튼(하늘 · 녹) · 닫기 = 제목 띠 X 만.
|
||||||
|
/// </summary>
|
||||||
|
void StaminaPopup(string why, bool good)
|
||||||
|
{
|
||||||
|
var e = Session.Db.Economy;
|
||||||
|
var d = Session.Save;
|
||||||
|
const float H = 760f;
|
||||||
|
var content = ModalCustom("군량 충전", H);
|
||||||
|
var panel = content.parent;
|
||||||
|
content.gameObject.SetActive(false);
|
||||||
|
var field = UiKit.Layer(panel, "Field", "panel_field", UiKit.Col("panel_field", UiKit.Dark), 20f, 126f, 20f, 20f).rectTransform;
|
||||||
|
float w = 940f - 40f;
|
||||||
|
// 현재 군량(아이콘 96 · 값 56 Sen · 회복 · 소모)
|
||||||
|
var ic = UiKit.Icon(field, "cur_stamina", new Vector2(0f, 1f), new Vector2(0.5f, 0.5f), new Vector2(92f, -90f), 104f);
|
||||||
|
UiKit.DropShadow(ic, 5f);
|
||||||
|
var now = UiKit.Title(UiKit.Label(field, d.stamina + " <size=40>/ " + EconomyRules.StaminaMax(Session.Db, d) + "</size>", 60, UiKit.White, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(170f, -26f), new Vector2(400f, 70f)), true);
|
||||||
|
now.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
int left = Session.StaminaSecondsToNext();
|
||||||
|
string regen = (EconomyRules.RegenSec(Session.Db, d) / 60f).ToString("0.#") + "분마다 1 회복" + (left > 0 ? " · 다음 " + (left / 60).ToString("00") + ":" + (left % 60).ToString("00") : " · 가득");
|
||||||
|
UiKit.Label(field, regen, 28, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(172f, -100f), new Vector2(w - 190f, 40f), false);
|
||||||
|
UiKit.InfoChip(field, "Cost", w - 24f - 300f, 34f, 300f, 52f, null, "스테이지 " + e.StageCost + " · 보스 " + e.BossCost, 26);
|
||||||
|
// 안내 줄(구매 결과 · 부족)
|
||||||
|
if (!string.IsNullOrEmpty(why))
|
||||||
|
{
|
||||||
|
var wt = UiKit.Title(UiKit.Label(field, why, 30, good ? UiKit.Col("ok", UiKit.Ok) : UiKit.Col("alert_red", UiKit.Red), TextAnchor.MiddleCenter, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(24f, -160f), new Vector2(w - 48f, 50f)), true);
|
||||||
|
wt.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
}
|
||||||
|
UiKit.SubTitle(field, "충전", 24f, 222f, w - 48f);
|
||||||
|
ExchangeRow(field, 0, 286f, w, "cur_gem", e.GemStaminaCost.ToString("N0"), e.GemStaminaAmount, "오늘 " + d.adsUsed.gemStamina + " / " + e.GemStaminaDaily,
|
||||||
|
d.adsUsed.gemStamina < e.GemStaminaDaily, "btn_sky", "구매", () =>
|
||||||
|
{
|
||||||
|
var r = Session.BuyStamina();
|
||||||
|
StaminaModal(r ?? "군량 +" + e.GemStaminaAmount, r == null);
|
||||||
|
if (Map != null) Map.RefreshPopup();
|
||||||
|
});
|
||||||
|
ExchangeRow(field, 1, 286f + 160f, w, "ad", "광고", e.AdStamina, "오늘 " + d.adsUsed.stamina + " / " + e.AdStaminaDaily + " · 광고 SDK 미연동(시험 지급)",
|
||||||
|
d.adsUsed.stamina < e.AdStaminaDaily, "btn_s_green", "보기", () =>
|
||||||
|
{
|
||||||
|
var r = Session.AdStamina();
|
||||||
|
StaminaModal(r ?? "군량 +" + e.AdStamina, r == null);
|
||||||
|
if (Map != null) Map.RefreshPopup();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>교환 행(필드 위 밝은 판 h140) — 왼쪽 [비용 아이콘 + 값] → [군량 + n] · 아래 오늘 횟수 · 오른쪽 Secondary 버튼(다 쓰면 회색).</summary>
|
||||||
|
void ExchangeRow(Transform field, int i, float y, float w, string costIcon, string cost, int gain, string note, bool can, string skin, string label, Action onClick)
|
||||||
|
{
|
||||||
|
const float Pad = 24f, Rh = 140f;
|
||||||
|
var row = UiKit.Skin(UiKit.At(field, "Row" + i, Pad, y, w - Pad * 2f, Rh), "panel12", UiKit.Col("row_on_field", UiKit.Paper)).transform;
|
||||||
|
var a = UiKit.Icon(row, costIcon, new Vector2(0f, 1f), new Vector2(0.5f, 0.5f), new Vector2(60f, -52f), costIcon == "ad" ? 44f : 64f);
|
||||||
|
if (a != null) UiKit.DropShadow(a, 3f);
|
||||||
|
var at = UiKit.Title(UiKit.Label(row, cost, 40, UiKit.White, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(100f, -22f), new Vector2(140f, 60f)), true);
|
||||||
|
at.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
float ax = 108f + Mathf.Ceil(at.preferredWidth) + 22f;
|
||||||
|
var arrow = UiKit.Icon(row, "arrow_next", new Vector2(0f, 1f), new Vector2(0.5f, 0.5f), new Vector2(ax + 12f, -52f), 40f);
|
||||||
|
if (arrow != null) arrow.color = UiKit.Col("text_soft", UiKit.InkSoft);
|
||||||
|
var b = UiKit.Icon(row, "cur_stamina", new Vector2(0f, 1f), new Vector2(0.5f, 0.5f), new Vector2(ax + 72f, -52f), 64f);
|
||||||
|
if (b != null) UiKit.DropShadow(b, 3f);
|
||||||
|
var bt = UiKit.Title(UiKit.Label(row, "+" + gain, 40, UiKit.Col("ok", UiKit.Ok), TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(ax + 112f, -22f), new Vector2(140f, 60f)), true);
|
||||||
|
bt.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
UiKit.Label(row, note, 24, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(30f, -96f), new Vector2(w - 380f, 36f), false);
|
||||||
|
var btn = UiKit.SkinBtn(row, "Btn", can || !UISkin.Has("btn_gray") ? skin : "btn_gray", UiKit.White, label, 38, can ? UiKit.White : UiKit.Col("disabled_text", UiKit.Disabled), w - Pad * 2f - 24f - 250f, 20f, 250f, 100f, onClick);
|
||||||
|
if (skin == "btn_s_green" && can) UiKit.BtnCost(btn, "ad", "", 36f, 24);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------- 월드맵 연결 ----------
|
// ---------- 월드맵 연결 ----------
|
||||||
|
|
||||||
string PopupInfo(int si)
|
string PopupInfo(int si)
|
||||||
|
|
@ -678,6 +753,111 @@ namespace TKS.OutGame
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 월드맵 스테이지 팝업 본문(Fable 제안서 §4-3 · #1104 · 필드 안 860 폭) — 제목 · 장소 → 「적 구성」 병종 원 아이콘 ×n + 장수 칩 →
|
||||||
|
/// 「보상」 타일(골드 · 경험 · 보옥(첫 클리어) · 장비 드랍 % · 첫 클리어 뱃지) → 「별 조건」 행 3(별 아이콘).
|
||||||
|
/// </summary>
|
||||||
|
void PopupFill(int si, bool locked, RectTransform field)
|
||||||
|
{
|
||||||
|
var s = Battle.Config.stages[si];
|
||||||
|
var db = Session.Db;
|
||||||
|
var d = Session.Save;
|
||||||
|
var e = db.Economy;
|
||||||
|
var row = db.Rewards.For(s.chapter);
|
||||||
|
const float W = 860f, Pad = 24f, Tile = 132f;
|
||||||
|
var soft = UiKit.Col("text_soft", UiKit.InkSoft);
|
||||||
|
var head = UiKit.Title(UiKit.Label(field, s.title, 38, UiKit.White, TextAnchor.MiddleCenter, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(Pad, -18f), new Vector2(W - Pad * 2f, 56f)), true);
|
||||||
|
head.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
if (!string.IsNullOrEmpty(s.place))
|
||||||
|
UiKit.Label(field, s.place + (string.IsNullOrEmpty(s.bgTheme) ? "" : " · " + s.bgTheme), 26, soft, TextAnchor.MiddleCenter, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(Pad, -76f), new Vector2(W - Pad * 2f, 34f), false);
|
||||||
|
|
||||||
|
// 적 구성 = 병종 원(type 색 Circle78 68 + 병종 아이콘 40) + 「×n」 · 가운데 정렬
|
||||||
|
float y = 124f;
|
||||||
|
UiKit.SubTitle(field, "적 구성", Pad, y, W - Pad * 2f);
|
||||||
|
var counts = new int[UnitTypeInfo.Count];
|
||||||
|
var lead = new List<string>();
|
||||||
|
foreach (var en in s.enemies)
|
||||||
|
{
|
||||||
|
counts[(int)en.type]++;
|
||||||
|
if (en.isBoss || en.isGeneral) lead.Add((en.isBoss ? "보스 " : "") + en.name);
|
||||||
|
}
|
||||||
|
var kinds = new List<int>();
|
||||||
|
for (int t = 0; t < counts.Length; t++)
|
||||||
|
if (counts[t] > 0) kinds.Add(t);
|
||||||
|
const float Ew = 172f;
|
||||||
|
float ex = (W - kinds.Count * Ew) * 0.5f;
|
||||||
|
for (int k = 0; k < kinds.Count; k++)
|
||||||
|
{
|
||||||
|
var ut = (UnitType)kinds[k];
|
||||||
|
float cx = ex + k * Ew + 44f;
|
||||||
|
var circ = UiKit.Skin(UiKit.Rect("Type" + k, field, new Vector2(0f, 1f), new Vector2(0.5f, 0.5f), new Vector2(cx, -y - 94f), new Vector2(80f, 80f)), "circle_frame", UiKit.TypeColor(ut));
|
||||||
|
var ti = UiKit.Icon(circ.transform, UiKit.TypeIconId(ut), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 2f), 52f);
|
||||||
|
if (ti != null)
|
||||||
|
{
|
||||||
|
ti.color = UiKit.White;
|
||||||
|
UiKit.DropShadow(ti, 2f);
|
||||||
|
}
|
||||||
|
var n = UiKit.Title(UiKit.Label(field, "×" + counts[kinds[k]], 36, UiKit.White, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 0.5f), new Vector2(cx + 50f, -y - 94f), new Vector2(100f, 50f)), true);
|
||||||
|
n.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
}
|
||||||
|
y += 140f;
|
||||||
|
if (lead.Count > 0)
|
||||||
|
{
|
||||||
|
string names = string.Join(" · ", lead.ToArray());
|
||||||
|
float cw = Mathf.Min(W - Pad * 2f, 120f + names.Length * 26f);
|
||||||
|
UiKit.InfoChip(field, "Lead", (W - cw) * 0.5f, y, cw, 48f, "badge_hot", names, 26);
|
||||||
|
y += 64f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 보상 타일
|
||||||
|
UiKit.SubTitle(field, "보상", Pad, y, W - Pad * 2f);
|
||||||
|
y += 56f;
|
||||||
|
var st = d.Stage(s.chapter, s.stage, false);
|
||||||
|
bool first = st == null || st.clears == 0;
|
||||||
|
bool boss = s.kind == StageKind.Boss;
|
||||||
|
if (row != null)
|
||||||
|
{
|
||||||
|
int gold = Mathf.RoundToInt((row.goldBase + s.stage * e.GoldPerStage) * (first ? e.FirstClearGoldMult : e.RepeatRewardMult));
|
||||||
|
int exp = Mathf.RoundToInt(row.expBase * (first ? 1f : e.RepeatRewardMult));
|
||||||
|
float drop = boss ? e.BossGearDropPct : row.gearDropPct;
|
||||||
|
var tiles = new List<string[]>(); // 아이콘 · 수량 · 칸 색 · 이름 · 첫 뱃지
|
||||||
|
tiles.Add(new[] { "cur_gold", gold.ToString("N0"), "gear_white_", first ? "골드" : "골드 ×" + e.RepeatRewardMult, first ? "1" : "" });
|
||||||
|
tiles.Add(new[] { "cur_exp", exp.ToString("N0"), "gear_white_", "경험 · 전원", "" });
|
||||||
|
if (first) tiles.Add(new[] { "cur_gem", (row.gemFirst + (boss ? row.gemBoss : 0)).ToString(), "gear_blue_", "보옥", "1" });
|
||||||
|
string gg = string.IsNullOrEmpty(row.gearGradeMax) ? "white" : row.gearGradeMax;
|
||||||
|
tiles.Add(new[] { "cur_gear", Mathf.RoundToInt(drop * 100f) + "%", "gear_" + gg + "_", "장비 ~" + UiKit.GradeKo(gg), "" });
|
||||||
|
const float Gap = 30f;
|
||||||
|
float tx0 = (W - tiles.Count * Tile - (tiles.Count - 1) * Gap) * 0.5f;
|
||||||
|
for (int i = 0; i < tiles.Count; i++)
|
||||||
|
{
|
||||||
|
var tl = tiles[i];
|
||||||
|
float tx = tx0 + i * (Tile + Gap);
|
||||||
|
var cell = UiKit.RewardTile(field, "Tile" + i, tx, y, Tile, tl[2], tl[0], tl[1], tl[2] != "gear_white_");
|
||||||
|
if (tl[4] == "1")
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
var nm = UiKit.Label(field, tl[3], 24, soft, TextAnchor.UpperCenter, new Vector2(0f, 1f), new Vector2(0.5f, 1f), new Vector2(tx + Tile * 0.5f, -y - Tile - 10f), new Vector2(Tile + Gap, 34f), false);
|
||||||
|
nm.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
y += Tile + 64f;
|
||||||
|
|
||||||
|
// 별 조건 3행(별 아이콘 = 지금까지 받은 별 수만큼 켜짐)
|
||||||
|
UiKit.SubTitle(field, "별 조건", Pad, y, W - Pad * 2f);
|
||||||
|
y += 56f;
|
||||||
|
int stars = st != null ? st.stars : 0;
|
||||||
|
string[] cond = { "스테이지 클리어", "아군 전원 생존", (row != null ? row.starTurns : 0) + "턴 이내 클리어" };
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
UiKit.CondRow(field, "Star" + i, Pad, y + i * 64f, W - Pad * 2f, 58f, i < stars ? "star_on" : "star_off", i < stars, cond[i], 28, false, "row_on_field");
|
||||||
|
y += 3 * 64f;
|
||||||
|
if (locked)
|
||||||
|
UiKit.Label(field, "앞 스테이지를 먼저 깨세요", 28, UiKit.Col("alert_red", UiKit.Red), TextAnchor.MiddleCenter, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(Pad, -y), new Vector2(W - Pad * 2f, 40f));
|
||||||
|
else if (stars >= 3)
|
||||||
|
UiKit.Label(field, "별 3 = 소탕 가능(군량만 · 전투 없음)", 26, UiKit.Col("ok", UiKit.Ok), TextAnchor.MiddleCenter, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(Pad, -y), new Vector2(W - Pad * 2f, 40f), false);
|
||||||
|
}
|
||||||
|
|
||||||
bool TryEnter(int si)
|
bool TryEnter(int si)
|
||||||
{
|
{
|
||||||
if (Session.TryPayEntry(Battle.Config.stages[si])) return true;
|
if (Session.TryPayEntry(Battle.Config.stages[si])) return true;
|
||||||
|
|
@ -714,6 +894,14 @@ namespace TKS.OutGame
|
||||||
result.Fill(r);
|
result.Fill(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>결과 「다시」(#1104) — 월드맵이 있으면 같은 노드 재출전(군량 확인) · 없으면 화면 탭과 같음.</summary>
|
||||||
|
public void RetryStage()
|
||||||
|
{
|
||||||
|
if (Battle == null || (Battle.Phase != BattlePhase.StageClear && Battle.Phase != BattlePhase.Defeat)) return;
|
||||||
|
if (Map != null && Map.HasData && Battle.Mode == null) Map.RetryLast();
|
||||||
|
else Battle.ContinueAfterResult();
|
||||||
|
}
|
||||||
|
|
||||||
// ---------- 연무장 전투(PD #1093 C) ----------
|
// ---------- 연무장 전투(PD #1093 C) ----------
|
||||||
|
|
||||||
/// <summary>연무장 모드 전투 시작 — 아웃게임 화면을 닫고 HUD·조작을 켠 뒤 BattleManager.StartMode · 결과 탭 = 연무장 returnPage 로.</summary>
|
/// <summary>연무장 모드 전투 시작 — 아웃게임 화면을 닫고 HUD·조작을 켠 뒤 BattleManager.StartMode · 결과 탭 = 연무장 returnPage 로.</summary>
|
||||||
|
|
|
||||||
|
|
@ -68,19 +68,112 @@ namespace TKS.OutGame
|
||||||
public override void Build()
|
public override void Build()
|
||||||
{
|
{
|
||||||
Tab = 4;
|
Tab = 4;
|
||||||
|
if (UISkin.On) UiKit.Paint(UiKit.Fill("ListBg", Rt), UiKit.Col("list_bg", UiKit.Bg), false); // 목록형 바탕(Fable §5-3)
|
||||||
Header("거래", "뽑기 · 상자 · 상점 · 패스", true);
|
Header("거래", "뽑기 · 상자 · 상점 · 패스", true);
|
||||||
var body = Body();
|
var body = Body();
|
||||||
string[] names = { "영웅·유닛 뽑기", "보물 상자", "상점·패스" };
|
string[] names = { "영웅·유닛 뽑기", "보물 상자", "상점·패스" };
|
||||||
for (int i = 0; i < names.Length; i++)
|
for (int i = 0; i < names.Length; i++)
|
||||||
{
|
{
|
||||||
int k = i;
|
int k = i;
|
||||||
tabs.Add(UiKit.Btn("Tab" + i, body, names[i], 32, UiKit.Paper, UiKit.Ink, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(24f + i * 348f, -18f), new Vector2(332f, 84f), () => SetPage(k)));
|
tabs.Add(UISkin.On
|
||||||
|
? UiKit.SubTab(body, "Tab" + i, names[i], 24f + i * 348f, 18f, 332f, 84f, () => SetPage(k))
|
||||||
|
: UiKit.Btn("Tab" + i, body, names[i], 32, UiKit.Paper, UiKit.Ink, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(24f + i * 348f, -18f), new Vector2(332f, 84f), () => SetPage(k)));
|
||||||
pages.Add(UiKit.Fill("Page" + i, body, 0f, 0f, 118f, 0f));
|
pages.Add(UiKit.Fill("Page" + i, body, 0f, 0f, 118f, 0f));
|
||||||
}
|
}
|
||||||
BuildGacha(pages[0]);
|
if (UISkin.Has("panel_field") && UISkin.Has("btn_l_yellow")) BuildGachaKit(pages[0]);
|
||||||
|
else BuildGacha(pages[0]);
|
||||||
BuildShop(pages[2]);
|
BuildShop(pages[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- 뽑기(Fable 제안서 §4-4 · #1104) ----------
|
||||||
|
|
||||||
|
const float GaugeW = 820f;
|
||||||
|
Text pityBadge;
|
||||||
|
Text tenCost;
|
||||||
|
Text singleCost;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 뽑기 = 배너(틀 유지 · 아래 문양 띠 흰 8 % · 오른쪽 위 「픽업」 뱃지) → 천장 섹션(레벨형 게이지 + 노랑 배지) →
|
||||||
|
/// 확률 섹션(제목 띠 · 행 3 = 별 아이콘 ×n + 바 + % Sen) → 1회(Secondary 하늘 + 보옥 비용) · 10연(Primary 노랑 + 「첫 무료」 꼬리 칩) · 각주 = ⓘ 팝업.
|
||||||
|
/// </summary>
|
||||||
|
void BuildGachaKit(RectTransform p)
|
||||||
|
{
|
||||||
|
var g = S.Db.Gacha;
|
||||||
|
// 배너
|
||||||
|
var banner = UiKit.At(p, "Banner", 24f, 12f, 1032f, 470f);
|
||||||
|
UiKit.Skin(banner, "banner", Color.white);
|
||||||
|
if (UISkin.Has("banner_pattern"))
|
||||||
|
{
|
||||||
|
var pat = UiKit.Skin(UiKit.At(banner, "Pattern", 18f, 470f - 112f, 1032f - 36f, 90f), "banner_pattern", UiKit.Col("banner_pattern", Color.clear));
|
||||||
|
pat.type = Image.Type.Tiled;
|
||||||
|
}
|
||||||
|
UiKit.InfoChip(banner, "Period", 30f, 26f, 220f, 52f, null, "픽업 · 2주", 28);
|
||||||
|
UiKit.Title(UiKit.Label(banner, "영웅·유닛 뽑기", 60, UiKit.White, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(36f, -100f), new Vector2(600f, 90f)), true);
|
||||||
|
UiKit.Label(banner, "모든 영웅·병사 유닛\n= 뽑기로 획득", 32, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.UpperLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(36f, -200f), new Vector2(520f, 110f), false);
|
||||||
|
var free = UiKit.Skin(UiKit.At(banner, "Free", 36f, 470f - 104f, 300f, 64f), "tail", UiKit.Col("tail_red", UiKit.Red));
|
||||||
|
UiKit.Title(UiKit.FillLabel(free.transform, "첫 10연 무료", 30, UiKit.White), true);
|
||||||
|
freeChip = free.gameObject;
|
||||||
|
pickupArt = UiKit.Rect("PickupArt", banner, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-20f, 22f), new Vector2(440f, 420f));
|
||||||
|
var hot = UiKit.Icon(banner, "badge_hot", new Vector2(1f, 1f), new Vector2(0.5f, 0.5f), new Vector2(-34f, -30f), 120f);
|
||||||
|
if (hot != null)
|
||||||
|
{
|
||||||
|
UiKit.DropShadow(hot, 4f);
|
||||||
|
UiKit.Title(UiKit.FillLabel(hot.transform, "픽업", 30, UiKit.White), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 천장 게이지
|
||||||
|
RectTransform pr;
|
||||||
|
var pf = UiKit.SectionPanel(p, "Pity", 24f, 504f, 1032f, 156f, false, false, out pr);
|
||||||
|
UiKit.Title(UiKit.Label(pf, "천장", 34, UiKit.White, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(26f, -12f), new Vector2(200f, 50f)), true);
|
||||||
|
pityText = UiKit.Label(pf, "", 28, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.MiddleRight, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-26f, -12f), new Vector2(620f, 50f), false);
|
||||||
|
pityBar = UiKit.Gauge(pf, "Gauge", 20f, 52f, GaugeW + 60f, "lv_badge_y", "lv_fill", out pityBadge);
|
||||||
|
|
||||||
|
// 확률 공개
|
||||||
|
RectTransform probRoot;
|
||||||
|
var prob = UiKit.SectionPanel(p, "Prob", 24f, 682f, 1032f, 330f, false, false, out probRoot);
|
||||||
|
UiKit.SectionTitle(probRoot, "확률 공개");
|
||||||
|
var info = UiKit.Rect("Info", probRoot, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-16f, -12f), new Vector2(64f, 64f));
|
||||||
|
UiKit.Skin(info, "badge_circle", UiKit.Col("chip_dark", UiKit.Dark), true);
|
||||||
|
var ii = UiKit.Icon(info, "info", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 34f);
|
||||||
|
if (ii == null) UiKit.Title(UiKit.FillLabel(info, "i", 34, UiKit.White), true);
|
||||||
|
info.gameObject.AddComponent<Button>().onClick.AddListener(ShowGachaRules);
|
||||||
|
for (int t = 3; t >= 1; t--)
|
||||||
|
{
|
||||||
|
float y = 84f + (3 - t) * 74f;
|
||||||
|
var row = UiKit.Skin(UiKit.At(prob, "Row" + t, 20f, y, 1032f - 12f - 40f, 62f), "panel12", UiKit.Col("row_on_field", UiKit.Paper)).transform;
|
||||||
|
for (int s = 0; s < t; s++)
|
||||||
|
{
|
||||||
|
var st = UiKit.Icon(row, "star_on", new Vector2(0f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(40f + s * 40f, 0f), 40f);
|
||||||
|
if (st != null) UiKit.DropShadow(st, 2f);
|
||||||
|
}
|
||||||
|
var fill = UiKit.Bar("P" + t, row, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(180f, 0f), new Vector2(500f, 30f), UiKit.Slot, t == 3 ? UiKit.Col("grade_orange_card_bg", UiKit.Coin) : t == 2 ? UiKit.Col("grade_purple_card_bg", UiKit.Purple) : UiKit.Col("grade_blue_card_bg", UiKit.Jade));
|
||||||
|
UiKit.SetBar(fill, g.P(t));
|
||||||
|
var pt = UiKit.Title(UiKit.Label(row, (g.P(t) * 100f).ToString("0.#") + "%", 32, UiKit.White, TextAnchor.MiddleLeft, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(700f, 0f), new Vector2(140f, 50f)), true);
|
||||||
|
pt.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
if (t == 1) UiKit.Label(row, "병사 포함", 24, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.MiddleRight, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-20f, 0f), new Vector2(140f, 40f), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1회 · 10연
|
||||||
|
singleBtn = UiKit.SkinBtn(p, "Single", "btn_sky", UiKit.White, "1회", 42, UiKit.White, 24f, 1046f, 420f, 116f, () => DoDraw(1));
|
||||||
|
singleCost = UiKit.BtnCost(singleBtn, "cur_gem", "", 44f, 36);
|
||||||
|
tenBtn = UiKit.SkinBtn(p, "Ten", "btn_l_yellow", UiKit.White, g.TenCount + "연", 46, UiKit.Col("text_on_yellow", UiKit.Ink), 1056f - 580f, 1040f, 580f, 122f, () => DoDraw(g.TenCount));
|
||||||
|
tenCost = UiKit.BtnCost(tenBtn, "cur_gem", "", 44f, 36);
|
||||||
|
var f2 = UiKit.Skin(UiKit.Rect("Free2", tenBtn.transform, new Vector2(1f, 1f), new Vector2(1f, 0.5f), new Vector2(-14f, 2f), new Vector2(200f, 50f)), "tail", UiKit.Col("tail_red", UiKit.Red));
|
||||||
|
UiKit.Title(UiKit.FillLabel(f2.transform, "첫 무료", 26, UiKit.White), true);
|
||||||
|
freeChip2 = f2.gameObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>뽑기 규칙(구 각주 → ⓘ 팝업 · Fable §4-4).</summary>
|
||||||
|
void ShowGachaRules()
|
||||||
|
{
|
||||||
|
var e = S.Db.Economy;
|
||||||
|
var g = S.Db.Gacha;
|
||||||
|
Root.Modal("뽑기 규칙",
|
||||||
|
"중복 = 영웅 조각\n★★★ " + e.ShardDup(3) + " · ★★ " + e.ShardDup(2) + " · ★ " + e.ShardDup(1) + "\n병사 중복 = 골드 " + e.SoldierDupGold +
|
||||||
|
"\n\n" + g.TenCount + "연 = ★★ 이상 1 보장\n천장 " + g.Pity + "회 = ★★★ 확정\n확률·천장 전부 공개",
|
||||||
|
new OutGameRoot.ModalButton("확인", UiKit.Dark, null));
|
||||||
|
}
|
||||||
|
|
||||||
public void SetPage(int p)
|
public void SetPage(int p)
|
||||||
{
|
{
|
||||||
page = Mathf.Clamp(p, 0, pages.Count - 1);
|
page = Mathf.Clamp(p, 0, pages.Count - 1);
|
||||||
|
|
@ -152,13 +245,26 @@ namespace TKS.OutGame
|
||||||
{
|
{
|
||||||
var g = S.Db.Gacha;
|
var g = S.Db.Gacha;
|
||||||
var d = S.Save;
|
var d = S.Save;
|
||||||
pityText.text = d.gacha.pity + " / " + g.Pity + " · " + g.Pity + "회 ★★★ 확정";
|
|
||||||
UiKit.SetBar(pityBar, d.gacha.pity / (float)Mathf.Max(1, g.Pity));
|
|
||||||
bool free = GachaRules.FirstTenFree(S.Db, d);
|
bool free = GachaRules.FirstTenFree(S.Db, d);
|
||||||
freeChip.SetActive(free);
|
freeChip.SetActive(free);
|
||||||
freeChip2.SetActive(free);
|
freeChip2.SetActive(free);
|
||||||
|
if (pityBadge != null)
|
||||||
|
{
|
||||||
|
pityText.text = d.gacha.pity + " / " + g.Pity + " · " + g.Pity + "회째 ★★★ 확정";
|
||||||
|
pityBadge.text = d.gacha.pity.ToString();
|
||||||
|
UiKit.SetGauge(pityBar, d.gacha.pity / (float)Mathf.Max(1, g.Pity), GaugeW + 60f);
|
||||||
|
singleCost.text = g.CostSingle.ToString("N0");
|
||||||
|
tenCost.text = free ? "무료" : g.CostTen.ToString("N0");
|
||||||
|
var ic = tenCost.transform.parent.GetComponentInChildren<Image>(true);
|
||||||
|
if (ic != null) ic.gameObject.SetActive(!free);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pityText.text = d.gacha.pity + " / " + g.Pity + " · " + g.Pity + "회 ★★★ 확정";
|
||||||
|
UiKit.SetBar(pityBar, d.gacha.pity / (float)Mathf.Max(1, g.Pity));
|
||||||
UiKit.LabelOf(singleBtn).text = "1회\n<size=32>보옥 " + g.CostSingle.ToString("N0") + "</size>";
|
UiKit.LabelOf(singleBtn).text = "1회\n<size=32>보옥 " + g.CostSingle.ToString("N0") + "</size>";
|
||||||
UiKit.LabelOf(tenBtn).text = g.TenCount + "연\n<size=32>" + (free ? "무료" : "보옥 " + g.CostTen.ToString("N0")) + "</size>";
|
UiKit.LabelOf(tenBtn).text = g.TenCount + "연\n<size=32>" + (free ? "무료" : "보옥 " + g.CostTen.ToString("N0")) + "</size>";
|
||||||
|
}
|
||||||
UiKit.Clear(pickupArt);
|
UiKit.Clear(pickupArt);
|
||||||
var picks = new List<HeroDb.Hero>();
|
var picks = new List<HeroDb.Hero>();
|
||||||
foreach (var pe in g.pool)
|
foreach (var pe in g.pool)
|
||||||
|
|
@ -408,8 +514,12 @@ namespace TKS.OutGame
|
||||||
for (int i = 0; i < tabs.Count; i++)
|
for (int i = 0; i < tabs.Count; i++)
|
||||||
{
|
{
|
||||||
bool on = i == page;
|
bool on = i == page;
|
||||||
|
if (UISkin.On) UiKit.SetSubTab(tabs[i], on);
|
||||||
|
else
|
||||||
|
{
|
||||||
tabs[i].GetComponent<Image>().color = on ? UiKit.Red : UiKit.Paper;
|
tabs[i].GetComponent<Image>().color = on ? UiKit.Red : UiKit.Paper;
|
||||||
UiKit.LabelOf(tabs[i]).color = on ? UiKit.White : UiKit.Ink;
|
UiKit.LabelOf(tabs[i]).color = on ? UiKit.White : UiKit.Ink;
|
||||||
|
}
|
||||||
pages[i].gameObject.SetActive(on);
|
pages[i].gameObject.SetActive(on);
|
||||||
}
|
}
|
||||||
if (page == 0) RefreshGacha();
|
if (page == 0) RefreshGacha();
|
||||||
|
|
|
||||||
|
|
@ -242,6 +242,175 @@ namespace TKS.OutGame
|
||||||
s.effectDistance = new Vector2(0f, -d);
|
s.effectDistance = new Vector2(0f, -d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- 공용 부품 ②(Fable 제안서 §4~§5 · 나머지 화면 #1104) ----------
|
||||||
|
|
||||||
|
/// <summary>부모 왼쪽 위 기준 사각(x 오른쪽 · y 아래로).</summary>
|
||||||
|
public static RectTransform At(Transform p, string name, float x, float y, float w, float h)
|
||||||
|
{
|
||||||
|
return Rect(name, p, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(x, -y), new Vector2(w, h));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 스킨 버튼(§5-5 버튼 위계 · Primary btn_l_yellow·btn_l_green·btn_l_red · Secondary btn_sky·btn_s_green·btn_purple · Tertiary round08) —
|
||||||
|
/// 틀 + 틴트 + 글자(제목 폰트 · 밝은 글자만 외곽선 · 팩 버튼 아래 턱만큼 올림) · 왼쪽 위 기준.
|
||||||
|
/// </summary>
|
||||||
|
public static Button SkinBtn(Transform p, string name, string skin, Color tint, string label, int size, Color fg, float x, float y, float w, float h, Action onClick)
|
||||||
|
{
|
||||||
|
var img = Skin(At(p, name, x, y, w, h), skin, tint, true);
|
||||||
|
var b = img.gameObject.AddComponent<Button>();
|
||||||
|
var cb = b.colors;
|
||||||
|
cb.disabledColor = new Color(0.75f, 0.75f, 0.75f, 0.85f);
|
||||||
|
b.colors = cb;
|
||||||
|
if (onClick != null) b.onClick.AddListener(() => onClick());
|
||||||
|
var t = Title(FillLabel(img.transform, label ?? "", size, fg, TextAnchor.MiddleCenter, true, 0f), fg.r + fg.g + fg.b > 2.4f);
|
||||||
|
t.rectTransform.offsetMin = new Vector2(14f, Mathf.Min(12f, h * 0.1f));
|
||||||
|
t.rectTransform.offsetMax = new Vector2(-14f, 0f);
|
||||||
|
t.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>버튼 글자 옆 비용(§5-5 「비용 = 아이콘 + 숫자 Sen」) — 글자 · 아이콘 · 숫자를 가운데 한 줄로 · 반환 = 숫자 글자.</summary>
|
||||||
|
public static Text BtnCost(Button b, string icon, string num, float iconSize, int numSize)
|
||||||
|
{
|
||||||
|
var label = LabelOf(b);
|
||||||
|
var lrt = label.rectTransform;
|
||||||
|
var row = Fill("Row", b.transform, lrt.offsetMin.x, -lrt.offsetMax.x, 0f, lrt.offsetMin.y);
|
||||||
|
var hl = row.gameObject.AddComponent<HorizontalLayoutGroup>();
|
||||||
|
hl.childAlignment = TextAnchor.MiddleCenter;
|
||||||
|
hl.spacing = 8f;
|
||||||
|
hl.childControlWidth = true; // 글자 = 선호 폭 · 아이콘 = LayoutElement 폭
|
||||||
|
hl.childControlHeight = false;
|
||||||
|
hl.childForceExpandWidth = hl.childForceExpandHeight = false;
|
||||||
|
label.transform.SetParent(row, false);
|
||||||
|
float rh = row.rect.height > 1f ? row.rect.height : 80f;
|
||||||
|
label.rectTransform.anchorMin = label.rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
|
||||||
|
label.rectTransform.sizeDelta = new Vector2(Mathf.Ceil(label.preferredWidth), rh);
|
||||||
|
var ic = Icon(row, icon, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, iconSize);
|
||||||
|
if (ic != null)
|
||||||
|
{
|
||||||
|
DropShadow(ic, 3f);
|
||||||
|
var le = ic.gameObject.AddComponent<LayoutElement>();
|
||||||
|
le.minWidth = le.preferredWidth = iconSize;
|
||||||
|
}
|
||||||
|
var n = Title(Label(row, num, numSize, label.color, TextAnchor.MiddleLeft, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(80f, rh)), label.color.r + label.color.g + label.color.b > 2.4f);
|
||||||
|
n.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>서브탭(§5-5 · Button_Round10 + 윗면 광택 · 선택 tab_focus / 꺼짐 subtab_off · 32 흰 외곽선) · 왼쪽 위 기준.</summary>
|
||||||
|
public static Button SubTab(Transform p, string name, string label, float x, float y, float w, float h, Action onClick)
|
||||||
|
{
|
||||||
|
var img = Skin(At(p, name, x, y, w, h), UISkin.Has("subtab") ? "subtab" : "button", Col("subtab_off", Paper), true);
|
||||||
|
var b = img.gameObject.AddComponent<Button>();
|
||||||
|
if (onClick != null) b.onClick.AddListener(() => onClick());
|
||||||
|
Title(FillLabel(img.transform, label, 32, White, TextAnchor.MiddleCenter, true, 8f), true);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetSubTab(Button b, bool on)
|
||||||
|
{
|
||||||
|
b.GetComponent<Image>().color = on ? Col("tab_focus", Red) : Col("subtab_off", Paper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>레벨형 게이지(§4-4 · Slider_Level02 바탕 + 채움 틴트 + 왼쪽 배지 · 영웅 상세 수치) · 반환 = 채움(SetGauge) · 배지 글자 = out.</summary>
|
||||||
|
public static RectTransform Gauge(Transform p, string name, float x, float y, float w, string badge, string fillColor, out Text badgeText)
|
||||||
|
{
|
||||||
|
var root = At(p, name, x, y, w + 86f, 96f);
|
||||||
|
Skin(At(root, "Bg", 86f, 21f, w, 54f), "lv_bg", White);
|
||||||
|
var fill = At(root, "Fill", 96f, 27f, w - 20f, 38f);
|
||||||
|
Skin(fill, "lv_fill", Col(fillColor, Coin));
|
||||||
|
var bi = Icon(root, badge, new Vector2(0f, 1f), new Vector2(0f, 1f), Vector2.zero, 96f);
|
||||||
|
if (bi != null) DropShadow(bi, 3f);
|
||||||
|
badgeText = Title(Label(root, "", 34, White, TextAnchor.MiddleCenter, new Vector2(0f, 1f), new Vector2(0.5f, 0.5f), new Vector2(46f, -46f), new Vector2(92f, 60f)), true);
|
||||||
|
badgeText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
return fill;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetGauge(RectTransform fill, float v, float w)
|
||||||
|
{
|
||||||
|
v = Mathf.Clamp01(v);
|
||||||
|
fill.sizeDelta = new Vector2(Mathf.Max(18f, (w - 20f) * v), fill.sizeDelta.y);
|
||||||
|
fill.gameObject.SetActive(v > 0.001f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>정보 칩(§5-6 · Oval46 chip_dark · 좌 아이콘 + 글자 Sen) · 왼쪽 위 기준 · 반환 = 글자.</summary>
|
||||||
|
public static Text InfoChip(Transform p, string name, float x, float y, float w, float h, string icon, string text, int size)
|
||||||
|
{
|
||||||
|
var chip = Skin(At(p, name, x, y, w, h), "chip", Col("chip_dark", Dark));
|
||||||
|
float lx = 20f;
|
||||||
|
if (!string.IsNullOrEmpty(icon))
|
||||||
|
{
|
||||||
|
float s = Mathf.Min(h + 6f, 48f);
|
||||||
|
var ic = Icon(chip.transform, icon, new Vector2(0f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(h * 0.5f + 2f, 0f), s);
|
||||||
|
if (ic != null)
|
||||||
|
{
|
||||||
|
DropShadow(ic, 3f);
|
||||||
|
lx = h + 8f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var t = Title(Label(chip.transform, text, size, White, TextAnchor.MiddleCenter, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(lx, 2f), new Vector2(w - lx - 16f, h)), true);
|
||||||
|
t.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>수량 칩(§4-2 · 칸 오른쪽 아래에 걸친 Oval46 · 글자 Sen 흰 외곽선) · 폭 = 글자에 맞춤.</summary>
|
||||||
|
public static Text QtyChip(Transform cell, string qty, int size)
|
||||||
|
{
|
||||||
|
float h = size + 12f;
|
||||||
|
var chip = Skin(Rect("Qty", cell, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(8f, -8f), new Vector2(60f, h)), "chip", Col("chip_dark", Dark));
|
||||||
|
var t = Title(FillLabel(chip.transform, qty, size, White, TextAnchor.MiddleCenter, true, 0f), true);
|
||||||
|
t.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
chip.rectTransform.sizeDelta = new Vector2(Mathf.Max(h + 8f, Mathf.Ceil(t.preferredWidth) + 30f), h);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>보상 타일(§4-2 · ItemFrame 5층 + 아이콘 68 % + 수량 칩) · prefix = 칸 색(gear_white_ · gear_<등급>_ …) · 왼쪽 위 기준.</summary>
|
||||||
|
public static RectTransform RewardTile(Transform p, string name, float x, float y, float size, string prefix, string icon, string qty, bool lit)
|
||||||
|
{
|
||||||
|
var cell = At(p, name, x, y, size, size);
|
||||||
|
ItemSlot(cell, prefix, lit);
|
||||||
|
var ic = Icon(cell, icon, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 4f), size * 0.68f);
|
||||||
|
DropShadow(ic, 4f);
|
||||||
|
if (!string.IsNullOrEmpty(qty)) QtyChip(cell, qty, size >= 120f ? 30 : 24);
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>조건·정보 행(§4-2 · BasicFrame_Round12 panel_field · 좌 아이콘(tint = 켜짐 ok · 꺼짐 disabled) + 글자) · 왼쪽 위 기준 · icon null = 아이콘 없음.</summary>
|
||||||
|
public static Text CondRow(Transform p, string name, float x, float y, float w, float h, string icon, bool on, string text, int size, bool tint = true, string plate = "panel_field")
|
||||||
|
{
|
||||||
|
var row = Skin(At(p, name, x, y, w, h), "panel12", Col(plate, Dark));
|
||||||
|
float lx = 24f;
|
||||||
|
if (!string.IsNullOrEmpty(icon))
|
||||||
|
{
|
||||||
|
var ic = Icon(row.transform, icon, new Vector2(0f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(h * 0.5f + 6f, 0f), Mathf.Min(40f, h - 16f));
|
||||||
|
if (ic != null)
|
||||||
|
{
|
||||||
|
if (tint) ic.color = on ? Col("ok", Ok) : Col("disabled", Disabled);
|
||||||
|
DropShadow(ic, 2f);
|
||||||
|
lx = h + 12f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var t = Label(row.transform, text, size, on ? White : Col("text_soft", InkSoft), TextAnchor.MiddleLeft, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(lx, 0f), new Vector2(w - lx - 20f, h), false);
|
||||||
|
t.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>구역 소제목(§5-2 · Title_Line01_Divider 좌·우 + 글자 32 흰 외곽선) · x·y = 왼쪽 위 · w = 전체 폭.</summary>
|
||||||
|
public static Text SubTitle(Transform p, string text, float x, float y, float w, int size = 32)
|
||||||
|
{
|
||||||
|
var box = At(p, "Sub_" + text, x, y, w, 44f);
|
||||||
|
var t = Title(FillLabel(box, text, size, White, TextAnchor.MiddleCenter, true, 0f), true);
|
||||||
|
t.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
float tw = Mathf.Ceil(t.preferredWidth);
|
||||||
|
float lw = Mathf.Max(0f, (w - tw) * 0.5f - 18f);
|
||||||
|
if (lw > 0f && UISkin.Has("title_divider_l") && UISkin.Has("title_divider_r"))
|
||||||
|
{
|
||||||
|
Skin(Rect("L", box, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), Vector2.zero, new Vector2(lw, 30f)), "title_divider_l", Col("divider", White));
|
||||||
|
Skin(Rect("R", box, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), Vector2.zero, new Vector2(lw, 30f)), "title_divider_r", Col("divider", White));
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>아이콘(테마 id · 없으면 null).</summary>
|
/// <summary>아이콘(테마 id · 없으면 null).</summary>
|
||||||
public static Image Icon(Transform parent, string id, Vector2 anchor, Vector2 pivot, Vector2 pos, float size)
|
public static Image Icon(Transform parent, string id, Vector2 anchor, Vector2 pivot, Vector2 pos, float size)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace TKS.OutGame
|
||||||
|
{
|
||||||
|
/// <summary>등장 튀김(Fable 제안서 §4-2 「별 0.15 s 간격 scale 1.4→1」) — 켜질 때마다 delay 뒤 from → 1 · 시간 = 실시간(일시정지 무관).</summary>
|
||||||
|
public class UiPop : MonoBehaviour
|
||||||
|
{
|
||||||
|
public float delay;
|
||||||
|
public float from = 1.4f;
|
||||||
|
public float duration = 0.18f;
|
||||||
|
float t0;
|
||||||
|
|
||||||
|
void OnEnable()
|
||||||
|
{
|
||||||
|
Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Play()
|
||||||
|
{
|
||||||
|
t0 = Time.unscaledTime + delay;
|
||||||
|
transform.localScale = Vector3.zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
float t = Time.unscaledTime - t0;
|
||||||
|
if (t < 0f)
|
||||||
|
{
|
||||||
|
transform.localScale = Vector3.zero;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float k = duration > 0f ? Mathf.Clamp01(t / duration) : 1f;
|
||||||
|
transform.localScale = Vector3.one * Mathf.Lerp(from, 1f, 1f - (1f - k) * (1f - k));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a10e083dddf226e45ad2599ec94edf66
|
||||||
|
|
@ -24,6 +24,9 @@ namespace TKS
|
||||||
CameraController camCtrl;
|
CameraController camCtrl;
|
||||||
RangeIndicator range;
|
RangeIndicator range;
|
||||||
|
|
||||||
|
/// <summary>결과 화면 탭(= 계속) 을 건너뛸 자리인가(화면 좌표) — 결과 패널 「다시」 버튼 위(#1104).</summary>
|
||||||
|
public System.Func<Vector2, bool> HoldResultTap;
|
||||||
|
|
||||||
Unit selected;
|
Unit selected;
|
||||||
bool dragging;
|
bool dragging;
|
||||||
bool panning;
|
bool panning;
|
||||||
|
|
@ -130,7 +133,7 @@ namespace TKS
|
||||||
var phase = battle.Phase;
|
var phase = battle.Phase;
|
||||||
if (phase == BattlePhase.StageClear || phase == BattlePhase.Defeat)
|
if (phase == BattlePhase.StageClear || phase == BattlePhase.Defeat)
|
||||||
{
|
{
|
||||||
if (Input.GetMouseButtonDown(0)) battle.ContinueAfterResult();
|
if (Input.GetMouseButtonDown(0) && (HoldResultTap == null || !HoldResultTap(Input.mousePosition))) battle.ContinueAfterResult();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -266,6 +266,8 @@ namespace TKS
|
||||||
Text popupGoLabel;
|
Text popupGoLabel;
|
||||||
Button popupSweep;
|
Button popupSweep;
|
||||||
Text popupSweepLabel;
|
Text popupSweepLabel;
|
||||||
|
RectTransform popupField;
|
||||||
|
Text popupCost;
|
||||||
int popupNode = -1;
|
int popupNode = -1;
|
||||||
RectTransform bannerRt;
|
RectTransform bannerRt;
|
||||||
RectTransform prevRt;
|
RectTransform prevRt;
|
||||||
|
|
@ -275,6 +277,10 @@ namespace TKS
|
||||||
// ---------- 아웃게임 연결(2026-11-05 #1093 · OutGame/OutGameRoot 가 채움 · 비면 기존 동작) ----------
|
// ---------- 아웃게임 연결(2026-11-05 #1093 · OutGame/OutGameRoot 가 채움 · 비면 기존 동작) ----------
|
||||||
/// <summary>스테이지 인덱스 → 팝업 추가 줄(군량 · 보상 · 별).</summary>
|
/// <summary>스테이지 인덱스 → 팝업 추가 줄(군량 · 보상 · 별).</summary>
|
||||||
public Func<int, string> PopupInfo;
|
public Func<int, string> PopupInfo;
|
||||||
|
/// <summary>스테이지 팝업 본문 그리기(스테이지 인덱스 · 잠김 · 필드) — 있으면 글자 본문 대신(Fable 제안서 §4-3 · #1104).</summary>
|
||||||
|
public Action<int, bool, RectTransform> PopupFill;
|
||||||
|
/// <summary>출전 군량(스테이지 인덱스) — 출정 버튼 비용 칩.</summary>
|
||||||
|
public Func<int, int> CostOf;
|
||||||
/// <summary>출전 직전(군량 지불) · false = 출전 안 함(부족 안내는 연결한 쪽이 띄움).</summary>
|
/// <summary>출전 직전(군량 지불) · false = 출전 안 함(부족 안내는 연결한 쪽이 띄움).</summary>
|
||||||
public Func<int, bool> TryEnter;
|
public Func<int, bool> TryEnter;
|
||||||
/// <summary>깬 노드 별 수(0~3) · null 이면 깬 노드 = 별 전부.</summary>
|
/// <summary>깬 노드 별 수(0~3) · null 이면 깬 노드 = 별 전부.</summary>
|
||||||
|
|
@ -639,9 +645,26 @@ namespace TKS
|
||||||
if (st == NodeState.Lock) body.Append("\n\n잠긴 스테이지 — 앞 스테이지를 먼저 깨세요");
|
if (st == NodeState.Lock) body.Append("\n\n잠긴 스테이지 — 앞 스테이지를 먼저 깨세요");
|
||||||
popupBody.text = body.ToString();
|
popupBody.text = body.ToString();
|
||||||
popupGo.interactable = st != NodeState.Lock;
|
popupGo.interactable = st != NodeState.Lock;
|
||||||
popupGoLabel.text = st == NodeState.Clear ? "다시 출전" : "출전";
|
|
||||||
bool sweep = st == NodeState.Clear && CanSweep != null && Sweep != null && CanSweep(si);
|
bool sweep = st == NodeState.Clear && CanSweep != null && Sweep != null && CanSweep(si);
|
||||||
popupSweep.gameObject.SetActive(sweep);
|
popupSweep.gameObject.SetActive(sweep);
|
||||||
|
if (popupField != null && PopupFill != null)
|
||||||
|
{
|
||||||
|
// 팩 팝업(#1104): 본문 = 필드 안 그림 · 출정(붉은 Primary + 군량 비용) · 소탕(녹 Secondary) 왼쪽
|
||||||
|
popupBody.gameObject.SetActive(false);
|
||||||
|
popupField.gameObject.SetActive(true);
|
||||||
|
foreach (Transform c in popupField) c.gameObject.SetActive(false);
|
||||||
|
for (int i = popupField.childCount - 1; i >= 0; i--) Destroy(popupField.GetChild(i).gameObject);
|
||||||
|
PopupFill(si, st == NodeState.Lock, popupField);
|
||||||
|
popupGoLabel.text = st == NodeState.Lock ? "잠김" : st == NodeState.Clear ? "다시 출정" : "출정";
|
||||||
|
if (popupCost != null) popupCost.text = CostOf != null ? CostOf(si).ToString() : "";
|
||||||
|
((RectTransform)popupGo.transform).anchoredPosition = new Vector2(sweep ? 390f : 240f, -PopupBtnY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
popupBody.gameObject.SetActive(true);
|
||||||
|
if (popupField != null) popupField.gameObject.SetActive(false);
|
||||||
|
popupGoLabel.text = st == NodeState.Clear ? "다시 출전" : "출전";
|
||||||
|
}
|
||||||
popup.SetActive(true);
|
popup.SetActive(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -686,6 +709,17 @@ namespace TKS
|
||||||
battle.StartStage(si);
|
battle.StartStage(si);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>결과 화면 「다시」(#1104) — 결과 처리(진행 기록 · 월드맵 복귀)를 한 뒤 같은 노드로 다시 출전 · 군량이 모자라면 월드맵에 남음(충전 팝업).</summary>
|
||||||
|
public void RetryLast()
|
||||||
|
{
|
||||||
|
int ch = entryChapter >= 0 ? entryChapter : chapter;
|
||||||
|
int node = entryNode;
|
||||||
|
battle.ContinueAfterResult();
|
||||||
|
if (node < 0 || !HasData) return;
|
||||||
|
if (TryEnter != null && !TryEnter(StageIndexOf(ch, node))) return;
|
||||||
|
EnterStage(ch, node);
|
||||||
|
}
|
||||||
|
|
||||||
void OnBattleResult(bool win)
|
void OnBattleResult(bool win)
|
||||||
{
|
{
|
||||||
int ch = entryChapter >= 0 ? entryChapter : chapter;
|
int ch = entryChapter >= 0 ? entryChapter : chapter;
|
||||||
|
|
@ -725,6 +759,11 @@ namespace TKS
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 팩 스테이지 팝업 배치(UI px · 패널 왼쪽 위 기준 · #1104)
|
||||||
|
const float PopupW = 900f;
|
||||||
|
const float PopupH = 1160f;
|
||||||
|
const float PopupBtnY = PopupH - 32f - 104f;
|
||||||
|
|
||||||
void BuildPopup()
|
void BuildPopup()
|
||||||
{
|
{
|
||||||
var dim = Img("Popup", root.transform, null, Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f), Vector2.zero, Vector2.zero);
|
var dim = Img("Popup", root.transform, null, Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f), Vector2.zero, Vector2.zero);
|
||||||
|
|
@ -764,6 +803,25 @@ namespace TKS
|
||||||
popupBody.rectTransform.sizeDelta = new Vector2(800f, pack ? 640f : 720f);
|
popupBody.rectTransform.sizeDelta = new Vector2(800f, pack ? 640f : 720f);
|
||||||
popupBody.horizontalOverflow = HorizontalWrapMode.Wrap;
|
popupBody.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||||
popupBody.supportRichText = true;
|
popupBody.supportRichText = true;
|
||||||
|
if (pack && UISkin.Has("panel_field") && UISkin.Has("btn_l_red"))
|
||||||
|
{
|
||||||
|
// Fable 제안서 §4-3(#1104): 팝업 900×1160 · 본문 필드(panel_field 인셋 20) · 출정 = 붉은 Primary 420×104 + 군량 비용 · 소탕 = 녹 Secondary · 닫기 = X 만
|
||||||
|
panel.rectTransform.sizeDelta = new Vector2(PopupW, PopupH);
|
||||||
|
var field = Img("Field", panel.transform, null, Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f), Vector2.zero, Vector2.zero);
|
||||||
|
UISkin.Apply(field, "panel_field");
|
||||||
|
field.color = UISkin.Col("panel_field", Ink);
|
||||||
|
field.rectTransform.offsetMin = new Vector2(20f, PopupH - PopupBtnY + 16f);
|
||||||
|
field.rectTransform.offsetMax = new Vector2(-20f, -166f);
|
||||||
|
popupField = field.rectTransform;
|
||||||
|
popupGo = TKS.OutGame.UiKit.SkinBtn(panel.transform, "Go", "btn_l_red", UISkin.Col("red", new Color(0.89f, 0.33f, 0.23f)), "출정", 46, Color.white, 240f, PopupBtnY, 420f, 104f, ConfirmPopup);
|
||||||
|
popupGoLabel = TKS.OutGame.UiKit.LabelOf(popupGo);
|
||||||
|
popupCost = TKS.OutGame.UiKit.BtnCost(popupGo, "cur_stamina", "", 44f, 38);
|
||||||
|
popupSweep = TKS.OutGame.UiKit.SkinBtn(panel.transform, "Sweep", "btn_s_green", Color.white, "소탕", 40, Color.white, 90f, PopupBtnY + 4f, 280f, 100f, OnSweepClicked);
|
||||||
|
popupSweepLabel = TKS.OutGame.UiKit.LabelOf(popupSweep);
|
||||||
|
popupSweep.gameObject.SetActive(false);
|
||||||
|
popup.SetActive(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
popupGo = WideButton("Go", panel.transform, "출전", new Vector2(-180f, 80f), UISkin.Col("red", new Color(0.89f, 0.33f, 0.23f)), ConfirmPopup, out popupGoLabel);
|
popupGo = WideButton("Go", panel.transform, "출전", new Vector2(-180f, 80f), UISkin.Col("red", new Color(0.89f, 0.33f, 0.23f)), ConfirmPopup, out popupGoLabel);
|
||||||
Text closeLabel;
|
Text closeLabel;
|
||||||
WideButton("Close", panel.transform, "닫기", new Vector2(180f, 80f), UISkin.Col("dark", new Color(0.6f, 0.55f, 0.5f)), ClosePopup, out closeLabel);
|
WideButton("Close", panel.transform, "닫기", new Vector2(180f, 80f), UISkin.Col("dark", new Color(0.6f, 0.55f, 0.5f)), ClosePopup, out closeLabel);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue