92 lines
6.1 KiB
C#
92 lines
6.1 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using VS.Sim;
|
|
using Vector2 = UnityEngine.Vector2;
|
|
|
|
// 의상 팝업 — 원작 ClosetPopup(미리보기 · 레벨 업그레이드 · 의상 칸 목록 · 장착)
|
|
namespace VS.View
|
|
{
|
|
public partial class GameApp
|
|
{
|
|
public void OpenCloset()
|
|
{
|
|
var p = NewPopup("Closet", L("UI.Closet.Title", "의상"), 1640, Pal.Pink);
|
|
var top = UI.Img(p.body, "Preview", Skin.Round, new Color32(255, 236, 246, 255));
|
|
top.rectTransform.Place(new Vector2(0, 1), new Vector2(1, 1), new Vector2(0, 0), new Vector2(0, 560), new Vector2(0.5f, 1));
|
|
var idol = UI.Img(top.transform, "Idol", null, Color.white); idol.preserveAspect = true;
|
|
idol.rectTransform.Place(new Vector2(0, 0.5f), new Vector2(0, 0.5f), new Vector2(190, 0), new Vector2(340, 520));
|
|
var lv = UI.Txt(top.transform, "Level", "", 50, Pal.Ink, TextAnchor.MiddleLeft);
|
|
lv.rectTransform.Place(new Vector2(0, 1), new Vector2(1, 1), new Vector2(380, -70), new Vector2(-400, 70), new Vector2(0, 0.5f));
|
|
var stat = UI.Txt(top.transform, "Stat", "", 36, Pal.PinkDark, TextAnchor.MiddleLeft);
|
|
stat.rectTransform.Place(new Vector2(0, 1), new Vector2(1, 1), new Vector2(380, -150), new Vector2(-400, 60), new Vector2(0, 0.5f));
|
|
var cond = UI.Txt(top.transform, "Cond", "", 30, new Color32(120, 100, 140, 255), TextAnchor.MiddleLeft);
|
|
cond.rectTransform.Place(new Vector2(0, 1), new Vector2(1, 1), new Vector2(380, -220), new Vector2(-400, 60), new Vector2(0, 0.5f));
|
|
var up = UI.TextBtn(top.transform, "Upgrade", "", Pal.Green, 38, () => { var r = G.UpgradeCloset(); if (r != BuyResult.Ok) Toast(r == BuyResult.Locked ? "랭크가 부족합니다" : BuyMsg(r)); RefreshAll(); }, out var upText);
|
|
up.GetComponent<RectTransform>().Place(new Vector2(0, 0), new Vector2(0, 0), new Vector2(620, 120), new Vector2(440, 150));
|
|
// 의상 칸 (5열)
|
|
var grid = UI.Rect("Grid", p.body).Fill(0, 0, 0, 590);
|
|
var sr = UI.Scroll(grid, "Scroll", out var content, 10);
|
|
sr.GetComponent<RectTransform>().Fill();
|
|
Object.DestroyImmediate(content.GetComponent<VerticalLayoutGroup>());
|
|
var gl = content.gameObject.AddComponent<GridLayoutGroup>();
|
|
gl.cellSize = new Vector2(170, 210); gl.spacing = new Vector2(14, 14); gl.padding = new RectOffset(6, 6, 6, 30);
|
|
gl.constraint = GridLayoutGroup.Constraint.FixedColumnCount; gl.constraintCount = 5;
|
|
var cells = new List<(OutfitRow o, Image bg, Image face, Text label, Image lockIcon)>();
|
|
foreach (var o in T.Cfg.closet.outfits)
|
|
{
|
|
var outfit = o;
|
|
var b = UI.Btn(content, "Outfit" + o.Type, Skin.Round, Color.white, () => OnOutfitClick(outfit));
|
|
var face = UI.Img(b.transform, "Face", null, Color.white); face.preserveAspect = true;
|
|
face.rectTransform.Place(new Vector2(0.5f, 1), new Vector2(0.5f, 1), new Vector2(0, -78), new Vector2(150, 150));
|
|
var lb = UI.Txt(b.transform, "Label", "", 24, Pal.Ink); lb.rectTransform.Place(new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 26), new Vector2(-6, 40));
|
|
var lk = UI.Icon(b.transform, "Lock", Skin.Icon("lock"), Color.white); lk.rectTransform.Place(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0, 18), new Vector2(80, 80));
|
|
cells.Add((o, b.GetComponent<Image>(), face, lb, lk));
|
|
}
|
|
p.refresh = () =>
|
|
{
|
|
int show = PreviewOutfit >= 0 ? PreviewOutfit : G.S.closetCurrent;
|
|
idol.sprite = Art.Idol(show, 0);
|
|
lv.text = $"의상 레벨 {G.S.closetLevel} / {G.ClosetMaxLevel}";
|
|
stat.text = $"전체 수익 x{G.ClosetStatRate(G.ClosetEffLevel()) / 10000f:0.##}";
|
|
var nx = G.ClosetNext;
|
|
if (nx == null) { cond.text = "최대 레벨"; upText.text = "MAX"; up.interactable = false; }
|
|
else
|
|
{
|
|
cond.text = $"다음: x{nx.StatRate / 10000f:0.##} · 랭크 {nx.RankDependency} 필요";
|
|
var price = G.ClosetNextPrice();
|
|
upText.text = "레벨 업\n" + Fmt.Num(price);
|
|
up.interactable = G.ClosetRankOk() && price <= G.Coin && !G.ClosetUpgrading;
|
|
}
|
|
foreach (var (o, bg, face, label, lockIcon) in cells)
|
|
{
|
|
bool vis = o.UnlockType != ClosetUnlock.InEvent || G.OutfitUnlocked(o.Type);
|
|
bg.gameObject.SetActive(vis);
|
|
if (!vis) continue;
|
|
bool un = G.OutfitUnlocked(o.Type);
|
|
face.sprite = Art.Idol(o.Type, 0);
|
|
face.color = un ? Color.white : new Color(0.35f, 0.3f, 0.45f, 1f);
|
|
lockIcon.gameObject.SetActive(!un);
|
|
bg.color = G.S.closetCurrent == o.Type ? new Color32(255, 214, 236, 255) : (PreviewOutfit == o.Type ? new Color32(236, 226, 255, 255) : Color.white);
|
|
label.text = o.Type == 1000 ? "기본" : un ? (G.S.closetCurrent == o.Type ? "장착 중" : "장착")
|
|
: (o.UnlockType == ClosetUnlock.Ticket ? (G.OutfitRankOk(o) ? $"티켓 {G.OutfitTicketPrice(o)}" : $"랭크 {o.VisibilityRank}") : $"Lv.{o.UnlockLevel}");
|
|
}
|
|
};
|
|
p.refresh();
|
|
}
|
|
|
|
void OnOutfitClick(OutfitRow o)
|
|
{
|
|
if (G.OutfitUnlocked(o.Type)) { G.EquipOutfit(o.Type); PreviewOutfit = -1; }
|
|
else if (o.UnlockType == ClosetUnlock.Ticket && G.OutfitRankOk(o))
|
|
{
|
|
var r = G.UnlockTicketOutfit(o.Type);
|
|
if (r == BuyResult.Ok) { G.EquipOutfit(o.Type); Toast("새 의상을 얻었습니다"); }
|
|
else { PreviewOutfit = o.Type; Toast(r == BuyResult.NoMoney ? "티켓이 부족합니다" : "잠겨 있습니다"); }
|
|
}
|
|
else { PreviewOutfit = o.Type; Toast($"의상 레벨 {o.UnlockLevel} 에 열립니다"); }
|
|
RefreshAll();
|
|
}
|
|
}
|
|
}
|