asd
This commit is contained in:
@@ -19,7 +19,7 @@ public class WeaponItemDefinition : BaseItemDefinition, IEquipable
|
||||
public float Damage { get; set; } = 10f;
|
||||
|
||||
[Property, Category( "Weapon Properties" )]
|
||||
public float FireRate { get; set; } = 1f;
|
||||
public float FireRate { get; set; } = 10f; // Выстрелов в секунду
|
||||
|
||||
[Property, Category( "Weapon Properties" )]
|
||||
public float Range { get; set; } = 1000f;
|
||||
@@ -30,6 +30,15 @@ public class WeaponItemDefinition : BaseItemDefinition, IEquipable
|
||||
[Property, Category( "Weapon Properties" )]
|
||||
public string AmmoType { get; set; } = "Pistol";
|
||||
|
||||
[Property, Category( "Weapon Properties" )]
|
||||
public float ReloadTime { get; set; } = 2f;
|
||||
|
||||
[Property, Category( "Weapon Properties" )]
|
||||
public float Spread { get; set; } = 0.02f; // Разброс при стрельбе
|
||||
|
||||
[Property, Category( "Weapon Properties" )]
|
||||
public bool IsAutomatic { get; set; } = true; // Всегда автоматический режим
|
||||
|
||||
public override Inventar.InventorySlot? GetSlot() => Slot;
|
||||
|
||||
public override ItemCategory Category => ItemCategory.Weapon;
|
||||
|
||||
@@ -65,36 +65,37 @@ public class Inventar : Component
|
||||
/// <summary>
|
||||
/// Добавляет предмет в инвентарь, распределяя по существующим и новым стекам. Возвращает остаток, который не удалось добавить (или 0, если всё добавлено).
|
||||
/// </summary>
|
||||
public int AddItem(InventoryItem item)
|
||||
public int AddItem( InventoryItem item )
|
||||
{
|
||||
if (item == null || item.Definition == null || item.Count <= 0)
|
||||
if ( item == null || item.Definition == null || item.Count <= 0 )
|
||||
return item.Count;
|
||||
|
||||
int toAdd = item.Count;
|
||||
|
||||
// 1. Заполняем существующие стаки
|
||||
foreach (var stack in Items.Where(x => x.Definition == item.Definition && x.Count < x.Definition.MaxCount))
|
||||
foreach ( var stack in Items.Where( x => x.Definition == item.Definition && x.Count < x.Definition.MaxCount ) )
|
||||
{
|
||||
int canAdd = Math.Min(toAdd, stack.Definition.MaxCount - stack.Count);
|
||||
if (canAdd > 0)
|
||||
int canAdd = Math.Min( toAdd, stack.Definition.MaxCount - stack.Count );
|
||||
if ( canAdd > 0 )
|
||||
{
|
||||
stack.Count += canAdd;
|
||||
toAdd -= canAdd;
|
||||
OnChanged?.Invoke();
|
||||
OnItemAdded?.Invoke(stack);
|
||||
OnItemAdded?.Invoke( stack );
|
||||
}
|
||||
if (toAdd <= 0) return 0;
|
||||
|
||||
if ( toAdd <= 0 ) return 0;
|
||||
}
|
||||
|
||||
// 2. Добавляем новые стаки, если есть место
|
||||
while (toAdd > 0 && (UnlimitedSlots || Items.Count < MaxInventorySlots))
|
||||
while ( toAdd > 0 && (UnlimitedSlots || Items.Count < MaxInventorySlots) )
|
||||
{
|
||||
int stackCount = Math.Min(toAdd, item.Definition.MaxCount);
|
||||
int stackCount = Math.Min( toAdd, item.Definition.MaxCount );
|
||||
var newStack = new InventoryItem { Definition = item.Definition, Count = stackCount };
|
||||
Items.Add(newStack);
|
||||
Items.Add( newStack );
|
||||
toAdd -= stackCount;
|
||||
OnChanged?.Invoke();
|
||||
OnItemAdded?.Invoke(newStack);
|
||||
OnItemAdded?.Invoke( newStack );
|
||||
}
|
||||
|
||||
// 3. Возвращаем остаток, если не всё удалось добавить
|
||||
@@ -149,6 +150,7 @@ public class Inventar : Component
|
||||
// Экипировать новый предмет
|
||||
EquippedItems[slot.Value] = item;
|
||||
item.Equipped = true;
|
||||
item.OnEquipped();
|
||||
OnEquipped?.Invoke( item );
|
||||
OnChanged?.Invoke();
|
||||
return true;
|
||||
@@ -159,23 +161,23 @@ public class Inventar : Component
|
||||
if ( item == null || !Items.Contains( item ) )
|
||||
return;
|
||||
|
||||
// Создаем копию предмета для выбрасывания
|
||||
var droppedItem = new InventoryItem
|
||||
{
|
||||
Definition = item.Definition,
|
||||
Count = item.Count // Выбрасываем всю стопку
|
||||
};
|
||||
// // Создаем копию предмета для выбрасывания
|
||||
// var droppedItem = new InventoryItem
|
||||
// {
|
||||
// Definition = item.Definition,
|
||||
// Count = item.Count // Выбрасываем всю стопку
|
||||
// };
|
||||
|
||||
GameObject gO = item.Definition.Prefab.Clone( position );
|
||||
|
||||
if ( gO.Components.TryGet<InventoryItem>( out var inventoryItem ) )
|
||||
{
|
||||
inventoryItem.Count = droppedItem.Count;
|
||||
inventoryItem.Definition = droppedItem.Definition;
|
||||
inventoryItem.Count = item.Count;
|
||||
inventoryItem.Definition = item.Definition;
|
||||
}
|
||||
|
||||
gO.NetworkSpawn();
|
||||
|
||||
|
||||
// Удаляем весь предмет из инвентаря
|
||||
RemoveItem( item, item.Count );
|
||||
}
|
||||
@@ -191,6 +193,7 @@ public class Inventar : Component
|
||||
{
|
||||
EquippedItems.Remove( slotToRemove );
|
||||
item.Equipped = false;
|
||||
item.OnUnEquipped();
|
||||
OnUnEquipped?.Invoke( item );
|
||||
OnChanged?.Invoke();
|
||||
}
|
||||
@@ -240,7 +243,7 @@ public class Inventar : Component
|
||||
{
|
||||
if ( UnlimitedSlots )
|
||||
return int.MaxValue;
|
||||
|
||||
|
||||
return Math.Max( 0, MaxInventorySlots - Items.Count );
|
||||
}
|
||||
|
||||
@@ -248,7 +251,7 @@ public class Inventar : Component
|
||||
{
|
||||
if ( UnlimitedSlots )
|
||||
return false;
|
||||
|
||||
|
||||
return Items.Count >= MaxInventorySlots;
|
||||
}
|
||||
|
||||
@@ -256,7 +259,7 @@ public class Inventar : Component
|
||||
{
|
||||
if ( UnlimitedSlots )
|
||||
return 0f;
|
||||
|
||||
|
||||
return (float)Items.Count / MaxInventorySlots * 100f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,18 @@ public class InventoryItem : Component
|
||||
{
|
||||
if ( GameObject.Components.TryGet<PickupItem>( out var item ) )
|
||||
{
|
||||
item.Label = Definition?.Name ?? "Unknown Item";
|
||||
string itemName = Definition?.Name;
|
||||
|
||||
if ( string.IsNullOrEmpty( itemName ) )
|
||||
{
|
||||
item.Label = "Unknown Item";
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Label = Count > 1
|
||||
? $"{itemName} x{Count}"
|
||||
: itemName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +69,22 @@ public class InventoryItem : Component
|
||||
return clone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Виртуальный метод для экипировки предмета
|
||||
/// </summary>
|
||||
public virtual void OnEquipped()
|
||||
{
|
||||
Equipped = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Виртуальный метод для снятия предмета
|
||||
/// </summary>
|
||||
public virtual void OnUnEquipped()
|
||||
{
|
||||
Equipped = false;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Definition?.Name ?? "Unknown"} x{Count}";
|
||||
|
||||
@@ -1,85 +1,14 @@
|
||||
namespace Sasalka;
|
||||
|
||||
/// <summary>
|
||||
/// Базовый класс для предметов, которые используют патроны
|
||||
/// Теперь используется только для совместимости со старой системой
|
||||
/// </summary>
|
||||
public abstract class AmmoUseableBase : UseableBase
|
||||
{
|
||||
private WeaponItemDefinition _cachedWeaponDef;
|
||||
private InventoryItem _cachedAmmoItem;
|
||||
|
||||
protected InventoryItem AmmoItem => FindAmmoItem();
|
||||
|
||||
private InventoryItem FindAmmoItem()
|
||||
protected override void OnUse()
|
||||
{
|
||||
var player = Dedugan.Local;
|
||||
if (player?.Inventory == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Кэшируем WeaponDefinition для избежания повторных вызовов
|
||||
if (_cachedWeaponDef == null)
|
||||
{
|
||||
_cachedWeaponDef = GetWeaponDefinition();
|
||||
if (_cachedWeaponDef == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Проверяем кэшированный результат
|
||||
if (_cachedAmmoItem != null && _cachedAmmoItem.Count > 0)
|
||||
{
|
||||
return _cachedAmmoItem;
|
||||
}
|
||||
|
||||
// Ищем патроны
|
||||
foreach (var item in player.Inventory.Items)
|
||||
{
|
||||
if (item.Definition is AmmoItemDefinition ammoDef && ammoDef.IsCompatibleWith(_cachedWeaponDef.AmmoType))
|
||||
{
|
||||
_cachedAmmoItem = item;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
_cachedAmmoItem = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual WeaponItemDefinition GetWeaponDefinition()
|
||||
{
|
||||
// Переопределите в наследниках для возврата определения оружия
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool CanUse()
|
||||
{
|
||||
var ammo = AmmoItem;
|
||||
var baseCanUse = base.CanUse();
|
||||
var hasAmmo = ammo != null && ammo.Count > 0;
|
||||
|
||||
return baseCanUse && hasAmmo;
|
||||
}
|
||||
|
||||
public override void Use()
|
||||
{
|
||||
if (!CanUse())
|
||||
return;
|
||||
|
||||
OnUse();
|
||||
|
||||
var ammo = AmmoItem;
|
||||
if (ammo != null)
|
||||
{
|
||||
// Уменьшаем количество патронов
|
||||
if (ammo.TryRemoveCount(1))
|
||||
{
|
||||
// Если патроны закончились, удаляем предмет из инвентаря
|
||||
if (ammo.Count <= 0)
|
||||
{
|
||||
Dedugan.Local.Inventory.RemoveItem(ammo);
|
||||
_cachedAmmoItem = null; // Очищаем кэш
|
||||
}
|
||||
}
|
||||
}
|
||||
// Базовая реализация - ничего не делает
|
||||
// Логика использования патронов теперь в BaseWeapon
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,9 @@ public sealed class PickupItem : InteractionButton
|
||||
// Устанавливаем правильную метку для предмета
|
||||
if ( GameObject.Components.TryGet<InventoryItem>( out var inventoryItem ) )
|
||||
{
|
||||
Label = inventoryItem.Definition?.Name ?? "Подобрать";
|
||||
Label = inventoryItem.Definition?.Name != ""
|
||||
? $"{inventoryItem.Definition.Name} x{inventoryItem.Count}"
|
||||
: "Подобрать";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user