// ───────────────────────────────────────────────────────────────────────────── // WLEquipSettings.cs — FR 장비 시스템 WL 이식 설정(SO · `Resources/WL/WLEquipSettings.asset`) (#821) // // C45: 세이브 이름 · 재화 ID · 드랍 규칙 · FR 능력치 → 힘민지 스탯 대응표 · UI 크기를 전부 여기 둔다. // 🔴 SO 는 클래스와 같은 이름의 .cs 파일에만 둔다(816g 교훈 — 아니면 .asset 의 m_Script 가 빈다). // ───────────────────────────────────────────────────────────────────────────── using System.Collections.Generic; using UnityEngine; namespace WL.Equip { /// FR eAbility(%) 한 항목을 힘민지 eStat 하나에 더하는 규칙. 같은 ability 를 여러 행에 적으면 모두 더한다. [System.Serializable] public struct WLAbilityMap { public eFRAbility ability; public eStat stat; [Tooltip("FR 값(%)에 곱해 힘민지 값으로. 힘민지 Multiplier 계열은 1000 분율(100 = 1 %) 이라 FR 1 % → 10")] public float scale; } public sealed class WLEquipSettings : ScriptableObject { [Header("스위치")] [Tooltip("0 이면 장비 시스템 전체 무동작(스탯 훅·드랍·메뉴 전부)")] public int enabled_ = 1; public int verboseLog = 1; [Header("데이터")] [Tooltip("FR 표 json 이 든 Resources 폴더")] public string tableFolder = "WL/FR"; [Header("세이브")] [Tooltip("persistentDataPath 아래 파일 이름(확장자 제외)")] public string saveName = "WL_Equip"; [Tooltip("1 이면 Play(실행) 1회당 첫 로드 때 세이브를 지운다 — 섬 세이브(resetSaveEveryStart)와 같은 정책")] public int resetSaveEveryStart = 1; [Header("재화 — FR ItemTable 의 특수 인덱스")] [Tooltip("FR 골드 아이템 Index(강화 비용 MoneyKeyRequired). 섬이 떠 있으면 섬 코인(IslandManager.Coin)을 쓴다")] public int goldItemIndex = 1; [Header("던전 클리어 드랍 (FR ItemDropGroupTable)")] [Tooltip("클리어 때 굴릴 드랍 그룹 ID(1001 = 일반 장비 상자 · 패키지 10001 에서 1개)")] public int clearDropGroupId = 1001; public int clearDropRolls = 1; public int bossExtraRolls = 1; [Tooltip("클리어마다 주는 강화석 Item Index 목록(101~106 = 부위별 강화석)")] public int[] clearStoneItemIds = { 101, 102, 103, 104, 105, 106 }; public int clearStoneCountEach = 2; [Tooltip("클리어 골드 보상에 더해 FR 골드도 지급할지(섬 코인으로 들어간다) · 0 = 안 줌")] public int clearGoldBonus = 0; [Header("플레이어 기본 공격력 (PD 2026-10-09 「기본 공격력은 5」)")] [Tooltip("0 보다 크면 스탯 재계산 뒤 PC 의 ATK 를 「이 값 + 장착 장비 공격 합(기본 수치 + 주스탯 × 등급 %)」 으로 덮고 BaseDmg 도 같은 비율로 맞춘다. 0 = 힘민지 원본 공식(주스탯 × 배율)에 장비 공격 합을 더한다")] public double pcBaseAttackOverride = 5; [Header("WL 등급 7단계 · 장비 상자 (PD 2026-10-09)")] [Tooltip("등급 표 json(Resources 경로 · 확장자 제외) — 등급 이름·색·주스탯 % · FR 14단계 대응 · 부위별 출력")] public string gradeTablePath = "WL/WLGradeTable"; [Tooltip("상자 표 json — 등급 가중치 · 에픽 확정 주기 · S급 천장 · 열쇠 비용")] public string boxTablePath = "WL/WLEquipBoxTable"; [Tooltip("더미 UI 의 상자 버튼이 여는 상자 id")] public int defaultBoxId = 1; [Tooltip("「열쇠 +N」 테스트 버튼이 주는 열쇠 수(cheatGrantEnabled 일 때만 보임)")] public int cheatKeyGrant = 10; [Tooltip("1 이면 구 FR 등급 % 옵션(abilityMap)도 Reset 안에서 함께 더한다. 기본 0 = 새 공식(기본 수치 + 주스탯 × 등급 %)만")] public int applyLegacyFrOptions = 0; [Header("레벨표 능력치 → 힘민지 스탯")] public eStat levelAttackStat = eStat.ATK; public eStat levelDefenceStat = eStat.DEF; public eStat levelHealthStat = eStat.HP; public float levelStatScale = 1f; [Header("등급 옵션(FR eAbility %) → 힘민지 스탯")] public List abilityMap = new List { new WLAbilityMap { ability = eFRAbility.Health, stat = eStat.HP_Multiplier, scale = 10f }, new WLAbilityMap { ability = eFRAbility.Attack, stat = eStat.ATK_Multiplier, scale = 10f }, new WLAbilityMap { ability = eFRAbility.Defence, stat = eStat.DEF_Multiplier, scale = 10f }, new WLAbilityMap { ability = eFRAbility.AttackDefence, stat = eStat.ATK_Multiplier, scale = 10f }, new WLAbilityMap { ability = eFRAbility.AttackDefence, stat = eStat.DEF_Multiplier, scale = 10f }, new WLAbilityMap { ability = eFRAbility.Speed, stat = eStat.MOVE_SPD_Multiplier, scale = 10f }, new WLAbilityMap { ability = eFRAbility.Critical, stat = eStat.CRI, scale = 10f }, new WLAbilityMap { ability = eFRAbility.CriticalDamage, stat = eStat.CRI_DMG_Multiplier, scale = 10f }, new WLAbilityMap { ability = eFRAbility.Cooltime, stat = eStat.COOLTIME_Multiplier, scale = 10f }, new WLAbilityMap { ability = eFRAbility.RecoveryHealth, stat = eStat.HP_REGEN_Multiplier, scale = 10f }, new WLAbilityMap { ability = eFRAbility.Passive, stat = eStat.SKILL_Multiplier, scale = 10f }, new WLAbilityMap { ability = eFRAbility.IncreaseDrop, stat = eStat.GOLD_Multiplier, scale = 10f }, new WLAbilityMap { ability = eFRAbility.IncreaseDrop, stat = eStat.EXP_Multiplier, scale = 10f }, new WLAbilityMap { ability = eFRAbility.IncreaseDrop, stat = eStat.ITEM_Multiplier, scale = 10f }, }; [Header("GUI v2 — XP Hero 레퍼런스 이식 (PD 2026-10-09)")] [Tooltip("1 이면 장비 화면을 WLEquipGui(XP Hero 레이아웃 · 스프라이트)로 연다 · 0 = 구 더미 텍스트 UI")] public int useGuiV2 = 1; [Tooltip("GUI 설정 json(Resources 경로 · 확장자 제외) — 치수·색·스프라이트 이름·아이콘 대응")] public string guiConfigPath = "WL/WLEquipGui"; [Header("메뉴 연결")] [Tooltip("하단 메뉴 DummyMenuButton 의 menuId — 이 값이면 장비 화면을 연다(쉼표로 여러 개)")] public string openMenuIds = "weapon,upgrade"; [Tooltip("1 이면 화면에 「테스트 획득」 버튼(드랍 그룹을 굴려 바로 지급)을 둔다")] public int cheatGrantEnabled = 1; public int cheatGrantGroupId = 1001; public int cheatGrantRolls = 5; [Header("런처 버튼 — 인게임(섬·던전)에서 항상 보이는 「장비」 버튼 (하단 메뉴는 섬에서 숨겨져 있어 별도 진입점)")] public int launcherEnabled = 1; [Tooltip("이 씬이 활성 씬이고 서버 데이터가 있을 때만 보인다")] public string launcherSceneName = "InGame"; public string launcherLabel = "장비"; public Vector2 launcherSizePx = new Vector2(200f, 84f); [Tooltip("화면 오른쪽·아래 모서리에서의 거리(px · 1080×1920 기준)")] public Vector2 launcherOffsetPx = new Vector2(24f, 300f); [Tooltip("1 이면 장비 화면을 열 때 힘민지 원본 EquipmentUI 가 켜져 있으면 끈다(하단 「무기」 버튼의 원본 onClick 이 초기화 없이 켜는 사고 방지)")] public int closeLegacyEquipmentUi = 1; [Header("더미 UI (기준 1080×1920 px)")] public int uiSortingOrder = 300; public Color dimColor = new Color(0f, 0f, 0f, 0.75f); public Color panelColor = new Color(0.12f, 0.12f, 0.14f, 0.98f); public Color boxColor = new Color(0.2f, 0.2f, 0.24f, 1f); public Color buttonColor = new Color(0.32f, 0.36f, 0.5f, 1f); public Color buttonDisabledColor = new Color(0.25f, 0.25f, 0.28f, 1f); public Color equippedRowColor = new Color(0.2f, 0.45f, 0.3f, 1f); public Color rowColor = new Color(0.22f, 0.22f, 0.26f, 1f); public Color selectedRowColor = new Color(0.55f, 0.45f, 0.2f, 1f); public float panelMarginPx = 30f; public float titleFontPx = 44f; public float bodyFontPx = 30f; public float smallFontPx = 26f; public float rowHeightPx = 72f; public float slotHeightPx = 110f; public float buttonHeightPx = 84f; public float detailHeightPx = 420f; public int maxListRows = 300; [Tooltip("한글 TMP 폰트 에셋 경로(비우면 화면에 있는 TMP 라벨의 폰트를 빌린다)")] public string fontPath = ""; static WLEquipSettings s_cache; public static WLEquipSettings Instance { get { if (s_cache == null) s_cache = Resources.Load("WL/WLEquipSettings"); return s_cache; } } public static bool Enabled { get { var c = Instance; return c != null && c.enabled_ != 0; } } public bool IsOpenMenuId(string id) { if (string.IsNullOrEmpty(openMenuIds) || string.IsNullOrEmpty(id)) return false; var parts = openMenuIds.Split(','); for (int i = 0; i < parts.Length; i++) if (parts[i].Trim() == id) return true; return false; } } }