diff --git a/Config/XUi_InGame/windows.xml b/Config/XUi_InGame/windows.xml
index 673a8ab..1f688c4 100644
--- a/Config/XUi_InGame/windows.xml
+++ b/Config/XUi_InGame/windows.xml
@@ -208,21 +208,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Config/XUi_InGame/xui.xml b/Config/XUi_InGame/xui.xml
index 13caeb2..e6ac8a7 100644
--- a/Config/XUi_InGame/xui.xml
+++ b/Config/XUi_InGame/xui.xml
@@ -59,10 +59,4 @@
-
-
-
-
-
-
diff --git a/HarmonySrc/Cinerarium.cs b/HarmonySrc/Cinerarium.cs
index 0f0113a..ab2cf98 100644
--- a/HarmonySrc/Cinerarium.cs
+++ b/HarmonySrc/Cinerarium.cs
@@ -70,7 +70,7 @@ namespace NecromancerTome
base.OnRemove(_world);
RemoveBounds();
RemoveGenie(false);
- XUiC_NecroCinerariumSkullGrid.CloseIfShowing(this);
+ CinerariumContents.CloseIfShowing(this);
if (!ConnectionManager.Instance.IsServer)
{
return;
@@ -96,7 +96,7 @@ namespace NecromancerTome
base.OnUnload(_world);
RemoveBounds();
RemoveGenie(false);
- XUiC_NecroCinerariumSkullGrid.CloseIfShowing(this);
+ CinerariumContents.CloseIfShowing(this);
}
public override void Write(PooledBinaryWriter _bw, StreamModeWrite _eStreamMode)
@@ -602,7 +602,7 @@ namespace NecromancerTome
}
if (skull)
{
- XUiC_NecroCinerariumSkullGrid.Open(_player, urn);
+ CinerariumContents.Open(_player, urn);
}
else if (repair)
{
diff --git a/HarmonySrc/CinerariumTrunk.cs b/HarmonySrc/CinerariumTrunk.cs
index d7f9633..eaa0136 100644
--- a/HarmonySrc/CinerariumTrunk.cs
+++ b/HarmonySrc/CinerariumTrunk.cs
@@ -3,83 +3,116 @@ using UnityEngine;
namespace NecromancerTome
{
///
- /// «Багажник» урны-цинерария (решение 16.10: «урна как транспорт» - на E круговое меню, как у велосипеда:
- /// багажник с ячейкой черепа и сумка духа). Окно necroCinerariumTrunk (Config/XUi_InGame) - панель с одной
- /// ячейкой игры для обязательного предмета (XUiC_RequiredItemStack, как в панели модификаций коллектора
- /// росы), рядом рюкзак (open_backpack_on_open). Ячейка принимает только череп и не больше одного
- /// (override_stack_count="1" в XML). Череп - обычный предмет (ItemClass): в сейвах он уже есть, менять ему
- /// класс на модификацию нельзя (см. память про сейвы), поэтому ячейка, а не сборка как у робомолота.
+ /// «Содержимое» урны-цинерария - ячейка черепа (решение 16.10: «урна как транспорт»; переименовано из «Багажника»).
+ /// Окно - родное окно хранилища игры (XUiC_BagStorageWindowGroup, как сумка транспорта и сумка волка) с сумкой на одну
+ /// ячейку: перетаскивание, Shift+клик и правый клик - кодом игры (16.10: «Сумки, ящики в игре есть» - своё окно с
+ /// ячейкой коллектора не принимало череп ни перетаскиванием, ни Shift+кликом). Своё здесь одно: после каждого изменения
+ /// в ячейке остаётся один череп, всё остальное (лишние черепа, чужие предметы) - назад в рюкзак, и урна узнаёт, есть ли
+ /// в ней череп. Череп - обычный предмет (ItemClass): он уже в сейвах, менять ему класс на модификацию нельзя.
///
- public class XUiC_NecroCinerariumSkullGrid : XUiC_ItemStackGrid
+ public static class CinerariumContents
{
- public const string WindowGroup = "necroCinerariumTrunk";
+ public const string LootTemplate = "roboticDrone"; // звуки и время открытия, как у сумки волка
- /// Урна, чей багажник открыт (ставится перед открытием окна).
- public static TEFeatureCinerarium Urn;
+ static TEFeatureCinerarium _urn;
+ static Bag _bag;
+ static EntityPlayerLocal _player;
- public static void Open(EntityPlayerLocal _player, TEFeatureCinerarium _urn)
+ public static void Open(EntityPlayerLocal _p, TEFeatureCinerarium _u)
{
- LocalPlayerUI ui = _player?.PlayerUI;
- if (ui == null || _urn == null)
+ LocalPlayerUI ui = _p != null ? LocalPlayerUI.GetUIForPlayer(_p) : null;
+ ItemValue skull = ItemClass.GetItem(TEFeatureCinerarium.SkullItemName);
+ if (ui == null || _u == null)
{
return;
}
- Urn = _urn;
- ui.windowManager.Open(WindowGroup, true);
+ _urn = _u;
+ _player = _p;
+ _bag = new Bag(new Vector2i(1, 1), XUiC_ItemStack.StackLocationTypes.LootContainer, null);
+ if (_u.HasSkull && skull != null && skull.type > 0)
+ {
+ _bag.SetSlot(0, new ItemStack(skull, 1));
+ }
+ XUiC_BagStorageWindowGroup.Open(ui.xui, _p, _bag, LootContainer.GetLootContainer(LootTemplate),
+ Localization.Get("necroCinerariumTrunk"), Check, () =>
+ {
+ Check();
+ _urn = null;
+ _bag = null;
+ _player = null;
+ });
+ Debug.Log("[NecromancerTome] Cinerarium: «Содержимое» урны " + _u.ToWorldPos() + " открыто, череп " + (_u.HasSkull ? "есть" : "нет"));
}
- public override void OnOpen()
+ /// Оставить в ячейке один череп, остальное - игроку; отметить в урне.
+ static void Check()
{
- base.OnOpen();
- ItemValue skull = ItemClass.GetItem(TEFeatureCinerarium.SkullItemName);
- for (int i = 0; i < itemControllers.Length; i++)
+ if (_bag == null || _urn == null)
{
- if (itemControllers[i] is XUiC_RequiredItemStack slot)
+ return;
+ }
+ ItemStack s = _bag.ItemGrid.items[0];
+ bool has = false;
+ if (s != null && !s.IsEmpty())
+ {
+ ItemStack back = null;
+ if (s.itemValue.ItemClass?.GetItemName() != TEFeatureCinerarium.SkullItemName)
{
- slot.SetAllowedItemClassSingle(TEFeatureCinerarium.SkullItemName);
- slot.RequiredItemOnly = true;
- slot.StackLocation = XUiC_ItemStack.StackLocationTypes.Workstation;
+ back = s.Clone();
+ _bag.SetSlot(0, ItemStack.Empty.Clone());
+ }
+ else
+ {
+ has = true;
+ if (s.count > 1)
+ {
+ back = s.Clone();
+ back.count = s.count - 1;
+ ItemStack one = s.Clone();
+ one.count = 1;
+ _bag.SetSlot(0, one);
+ }
+ }
+ if (back != null)
+ {
+ GiveBack(back);
}
}
- ItemStack[] stacks = new ItemStack[itemControllers.Length];
- for (int i = 0; i < stacks.Length; i++)
- {
- stacks[i] = ItemStack.Empty.Clone();
- }
- if (stacks.Length > 0 && Urn != null && Urn.HasSkull && skull != null && skull.type > 0)
- {
- stacks[0] = new ItemStack(skull, 1);
- }
- SetStacks(stacks);
+ _urn.SetSkull(has);
}
- public override void OnClose()
+ static void GiveBack(ItemStack _s)
{
- base.OnClose();
- Urn = null;
- }
-
- public override void UpdateBackend(ItemStack[] stackList)
- {
- base.UpdateBackend(stackList);
- bool has = stackList != null && stackList.Length > 0 && stackList[0] != null && !stackList[0].IsEmpty();
- Urn?.SetSkull(has);
- }
-
- /// Урна убрана или выгружена, пока открыт её багажник, - закрыть окно (иначе череп в ячейке
- /// уже ни к чему не привязан).
- public static void CloseIfShowing(TEFeatureCinerarium _urn)
- {
- if (Urn == null || Urn != _urn)
+ if (_player == null)
{
return;
}
- LocalPlayerUI ui = GameManager.Instance?.World?.GetPrimaryPlayer()?.PlayerUI;
- if (ui != null && ui.windowManager.IsWindowOpen(WindowGroup))
+ if (_player.bag != null && _player.bag.AddItem(_s))
{
- ui.windowManager.Close(WindowGroup);
+ return;
+ }
+ if (_player.inventory != null && _player.inventory.AddItem(_s))
+ {
+ return;
+ }
+ _player.world.gameManager.ItemDropServer(_s, _player.GetPosition(), Vector3.zero);
+ }
+
+ /// Урна убрана или выгружена, пока открыто её «Содержимое», - закрыть окно (череп из ячейки не потеряется:
+ /// Check успеет отметить его в урне, а урна при разрушении роняет череп).
+ public static void CloseIfShowing(TEFeatureCinerarium _u)
+ {
+ if (_urn == null || _urn != _u)
+ {
+ return;
+ }
+ Check();
+ LocalPlayerUI ui = _player != null ? LocalPlayerUI.GetUIForPlayer(_player) : null;
+ _urn = null;
+ if (ui != null && ui.windowManager.IsWindowOpen(XUiC_BagStorageWindowGroup.ID))
+ {
+ ui.windowManager.Close(XUiC_BagStorageWindowGroup.ID);
}
- Urn = null;
}
}
}
diff --git a/NecromancerHarmony.dll b/NecromancerHarmony.dll
index b0de7d9..faeacb3 100644
Binary files a/NecromancerHarmony.dll and b/NecromancerHarmony.dll differ