Files
necromants-tome-7d2d-3-2/HarmonySrc/ChalkboardPatch.cs
T
AlexCubeandClaude Opus 5.5 4e14a0562b Книга: главы ножа и Могильной крысы; плакат ножа, грифельная доска, дверь-шкаф; чертоги 25x8x25; плата силовой ножа 20/40
- Книга некроманта: главы «Нож некроманта» и «Могильная крыса» - лист-чертёж сверху (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>
2026-10-09 18:26:17 +03:00

107 lines
4.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}
}
}