using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Scripting; namespace NecromancerTome { /// /// Книга с оглавлением (03.10.2026, BACKLOG «Книга с оглавлением и главами»). Окно necroTome /// (Config/XUi_InGame/windows.xml): оглавление - кнопки глав (до восьми), глава - страницы /// с «Назад/Далее», «Оглавление» возвращает к списку, «Закрыть» и Esc закрывают. /// /// СОДЕРЖАНИЕ - список Chapters ниже: ключ названия, ключи страниц (Localization.csv, /// necroTome*), условие открытия. Закрытая глава в оглавлении не показывается. Условия брать /// из того, что игра уже хранит (уровень некромантии, рецепты, испытания), своё хранение - только /// для чистых событий, по cvar на событие. /// public static class NecroTomeBook { public const string WindowGroup = "necroTome"; public class Chapter { public string TitleKey; public string[] PageKeys; public Func Unlocked; } public static readonly List Chapters = new List { // Глава 1 (указание 03.10): статья о некроэнергии, сокращённая - без примеров и бытовой речи. new Chapter { TitleKey = "necroTomeCh1Title", PageKeys = new[] { "necroTomeCh1P1", "necroTomeCh1P2", "necroTomeCh1P3", "necroTomeCh1P4" }, Unlocked = _p => true }, }; public static void Open(EntityPlayerLocal _player) { LocalPlayerUI ui = LocalPlayerUI.GetUIForPlayer(_player); ui?.windowManager.Open(WindowGroup, true); } } [Preserve] public class XUiC_NecroTome : XUiController { const int MaxButtons = 8; XUiV_Label _title, _text, _page; XUiC_SimpleButton _toc, _prev, _next, _close; readonly XUiC_SimpleButton[] _chapterButtons = new XUiC_SimpleButton[MaxButtons]; /// Глава по кнопке оглавления (только открытые главы, по порядку). readonly int[] _buttonChapter = new int[MaxButtons]; int _chapter = -1, _pageIndex; public override void Init() { base.Init(); _title = GetChildById("lblTitle")?.ViewComponent as XUiV_Label; _text = GetChildById("lblText")?.ViewComponent as XUiV_Label; _page = GetChildById("lblPage")?.ViewComponent as XUiV_Label; _toc = GetChildById("btnToc") as XUiC_SimpleButton; _prev = GetChildById("btnPrev") as XUiC_SimpleButton; _next = GetChildById("btnNext") as XUiC_SimpleButton; _close = GetChildById("btnClose") as XUiC_SimpleButton; if (_toc != null) _toc.OnPressed += (_s, _m) => ShowToc(); if (_prev != null) _prev.OnPressed += (_s, _m) => Turn(-1); if (_next != null) _next.OnPressed += (_s, _m) => Turn(1); if (_close != null) _close.OnPressed += (_s, _m) => xui.playerUI.windowManager.Close(NecroTomeBook.WindowGroup); for (int i = 0; i < MaxButtons; i++) { int idx = i; _chapterButtons[i] = GetChildById("btnCh" + (i + 1)) as XUiC_SimpleButton; if (_chapterButtons[i] != null) { _chapterButtons[i].OnPressed += (_s, _m) => ShowChapter(_buttonChapter[idx], 0); } } } public override void OnOpen() { base.OnOpen(); ShowToc(); } void ShowToc() { _chapter = -1; SetLabel(_title, Localization.Get("necroTomeToc")); SetLabel(_text, ""); SetLabel(_page, ""); EntityPlayerLocal player = xui.playerUI.entityPlayer; int b = 0; for (int c = 0; c < NecroTomeBook.Chapters.Count && b < MaxButtons; c++) { NecroTomeBook.Chapter ch = NecroTomeBook.Chapters[c]; if (ch.Unlocked != null && !ch.Unlocked(player)) { continue; } _buttonChapter[b] = c; if (_chapterButtons[b] != null) { _chapterButtons[b].Text = Localization.Get(ch.TitleKey); _chapterButtons[b].ViewComponent.IsVisible = true; } b++; } for (; b < MaxButtons; b++) { if (_chapterButtons[b] != null) { _chapterButtons[b].ViewComponent.IsVisible = false; } } SetVisible(_toc, false); SetVisible(_prev, false); SetVisible(_next, false); } void ShowChapter(int _c, int _p) { if (_c < 0 || _c >= NecroTomeBook.Chapters.Count) { return; } NecroTomeBook.Chapter ch = NecroTomeBook.Chapters[_c]; _chapter = _c; _pageIndex = Mathf.Clamp(_p, 0, ch.PageKeys.Length - 1); foreach (XUiC_SimpleButton btn in _chapterButtons) { SetVisible(btn, false); } SetLabel(_title, Localization.Get(ch.TitleKey)); SetLabel(_text, Localization.Get(ch.PageKeys[_pageIndex])); SetLabel(_page, (_pageIndex + 1) + " / " + ch.PageKeys.Length); SetVisible(_toc, true); SetVisible(_prev, true); SetVisible(_next, true); if (_prev != null) _prev.Enabled = _pageIndex > 0; if (_next != null) _next.Enabled = _pageIndex < ch.PageKeys.Length - 1; } void Turn(int _d) { if (_chapter >= 0) { ShowChapter(_chapter, _pageIndex + _d); } } static void SetLabel(XUiV_Label _l, string _s) { if (_l != null) { _l.Text = _s; } } static void SetVisible(XUiController _c, bool _v) { if (_c?.ViewComponent != null) { _c.ViewComponent.IsVisible = _v; } } } /// necrotome - открыть книгу (проверка окна без чертогов, в том числе через почтовый ящик). [Preserve] public class ConsoleCmdNecroTome : ConsoleCmdAbstract { public override string[] getCommands() => new[] { "necrotome" }; public override string getDescription() => "NecromancerTome: открыть книгу с оглавлением"; public override void Execute(List _params, CommandSenderInfo _senderInfo) { EntityPlayerLocal player = GameManager.Instance.World?.GetPrimaryPlayer(); if (player != null) { NecroTomeBook.Open(player); } } } }