1069 lines
36 KiB
C#
1069 lines
36 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using TMPro;
|
||
using UnityEngine;
|
||
using UnityEngine.SceneManagement;
|
||
using UnityEngine.UI;
|
||
|
||
|
||
|
||
public class SceneController : MonoBehaviour
|
||
{
|
||
// --- ОСНОВНЫЕ ПОЛЯ СЦЕНАРИЯ И UI ---
|
||
[Header("Main")]
|
||
public GameObject startScreen;
|
||
public GameObject mainScreenTextGO;
|
||
public TextMeshProUGUI mainScreenText;
|
||
public GameObject characterTextGO;
|
||
public TextMeshProUGUI characterText;
|
||
public float delay = 0.05f;
|
||
public float delayMainScreen = 0.05f;
|
||
private bool flag = false; // Флаг для блокировки ввода во время печати
|
||
private bool isLogShowed = false; // Флаг для активации Drag & Drop
|
||
public LaptopClicks laptopClicks;
|
||
public string Status; // Текущее состояние игры
|
||
public LocalizationManager localizationManager;
|
||
private string correctPassword; // Пароль, загруженный из файла
|
||
private bool flag1 = false;
|
||
private bool flag2 = false;
|
||
|
||
// --- НАСТРОЙКИ (Settings) ---
|
||
[Header("Settings")]
|
||
public GameObject settingsGO;
|
||
public Slider textSpeed;
|
||
public TMP_Dropdown languageDropdown;
|
||
public TextMeshProUGUI pauseText;
|
||
public TextMeshProUGUI textSpeedText;
|
||
public TextMeshProUGUI languageText;
|
||
|
||
// --- СОХРАНЕНИЯ (Saves) ---
|
||
[Header("Saves")]
|
||
public GameObject savesGO;
|
||
public RawImage[] saveImages;
|
||
public GameObject[] withSaveGO;
|
||
public GameObject[] emptySaveGO;
|
||
public TextMeshProUGUI[] savesNames;
|
||
public TextMeshProUGUI[] savesDates;
|
||
public GameObject confirmSaveGo;
|
||
public TextMeshProUGUI saveNameInput;
|
||
private int saveNumberTemp;
|
||
|
||
// --- КОТ (Cat Animation) ---
|
||
[Header("Cat")]
|
||
public GameObject[] catSprites;
|
||
public GameObject[] catSpritesToSleep;
|
||
public GameObject[] catSpritesToActive;
|
||
public GameObject[] catSpritesEar;
|
||
public GameObject catSpritesBlink;
|
||
public float catDelay = 0.1f;
|
||
public GameObject[] cupSmoke;
|
||
public float cupDekay = 0.01f;
|
||
|
||
// --- ФИНАЛЬНЫЙ ПАРОЛЬ (Wallet Access) ---
|
||
[Header("Final Password (Wallet)")]
|
||
public GameObject notesPanelGO; // Панель для ввода пароля
|
||
public TMP_InputField passwordInput;
|
||
public TextMeshProUGUI passwordMessageText;
|
||
public GameObject finalAccessGo; // Финальный экран
|
||
|
||
// --- МИНИ-ИГРА I: DRAG & DROP (Log) ---
|
||
private List<string> currentLogLines = new List<string>();
|
||
|
||
// --- МИНИ-ИГРА II: PART A (Memory Map Hack) ---
|
||
[Header("Part A: Memory Map Hack")]
|
||
public GameObject partAHackPanelGO;
|
||
public Button[] hackNodes;
|
||
public TextMeshProUGUI hackMessageText;
|
||
|
||
private List<int> correctSequence = new List<int> { 0, 3, 1, 4, 2 };
|
||
private int currentSequenceIndex = 0;
|
||
|
||
// --- МИНИ-ИГРА III: PART B (Hex Decrypt) ---
|
||
[Header("Part B: Hex Decrypt")]
|
||
public GameObject partBDecryptPanelGO;
|
||
public TextMeshProUGUI hexDumpText;
|
||
public TMP_InputField checksumInput;
|
||
public TextMeshProUGUI decryptMessageText;
|
||
|
||
private int byte1Dec = 26; // 1A hex
|
||
private int byte5Dec = 75; // 4B hex
|
||
private int byte7Dec = 34; // 22 hex
|
||
private int expectedChecksum; // 26 + 75 + 34 = 135
|
||
|
||
// ----------------------------------------------------------------------
|
||
|
||
void Start()
|
||
{
|
||
SaveSystem.Initialize();
|
||
StartCoroutine(catAnim());
|
||
|
||
// --- 🔑 Инициализация и загрузка пароля ---
|
||
LoadSecretPassword();
|
||
expectedChecksum = byte1Dec + byte5Dec + byte7Dec;
|
||
// ------------------------------------------
|
||
|
||
LoadSaveImages();
|
||
|
||
if (laptopClicks != null)
|
||
{
|
||
laptopClicks.OnLineClicked -= HandleLineClicked;
|
||
laptopClicks.OnLineDragStart += HandleDragStart;
|
||
laptopClicks.OnLineDragged += HandleDragging;
|
||
laptopClicks.OnDragEnd += HandleDrop;
|
||
laptopClicks.OnLineClicked += HandleLineClicked;
|
||
}
|
||
|
||
// Скрытие всех модальных окон и финального экрана
|
||
settingsGO.SetActive(false);
|
||
savesGO.SetActive(false);
|
||
confirmSaveGo.SetActive(false);
|
||
settingsGO.SetActive(false);
|
||
savesGO.SetActive(false);
|
||
confirmSaveGo.SetActive(false);
|
||
characterTextGO.SetActive(false);
|
||
mainScreenTextGO.SetActive(false);
|
||
|
||
startScreen.SetActive(true);
|
||
|
||
if (finalAccessGo != null) finalAccessGo.SetActive(false);
|
||
if (notesPanelGO != null) notesPanelGO.SetActive(false);
|
||
if (partAHackPanelGO != null) partAHackPanelGO.SetActive(false);
|
||
if (partBDecryptPanelGO != null) partBDecryptPanelGO.SetActive(false);
|
||
|
||
// Настройка локализации и UI
|
||
languageDropdown.ClearOptions();
|
||
Dictionary<string, string> languages = localizationManager.GetAllLanguages();
|
||
foreach (var language in languages)
|
||
{
|
||
print(language.Key); print(language.Value);
|
||
}
|
||
List<string> options = new List<string>(languages.Keys);
|
||
GameSettings settings = SaveSystem.Load();
|
||
languageDropdown.AddOptions(options);
|
||
int index = languageDropdown.options.FindIndex(option => option.text == languages[settings.lang]) ;
|
||
|
||
|
||
if (index != -1)
|
||
{
|
||
languageDropdown.value = index;
|
||
}
|
||
|
||
localizationManager.SetLanguage(settings.lang);
|
||
delay = settings.textSpeed;
|
||
textSpeed.value = delay;
|
||
pauseText.text = localizationManager.GetText("pause");
|
||
textSpeedText.text = localizationManager.GetText("textSpeed");
|
||
languageText.text = localizationManager.GetText("language");
|
||
mainScreenText.fontSize = localizationManager.GetFloat("fontSize");
|
||
|
||
}
|
||
|
||
public void setGameState(string action)
|
||
{
|
||
if (action == null) return;
|
||
var auto = SaveSystem.LoadAutoSave();
|
||
if (action == "continue")
|
||
{
|
||
}
|
||
if (action == "newGame")
|
||
{
|
||
auto = null;
|
||
}
|
||
startScreen.SetActive(false);
|
||
|
||
if (auto != null)
|
||
Status = auto.status;
|
||
else
|
||
Status = "";
|
||
StartCoroutine(AutoSave());
|
||
mainScreenTextGO.SetActive(true);
|
||
startScreen.SetActive(false);
|
||
// Запуск или восстановление сценария
|
||
if (string.IsNullOrEmpty(Status))
|
||
{
|
||
StartCoroutine(MainCouroutine());
|
||
}
|
||
else
|
||
{
|
||
RestoreGameByStatus(Status);
|
||
}
|
||
|
||
}
|
||
|
||
// --- 🔑 ЛОГИКА ЗАГРУЗКИ ПАРОЛЯ ИЗ TXT ---
|
||
private void LoadSecretPassword()
|
||
{
|
||
string filePath = Path.Combine(Application.dataPath, "password.txt");
|
||
if (File.Exists(filePath))
|
||
{
|
||
try
|
||
{
|
||
correctPassword = File.ReadAllText(filePath).Trim();
|
||
}
|
||
catch (System.Exception ex)
|
||
{
|
||
Debug.LogError($"Ошибка при чтении password.txt: {ex.Message}");
|
||
correctPassword = "1138";
|
||
}
|
||
}
|
||
else
|
||
{
|
||
TextAsset txtFile = Resources.Load<TextAsset>("password");
|
||
if (txtFile != null)
|
||
{
|
||
correctPassword = txtFile.text.Trim();
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("Не удалось найти password.txt! Используется пароль по умолчанию (1138).");
|
||
correctPassword = "1138";
|
||
}
|
||
}
|
||
}
|
||
|
||
// --- ВСПОМОГАТЕЛЬНЫЕ МЕТОДЫ СЦЕНАРИЯ ---
|
||
private void ShowRootDirectory()
|
||
{
|
||
string dirText = $"C:\\ \n\\\\{localizationManager.GetText("projectsDir")}\n" +
|
||
$"\\\\{localizationManager.GetText("musicDir")}\n" +
|
||
$"\\\\{localizationManager.GetText("notesDir")}\n" +
|
||
$"\\\\{localizationManager.GetText("walletProtectedDir")}\n" +
|
||
$"\\\\{localizationManager.GetText("recycleBinDir")}";
|
||
mainScreenText.text = dirText;
|
||
mainScreenText.fontSize = localizationManager.GetFloat("fontSize");
|
||
}
|
||
|
||
private void RestoreGameByStatus(string status)
|
||
{
|
||
mainScreenText.gameObject.SetActive(true);
|
||
characterTextGO.SetActive(true);
|
||
|
||
switch (status)
|
||
{
|
||
case "waitProjects":
|
||
case "waitMusic":
|
||
case "waitNotesDir":
|
||
case "waitPartAHack":
|
||
case "waitPartBDecrypt":
|
||
case "waitPartCRecycle":
|
||
case "waitWallet":
|
||
case "inWalletPassword":
|
||
StartCoroutine(TypeText(localizationManager.GetText("firstText")));
|
||
ShowRootDirectory();
|
||
if (status == "inWalletPassword")
|
||
{
|
||
notesPanelGO.SetActive(true);
|
||
//Freeze(true);
|
||
passwordMessageText.text = localizationManager.GetText("walletPasswordPrompt");
|
||
passwordInput.text = "";
|
||
}
|
||
break;
|
||
|
||
case "waitLogFile":
|
||
StartCoroutine(TypeText(localizationManager.GetText("firstText")));
|
||
mainScreenText.text =
|
||
$"C:\\\\{localizationManager.GetText("projectsDir")}\\ \n" +
|
||
$"\\\\{localizationManager.GetText("projectsFile1")}\n" +
|
||
$"\\\\{localizationManager.GetText("projectsFile2")}\n" +
|
||
$"\\\\{localizationManager.GetText("projectsFile3")}\n" +
|
||
$"\\\\{localizationManager.GetText("projectsFile4")}";
|
||
break;
|
||
|
||
case "logFile":
|
||
StartCoroutine(TypeText(localizationManager.GetText("restoreLog")));
|
||
ShowShuffledLog();
|
||
isLogShowed = true;
|
||
break;
|
||
|
||
case "waitAnyButtonAfterMusic":
|
||
mainScreenText.text = localizationManager.GetText("musicNotReady");
|
||
StartCoroutine(TypeText(""));
|
||
break;
|
||
|
||
case "finalScreen":
|
||
StartCoroutine(TypeText(localizationManager.GetText("successFinal")));
|
||
if (finalAccessGo != null) finalAccessGo.SetActive(true);
|
||
break;
|
||
|
||
default:
|
||
StartCoroutine(MainCouroutine());
|
||
break;
|
||
}
|
||
}
|
||
|
||
private IEnumerator MainCouroutine()
|
||
{
|
||
mainScreenText.text = localizationManager.GetText("errorMessage");
|
||
mainScreenText.gameObject.SetActive(true);
|
||
characterTextGO.SetActive(true);
|
||
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("firstText")));
|
||
|
||
Status = "waitProjects";
|
||
ShowRootDirectory();
|
||
}
|
||
|
||
private IEnumerator TransitionToNotes()
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("seeNotesFolder")));
|
||
ShowRootDirectory();
|
||
}
|
||
|
||
// ----------------------------------------------------------------------
|
||
// --- ОБРАБОТКА КЛИКОВ И ЛОГИКА СЦЕНАРИЯ ---
|
||
// ----------------------------------------------------------------------
|
||
|
||
private void HandleLineClicked(string lineText)
|
||
{
|
||
if (!flag) return;
|
||
StartCoroutine(HandleClickRoutine(lineText));
|
||
}
|
||
|
||
private IEnumerator HandleClickRoutine(string lineText)
|
||
{
|
||
flag = false;
|
||
|
||
// --- 1. waitProjects -> waitLogFile ---
|
||
if (Status == "waitProjects")
|
||
{
|
||
if (!lineText.Contains("C:"))
|
||
{
|
||
if (lineText.Contains(localizationManager.GetText("projectsDir")))
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("seeProjects")));
|
||
mainScreenText.text =
|
||
$"C:\\\\{localizationManager.GetText("projectsDir")}\\ \n" +
|
||
$"\\\\{localizationManager.GetText("projectsFile1")}\n" +
|
||
$"\\\\{localizationManager.GetText("projectsFile2")}\n" +
|
||
$"\\\\{localizationManager.GetText("projectsFile3")}\n" +
|
||
$"\\\\{localizationManager.GetText("projectsFile4")}";
|
||
Status = "waitLogFile";
|
||
}
|
||
else
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("seeProjects")));
|
||
}
|
||
}
|
||
}
|
||
// --- 2. waitLogFile -> logFile (Start Mini-Game I) ---
|
||
else if (Status == "waitLogFile")
|
||
{
|
||
if (!lineText.Contains("C:"))
|
||
{
|
||
if (lineText.Contains(localizationManager.GetText("projectsFile3"))) // boot.log
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("restoreLog")));
|
||
ShowShuffledLog();
|
||
Status = "logFile";
|
||
}
|
||
else
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("seeLogFile")));
|
||
}
|
||
}
|
||
}
|
||
// --- 3. waitMusic -> waitAnyButtonAfterMusic ---
|
||
else if (Status == "waitMusic")
|
||
{
|
||
if (!lineText.Contains("C:"))
|
||
{
|
||
if (lineText.Contains(localizationManager.GetText("musicDir")))
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("musicNotReady")));
|
||
mainScreenText.text = localizationManager.GetText("musicNotReady");
|
||
Status = "waitAnyButtonAfterMusic";
|
||
}
|
||
else
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("seeMusicFolder")));
|
||
}
|
||
}
|
||
}
|
||
// --- 4. waitNotesDir -> waitPartAHack (Start Mini-Game II) ---
|
||
else if (Status == "waitNotesDir")
|
||
{
|
||
if (!lineText.Contains("C:"))
|
||
{
|
||
if (lineText.Contains(localizationManager.GetText("notesDir")))
|
||
{
|
||
partAHackPanelGO.SetActive(true);
|
||
//Freeze(true);
|
||
currentSequenceIndex = 0;
|
||
hackMessageText.text = localizationManager.GetText("hackInstruction");
|
||
Status = "waitPartAHack";
|
||
}
|
||
else
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("seeNotesFolder")));
|
||
}
|
||
}
|
||
}
|
||
// --- 5. waitPartBDecrypt -> inPartBDecrypt (Start Mini-Game III) ---
|
||
else if (Status == "waitPartBDecrypt")
|
||
{
|
||
if (!lineText.Contains("C:"))
|
||
{
|
||
if (lineText.Contains(localizationManager.GetText("notesDir")))
|
||
{
|
||
partBDecryptPanelGO.SetActive(true);
|
||
//Freeze(true);
|
||
ShowHexDump();
|
||
Status = "inPartBDecrypt";
|
||
}
|
||
else
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("exploreOtherFolders")));
|
||
}
|
||
}
|
||
}
|
||
// --- 6. waitPartCRecycle -> waitWallet (Recycle Bin Click) ---
|
||
else if (Status == "waitPartCRecycle")
|
||
{
|
||
if (!lineText.Contains("C:"))
|
||
{
|
||
if (lineText.Contains(localizationManager.GetText("recycleBinDir")))
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("recycleSuccess")));
|
||
Status = "waitWallet";
|
||
ShowRootDirectory();
|
||
}
|
||
else
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("exploreOtherFolders")));
|
||
}
|
||
}
|
||
}
|
||
// --- 7. waitWallet -> inWalletPassword (Final Password Trigger) ---
|
||
else if (Status == "waitWallet" || Status == "inWalletPassword")
|
||
{
|
||
if (!lineText.Contains("C:"))
|
||
{
|
||
if (lineText.Contains(localizationManager.GetText("walletProtectedDir")))
|
||
{
|
||
if (Status == "waitWallet")
|
||
{
|
||
notesPanelGO.SetActive(true);
|
||
//Freeze(true);
|
||
passwordMessageText.text = localizationManager.GetText("walletPasswordPrompt");
|
||
passwordInput.text = "";
|
||
Status = "inWalletPassword";
|
||
}
|
||
else
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("enterPasswordFirst")));
|
||
}
|
||
}
|
||
else if (lineText.Contains(localizationManager.GetText("recycleBinDir")))
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("exploreWalletNow")));
|
||
}
|
||
else
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("exploreOtherFolders")));
|
||
}
|
||
}
|
||
}
|
||
|
||
// --- Обработка клика по C:\ ---
|
||
if (lineText.Contains("C:"))
|
||
{
|
||
if (Status == "waitLogFile") Status = "waitProjects";
|
||
if (Status == "waitMusic" || Status == "waitAnyButtonAfterMusic") Status = "waitMusic";
|
||
if (Status == "waitPartAHack" || Status == "waitPartBDecrypt") Status = "waitNotesDir";
|
||
if (Status == "waitWallet" || Status == "inWalletPassword") Status = "waitWallet";
|
||
|
||
ShowRootDirectory();
|
||
}
|
||
|
||
flag = true;
|
||
}
|
||
|
||
|
||
void Update()
|
||
{
|
||
if (Status == "waitAnyButtonAfterMusic")
|
||
{
|
||
if (Input.anyKeyDown)
|
||
{
|
||
Status = "waitNotesDir";
|
||
StartCoroutine(TransitionToNotes());
|
||
}
|
||
}
|
||
//StartCoroutine(smoke());
|
||
}
|
||
|
||
int counter = 0;
|
||
bool smokeFlag = false;
|
||
IEnumerator smoke()
|
||
{
|
||
if (smokeFlag) yield break;
|
||
smokeFlag = true;
|
||
if (counter == cupSmoke.Length)
|
||
counter = 0;
|
||
for (int i = 0; i < cupSmoke.Length; i++)
|
||
{
|
||
cupSmoke[i].SetActive(false);
|
||
}
|
||
cupSmoke[counter].SetActive(true);
|
||
counter++;
|
||
yield return new WaitForSeconds(cupDekay);
|
||
smokeFlag = false;
|
||
}
|
||
|
||
// ----------------------------------------------------------------------
|
||
// --- МИНИ-ИГРА I: DRAG & DROP ЛОГИКА ---
|
||
// ----------------------------------------------------------------------
|
||
|
||
private void ShowShuffledLog()
|
||
{
|
||
List<string> logLines = GetLogLines();
|
||
List<string> shuffled = ShuffleLines(logLines);
|
||
string shuffledLog = string.Join("\n", shuffled);
|
||
|
||
mainScreenText.fontSize = localizationManager.GetFloat("logFontSize");
|
||
StartCoroutine(TypeTextToMainScreen(shuffledLog));
|
||
}
|
||
|
||
private List<string> ShuffleLines(List<string> lines)
|
||
{
|
||
System.Random rng = new System.Random();
|
||
List<string> shuffled = new List<string>(lines);
|
||
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 List<string> GetLogLines()
|
||
{
|
||
List<string> logLines = new List<string>();
|
||
|
||
for (int i = 1; i <= 6; i++)
|
||
{
|
||
string key = $"logLine{i}";
|
||
string line = localizationManager.GetText(key);
|
||
if (!string.IsNullOrEmpty(line))
|
||
logLines.Add(line);
|
||
}
|
||
|
||
return logLines;
|
||
}
|
||
|
||
private IEnumerator TypeTextToMainScreen(string text)
|
||
{
|
||
mainScreenText.text = "";
|
||
foreach (char c in text)
|
||
{
|
||
mainScreenText.text += c;
|
||
yield return new WaitForSeconds(delayMainScreen);
|
||
|
||
if (Input.GetKeyDown(KeyCode.Space))
|
||
{
|
||
mainScreenText.text = text;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (Status == "logFile")
|
||
{
|
||
isLogShowed = true;
|
||
}
|
||
}
|
||
|
||
private void HandleDragStart(int line)
|
||
{
|
||
if (Status == "logFile" && isLogShowed)
|
||
{
|
||
currentLogLines = new List<string>(mainScreenText.text.Split('\n'));
|
||
}
|
||
}
|
||
|
||
private void HandleDragging(int from, int to)
|
||
{
|
||
if (Status == "logFile" && currentLogLines.Count > 0)
|
||
{
|
||
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 (!isLogShowed || Status != "logFile") return;
|
||
|
||
List<string> correctLogLines = GetLogLines();
|
||
bool isCorrectlySorted = true;
|
||
|
||
if (currentLogLines.Count == correctLogLines.Count)
|
||
{
|
||
for (int i = 0; i < currentLogLines.Count; i++)
|
||
{
|
||
if (currentLogLines[i].Trim() != correctLogLines[i].Trim())
|
||
{
|
||
isCorrectlySorted = false;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else { isCorrectlySorted = false; }
|
||
|
||
if (isCorrectlySorted)
|
||
{
|
||
StartCoroutine(LogSuccessRoutine());
|
||
}
|
||
}
|
||
|
||
private IEnumerator LogSuccessRoutine()
|
||
{
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("seeMusicFolder")));
|
||
Status = "waitMusic";
|
||
mainScreenText.fontSize = localizationManager.GetFloat("fontSize");
|
||
ShowRootDirectory();
|
||
}
|
||
|
||
// ----------------------------------------------------------------------
|
||
// --- МИНИ-ИГРА II: PART A - MEMORY MAP HACK ЛОГИКА ---
|
||
// ----------------------------------------------------------------------
|
||
|
||
public void OnHackNodeClick(int nodeID)
|
||
{
|
||
if (Status != "waitPartAHack" || currentSequenceIndex >= correctSequence.Count) return;
|
||
|
||
if (nodeID == correctSequence[currentSequenceIndex])
|
||
{
|
||
currentSequenceIndex++;
|
||
hackMessageText.text = localizationManager.GetText("nodeSynced") + $" ({currentSequenceIndex}/{correctSequence.Count})";
|
||
|
||
if (currentSequenceIndex >= correctSequence.Count)
|
||
{
|
||
StartCoroutine(PartAHackSuccessRoutine());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
hackMessageText.text = localizationManager.GetText("nodeFailure");
|
||
currentSequenceIndex = 0;
|
||
}
|
||
}
|
||
|
||
private IEnumerator PartAHackSuccessRoutine()
|
||
{
|
||
hackMessageText.text = localizationManager.GetText("partASuccessMessage");
|
||
yield return new WaitForSecondsRealtime(2f);
|
||
|
||
partAHackPanelGO.SetActive(false);
|
||
Freeze(false);
|
||
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("partAScriptFragment")));
|
||
|
||
Status = "waitPartBDecrypt";
|
||
ShowRootDirectory();
|
||
}
|
||
|
||
public void ClosePartAHackPanel()
|
||
{
|
||
partAHackPanelGO.SetActive(false);
|
||
Freeze(false);
|
||
currentSequenceIndex = 0;
|
||
hackMessageText.text = localizationManager.GetText("hackInstruction");
|
||
Status = "waitNotesDir";
|
||
}
|
||
|
||
// ----------------------------------------------------------------------
|
||
// --- МИНИ-ИГРА III: PART B - HEX DECRYPT ЛОГИКА ---
|
||
// ----------------------------------------------------------------------
|
||
|
||
private void ShowHexDump()
|
||
{
|
||
string dump = "C[0] 01 23 45 67 89 AB CD EF\n" +
|
||
$"C[1] <color=#FFFF00>1A</color> 33 44 55 66 77 88 99\n" +
|
||
"C[2] 11 22 33 44 55 66 77 88 99\n" +
|
||
"C[3] 11 22 33 44 55 66 77 88 99\n" +
|
||
"C[4] 11 22 33 44 55 66 77 88 99\n" +
|
||
$"C[5] <color=#FFFF00>4B</color> 11 22 33 44 55 66 77\n" +
|
||
"C[6] 11 22 33 44 55 66 77 88 99\n" +
|
||
$"C[7] <color=#FFFF00>22</color> 11 22 33 44 55 66 77";
|
||
|
||
hexDumpText.text = dump;
|
||
checksumInput.text = "";
|
||
decryptMessageText.text = localizationManager.GetText("decryptInstruction");
|
||
}
|
||
|
||
public void CheckChecksum()
|
||
{
|
||
if (flag2) return;
|
||
if (Status != "inPartBDecrypt") return;
|
||
|
||
if (int.TryParse(checksumInput.text, out int enteredValue))
|
||
{
|
||
if (enteredValue == expectedChecksum) // 135
|
||
{
|
||
StartCoroutine(PartBDecryptSuccessRoutine());
|
||
flag2 = true;
|
||
}
|
||
else
|
||
{
|
||
decryptMessageText.text = localizationManager.GetText("decryptFailure");
|
||
checksumInput.text = "";
|
||
}
|
||
}
|
||
else
|
||
{
|
||
decryptMessageText.text = localizationManager.GetText("decryptInputError");
|
||
}
|
||
}
|
||
|
||
private IEnumerator PartBDecryptSuccessRoutine()
|
||
{
|
||
decryptMessageText.text = localizationManager.GetText("decryptSuccessMessage");
|
||
yield return new WaitForSecondsRealtime(3f);
|
||
|
||
partBDecryptPanelGO.SetActive(false);
|
||
Freeze(false);
|
||
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("partBScriptFragment")));
|
||
|
||
Status = "waitPartCRecycle";
|
||
ShowRootDirectory();
|
||
}
|
||
|
||
public void ClosePartBDecryptPanel()
|
||
{
|
||
partBDecryptPanelGO.SetActive(false);
|
||
Freeze(false);
|
||
Status = "waitPartBDecrypt";
|
||
}
|
||
|
||
// ----------------------------------------------------------------------
|
||
// --- 🔑 ФИНАЛЬНЫЙ ЭТАП: ВВОД ПАРОЛЯ (WALLET) ---
|
||
// ----------------------------------------------------------------------
|
||
|
||
public void ConfirmPassword()
|
||
{
|
||
if (flag1 == true) return;
|
||
if (Status != "inWalletPassword") return;
|
||
|
||
// Сравнение введенного текста с паролем, загруженным из файла
|
||
if (passwordInput.text.Trim() == correctPassword)
|
||
{
|
||
StartCoroutine(PasswordSuccessRoutine());
|
||
flag1 = true;
|
||
}
|
||
else
|
||
{
|
||
passwordMessageText.text = localizationManager.GetText("passwordIncorrect");
|
||
passwordInput.text = "";
|
||
}
|
||
}
|
||
|
||
private IEnumerator PasswordSuccessRoutine()
|
||
{
|
||
Freeze(false);
|
||
passwordMessageText.text = localizationManager.GetText("passwordCorrect");
|
||
yield return new WaitForSecondsRealtime(2f);
|
||
yield return StartCoroutine(TypeText(localizationManager.GetText("successFinal")));
|
||
|
||
//notesPanelGO.SetActive(false);
|
||
|
||
//yield return StartCoroutine(TypeText(localizationManager.GetText("successFinal")));
|
||
|
||
//Status = "finalScreen";
|
||
//if (finalAccessGo != null) finalAccessGo.SetActive(true);
|
||
}
|
||
|
||
public void CloseNotesPanel()
|
||
{
|
||
notesPanelGO.SetActive(false);
|
||
Freeze(false);
|
||
Status = "waitWallet";
|
||
}
|
||
|
||
// ----------------------------------------------------------------------
|
||
// --- ОБЩИЕ МЕТОДЫ (Typing, Freeze) ---
|
||
// ----------------------------------------------------------------------
|
||
|
||
private IEnumerator TypeText(string text)
|
||
{
|
||
flag = 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;
|
||
}
|
||
}
|
||
flag = true;
|
||
}
|
||
|
||
public void Freeze(bool isFreeze)
|
||
{
|
||
Time.timeScale = isFreeze ? 0f : 1.0f;
|
||
}
|
||
|
||
// ----------------------------------------------------------------------
|
||
// --- СИСТЕМА СОХРАНЕНИЙ И НАСТРОЕК (Adapters) ---
|
||
// ----------------------------------------------------------------------
|
||
|
||
public void LoadSaveImages()
|
||
{
|
||
for (int i = 0; i < 4; 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;
|
||
LoadImage(i + 1, saveImages[i]);
|
||
}
|
||
else
|
||
{
|
||
withSaveGO[i].SetActive(false);
|
||
emptySaveGO[i].SetActive(true);
|
||
saveImages[i].texture = null;
|
||
}
|
||
}
|
||
}
|
||
|
||
public void LoadImage(int saveNumber, RawImage rawImage)
|
||
{
|
||
string path;
|
||
if (saveNumber == 0)
|
||
{
|
||
path = Application.persistentDataPath + "/Saves/ImageAutosave.png";
|
||
}
|
||
else
|
||
{
|
||
path = Application.persistentDataPath + $"/Saves/ImageSave{saveNumber}.png";
|
||
}
|
||
|
||
if (File.Exists(path))
|
||
{
|
||
byte[] fileData = File.ReadAllBytes(path);
|
||
Texture2D texture = new Texture2D(2, 2);
|
||
if (texture.LoadImage(fileData))
|
||
{
|
||
rawImage.texture = texture;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
rawImage.texture = null;
|
||
}
|
||
}
|
||
|
||
private IEnumerator AutoSave()
|
||
{
|
||
while (true)
|
||
{
|
||
yield return new WaitForSeconds(1f);
|
||
|
||
GameData data = new GameData
|
||
{
|
||
saveName = localizationManager.GetText("autosaveName"),
|
||
status = Status
|
||
};
|
||
SaveSystem.AutoSave(data);
|
||
}
|
||
}
|
||
|
||
public void SaveGame(int saveNumber)
|
||
{
|
||
saveNumberTemp = saveNumber;
|
||
confirmSaveGo.SetActive(true);
|
||
}
|
||
|
||
public void ConfirmSaveGame()
|
||
{
|
||
GameData data = new GameData
|
||
{
|
||
saveName = saveNameInput.text,
|
||
status = Status
|
||
};
|
||
SaveSystem.SaveGame(saveNumberTemp, data);
|
||
LoadSaveImages();
|
||
confirmSaveGo.SetActive(false);
|
||
}
|
||
|
||
public void LoadGame(int loadNumber)
|
||
{
|
||
GameData data = SaveSystem.LoadGame(loadNumber);
|
||
if (data != null)
|
||
{
|
||
Restart();
|
||
}
|
||
}
|
||
|
||
public void DeleteGame(int loadNumber)
|
||
{
|
||
SaveSystem.DeleteGame(loadNumber);
|
||
LoadSaveImages();
|
||
}
|
||
|
||
public void DeleteAutoSave()
|
||
{
|
||
SaveSystem.DeleteAutoSave();
|
||
Restart();
|
||
}
|
||
|
||
public void Restart()
|
||
{
|
||
Time.timeScale = 1.0f;
|
||
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
|
||
}
|
||
|
||
public void UpdateTextSpeed()
|
||
{
|
||
GameSettings settings = SaveSystem.Load();
|
||
settings.textSpeed = textSpeed.value;
|
||
delay = textSpeed.value;
|
||
SaveSystem.Save(settings);
|
||
}
|
||
|
||
public void UpdateLocale()
|
||
{
|
||
localizationManager.SetLanguage(languageDropdown.captionText.text);
|
||
GameSettings settings = SaveSystem.Load();
|
||
|
||
string selectedLanguageKey = localizationManager.GetAllLanguages()[languageDropdown.captionText.text];
|
||
|
||
if (selectedLanguageKey != settings.lang)
|
||
{
|
||
settings.lang = selectedLanguageKey;
|
||
SaveSystem.Save(settings);
|
||
Restart();
|
||
}
|
||
}
|
||
|
||
// ----------------------------------------------------------------------
|
||
// --- АНИМАЦИЯ КОТА ---
|
||
// ----------------------------------------------------------------------
|
||
|
||
void catSpritesDisactivate()
|
||
{
|
||
if (catSprites.Length > 0)
|
||
{
|
||
for (int i = 0; i < catSprites.Length; i++)
|
||
{
|
||
if (catSprites[i] != null) catSprites[i].SetActive(false);
|
||
}
|
||
}
|
||
}
|
||
|
||
IEnumerator catAnim()
|
||
{
|
||
catSpritesDisactivate();
|
||
if (catSpritesToSleep.Length > 0) catSpritesToSleep[0].SetActive(true);
|
||
string catStatus = "active";
|
||
|
||
while (true)
|
||
{
|
||
int random = Random.Range(0, 1000);
|
||
|
||
if (random <= 3)
|
||
{
|
||
print(catStatus);
|
||
if (catStatus == "active")
|
||
{
|
||
catStatus = "sleep";
|
||
|
||
catSpritesDisactivate();
|
||
for (int cat_pos = 0; cat_pos < catSpritesToSleep.Length; cat_pos++)
|
||
{
|
||
for (int i = 0; i < catSpritesToSleep.Length; i++)
|
||
{
|
||
if (i == cat_pos)
|
||
catSpritesToSleep[i].SetActive(true);
|
||
else
|
||
catSpritesToSleep[i].SetActive(false);
|
||
}
|
||
yield return new WaitForSeconds(catDelay);
|
||
}
|
||
yield return new WaitForSeconds(3);
|
||
}
|
||
else if (catStatus == "sleep")
|
||
{
|
||
catStatus = "active";
|
||
|
||
catSpritesDisactivate();
|
||
for (int cat_pos = 0; cat_pos < catSpritesToActive.Length; cat_pos++)
|
||
{
|
||
for (int i = 0; i < catSpritesToActive.Length; i++)
|
||
{
|
||
if (i == cat_pos)
|
||
catSpritesToActive[i].SetActive(true);
|
||
else
|
||
catSpritesToActive[i].SetActive(false);
|
||
}
|
||
yield return new WaitForSeconds(catDelay);
|
||
}
|
||
yield return new WaitForSeconds(3);
|
||
}
|
||
print(catStatus);
|
||
}
|
||
else if (random > 980)
|
||
{
|
||
if (catStatus == "sleep")
|
||
{
|
||
print(catStatus);
|
||
catSpritesDisactivate();
|
||
for (int cat_pos = 0; cat_pos < catSpritesEar.Length; cat_pos++)
|
||
{
|
||
for (int i = 0; i < catSpritesEar.Length; i++)
|
||
{
|
||
if (i == cat_pos)
|
||
catSpritesEar[i].SetActive(true);
|
||
else
|
||
catSpritesEar[i].SetActive(false);
|
||
}
|
||
yield return new WaitForSeconds(catDelay);
|
||
}
|
||
catSpritesDisactivate();
|
||
if (catSpritesToActive.Length > 0) catSpritesToActive[0].SetActive(true);
|
||
yield return new WaitForSeconds(3);
|
||
}
|
||
}
|
||
else if (random > 940)
|
||
{
|
||
if (catStatus == "active")
|
||
{
|
||
print(catStatus);
|
||
catSpritesDisactivate();
|
||
if (catSprites.Length > 0) catSprites[0].SetActive(true);
|
||
yield return new WaitForSeconds(catDelay);
|
||
|
||
catSpritesDisactivate();
|
||
if (catSpritesBlink != null) catSpritesBlink.SetActive(true);
|
||
yield return new WaitForSeconds(catDelay);
|
||
|
||
catSpritesDisactivate();
|
||
if (catSprites.Length > 0) catSprites[0].SetActive(true);
|
||
yield return new WaitForSeconds(catDelay);
|
||
yield return new WaitForSeconds(3);
|
||
}
|
||
}
|
||
|
||
yield return new WaitForSeconds(catDelay);
|
||
}
|
||
}
|
||
} |