Волк: кнопки окон сумки работают или скрыты; ссылка на Telegram в описании

Багажник (Tab): только «Сортировать», перенос в рюкзак тела и замок скрыты.
При обыске над сумкой «Положить всё» / «Положить похожие» выкладывают в открытый
ящик или мешок, «Сортировать» сортирует сумку; ванильный перенос копий ячеек
(мог раздвоить вещи) выключен.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AlexCube
2026-10-12 11:15:14 +03:00
co-authored by Claude Opus 5.5
parent fd4545d1a8
commit 8b8d1d0feb
5 changed files with 142 additions and 2 deletions
+53 -1
View File
@@ -426,6 +426,10 @@ namespace NecromancerTome
{
return true;
}
if (WolfBagButton(__instance, false))
{
return false;
}
TEFeatureStorage te = __instance.GetParentByType<XUiC_LootWindow>()?.te;
if (Taking && te != null)
{
@@ -446,12 +450,60 @@ namespace NecromancerTome
[HarmonyPatch(typeof(XUiC_ContainerStandardControls), nameof(XUiC_ContainerStandardControls.Sort))]
public static class Patch_Sort
{
public static bool Prefix()
public static bool Prefix(XUiC_ContainerStandardControls __instance)
{
if (Viewing && WolfBagBackpack.On && __instance.GetParentByType<XUiC_BackpackWindow>() != null)
{
WolfBag.Sort();
}
return !Viewing;
}
}
/// <summary>Кнопки окна рюкзака, показывающего сумку волка: «Положить всё» / «Положить похожие» - в открытый
/// ящик или мешок (как щелчок по ячейке сумки). True - кнопка сумки волка, обработана.</summary>
static bool WolfBagButton(XUiC_ContainerStandardControls _c, bool _similarOnly)
{
if (!WolfBagBackpack.On || _c.GetParentByType<XUiC_BackpackWindow>() == null)
{
return false;
}
XUiC_LootWindow lw = _c.xui.GetChildByType<XUiC_LootWindow>();
TEFeatureStorage dst = lw != null && lw.ViewComponent.IsVisible ? lw.te : null;
if (dst != null || _viewBag != null)
{
WolfBag.PutAll(dst, dst == null ? _viewBag : null, _similarOnly);
}
return true;
}
/// <summary>«Положить похожие» у сумки волка; прочие переносы и замок ячеек при обыске - выключены (ячейки окна -
/// копии сумки, ванильный перенос их раздвоил бы).</summary>
[HarmonyPatch(typeof(XUiC_ContainerStandardControls))]
public static class Patch_OtherMoves
{
static System.Collections.Generic.IEnumerable<System.Reflection.MethodBase> TargetMethods()
{
yield return AccessTools.Method(typeof(XUiC_ContainerStandardControls), nameof(XUiC_ContainerStandardControls.MoveFillAndSmart));
yield return AccessTools.Method(typeof(XUiC_ContainerStandardControls), nameof(XUiC_ContainerStandardControls.MoveFillStacks));
yield return AccessTools.Method(typeof(XUiC_ContainerStandardControls), nameof(XUiC_ContainerStandardControls.MoveSmart));
yield return AccessTools.Method(typeof(XUiC_ContainerStandardControls), nameof(XUiC_ContainerStandardControls.ToggleLockMode));
}
public static bool Prefix(XUiC_ContainerStandardControls __instance, System.Reflection.MethodBase __originalMethod)
{
if (!Viewing)
{
return true;
}
if (__originalMethod.Name == nameof(XUiC_ContainerStandardControls.MoveFillAndSmart))
{
WolfBagButton(__instance, true);
}
return false;
}
}
/// <summary>Щелчок по запертой ячейке контейнера - отказ «рюкзак полон».</summary>
[HarmonyPatch(typeof(XUiC_ItemStack), nameof(XUiC_ItemStack.Update))]
public static class Patch_ItemStack_Update
+88 -1
View File
@@ -229,6 +229,38 @@ namespace NecromancerTome
return true;
}
/// <summary>Кнопки окна сумки при обыске (указание 12.10): «Положить всё» и «Положить похожие» - в открытый
/// ящик или мешок; похожие - только то, что в контейнере уже лежит.</summary>
public static void PutAll(TEFeatureStorage _te, EntityLootContainer _bag, bool _similarOnly)
{
bool any = false;
ItemStack[] slots = Get().ItemGrid.items;
for (int i = 0; i < slots.Length; i++)
{
if (slots[i] == null || slots[i].IsEmpty())
{
continue;
}
ItemStack[] dst = _te != null ? _te.ItemGrid.items : _bag?.bag.ItemGrid.items;
if (dst == null || (_similarOnly && System.Array.FindIndex(dst, s => s != null && !s.IsEmpty() && s.itemValue.type == slots[i].itemValue.type) < 0))
{
continue;
}
any |= _te != null ? PutTo(_te, i) : PutTo(_bag, i);
}
if (!any)
{
Audio.Manager.PlayInsidePlayerHead("ui_denied");
}
}
/// <summary>«Сортировать» - по самой сумке.</summary>
public static void Sort()
{
Get().ItemGrid.Sort();
Save();
}
/// <summary>Переложить ячейку сумки в массив ячеек контейнера (сами ячейки меняются, номера - в _changed).</summary>
static bool Give(int _idx, ItemStack[] _g, List<int> _changed)
{
@@ -542,10 +574,65 @@ namespace NecromancerTome
{
public static void Postfix(XUiC_BagStorageWindowGroup __instance)
{
if (WolfBag.WindowOpen && Possession.Active)
bool wolf = WolfBag.WindowOpen && Possession.Active;
if (wolf)
{
__instance.xui.playerUI.windowManager.Close("backpack");
}
// «Взять всё» / «Взять похожие» кладут в рюкзак тела, а оно далеко - у волка кнопок нет; у дрона и браслета - вернуть
XUiC_ContainerStandardControls c = __instance.GetChildByType<XUiC_BagContainer>()?.standardControls;
foreach (string id in WolfBagControls.Hidden)
{
XUiController b = c?.GetChildById(id);
if (b?.ViewComponent != null)
{
b.ViewComponent.IsVisible = !wolf;
}
}
}
}
/// <summary>Окно сумки волка: работает только «Сортировать» (по самой сумке, пишется через onModified).
/// Перенос в рюкзак (кнопки и клавиша R) и замки ячеек (нужны лишь для переноса) - выключены.</summary>
public static class WolfBagControls
{
public static readonly string[] Hidden = { "btnMoveAll", "btnMoveFillAndSmart", "btnMoveFillStacks", "btnMoveSmart" };
public static bool Blocked(XUiController _c)
{
return WolfBag.WindowOpen && Possession.Active && _c?.GetParentByType<XUiC_BagContainer>() != null;
}
}
[HarmonyPatch(typeof(XUiC_ContainerStandardControls))]
public static class Patch_ContainerStandardControls_Move_WolfBag
{
static IEnumerable<System.Reflection.MethodBase> TargetMethods()
{
yield return AccessTools.Method(typeof(XUiC_ContainerStandardControls), nameof(XUiC_ContainerStandardControls.MoveAll));
yield return AccessTools.Method(typeof(XUiC_ContainerStandardControls), nameof(XUiC_ContainerStandardControls.MoveFillAndSmart));
yield return AccessTools.Method(typeof(XUiC_ContainerStandardControls), nameof(XUiC_ContainerStandardControls.MoveFillStacks));
yield return AccessTools.Method(typeof(XUiC_ContainerStandardControls), nameof(XUiC_ContainerStandardControls.MoveSmart));
yield return AccessTools.Method(typeof(XUiC_ContainerStandardControls), nameof(XUiC_ContainerStandardControls.ToggleLockMode));
}
public static bool Prefix(XUiC_ContainerStandardControls __instance)
{
return !WolfBagControls.Blocked(__instance);
}
}
/// <summary>Кнопка замка видна по привязке {hasslotlocks} - у волка её нет.</summary>
[HarmonyPatch(typeof(XUiC_BagContainer), nameof(XUiC_BagContainer.GetBindingValueInternal))]
public static class Patch_BagContainer_Binding_WolfBag
{
public static void Postfix(XUiC_BagContainer __instance, ref string _value, string _bindingName, ref bool __result)
{
if (_bindingName == "hasslotlocks" && WolfBagControls.Blocked(__instance))
{
_value = "false";
__result = true;
}
}
}
+1
View File
@@ -63,3 +63,4 @@ Thanks to [b]The Fun Pimps[/b] for a game that survives this much rewriting, and
Source code, full change history and issue tracker: [url=https://git.08h.ru/alex/necromants-tome-7d2d-3-2]git.08h.ru/alex/necromants-tome-7d2d-3-2[/url]
Mod page on my site: [url=https://www.alexcube.ru/7-days-to-die-moi-mody/kniga-nekromanta-necromancer-s-tome/]alexcube.ru[/url]
My YouTube channel: [url=https://www.youtube.com/@alex_cube]@alex_cube[/url]
News and previews on Telegram: [url=https://t.me/necromancerstome]t.me/necromancerstome[/url]
Binary file not shown.
Binary file not shown.