This commit is contained in:
Oscar
2025-06-29 15:06:54 +03:00
parent 495c672818
commit 235d5ad90a
7 changed files with 423 additions and 111 deletions

View File

@@ -83,6 +83,7 @@ public class Inventar : Component
_itemCache[item.Definition] = item;
}
}
_cacheDirty = false;
}
@@ -116,7 +117,10 @@ public class Inventar : Component
while ( toAdd > 0 && (UnlimitedSlots || Items.Count < MaxInventorySlots) )
{
int stackCount = Math.Min( toAdd, item.Definition.MaxCount );
var newStack = new InventoryItem { Definition = item.Definition, Count = stackCount, MagazineAmmo = item.MagazineAmmo };
var newStack = new InventoryItem
{
Definition = item.Definition, Count = stackCount, MagazineAmmo = item.MagazineAmmo
};
Items.Add( newStack );
toAdd -= stackCount;
_cacheDirty = true; // Помечаем кэш как устаревший
@@ -193,22 +197,89 @@ public class Inventar : Component
if ( item == null || !Items.Contains( item ) )
return;
GameObject gO = item.Definition.Prefab.Clone( position );
if ( gO.Components.TryGet<InventoryItem>( out var inventoryItem ) )
// Проверяем, является ли предмет одеждой
if ( item.Definition is ClothingItemDefinition clothingDef )
{
inventoryItem.Count = item.Count;
inventoryItem.Definition = item.Definition;
// Копируем патроны из оригинального предмета
inventoryItem.MagazineAmmo = item.MagazineAmmo;
// Для одежды создаем специальный физический объект
DropClothingItem( item, position, clothingDef );
}
else
{
// Для остальных предметов используем стандартный префаб
if ( item.Definition.Prefab != null )
{
GameObject gO = item.Definition.Prefab.Clone( position );
gO.NetworkSpawn();
if ( gO.Components.TryGet<InventoryItem>( out var inventoryItem ) )
{
inventoryItem.Count = item.Count;
inventoryItem.Definition = item.Definition;
// Копируем патроны из оригинального предмета
inventoryItem.MagazineAmmo = item.MagazineAmmo;
}
gO.NetworkSpawn();
}
else
{
Log.Warning( $"Префаб не найден для предмета: {item.Definition.Name}" );
}
}
// Удаляем весь предмет из инвентаря
RemoveItem( item, item.Count );
}
/// <summary>
/// Выбрасывает предмет одежды как физический объект
/// </summary>
private void DropClothingItem( InventoryItem item, Vector3 position, ClothingItemDefinition clothingDef )
{
// Пытаемся найти подходящий префаб для одежды
GameObject clothingPrefab = GameObject.GetPrefab( "prefabs/item_parcel.prefab" );
GameObject clothingObject = null;
clothingObject = clothingPrefab.Clone( position );
// Добавляем компонент InventoryItem
if ( clothingObject.Components.TryGet<InventoryItem>( out var inventoryItem ) )
{
inventoryItem.Count = item.Count;
inventoryItem.Definition = item.Definition;
}
// Добавляем компонент PickupItem для подбора
if ( clothingObject.Components.TryGet<PickupItem>( out var pickupItem ) )
{
// Устанавливаем правильную метку для одежды
var slotName = GetSlotDisplayName( clothingDef.Slot );
pickupItem.Label = $"{clothingDef.Name} ({slotName})";
}
clothingObject.NetworkSpawn();
Log.Info( $"Выброшена одежда: {clothingDef.Name} ({clothingDef.Slot})" );
}
/// <summary>
/// Получает отображаемое название слота
/// </summary>
private string GetSlotDisplayName( InventorySlot slot )
{
return slot switch
{
InventorySlot.LeftHand => "Л.Рука",
InventorySlot.RightHand => "П.Рука",
InventorySlot.Head => "Голова",
InventorySlot.Body => "Тело",
InventorySlot.Hands => "Руки",
InventorySlot.Bottom => "Ноги",
InventorySlot.Feet => "Обувь",
_ => "Неизвестно"
};
}
public void UnEquipItem( InventoryItem item )
{
if ( item == null )
@@ -334,5 +405,55 @@ public class Inventar : Component
}
}
/// <summary>
/// Выбрасывает все предметы из инвентаря
/// </summary>
/// <param name="dropPosition">Базовая позиция для выбрасывания</param>
/// <param name="scatterRadius">Радиус разброса предметов</param>
/// <returns>Количество выброшенных предметов</returns>
public int DropAllItems( Vector3 dropPosition, float scatterRadius = 50f )
{
if ( !Network.IsOwner ) return 0;
Log.Info( "Выбрасываем все предметы из инвентаря..." );
// Создаем копию списка предметов для безопасной итерации
var itemsToDrop = Items.ToList();
var equippedItemsToDrop = EquippedItems.Values.ToList();
int droppedCount = 0;
// Сначала снимаем все экипированные предметы и добавляем их в список для выбрасывания
foreach ( var equippedItem in equippedItemsToDrop )
{
if ( equippedItem != null )
{
// Снимаем предмет
UnEquipItem( equippedItem );
// Добавляем в список для выбрасывания, если его там еще нет
if ( !itemsToDrop.Contains( equippedItem ) )
{
itemsToDrop.Add( equippedItem );
}
}
}
// Затем выбрасываем все предметы
foreach ( var item in itemsToDrop )
{
if ( item != null && item.Count > 0 )
{
// Выбираем случайную позицию в радиусе разброса
var scatteredPosition = dropPosition + Vector3.Random * scatterRadius + Vector3.Up * 10f;
DropItem( item, scatteredPosition );
droppedCount++;
}
}
Log.Info( $"Выброшено {droppedCount} предметов из инвентаря" );
return droppedCount;
}
#endregion
}