using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace TKS.OutGame { /// 영웅·병사 카드(2줄 · 기획 S12 v4) — 좌 초상(★ 는 초상 아래) · 1줄 = 병종 배지 · Lv · 출전 중 · 2줄 = 이름. public static class HeroCards { public static Image Card(Transform content, OutGameSession s, HeroDb.Hero h, bool deployed, bool owned, System.Action onTap) { var cell = UiKit.Cell(content, "Card_" + h.id, owned ? UiKit.Paper : new Color(0.86f, 0.84f, 0.8f), onTap); UiKit.Border(cell, deployed ? UiKit.Red : UiKit.Line, deployed ? 4f : 2f); var lv = s.Save.Level(h.id); var hs = s.Save.Hero(h.id); UiKit.Portrait("Face", cell.transform, h, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(12f, 8f), new Vector2(116f, 108f), false, 2f, new Color(0.9f, 0.86f, 0.8f)); int star = hs != null ? hs.star : h.rarity; UiKit.Label(cell.transform, UiKit.Stars(star, star), 22, UiKit.Star, TextAnchor.MiddleCenter, new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(12f, 2f), new Vector2(116f, 30f)); UiKit.TypeBadge(cell.transform, h.type, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(142f, -16f), 40f); UiKit.Label(cell.transform, owned ? "Lv " + (lv != null ? lv.lv : 1) : "미보유", 30, UiKit.Ink, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(204f, -12f), new Vector2(150f, 48f)); if (deployed) { var b = UiKit.Box("Deployed", cell.transform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-12f, -14f), new Vector2(124f, 44f), UiKit.Red); UiKit.FillLabel(b.transform, "출전 중", 24, UiKit.White); } if (hs != null) { var g = UiKit.Box("Grade", cell.transform, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-12f, 14f), new Vector2(56f, 40f), UiKit.GradeColor(hs.grade)); UiKit.FillLabel(g.transform, UiKit.GradeKo(hs.grade), 24, UiKit.White); } var name = UiKit.Label(cell.transform, h.nameKo, 44, owned ? UiKit.Ink : UiKit.InkSoft, TextAnchor.MiddleLeft, new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(142f, 12f), new Vector2(290f, 66f)); name.horizontalOverflow = HorizontalWrapMode.Overflow; if (owned && s.CanGrowAny(h.id)) UiKit.Dot("New", cell.transform, new Vector2(0f, 1f), new Vector2(0.5f, 0.5f), new Vector2(14f, -10f), 26f, UiKit.Red); return cell; } } /// 영웅 탭 = 보유 영웅·병사 목록(장수|병사 · 2줄 카드) → 탭 = 영웅 상세 · 도감. public class HeroListScreen : OutGameScreen { bool soldiers; RectTransform content; ScrollRect scroll; Button tabHero; Button tabSoldier; public bool ShowingSoldiers { get { return soldiers; } } public override void Build() { Tab = 0; Header("영웅", "레벨 · 승급 · 진화 · 스킬", true); var body = Body(); tabHero = UiKit.Btn("TabHero", body, "장수", 36, UiKit.Red, UiKit.White, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(24f, -20f), new Vector2(220f, 84f), () => SetFilter(false)); tabSoldier = UiKit.Btn("TabSoldier", body, "병사", 36, UiKit.Paper, UiKit.Ink, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(258f, -20f), new Vector2(220f, 84f), () => SetFilter(true)); UiKit.Btn("Codex", body, "도감", 36, UiKit.Dark, UiKit.White, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-24f, -20f), new Vector2(220f, 84f), () => HeroDetailScreen.ShowCodex(Root)); content = UiKit.ScrollGrid("List", body, 24f, 24f, 124f, 16f, new Vector2(506f, 150f), new Vector2(20f, 18f), 2, out scroll); } public void SetFilter(bool soldier) { soldiers = soldier; Refresh(); } public override void Refresh() { tabHero.GetComponent().color = soldiers ? UiKit.Paper : UiKit.Red; UiKit.LabelOf(tabHero).color = soldiers ? UiKit.Ink : UiKit.White; tabSoldier.GetComponent().color = soldiers ? UiKit.Red : UiKit.Paper; UiKit.LabelOf(tabSoldier).color = soldiers ? UiKit.White : UiKit.Ink; UiKit.LabelOf(tabHero).text = "장수 " + S.Owned(false).Count; UiKit.LabelOf(tabSoldier).text = "병사 " + S.Owned(true).Count; UiKit.Clear(content); foreach (var h in S.Owned(soldiers)) { var id = h.id; HeroCards.Card(content, S, h, S.InActivePreset(id), true, () => Root.ShowHero(id)); } } public int CardCount { get { return content.childCount; } } } /// /// 영웅 상세(img06 · 기획 S6 v4) — 전투력 · 일러 + 양옆 장비 6칸(빈 칸 탭 = 가방에서 장착 · 1칸 = 1강) · 이름 띠(병종 · 이름 · ★) · /// 스킬 정보(액티브·패시브 = 이름·효과·Lv·쿨 · 표시만 · 스킬 레벨업 = B 단계) · Lv/경험 바 + 레벨업(골드) · 승급(6칸) · 조각 바 + 진화 · 상세정보 · 도감 · ◀ ▶ 전환. /// public class HeroDetailScreen : OutGameScreen { string id; readonly List order = new List(); Text power; RectTransform art; readonly Image[] slotImg = new Image[6]; readonly Text[] slotName = new Text[6]; readonly Text[] slotState = new Text[6]; Image typeDot; Text typeMark; Text nameText; Text subText; Text starText; Text[] skillName = new Text[2]; Text[] skillDesc = new Text[2]; Text[] skillChip = new Text[2]; Text lvText; Text expText; RectTransform expBar; Button levelBtn; Button promoteBtn; Text shardText; RectTransform shardBar; Button evolveBtn; Button skillBtn; public string HeroId { get { return id; } } public void Select(string heroId) { id = heroId; var h = S.Def(heroId); order.Clear(); if (h != null) foreach (var o in S.Owned(h.isSoldier)) order.Add(o.id); } public override void Build() { Tab = 0; Header("영웅", "레벨 · 승급 · 진화 · 스킬", true); var body = Body(); // ① 카드: 전투력 · 일러 · 장비 6칸 · 이름 띠 var card = UiKit.TopBand("Card", body, 16f, 720f, 24f, 24f); var cimg = UiKit.Paint(card, UiKit.Paper); UiKit.Border(cimg, UiKit.Line, 3f); UiKit.Dot("Halo", card, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -100f), 500f, new Color(0.93f, 0.9f, 0.84f)); power = UiKit.Label(card, "", 44, UiKit.Ink, TextAnchor.MiddleCenter, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -16f), new Vector2(560f, 70f)); UiKit.Btn("Prev", card, "◀", 40, UiKit.Dark, UiKit.White, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(20f, -16f), new Vector2(96f, 72f), () => Step(-1)); UiKit.Btn("Next", card, "▶", 40, UiKit.Dark, UiKit.White, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-20f, -16f), new Vector2(96f, 72f), () => Step(1)); art = UiKit.Rect("Art", card, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -96f), new Vector2(560f, 500f)); for (int i = 0; i < 6; i++) { int k = i; bool left = i < 3; int row = i % 3; var a = left ? new Vector2(0f, 1f) : new Vector2(1f, 1f); var b = UiKit.Btn("Slot" + i, card, "", 24, UiKit.Slot, UiKit.Ink, a, a, new Vector2(left ? 22f : -22f, -104f - row * 172f), new Vector2(196f, 156f), () => OnSlot(k)); slotImg[i] = b.GetComponent(); UiKit.LabelOf(b).text = ""; slotName[i] = UiKit.Label(b.transform, "", 30, UiKit.Ink, TextAnchor.MiddleCenter, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -12f), new Vector2(186f, 84f)); slotState[i] = UiKit.Label(b.transform, "", 24, UiKit.InkSoft, TextAnchor.MiddleCenter, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 10f), new Vector2(186f, 44f), false); } var band = UiKit.Rect("NameBand", card, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), Vector2.zero, new Vector2(0f, 116f)); band.anchorMin = new Vector2(0f, 0f); band.anchorMax = new Vector2(1f, 0f); band.offsetMin = new Vector2(0f, 0f); band.offsetMax = new Vector2(0f, 116f); UiKit.Paint(band, UiKit.Dark); typeDot = UiKit.Dot("TypeDot", band, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(24f, 0f), 80f, UiKit.Red); typeMark = UiKit.FillLabel(typeDot.transform, "", 40, UiKit.White); nameText = UiKit.Label(band, "", 60, UiKit.White, TextAnchor.MiddleLeft, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(124f, 4f), new Vector2(300f, 90f)); nameText.horizontalOverflow = HorizontalWrapMode.Overflow; subText = UiKit.Label(band, "", 28, new Color(0.85f, 0.8f, 0.75f), TextAnchor.MiddleLeft, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(420f, 0f), new Vector2(330f, 80f), false); starText = UiKit.Label(band, "", 52, UiKit.Star, TextAnchor.MiddleRight, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-24f, 0f), new Vector2(300f, 80f)); // ② 스킬 정보 var skill = UiKit.TopBand("Skill", body, 752f, 400f, 24f, 24f); var simg = UiKit.Paint(skill, UiKit.Paper); UiKit.Border(simg, UiKit.Line, 3f); UiKit.Label(skill, "스킬", 40, UiKit.Ink, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(28f, -14f), new Vector2(300f, 60f)); UiKit.Label(skill, "액티브 1 · 패시브 1", 26, UiKit.InkSoft, TextAnchor.MiddleRight, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-28f, -14f), new Vector2(400f, 60f), false); for (int i = 0; i < 2; i++) { var c = UiKit.TopBand("Skill" + i, skill, 86f + i * 152f, 140f, 20f, 20f); var ci = UiKit.Paint(c, new Color(0.98f, 0.96f, 0.9f)); UiKit.Border(ci, UiKit.Line, 2f); var d = UiKit.Dot("Kind", c, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(18f, 0f), 92f, i == 0 ? UiKit.Red : UiKit.Dark); UiKit.FillLabel(d.transform, i == 0 ? "액" : "패", 40, UiKit.White); skillName[i] = UiKit.Label(c, "", 34, UiKit.Ink, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(128f, -8f), new Vector2(560f, 56f)); skillName[i].horizontalOverflow = HorizontalWrapMode.Overflow; skillDesc[i] = UiKit.Label(c, "", 26, UiKit.InkSoft, TextAnchor.UpperLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(128f, -64f), new Vector2(840f, 72f), false); var chip = UiKit.Box("Chip", c, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-14f, -12f), new Vector2(240f, 46f), i == 0 ? UiKit.Red : UiKit.Dark); skillChip[i] = UiKit.FillLabel(chip.transform, "", 24, UiKit.White); } // ③ 레벨 · 승급 var lvRow = UiKit.TopBand("Level", body, 1168f, 110f, 24f, 24f); lvText = UiKit.Label(lvRow, "", 42, UiKit.Ink, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(4f, 0f), new Vector2(330f, 60f)); lvText.horizontalOverflow = HorizontalWrapMode.Overflow; expText = UiKit.Label(lvRow, "", 28, UiKit.Ink, TextAnchor.MiddleRight, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(330f, 0f), new Vector2(230f, 60f)); expBar = UiKit.Bar("ExpBar", lvRow, new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(4f, 10f), new Vector2(556f, 30f), new Color(0.86f, 0.82f, 0.75f), new Color(0.47f, 0.38f, 0.32f)); levelBtn = UiKit.Btn("LevelUp", lvRow, "", 30, UiKit.Red, UiKit.White, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-252f, 0f), new Vector2(204f, 106f), OnLevelUp); promoteBtn = UiKit.Btn("Promote", lvRow, "", 30, UiKit.Disabled, UiKit.White, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(0f, 0f), new Vector2(236f, 106f), OnPromote); // ④ 조각 · 진화 var shRow = UiKit.TopBand("Shard", body, 1290f, 96f, 24f, 24f); var sd = UiKit.Dot("ShardDot", shRow, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(0f, -14f), 54f, UiKit.Purple); UiKit.FillLabel(sd.transform, "조", 28, UiKit.White); UiKit.Label(shRow, "영웅 조각", 32, UiKit.Ink, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(64f, 0f), new Vector2(300f, 46f)); shardBar = UiKit.Bar("ShardBar", shRow, new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(64f, 4f), new Vector2(690f, 42f), new Color(0.86f, 0.82f, 0.75f), UiKit.Purple); shardText = UiKit.Label(shardBar.parent, "", 28, UiKit.Ink, TextAnchor.MiddleCenter, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(680f, 42f)); evolveBtn = UiKit.Btn("Evolve", shRow, "", 30, UiKit.Red, UiKit.White, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(0f, 0f), new Vector2(236f, 96f), OnEvolve); // ⑤ 상세정보 · 도감 · 스킬 레벨업(B) var btnRow = UiKit.TopBand("Buttons", body, 1402f, 96f, 24f, 24f); float bw = (1032f - 40f) / 3f; UiKit.Btn("Detail", btnRow, "상세정보", 36, UiKit.Dark, UiKit.White, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), Vector2.zero, new Vector2(bw, 96f), ShowStats); UiKit.Btn("Codex", btnRow, "도감", 36, UiKit.Dark, UiKit.White, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(bw, 96f), () => ShowCodex(Root)); skillBtn = UiKit.Btn("SkillUp", btnRow, "스킬 레벨업\nB 단계(준비 중)", 32, UiKit.Red, UiKit.White, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), Vector2.zero, new Vector2(bw, 96f), null); skillBtn.interactable = false; } void Step(int d) { if (order.Count == 0) return; int i = Mathf.Max(0, order.IndexOf(id)); id = order[(i + d + order.Count) % order.Count]; Refresh(); } public override void Refresh() { var h = S.Def(id); if (h == null) return; var db = S.Db; var lv = S.Save.Level(id); var hs = S.Save.Hero(id); var st = S.StatsOf(id); power.text = "전투력 " + st.power.ToString("N0"); UiKit.Clear(art); UiKit.Portrait("Hero", art, h, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(560f, 500f), false, 1f, new Color(1f, 1f, 1f, 0f)); for (int i = 0; i < 6; i++) { string need = h.isSoldier ? null : HeroRules.RequiredGear(db, h, hs, i); var g = db.Gear.Get(need); bool on = hs != null && i < hs.gear.Count && !string.IsNullOrEmpty(hs.gear[i]); int have = need != null ? S.Save.inv.GearCount(need) : 0; slotImg[i].gameObject.SetActive(need != null); if (need == null) continue; slotName[i].text = g != null ? g.nameKo : need; if (on) { slotImg[i].color = new Color(0.9f, 0.95f, 0.86f); slotState[i].text = "○ 장착 · " + UiKit.GradeKo(g != null ? g.grade : ""); } else if (have > 0) { slotImg[i].color = new Color(1f, 0.93f, 0.86f); slotState[i].text = "탭하여 장착 ×" + have + ""; } else { slotImg[i].color = UiKit.Slot; slotState[i].text = "없음 · " + UiKit.GradeKo(g != null ? g.grade : ""); } } typeDot.color = UiKit.TypeColor(h.type); typeMark.text = UnitTypeInfo.Mark(h.type); nameText.text = h.nameKo; subText.text = UnitTypeInfo.Korean(h.type) + " · " + (h.isSoldier ? "병사 유닛" : UiKit.GradeKo(hs.grade) + " 등급"); starText.text = h.isSoldier ? UiKit.Stars(h.rarity, 3) : UiKit.Stars(hs.star, db.Evolve.MaxStar); var skills = new[] { db.Skills.Get(h.skillActive), db.Skills.Get(h.skillPassive) }; int cap = HeroRules.SkillCap(db, hs); for (int i = 0; i < 2; i++) { var sk = skills[i]; if (sk == null) { skillName[i].text = h.isSoldier ? "병사 유닛 — 스킬 없음" : "—"; skillDesc[i].text = ""; skillChip[i].transform.parent.gameObject.SetActive(false); continue; } skillChip[i].transform.parent.gameObject.SetActive(true); skillName[i].text = sk.nameKo + (string.IsNullOrEmpty(sk.hanja) ? "" : "(" + sk.hanja + ")") + " · " + (sk.kind == "active" ? "액티브" : "패시브"); skillDesc[i].text = SkillInfoDb.DisplayDesc(sk); int slv = hs != null && hs.skillLv != null && hs.skillLv.Length > i ? hs.skillLv[i] : 1; skillChip[i].text = "Lv " + slv + "/" + cap + (sk.kind == "active" ? " · 쿨 " + sk.cooldown + "턴" : ""); } int lvCap = HeroRules.LevelCap(db, S.Save); var row = db.Levels.Get(lv.lv); lvText.text = "Lv " + lv.lv + " / " + lvCap + (lvCap < db.Levels.MaxLevel ? "" : ""); float pct = row != null && row.expToNext > 0 ? lv.exp / (float)row.expToNext : 1f; expText.text = lv.lv >= db.Levels.MaxLevel ? "최고 레벨" : pct >= 1f ? "경험치 100% ↑" : "경험치 " + (pct * 100f).ToString("0.00") + "%"; UiKit.SetBar(expBar, pct); var lvWhy = HeroRules.CanLevelUp(db, S.Save, lv); UiKit.LabelOf(levelBtn).text = "레벨업\n" + (row != null && lv.lv < db.Levels.MaxLevel ? "골드 " + row.goldCost.ToString("N0") : "최고") + ""; levelBtn.GetComponent().color = lvWhy == null ? UiKit.Red : UiKit.Disabled; var promoWhy = HeroRules.CanPromote(db, h, hs); var gearList = h.isSoldier ? null : db.Heroes.GearFor(h, hs.grade); UiKit.LabelOf(promoteBtn).text = h.isSoldier ? "승급\n병사 없음" : gearList == null ? "승급\n최고 등급" : "승급\n장비 " + HeroRules.EquippedCount(hs) + "/" + gearList.Count + "칸"; promoteBtn.GetComponent().color = promoWhy == null ? UiKit.Red : UiKit.Disabled; int need2 = HeroRules.ShardsForNext(db, hs); if (h.isSoldier) { shardText.text = "병사 유닛 — 진화 없음 (중복 = 골드)"; UiKit.SetBar(shardBar, 0f); UiKit.LabelOf(evolveBtn).text = "진화\n없음"; evolveBtn.GetComponent().color = UiKit.Disabled; } else { shardText.text = need2 > 0 ? hs.shards + " / " + need2 : hs.shards + " · 최고 ★"; UiKit.SetBar(shardBar, need2 > 0 ? hs.shards / (float)need2 : 1f); UiKit.LabelOf(evolveBtn).text = hs.star >= db.Evolve.MaxStar ? "진화\n최고 ★" : "진화\n다음 ★" + (hs.star + 1) + ""; evolveBtn.GetComponent().color = HeroRules.CanEvolve(db, h, hs) == null ? UiKit.Red : UiKit.Disabled; } } void OnSlot(int i) { var h = S.Def(id); var hs = S.Save.Hero(id); if (h == null || hs == null) return; var need = HeroRules.RequiredGear(S.Db, h, hs, i); var g = S.Db.Gear.Get(need); if (need == null) return; if (!string.IsNullOrEmpty(hs.gear[i])) { Root.Toast("장착됨: " + (g != null ? g.nameKo : need) + " — 6칸을 모두 채우면 승급"); return; } var why = S.Equip(id, i); if (why == null) { Root.Toast((g != null ? g.nameKo : need) + " 장착 · 1칸 = 1강(누적 " + hs.gearTotal + ")"); return; } string from = g != null ? g.dropFromChapter + "장~ 스테이지 드랍" : ""; Root.Modal("필요 장비", (g != null ? g.nameKo + " (" + UiKit.GradeKo(g.grade) + " 등급)" : need) + "\n보유 0\n\n획득: " + from + " · 거래 > 상점(흰/녹)" + (g != null && g.craftCount > 0 ? "\n합성 = 하위 " + g.craftCount + "개 + 도면 " + g.craftBlueprint + " (2차)" : ""), new OutGameRoot.ModalButton("상점 가기", UiKit.Red, () => Root.Trade.OpenShop()), new OutGameRoot.ModalButton("닫기", UiKit.Dark, null)); } void OnLevelUp() { var why = S.LevelUp(id); Root.Toast(why ?? S.Def(id).nameKo + " Lv " + S.Save.Level(id).lv + "!"); } void OnPromote() { var h = S.Def(id); var why = S.Promote(id); Root.Toast(why ?? h.nameKo + " 승급 → " + UiKit.GradeKo(S.Save.Hero(id).grade) + " 등급 · 새 장비 6칸"); } void OnEvolve() { var why = S.Evolve(id); Root.Toast(why ?? S.Def(id).nameKo + " 진화 → ★" + S.Save.Hero(id).star); } void ShowStats() { var h = S.Def(id); var st = S.StatsOf(id); var e = S.Db.Economy; var hs = S.Save.Hero(id); string body = "기본(" + UnitTypeInfo.Korean(h.type) + ") HP " + st.baseHp + " · 공 " + st.baseAtk + " · 방 " + st.baseDef + "\n" + "영웅 배율 ×" + st.hpMult + " · ×" + st.atkMult + " · ×" + st.defMult + "\n" + "레벨 Lv " + S.Save.Level(id).lv + " +" + st.lvPct.ToString("0.#") + "%\n" + "승급 " + (hs != null ? UiKit.GradeKo(hs.grade) : "—") + " +" + st.promoPct.ToString("0.#") + "% · 장비 누적 " + (hs != null ? hs.gearTotal : 0) + "개 +" + st.gearPct.ToString("0.#") + "%\n" + "진화 " + (hs != null ? "★" + hs.star : "—") + " +" + st.starPct.ToString("0.#") + "%\n" + "훈련(내정 · 2차) +" + st.trainPct.ToString("0.#") + "%\n\n" + "HP " + st.Hp + " · 공 " + st.Atk + " · 방 " + st.Def + "\n" + "전투력 " + st.power.ToString("N0") + " = HP/" + e.PowerHpDiv + " + 공×" + e.PowerAtkW + " + 방×" + e.PowerDefW; Root.Modal("상세정보 — " + h.nameKo, body, new OutGameRoot.ModalButton("닫기", UiKit.Dark, null)); } /// 도감 = 전 영웅·병사(미보유 회색). public static void ShowCodex(OutGameRoot root) { var s = root.Session; int owned = 0; foreach (var h in s.Db.Heroes.heroes) if (s.Save.Owns(h.id)) owned++; var content = root.ModalCustom("도감 " + owned + " / " + s.Db.Heroes.heroes.Count, 1560f, new OutGameRoot.ModalButton("닫기", UiKit.Dark, null)); ScrollRect sr; var grid = UiKit.ScrollGrid("Codex", content, 0f, 0f, 0f, 0f, new Vector2(420f, 140f), new Vector2(20f, 14f), 2, out sr); foreach (var h in s.Db.Heroes.heroes) { bool own = s.Save.Owns(h.id); var hero = h; var cell = HeroCards.Card(grid, s, h, false, own, () => root.Toast(hero.nameKo + (string.IsNullOrEmpty(hero.hanja) ? "" : "(" + hero.hanja + ")") + " · " + UnitTypeInfo.Korean(hero.type) + " · ★" + hero.rarity + (hero.isSoldier ? " · 병사 유닛" : "") + (own ? " · 보유" : " · 미보유 — 거래 > 뽑기"))); if (!own) cell.color = new Color(0.78f, 0.76f, 0.73f); } } } }