// ───────────────────────────────────────────────────────────────────────────── // WLIslandSave.cs — 섬 세이브 파일 이름을 **경로와 무관하게 하나로** 고정한다. // // ■ 왜 필요한가 (Lead 실측 · 2026-09-13 · 816f 가 발견) // `IslandManager.cs:119` 가 `saveFileName = SceneManager.GetActiveScene().name` 이라 // 같은 섬인데도 **들어온 경로에 따라 세이브가 갈린다**: // · 섬 씬만 단독 Play → `Level01.dat` // · 게임 정식 경로(로그인 → Load_Map → 섬이 Additive) → **`InGame.dat`** // → 섬을 키워 놔도 다른 경로로 들어가면 초기 상태가 나온다. // // ■ PD 결정(2026-09-13): 「세이브가 경로마다 갈리면 안돼. 그냥 기존 세이브를 // 초기화하고 단일 경로로 맞춰」 → 이름을 하나로 고정한다. // // ■ 원본 수정은 `IslandManager.cs` **1줄**(그 대입문)뿐이다 — WL 하우스 규칙의 // 「1줄 훅 + 새 파일」 그대로. `enabled_ = 0` 이면 원래 동작(씬 이름)으로 돌아간다. // ───────────────────────────────────────────────────────────────────────────── using UnityEngine; namespace WL.Island { // 🔴 `WLIslandSaveSettings`(ScriptableObject)는 **`WLIslandSaveSettings.cs` 로 분리**했다. // 유니티는 SO 를 클래스 이름과 같은 이름의 .cs 파일에서만 MonoScript 로 인식한다 — // 여기 있던 동안 `.asset` 의 `m_Script` 가 비어 세이브 단일화가 동작하지 않았다(816g 실측). public static class WLIslandSave { /// /// `IslandManager.Awake` 의 **기존 1줄 훅**이 부른다. 끄면 받은 값을 그대로 돌려준다. /// /// 🔴 WL-816g — 이 호출은 `IslandManager.Awake` 안에서 `LoadGameData()` **바로 앞**에 있다 /// (`IslandManager.cs:119` vs `:120`). 그래서 「새 게임 시작 골드」와 「세이브 1회 초기화」를 /// 걸 수 있는 **유일한 시점**이다 — 덕분에 FI 원본에 새 줄을 한 줄도 넣지 않았다. /// public static string ResolveSaveName(string sceneName) { var cfg = WLIslandSaveSettings.Get(); string resolved = sceneName; if (cfg != null && cfg.enabled_ != 0 && !string.IsNullOrEmpty(cfg.saveName)) { resolved = cfg.saveName; if (cfg.verboseLog != 0) Debug.Log("[WL-816] 섬 세이브 이름 '" + sceneName + "' → '" + resolved + "' (경로 무관 고정)"); } WLIslandStart.Prepare(resolved); return resolved; } } /// /// 새 게임의 시작 상태(WL-816g §3) — **시작 골드 10** + 필요하면 세이브 1회 초기화. /// FI 기본 시작 골드는 500 이다(`IslandManager.cs:30` `startingMoney`). /// public static class WLIslandStart { public static int LastStartCoin = -1; public static bool DidReset; public static string LastLog = ""; const string kTokenKey = "WL_Island_SaveToken"; static System.Reflection.FieldInfo s_startingMoney; static bool s_resetDoneThisRun; // 2026-09-15 PD — 실행(Play) 1회당 1번만 초기화 /// `IslandManager.Awake` 안(= `LoadGameData()` 직전)에서 단 한 번 불린다. public static void Prepare(string saveName) { var cfg = WLIslandSettings.Instance; if (cfg == null || cfg.enabled_ == 0 || cfg.gateFlowEnabled == 0) return; // ① 세이브 초기화 — 토큰이 바뀌었을 때(1회) · 또는 `resetSaveEveryStart` 면 **게임 시작마다**(실행 1회당 1번 · // 던전에서 섬으로 돌아올 때는 아님 · 2026-09-15 PD 「내가 얘기하기 전까지 매번 초기화 상태에서 시작」) bool everyStart = cfg.resetSaveEveryStart != 0 && !s_resetDoneThisRun; if (everyStart || (!string.IsNullOrEmpty(cfg.saveResetToken) && PlayerPrefs.GetString(kTokenKey, "") != cfg.saveResetToken)) { s_resetDoneThisRun = true; try { string path = Application.persistentDataPath + "/" + saveName + ".dat"; if (System.IO.File.Exists(path)) { System.IO.File.Delete(path); DidReset = true; } } catch (System.Exception ex) { Debug.LogWarning("[WL-816g] 세이브 초기화 실패 — " + ex.Message); } PlayerPrefs.SetString(kTokenKey, cfg.saveResetToken); PlayerPrefs.SetInt(cfg.dungeonUnlockPrefsKey, 0); // 해금한 던전도 0 개로 // WL-816zc — 초기 플로우 단계·확장 개방도 같이 0 으로(시작마다 초기화 대상) if (!string.IsNullOrEmpty(cfg.flowStepPrefsKey)) PlayerPrefs.SetInt(cfg.flowStepPrefsKey, 0); if (!string.IsNullOrEmpty(cfg.expansionUnlockPrefsKey)) PlayerPrefs.SetInt(cfg.expansionUnlockPrefsKey, 0); WLIslandExpansionGate.ClearSpotMemory(); // 2026-09-17 — 확장 가격판 자리 기억도 세이브와 함께 초기화 PlayerPrefs.Save(); WLIslandBridge.ClearPending(); // 보류 보상도 비운다(정적 값까지) } // ② 시작 골드 — `startingMoney` 는 `data == null`(세이브 없음)일 때만 쓰인다(IslandManager.cs:397) if (cfg.applyStartCoin == 0) return; var mgr = CryingSnow.FarmingIsland.IslandManager.Instance; if (mgr == null) return; if (s_startingMoney == null) s_startingMoney = typeof(CryingSnow.FarmingIsland.IslandManager).GetField("startingMoney", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); if (s_startingMoney == null) return; s_startingMoney.SetValue(mgr, cfg.startCoin); LastStartCoin = cfg.startCoin; LastLog = "시작 골드 500 → " + cfg.startCoin + (DidReset ? " · 세이브 초기화함" : " · 기존 세이브 유지"); if (cfg.verboseLog != 0) Debug.Log("[WL-816g] " + LastLog); } } }