using System.Collections; using System.Collections.Generic; using System.IO; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; public class NewSceneController : MonoBehaviour { [Header("UI")] public TextMeshProUGUI mainScreenText; public GameObject characterTextGO; public TextMeshProUGUI characterText; public GameObject settingsGO; public Slider textSpeed; public TMP_Dropdown languageDropdown; public TextMeshProUGUI pauseText; public TextMeshProUGUI textSpeedText; public TextMeshProUGUI languageText; [Header("Saves UI")] public GameObject savesGO; public RawImage[] saveImages; public GameObject[] withSaveGO; public GameObject[] emptySaveGO; public TextMeshProUGUI[] savesNames; public TextMeshProUGUI[] savesDates; public GameObject confirmSaveGo; public TextMeshProUGUI saveName; [Header("Game")] public LaptopClicks laptopClicks; public LocalizationManager localizationManager; private float delay = 0.05f; private bool typingFlag = false; private int saveNumberTemp; private string Status = ""; private List currentLogLines = new List(); private List shuffledLogLines = new List(); private bool[] musicTracksActive; private bool musicSolved = false; private bool notesSolved = false; private bool walletSolved = false; private string partA = "", partB = "", partC = ""; private void Awake() { int width = Screen.currentResolution.width; int height = Screen.currentResolution.height; float ratio = (float)width / height; if (Mathf.Abs(ratio - 16f / 9f) > 0.01f) { Screen.SetResolution(1920, 1080, true); } } private void Start() { SaveSystem.Initialize(); GameData auto = SaveSystem.LoadAutoSave(); if (auto != null && !string.IsNullOrEmpty(auto.status)) Status = auto.status; else Status = ""; if (string.IsNullOrEmpty(Status)) Status = "desktopReady"; LoadSaveImages(); SetupLanguage(); laptopClicks.OnLineDragStart += HandleDragStart; laptopClicks.OnLineDragged += HandleDragging; laptopClicks.OnDragEnd += HandleDrop; laptopClicks.OnLineClicked += HandleLineClicked; StartCoroutine(AutoSave()); StartCoroutine(MainCoroutine()); } private void SetupLanguage() { languageDropdown.ClearOptions(); var languages = localizationManager.GetAllLanguages(); List options = new List(languages.Keys); languageDropdown.AddOptions(options); GameSettings settings = SaveSystem.Load(); int index = 0; foreach (var value in languages.Values) { if (value == settings.lang) break; index++; } if (index < options.Count) { languageDropdown.value = index; languageDropdown.RefreshShownValue(); } localizationManager.SetLanguage(settings.lang); pauseText.text = localizationManager.GetText("pause"); textSpeedText.text = localizationManager.GetText("textSpeed"); languageText.text = localizationManager.GetText("language"); mainScreenText.fontSize = localizationManager.GetFloat("fontSize"); } private void LoadSaveImages() { for (int i = 0; i < saveImages.Length; i++) { if (saveImages[i] == null) continue; LoadImage($"ImageSave{i + 1}.png", saveImages[i]); GameData data = SaveSystem.LoadGame(i + 1, false); if (data != null) { withSaveGO[i].SetActive(true); emptySaveGO[i].SetActive(false); savesNames[i].text = data.saveName; savesDates[i].text = data.saveTime; } else { withSaveGO[i].SetActive(false); emptySaveGO[i].SetActive(true); } } } private void LoadImage(string file, RawImage rawImage) { string path = Path.Combine(Application.persistentDataPath, "Saves", file); if (!File.Exists(path)) return; byte[] bytes = File.ReadAllBytes(path); Texture2D tex = new Texture2D(2, 2); tex.LoadImage(bytes); rawImage.texture = tex; } private IEnumerator AutoSave() { while (true) { if (Time.timeScale > 0f) { GameData data = new GameData(); data.status = Status; SaveSystem.AutoSave(data); } yield return new WaitForSeconds(2f); } } private IEnumerator MainCoroutine() { GameSettings settings = SaveSystem.Load(); delay = settings.textSpeed; textSpeed.value = delay; mainScreenText.text = localizationManager.GetText("errorMessage"); mainScreenText.gameObject.SetActive(true); characterTextGO.SetActive(true); yield return TypeText(localizationManager.GetText("firstText")); ProcessStatusOnStart(); } private void ProcessStatusOnStart() { switch (Status) { case "logRepaired": StartCoroutine(SetupMusicMiniGame()); break; case "musicSolved": StartCoroutine(SetupNotesMiniGame()); break; case "notesSolved": StartCoroutine(SetupWalletMiniGame()); break; } } private IEnumerator TypeText(string text) { typingFlag = false; characterText.text = ""; foreach (char c in text) { characterText.text += c; yield return new WaitForSeconds(delay); if (Input.GetKeyDown(KeyCode.Space)) { characterText.text = text; break; } } typingFlag = true; } private IEnumerator TypeTextToMainScreen(string text) { mainScreenText.text = ""; foreach (char c in text) { mainScreenText.text += c; yield return new WaitForSeconds(delay); if (Input.GetKeyDown(KeyCode.Space)) { mainScreenText.text = text; break; } } } // ================================================== // ==================== LINE CLICK ================= private void HandleLineClicked(string lineText) { if (Status == "" && lineText.Contains(localizationManager.GetText("errorMessage"))) { Status = "desktopReady"; StartCoroutine(TypeText(localizationManager.GetText("seeProjects"))); } else if (Status == "desktopReady" && lineText.Contains(localizationManager.GetText("projectsDir"))) { Status = "projectsOpen"; StartCoroutine(SetupLogMiniGame()); } else if (Status == "logRepaired") { Status = "musicOpen"; StartCoroutine(SetupMusicMiniGame()); } else if (Status == "musicSolved") { Status = "notesOpen"; StartCoroutine(SetupNotesMiniGame()); } else if (Status == "notesSolved") { Status = "walletOpen"; StartCoroutine(SetupWalletMiniGame()); } SaveSystem.AutoSave(new GameData { status = Status }); } // ================================================== // ==================== LOG MINI-GAME ============= private IEnumerator SetupLogMiniGame() { currentLogLines = GetLogLines(); shuffledLogLines = ShuffleLines(currentLogLines); string shuffledText = string.Join("\n", shuffledLogLines); yield return TypeTextToMainScreen(shuffledText); } private List GetLogLines() { List lines = new List(); for (int i = 1; i <= 6; i++) { string line = localizationManager.GetText($"logLine{i}"); if (!string.IsNullOrEmpty(line)) lines.Add(line); } return lines; } private List ShuffleLines(List lines) { List shuffled = new List(lines); System.Random rng = new System.Random(); int n = shuffled.Count; while (n > 1) { n--; int k = rng.Next(n + 1); (shuffled[k], shuffled[n]) = (shuffled[n], shuffled[k]); } return shuffled; } private void HandleDragStart(int line) { if (Status == "projectsOpen") currentLogLines = new List(mainScreenText.text.Split('\n')); } private void HandleDragging(int from, int to) { if (Status == "projectsOpen") { if (from < 0 || to < 0 || from >= currentLogLines.Count || to >= currentLogLines.Count) return; string item = currentLogLines[from]; currentLogLines.RemoveAt(from); currentLogLines.Insert(to, item); mainScreenText.text = string.Join("\n", currentLogLines); mainScreenText.ForceMeshUpdate(); } } private void HandleDrop() { if (Status == "projectsOpen") { bool correct = true; List correctOrder = GetLogLines(); for (int i = 0; i < correctOrder.Count; i++) { if (currentLogLines[i] != correctOrder[i]) { correct = false; break; } } if (correct) { Status = "logRepaired"; SaveSystem.AutoSave(new GameData { status = Status }); StartCoroutine(TypeText(localizationManager.GetText("restoredLog"))); } } } // ================================================== // ==================== MUSIC MINI-GAME ============ private IEnumerator SetupMusicMiniGame() { musicTracksActive = new bool[3]; mainScreenText.text = localizationManager.GetText("musicDir") + " folder unlocked. Click tracks to activate."; musicSolved = false; yield return null; } public void ToggleMusicTrack(int trackIndex) { if (trackIndex < 0 || trackIndex >= musicTracksActive.Length) return; musicTracksActive[trackIndex] = !musicTracksActive[trackIndex]; if (musicTracksActive[0] && musicTracksActive[2] && !musicTracksActive[1]) { musicSolved = true; Status = "musicSolved"; SaveSystem.AutoSave(new GameData { status = Status }); StartCoroutine(TypeText("Correct track configuration! /notes unlocked.")); } } // ================================================== // ==================== NOTES MINI-GAME ============ private IEnumerator SetupNotesMiniGame() { mainScreenText.text = localizationManager.GetText("notesDir") + " folder unlocked. Solve note_locked.txt by selecting correct byte."; notesSolved = false; yield return null; } public void SolveNotes(bool correct) { if (correct) { notesSolved = true; Status = "notesSolved"; SaveSystem.AutoSave(new GameData { status = Status }); StartCoroutine(TypeText("Notes decrypted! /wallet_protected unlocked.")); } } // ================================================== // ==================== WALLET MINI-GAME =========== private IEnumerator SetupWalletMiniGame() { mainScreenText.text = localizationManager.GetText("walletProtectedDir") + " folder locked. Solve parts A, B, C."; walletSolved = false; partA = partB = partC = ""; yield return null; } public void SolveWalletPart(string part, string value) { if (part == "A") partA = value; if (part == "B") partB = value; if (part == "C") partC = value; if (!string.IsNullOrEmpty(partA) && !string.IsNullOrEmpty(partB) && !string.IsNullOrEmpty(partC)) { walletSolved = true; Status = "walletComplete"; SaveSystem.AutoSave(new GameData { status = Status }); StartCoroutine(TypeText("Wallet opened! Access granted.")); } } // ================================================== // ==================== SAVE FUNCTIONS ============ public void SaveGame(int saveNumber) { confirmSaveGo.SetActive(true); savesGO.SetActive(false); saveNumberTemp = saveNumber; saveName.text = savesNames[saveNumber - 1].text; } public void ConfirmSaveGame() { confirmSaveGo.SetActive(false); savesGO.SetActive(true); GameData data = new GameData { saveName = saveName.text, status = Status }; SaveSystem.SaveGame(saveNumberTemp, data); LoadSaveImages(); } public void LoadGame(int loadNumber) { SaveSystem.LoadGame(loadNumber); SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); } public void Restart() { Time.timeScale = 1f; SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); } public void UpdateTextSpeed() { GameSettings settings = SaveSystem.Load(); settings.textSpeed = textSpeed.value; delay = textSpeed.value; SaveSystem.Save(settings); } }