- Книга некроманта: главы «Нож некроманта» и «Могильная крыса» - лист-чертёж сверху (Textures/, три вида из Blender, подписи на эсперанто), управление и лор; окно книги непрозрачное, текст с контуром - «Дух крысы» переименован в «Могильную крысу» на 13 языках (ключи прежние) - Блоки (Dev): плакат-синька ножа (necroPosterKnife, 3:2 под полотно рамки), грифельная доска necroChalkboard (надписи - TEFeatureSignable, писать только в редакторе/творческом; шрифт Neucha OFL, свой шейдер текста с тестом глубины), дверь-книжный шкаф necroBookDoor (своя модель с аниматором, хитбокс створки через RootTransformRefParent) - Чертоги: префаб 25x8x25 (промежуточный); открываются только межкомнатные двери; надписи на досках по дням игры: «Отомсти архимагу!», с 5-го дня «Берегись излучения красной луны» - Нож: силовая атака стоит 20 здоровья, с «Мёртвой бурей» 40; не хватает - itembreak, «Недостаточно здоровья» и обычный удар; описания на 13 языках - Консольная команда necromodel - устройство модели блока в лог Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
107 lines
4.1 KiB
C#
107 lines
4.1 KiB
C#
using System;
|
||
using HarmonyLib;
|
||
using UnityEngine;
|
||
|
||
namespace NecromancerTome
|
||
{
|
||
/// <summary>
|
||
/// Грифельная доска (necroChalkboard, 09.10.2026): надписи мелом - как на табличках (TEFeatureSignable), но
|
||
/// «игрок этого делать не будет, а нам для сюжета пригодится». Поэтому команда «написать» у доски есть
|
||
/// только в редакторе префабов, в творческом режиме и в режиме отладки (так мы и подписываем её - текст
|
||
/// сохраняется в префабе локации, IFeatureSavedInPrefab). В обычной игре доску только читают: без команды
|
||
/// нет и подсказки «E - использовать».
|
||
/// </summary>
|
||
public static class Chalkboard
|
||
{
|
||
public const string BlockName = "necroChalkboard";
|
||
|
||
public static bool Is(TEFeatureSignable _sign)
|
||
{
|
||
return _sign?.Parent?.TeData?.Block != null && _sign.Parent.TeData.Block.GetBlockName() == BlockName;
|
||
}
|
||
|
||
/// <summary>Кто может писать: редактор префабов, творческий режим, отладка.</summary>
|
||
public static bool CanWrite()
|
||
{
|
||
return GameManager.Instance != null && GameManager.Instance.IsEditMode() ||
|
||
GameStats.GetBool(EnumGameStats.IsCreativeMenuEnabled) ||
|
||
GamePrefs.GetBool(EnumGamePrefs.DebugMenuEnabled);
|
||
}
|
||
|
||
/// <summary>Материал надписи - из бандла, свой шейдер NecroTome/ChalkText с ZTest LEqual (тест 09.10: надпись
|
||
/// просвечивала сквозь стены - встроенный GUI/Text Shader берёт ZTest из глобального unity_GUIZTestMode, который
|
||
/// интерфейс держит «Always», и переопределение в материале не помогло). Шрифт динамический: его текстура
|
||
/// растёт и пересоздаётся при новых буквах - держим её в материале надписи (один материал на все доски).</summary>
|
||
static Material _mat;
|
||
static Font _font;
|
||
static bool _hooked;
|
||
|
||
public static void BindText(TextMesh _tm, MeshRenderer _r)
|
||
{
|
||
_mat = _r.sharedMaterial;
|
||
_font = _tm.font;
|
||
if (_mat == null || _font == null)
|
||
{
|
||
return;
|
||
}
|
||
_mat.mainTexture = _font.material.mainTexture;
|
||
if (!_hooked)
|
||
{
|
||
_hooked = true;
|
||
Font.textureRebuilt += _f =>
|
||
{
|
||
if (_mat != null && _f == _font)
|
||
{
|
||
_mat.mainTexture = _f.material.mainTexture;
|
||
}
|
||
};
|
||
}
|
||
}
|
||
}
|
||
|
||
[HarmonyPatch(typeof(TEFeatureSignable), nameof(TEFeatureSignable.SetBlockEntityData))]
|
||
public static class Patch_TEFeatureSignable_SetBlockEntityData_Chalkboard
|
||
{
|
||
public static void Postfix(TEFeatureSignable __instance, BlockEntityData _blockEntityData)
|
||
{
|
||
if (_blockEntityData == null || !_blockEntityData.bHasTransform || !Chalkboard.Is(__instance))
|
||
{
|
||
return;
|
||
}
|
||
foreach (TextMesh tm in _blockEntityData.transform.GetComponentsInChildren<TextMesh>())
|
||
{
|
||
MeshRenderer r = tm.GetComponent<MeshRenderer>();
|
||
if (r != null && tm.font != null)
|
||
{
|
||
Chalkboard.BindText(tm, r);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
[HarmonyPatch(typeof(TEFeatureSignable), nameof(TEFeatureSignable.AllowBlockActivationCommand))]
|
||
public static class Patch_TEFeatureSignable_AllowBlockActivationCommand_Chalkboard
|
||
{
|
||
public static void Postfix(TEFeatureSignable __instance, ITileEntityFeature _module, ReadOnlySpan<char> _commandName, ref bool __result)
|
||
{
|
||
if (__result && __instance.Equals(_module) && _commandName.SequenceEqual("edit".AsSpan()) &&
|
||
Chalkboard.Is(__instance) && !Chalkboard.CanWrite())
|
||
{
|
||
__result = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
[HarmonyPatch(typeof(TEFeatureSignable), nameof(TEFeatureSignable.GetActivationText))]
|
||
public static class Patch_TEFeatureSignable_GetActivationText_Chalkboard
|
||
{
|
||
public static void Postfix(TEFeatureSignable __instance, ref string __result)
|
||
{
|
||
if (Chalkboard.Is(__instance) && !Chalkboard.CanWrite())
|
||
{
|
||
__result = null;
|
||
}
|
||
}
|
||
}
|
||
}
|