diff --git a/HarmonySrc/RatLoot.cs b/HarmonySrc/RatLoot.cs index 0723ba3..aa8bc1c 100644 --- a/HarmonySrc/RatLoot.cs +++ b/HarmonySrc/RatLoot.cs @@ -426,6 +426,10 @@ namespace NecromancerTome { return true; } + if (WolfBagButton(__instance, false)) + { + return false; + } TEFeatureStorage te = __instance.GetParentByType()?.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() != null) + { + WolfBag.Sort(); + } return !Viewing; } } + /// Кнопки окна рюкзака, показывающего сумку волка: «Положить всё» / «Положить похожие» - в открытый + /// ящик или мешок (как щелчок по ячейке сумки). True - кнопка сумки волка, обработана. + static bool WolfBagButton(XUiC_ContainerStandardControls _c, bool _similarOnly) + { + if (!WolfBagBackpack.On || _c.GetParentByType() == null) + { + return false; + } + XUiC_LootWindow lw = _c.xui.GetChildByType(); + 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; + } + + /// «Положить похожие» у сумки волка; прочие переносы и замок ячеек при обыске - выключены (ячейки окна - + /// копии сумки, ванильный перенос их раздвоил бы). + [HarmonyPatch(typeof(XUiC_ContainerStandardControls))] + public static class Patch_OtherMoves + { + static System.Collections.Generic.IEnumerable 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; + } + } + /// Щелчок по запертой ячейке контейнера - отказ «рюкзак полон». [HarmonyPatch(typeof(XUiC_ItemStack), nameof(XUiC_ItemStack.Update))] public static class Patch_ItemStack_Update diff --git a/HarmonySrc/WolfBag.cs b/HarmonySrc/WolfBag.cs index bf701cd..451e2b3 100644 --- a/HarmonySrc/WolfBag.cs +++ b/HarmonySrc/WolfBag.cs @@ -229,6 +229,38 @@ namespace NecromancerTome return true; } + /// Кнопки окна сумки при обыске (указание 12.10): «Положить всё» и «Положить похожие» - в открытый + /// ящик или мешок; похожие - только то, что в контейнере уже лежит. + 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"); + } + } + + /// «Сортировать» - по самой сумке. + public static void Sort() + { + Get().ItemGrid.Sort(); + Save(); + } + /// Переложить ячейку сумки в массив ячеек контейнера (сами ячейки меняются, номера - в _changed). static bool Give(int _idx, ItemStack[] _g, List _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()?.standardControls; + foreach (string id in WolfBagControls.Hidden) + { + XUiController b = c?.GetChildById(id); + if (b?.ViewComponent != null) + { + b.ViewComponent.IsVisible = !wolf; + } + } + } + } + + /// Окно сумки волка: работает только «Сортировать» (по самой сумке, пишется через onModified). + /// Перенос в рюкзак (кнопки и клавиша R) и замки ячеек (нужны лишь для переноса) - выключены. + 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() != null; + } + } + + [HarmonyPatch(typeof(XUiC_ContainerStandardControls))] + public static class Patch_ContainerStandardControls_Move_WolfBag + { + static IEnumerable 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); + } + } + + /// Кнопка замка видна по привязке {hasslotlocks} - у волка её нет. + [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; + } } } diff --git a/NEXUS_DESCRIPTION.bbcode b/NEXUS_DESCRIPTION.bbcode index e3d405e..1bfd6ca 100644 --- a/NEXUS_DESCRIPTION.bbcode +++ b/NEXUS_DESCRIPTION.bbcode @@ -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] diff --git a/NecromancerHarmony.dll b/NecromancerHarmony.dll index 2689004..08ffcf0 100644 Binary files a/NecromancerHarmony.dll and b/NecromancerHarmony.dll differ diff --git a/NecromancerHarmony.pdb b/NecromancerHarmony.pdb index ee400ae..4b6e257 100644 Binary files a/NecromancerHarmony.pdb and b/NecromancerHarmony.pdb differ