using GUI_2;
using HarmonyLib;
using UnityEngine;
namespace NecromancerTome
{
///
/// Череп - предмет или декор (15.10.2026, вторая версия). Указание после теста: «Посмотри как ставится мебель. Например,
/// горшки с цветами... Три режима. Предмет, и два декора. Если выбран декор, хват меняется на тот который при установке
/// строительных блоков или мебели, и я начинаю видеть типа превью того как блок будет стоять»; поворот - как у блоков.
/// Череп-предмет в руке, удержание R - меню: «Просто череп» / «Череп: по центру» / «Череп: у стены». Выбор декора
/// превращает всю стопку в ячейке пояса в блок этого вида: в руке настоящий блок - превью, повороты блока.
/// Блок-декор в руке, R - обычное меню блока (короткое нажатие - поворот), к нему добавлены «Просто череп» (стопка
/// обратно в черепа) и второй вид декора.
/// Поднятый (E) и разрушенный декор - снова череп-предмет (blocks.xml: CanPickup param1 / drop).
/// Предмет necroSkull не меняется (ItemClass, без действий) - сейвы с черепом целы; блоки-декор - отдельные блоки.
/// R для предмета игра не обрабатывает (PlayerMoveController открывает меню только оружию, ближнему бою и блокам) -
/// нажатие ловится постфиксом к PlayerMoveController.Update.
///
public static class SkullDecorPlace
{
public const int ItemIdx = 0, CenterIdx = 1, BackIdx = 2;
/// Номера наших пунктов в меню блока - вне занятых игрой (-2..10).
public const int BlockMenuItem = 40, BlockMenuCenter = 41, BlockMenuBack = 42;
public const string CenterBlock = "necroSkullDecorCenter";
public const string BackBlock = "necroSkullDecorBack";
public static bool IsSkull(ItemClass _item) => _item != null && _item.Name == NecroSkull.ItemName;
public static bool IsDecor(ItemClass _item) => _item != null && (_item.Name == CenterBlock || _item.Name == BackBlock);
/// Стопка в руке превращается в _name (тот же счёт).
public static void Convert(EntityPlayerLocal _pl, string _name)
{
if (_pl?.inventory == null) return;
ItemStack cur = _pl.inventory.holdingItemStack;
if (cur == null || cur.IsEmpty() || !(IsSkull(cur.itemValue.ItemClass) || IsDecor(cur.itemValue.ItemClass))) return;
if (cur.itemValue.ItemClass.Name == _name) return;
ItemValue iv = ItemClass.GetItem(_name);
if (iv == null || iv.IsEmpty()) return;
_pl.inventory.SetItem(_pl.inventory.holdingItemIdx, new ItemStack(iv, cur.count));
}
public static void OnItemMenu(XUiC_Radial _sender, int _commandIndex, XUiC_Radial.RadialContextAbs _context)
{
EntityPlayerLocal pl = _sender?.xui?.playerUI?.entityPlayer;
if (_commandIndex == CenterIdx) Convert(pl, CenterBlock);
else if (_commandIndex == BackIdx) Convert(pl, BackBlock);
}
public static void OpenItemMenu(PlayerMoveController _pmc, EntityPlayerLocal _pl)
{
XUiC_Radial r = _pmc.playerUI?.xui?.RadialWindow;
if (r == null) return;
r.Open();
r.ResetRadialEntries();
r.CreateRadialEntry(ItemIdx, "necroSkull", "ItemIconAtlas", "", Localization.Get("necroSkullModeOff"), true);
r.CreateRadialEntry(CenterIdx, "ui_game_symbol_skull", "UIAtlas", "", Localization.Get("necroSkullDecorCenter"));
r.CreateRadialEntry(BackIdx, "ui_game_symbol_skull", "UIAtlas", "", Localization.Get("necroSkullDecorBack"));
r.SetCommonData(UIUtils.GetButtonIconForAction(_pmc.playerInput.Reload), OnItemMenu,
new XUiC_Radial.RadialContextHoldingSlotIndex(_pl.inventory.holdingItemIdx), ItemIdx, false,
XUiC_Radial.RadialValidSameHoldingSlotIndex);
}
/// Меню блока с декором в руке: наши пункты - сами, остальное - игре.
public static void OnBlockMenu(XUiC_Radial _sender, int _commandIndex, XUiC_Radial.RadialContextAbs _context)
{
EntityPlayerLocal pl = _sender?.xui?.playerUI?.entityPlayer;
switch (_commandIndex)
{
case BlockMenuItem: Convert(pl, NecroSkull.ItemName); return;
case BlockMenuCenter: Convert(pl, CenterBlock); return;
case BlockMenuBack: Convert(pl, BackBlock); return;
}
_sender.handleBlockShapeCommand(_sender, _commandIndex, _context);
}
}
/// R с черепом-предметом в руке - меню «предмет / два декора».
[HarmonyPatch(typeof(PlayerMoveController), nameof(PlayerMoveController.Update))]
public static class Patch_PlayerMoveController_Update_SkullDecor
{
public static void Postfix(PlayerMoveController __instance)
{
EntityPlayerLocal pl = __instance.entityPlayerLocal;
if (pl == null || pl.inventory == null || !SkullDecorPlace.IsSkull(pl.inventory.holdingItem) || pl.IsDead())
{
return;
}
PlayerActionsLocal inp = __instance.playerInput;
if (inp == null || !(inp.Reload.WasPressed || inp.PermanentActions.Reload.WasPressed) || pl.inventory.IsHandSwitching())
{
return;
}
if (__instance.playerUI == null || __instance.playerUI.windowManager.IsModalWindowOpen())
{
return;
}
SkullDecorPlace.OpenItemMenu(__instance, pl);
}
}
/// Меню блока с черепом-декором в руке: к пунктам игры - «Просто череп» и второй вид.
[HarmonyPatch(typeof(XUiC_Radial), nameof(XUiC_Radial.SetupBlockShapeData))]
public static class Patch_XUiC_Radial_SetupBlockShapeData_SkullDecor
{
public static void Postfix(XUiC_Radial __instance)
{
EntityPlayerLocal pl = __instance.xui?.playerUI?.entityPlayer;
ItemClass held = pl?.inventory?.holdingItem;
if (!SkullDecorPlace.IsDecor(held))
{
return;
}
__instance.CreateRadialEntry(SkullDecorPlace.BlockMenuItem, "necroSkull", "ItemIconAtlas", "", Localization.Get("necroSkullModeOff"));
if (held.Name == SkullDecorPlace.CenterBlock)
__instance.CreateRadialEntry(SkullDecorPlace.BlockMenuBack, "ui_game_symbol_skull", "UIAtlas", "", Localization.Get("necroSkullDecorBack"));
else
__instance.CreateRadialEntry(SkullDecorPlace.BlockMenuCenter, "ui_game_symbol_skull", "UIAtlas", "", Localization.Get("necroSkullDecorCenter"));
__instance.SetCommonData(UIUtils.GetButtonIconForAction(__instance.xui.playerUI.playerInput.Activate), SkullDecorPlace.OnBlockMenu,
new XUiC_Radial.RadialContextHoldingSlotIndex(pl.inventory.holdingItemIdx), -1, true, XUiC_Radial.RadialValidSameHoldingSlotIndex);
}
}
}