Оссуарий-котёл: одна ячейка образца, хранилище 6, перенос старых ячеек, свечение, огонёк, рецепт в кузне (#66, #69)
- blocks.xml: 6 ячеек хранилища (цикл вдвое дольше - добыча прежняя); видно одну ячейку образца и одну топлива, остальные спрятаны (в данных их по-прежнему 3 и 6 - сейвы не режутся). - Перенос: содержимое спрятанных ячеек у уже поставленных оссуариев уходит в хранилище (проверено на test8: уголь, камень, сферы). - Свечение рун и окошек и сфера на крышке - пока работает (OssuaryGlow). - Огонёк дикого духа: вылет из окошка с уходом в землю и затуханием, возврат с другой стороны в противоположное окошко; только пока работает. В игре пока не увиден - разобрать (necroossuary wisp on|off). - Рецепт - кузня, железо вместо дерева и юкки (плавильня / лом). - Описание на 13 языках под котёл и вольных духов. - Консоль: necroossuary info / put (отладка ячеек). - DLL включает и #72, #74. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
e3cdff0323
commit
c2610da59a
@@ -53,15 +53,23 @@ namespace NecromancerTome
|
||||
|
||||
public static bool Is(TileEntityCollector te) => te != null && Is(te.blockValue.Block);
|
||||
|
||||
/// <summary>os1 -> 0, os2 -> 1, os3 -> 2; иначе -1.</summary>
|
||||
/// <summary>Ячейка образца для выхода: у котла (#66, 22.10) образец один - все выходы os1..os6 берут ресурс из
|
||||
/// ячейки 0 («Ячейка под образец - одна»). Не наш выход - -1.</summary>
|
||||
public static int ModSlotOf(BlockCollector.OutputType outputType)
|
||||
{
|
||||
string name = outputType?.Name;
|
||||
if (name == null || name.Length != 3 || !name.StartsWith("os"))
|
||||
return -1;
|
||||
return name[2] - '1';
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>Видимых в окне ячеек образца и топлива (#66, 22.10: «Ячейка под образец - одна; ячейка под кровавую
|
||||
/// сферу (или камень) - одна»). В данных их по-прежнему 3 и 6: длины пишутся в сейв, а при загрузке игра обрезает
|
||||
/// лишнее по конфигу - уменьшение молча выбросило бы содержимое. Лишние прячутся в окне, их старое содержимое
|
||||
/// переносит в хранилище Patch_TileEntityCollector_UpdateTick_GeoOssuaryMigrate.</summary>
|
||||
public const int VisibleModSlots = 1;
|
||||
public const int VisibleFuelSlots = 1;
|
||||
|
||||
/// <summary>Ресурс в ячейке модификации, если он из списка; иначе null.</summary>
|
||||
public static ItemClass ResourceIn(TileEntityCollector te, int modSlot)
|
||||
{
|
||||
@@ -82,8 +90,11 @@ namespace NecromancerTome
|
||||
public static void Postfix(XUiC_DewCollectorModGrid __instance, TileEntityCollector te)
|
||||
{
|
||||
bool ossuary = GeoOssuary.Is(te);
|
||||
foreach (XUiC_ItemStack slot in __instance.itemControllers)
|
||||
for (int i = 0; i < __instance.itemControllers.Length; i++)
|
||||
{
|
||||
XUiC_ItemStack slot = __instance.itemControllers[i];
|
||||
// окно у всех коллекторов общее - чужим возвращаем все ячейки
|
||||
slot.ViewComponent.IsVisible = !ossuary || i < GeoOssuary.VisibleModSlots;
|
||||
if (!(slot is XUiC_RequiredItemStack required))
|
||||
continue;
|
||||
required.OverrideStackCount = ossuary ? 1 : -1;
|
||||
@@ -251,4 +262,104 @@ namespace NecromancerTome
|
||||
__result = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Одна ячейка топлива в окне (GeoOssuary.VisibleFuelSlots): остальные ячейки сетки и их подсказки-картинки
|
||||
/// спрятаны. Сетка общая для всех коллекторов (и для катализатора) - чужим всё показываем обратно.</summary>
|
||||
public static class GeoOssuaryFuelGrid
|
||||
{
|
||||
public static void Apply(XUiC_CollectorFuelGrid _grid)
|
||||
{
|
||||
if (_grid?.tileEntity == null || _grid.fuelBehavior != XUiC_CollectorFuelGrid.FuelBehavior.Fuel)
|
||||
return;
|
||||
bool ossuary = GeoOssuary.Is(_grid.tileEntity);
|
||||
int n = _grid.tileEntity.FuelGridLength;
|
||||
for (int i = 0; i < _grid.itemControllers.Length; i++)
|
||||
{
|
||||
bool show = i < n && (!ossuary || i < GeoOssuary.VisibleFuelSlots);
|
||||
if (_grid.itemControllers[i].ViewComponent.IsVisible != show && (ossuary || i < n))
|
||||
_grid.itemControllers[i].ViewComponent.IsVisible = show;
|
||||
if (_grid.previewSprites != null && i < _grid.previewSprites.Length && _grid.previewSprites[i] != null && ossuary && i >= GeoOssuary.VisibleFuelSlots)
|
||||
_grid.previewSprites[i].IsVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(XUiC_CollectorFuelGrid), nameof(XUiC_CollectorFuelGrid.SetTileEntity))]
|
||||
public static class Patch_XUiC_CollectorFuelGrid_SetTileEntity_GeoOssuary
|
||||
{
|
||||
public static void Postfix(XUiC_CollectorFuelGrid __instance) => GeoOssuaryFuelGrid.Apply(__instance);
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(XUiC_CollectorFuelGrid), nameof(XUiC_CollectorFuelGrid.OnTileEntityChanged))]
|
||||
public static class Patch_XUiC_CollectorFuelGrid_OnTileEntityChanged_GeoOssuary
|
||||
{
|
||||
public static void Postfix(XUiC_CollectorFuelGrid __instance) => GeoOssuaryFuelGrid.Apply(__instance);
|
||||
}
|
||||
|
||||
/// <summary>Shift-клик топливом: у оссуария - только в видимую ячейку (ваниль раскладывает по всей сетке).</summary>
|
||||
[HarmonyPatch(typeof(XUiC_CollectorFuelGrid), nameof(XUiC_CollectorFuelGrid.TryAddFuel))]
|
||||
public static class Patch_XUiC_CollectorFuelGrid_TryAddFuel_GeoOssuary
|
||||
{
|
||||
public static bool Prefix(XUiC_CollectorFuelGrid __instance, ItemClass newItemClass, ItemStack newItemStack, ref bool __result)
|
||||
{
|
||||
if (__instance.fuelBehavior != XUiC_CollectorFuelGrid.FuelBehavior.Fuel || !GeoOssuary.Is(__instance.tileEntity))
|
||||
return true;
|
||||
if (System.Array.IndexOf(__instance.tileEntity.GetFuelTypes(), newItemClass.Name) >= 0)
|
||||
{
|
||||
XUiC_ItemStack slot = __instance.itemControllers[0];
|
||||
if (slot.ItemStack.IsEmpty())
|
||||
{
|
||||
slot.ItemStack = newItemStack.Clone();
|
||||
newItemStack.count = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int n = slot.ItemStack.StackTransferCount(newItemStack);
|
||||
slot.ItemStack.count += n;
|
||||
newItemStack.count -= n;
|
||||
}
|
||||
__instance.UpdateBackend(__instance.getUISlots());
|
||||
}
|
||||
__result = newItemStack.count == 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Переход на котёл (#66, 22.10: «у уже поставленных оссуариев при первой загрузке новой версии всё лишнее из
|
||||
/// старых ячеек образцов и топлива переложить в новое хранилище - ничего не теряется»). Сервер на каждом тике смотрит
|
||||
/// спрятанные ячейки (образцы 2-3, топливо 2-6) и перекладывает их содержимое в свободные ячейки хранилища; нет места -
|
||||
/// ждёт, пока игрок заберёт добычу.</summary>
|
||||
[HarmonyPatch(typeof(TileEntityCollector), nameof(TileEntityCollector.UpdateTick))]
|
||||
public static class Patch_TileEntityCollector_UpdateTick_GeoOssuaryMigrate
|
||||
{
|
||||
public static void Postfix(TileEntityCollector __instance)
|
||||
{
|
||||
if (!GeoOssuary.Is(__instance) || !SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer)
|
||||
return;
|
||||
bool moved = Move(__instance, __instance.ModSlots, GeoOssuary.VisibleModSlots, "образца");
|
||||
moved |= Move(__instance, __instance.FuelSlots, GeoOssuary.VisibleFuelSlots, "топлива");
|
||||
if (moved)
|
||||
__instance.SetModified();
|
||||
}
|
||||
|
||||
static bool Move(TileEntityCollector _te, ItemStack[] _from, int _keep, string _what)
|
||||
{
|
||||
bool moved = false;
|
||||
ItemStack[] store = _te.Items;
|
||||
for (int i = _keep; i < _from.Length; i++)
|
||||
{
|
||||
if (_from[i] == null || _from[i].IsEmpty())
|
||||
continue;
|
||||
int free = System.Array.FindIndex(store, s => s == null || s.IsEmpty());
|
||||
if (free < 0)
|
||||
return moved;
|
||||
store[free] = _from[i].Clone();
|
||||
_from[i] = ItemStack.Empty.Clone();
|
||||
moved = true;
|
||||
Debug.Log("[NecromancerTome] GeoOssuary: " + store[free].itemValue.ItemClass?.Name + " x" + store[free].count +
|
||||
" из ячейки " + _what + " " + (i + 1) + " -> хранилище " + (free + 1) + " в " + _te.ToWorldPos());
|
||||
}
|
||||
return moved;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user