Files
necromants-tome-7d2d-3-2/HarmonySrc/ChalkboardPatch.cs
T
AlexCubeandClaude Opus 5.5 3780a69d93 Меловая доска игрока: рецепт, записи в обычной игре
Отдельный блок necroChalkboardPlayer (модель и надпись сюжетной доски):
крафт с начала игры - краска 2, дерево 8, гвозди 4, волокна 3, кости 2;
писать можно в обычной игре, записи свои у каждой доски; можно подобрать.
Сюжетная necroChalkboard (чертоги) по-прежнему пишется только модом.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 14:04:48 +03:00

123 lines
4.9 KiB
C#
Raw Permalink 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
{
/// <summary>Сюжетная доска (чертоги, локации): пишет мод или автор префаба.</summary>
public const string BlockName = "necroChalkboard";
/// <summary>Доска игрока (10.10): крафтится, пишется в обычной игре - записи свои у каждой доски.</summary>
public const string PlayerBlockName = "necroChalkboardPlayer";
static string NameOf(TEFeatureSignable _sign)
{
return _sign?.Parent?.TeData?.Block?.GetBlockName();
}
/// <summary>Любая из досок - для материала надписи.</summary>
public static bool Is(TEFeatureSignable _sign)
{
string n = NameOf(_sign);
return n == BlockName || n == PlayerBlockName;
}
/// <summary>Сюжетная доска - писать только в редакторе, творческом режиме, отладке.</summary>
public static bool IsLocked(TEFeatureSignable _sign)
{
return NameOf(_sign) == BlockName && !CanWrite();
}
/// <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.IsLocked(__instance))
{
__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.IsLocked(__instance))
{
__result = null;
}
}
}
}