upd
This commit is contained in:
@@ -9,4 +9,6 @@ public class BaseItemDefinition : GameResource
|
||||
[ResourceType( "prefab" )] public GameObject Prefab { get; set; }
|
||||
public Texture ImageTexture { get; set; }
|
||||
public string ImageUrl { get; set; }
|
||||
|
||||
public int MaxCount { get; set; } = 1;
|
||||
}
|
||||
|
||||
@@ -36,34 +36,50 @@ public class Inventar
|
||||
OnChanged?.Invoke();
|
||||
}
|
||||
|
||||
// public void EquipItem( InventoryItem item )
|
||||
// {
|
||||
// if ( EquippedItems.ContainsValue( item ) )
|
||||
// {
|
||||
// UnEquipItem( item );
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// EquippedItems.Add( item.Definition.Slot, item );
|
||||
// OnEquipped?.Invoke( item );
|
||||
// }
|
||||
// }
|
||||
|
||||
public void EquipItem( InventoryItem item )
|
||||
{
|
||||
if ( item.Definition is not IEquipable equipable ) return;
|
||||
if ( item.Definition is not IEquipable equipable )
|
||||
return;
|
||||
|
||||
// Если уже экипирован этот же предмет — снять его
|
||||
if ( EquippedItems.ContainsValue( item ) )
|
||||
{
|
||||
UnEquipItem( item );
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
// Если на этом слоте уже что-то есть — снять старый предмет
|
||||
if ( EquippedItems.TryGetValue( equipable.Slot, out var oldItem ) )
|
||||
{
|
||||
EquippedItems[equipable.Slot] = item;
|
||||
OnEquipped?.Invoke( item );
|
||||
UnEquipItem( oldItem );
|
||||
|
||||
// Вернуть снятый предмет обратно в инвентарь, если его там нет
|
||||
if ( !Items.Contains( oldItem ) )
|
||||
Items.Add( oldItem );
|
||||
}
|
||||
|
||||
// Экипировать новый предмет
|
||||
EquippedItems[equipable.Slot] = item;
|
||||
OnEquipped?.Invoke( item );
|
||||
}
|
||||
|
||||
public void DropItem( InventoryItem item, Vector3 position )
|
||||
{
|
||||
var gO = item.Definition.Prefab.Clone( position );
|
||||
|
||||
if ( gO.Components.TryGet<InventoryItem>( out var inventoryItem ) )
|
||||
{
|
||||
inventoryItem.Count = item.Count;
|
||||
}
|
||||
|
||||
gO.NetworkSpawn( null );
|
||||
|
||||
RemoveItem( item );
|
||||
// Items.Remove( item );
|
||||
// OnChanged?.Invoke();
|
||||
}
|
||||
|
||||
|
||||
public void UnEquipItem( InventoryItem item )
|
||||
{
|
||||
foreach ( var kvp in EquippedItems.Where( kvp => kvp.Value == item ).ToList() )
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Sasalka;
|
||||
|
||||
public class InventoryItem : Component
|
||||
{
|
||||
public BaseItemDefinition Definition { get; set; }
|
||||
public int Count { get; set; } = 1;
|
||||
public int MaxCount { get; set; } = 1;
|
||||
[Property] public BaseItemDefinition Definition { get; set; }
|
||||
[Property] public int Count { get; set; } = 1;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,12 @@
|
||||
|
||||
<root class="@( Inventar.IsInventoryOpen ? "" : "hidden" )">
|
||||
<div class="inventory-panel">
|
||||
@foreach ( var item in PlayerInventory.Items )
|
||||
@if ( PlayerInventory.Items.Count > 0 )
|
||||
{
|
||||
<Sasalka.Ui.InventoryItem Item="@item" OnItemClick="@( UseItem )"/>
|
||||
@foreach ( var item in PlayerInventory.Items )
|
||||
{
|
||||
<Sasalka.Ui.InventoryItem Item="@item" OnItemClick="@( UseItem )" OnItemRightClick="@( DropItem )"/>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</root>
|
||||
@@ -21,6 +24,11 @@
|
||||
Player?.Inventory?.EquipItem( item );
|
||||
}
|
||||
|
||||
void DropItem( Sasalka.InventoryItem item )
|
||||
{
|
||||
Player?.Inventory?.DropItem( item, Player.CameraPivot.WorldPosition + Player.Camera.LocalRotation.Right * 50 );
|
||||
}
|
||||
|
||||
protected override void OnUpdate()
|
||||
{
|
||||
if ( Input.Pressed( "Score" ) )
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
@inherits Sandbox.UI.Panel
|
||||
@namespace Sasalka.Ui
|
||||
|
||||
<root class="inventory-item @( Equipped ? "equipped" : "" )" @onclick="@(() => OnItemClick?.Invoke( Item ))">
|
||||
<input type="checkbox" class="equipped-checkbox" checked="@Equipped" disabled/>
|
||||
<root class="inventory-item @( Equipped ? "equipped" : "" )" @onclick="@(() => OnItemClick?.Invoke( Item ))" @onrightclick=@( () => OnItemRightClick?.Invoke( Item ) )>
|
||||
|
||||
@* <input type="checkbox" class="equipped-checkbox" checked="@Equipped" disabled/> *@
|
||||
|
||||
@if ( Item.Definition.ImageTexture.IsValid() )
|
||||
{
|
||||
<img src="@Item.Definition.ImageTexture.ResourcePath" alt="@Item.Definition.Name"/>
|
||||
@@ -16,12 +18,17 @@
|
||||
|
||||
<div class="inventory-item__name">@Item?.Definition.Name</div>
|
||||
|
||||
<div class="inventory-item__count">@Item?.Count / @Item?.MaxCount</div>
|
||||
@if ( Item?.Definition.MaxCount > 1 )
|
||||
{
|
||||
<div class="inventory-item__count">@Item?.Count / @Item?.Definition.MaxCount</div>
|
||||
}
|
||||
</root>
|
||||
|
||||
@code {
|
||||
public Sasalka.InventoryItem Item { get; set; }
|
||||
public Action<Sasalka.InventoryItem> OnItemClick { get; set; }
|
||||
public Action<Sasalka.InventoryItem> OnItemRightClick { get; set; }
|
||||
|
||||
public bool Equipped { get; set; }
|
||||
|
||||
protected override int BuildHash()
|
||||
|
||||
@@ -6,8 +6,7 @@ public abstract class AmmoUseableBase : UseableBase
|
||||
|
||||
private InventoryItem FindAmmoItem()
|
||||
{
|
||||
// var ammoDefinition = new InventoryItemDefinition();
|
||||
|
||||
//По типу патрон поиск + енум типа патрон
|
||||
return Dedugan.Local.Inventory.Items.FirstOrDefault( i => i.Definition.Name == "Pistol Ammo" );
|
||||
}
|
||||
|
||||
@@ -28,7 +27,6 @@ public abstract class AmmoUseableBase : UseableBase
|
||||
if ( ammo != null )
|
||||
{
|
||||
ammo.Count--;
|
||||
Log.Info( $"[AmmoUseableBase] Ammo left: {ammo.Count}" );
|
||||
|
||||
if ( ammo.Count <= 0 )
|
||||
{
|
||||
|
||||
29
Code/Inventory/Usable/PickupItem.cs
Normal file
29
Code/Inventory/Usable/PickupItem.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using Sandbox.Gravity;
|
||||
using Sasalka;
|
||||
|
||||
namespace Sandbox.UI;
|
||||
|
||||
[Icon( "skip_next" )]
|
||||
public sealed class PickupItem : InteractionButton
|
||||
{
|
||||
[Property] public override string Label { get; set; } = "E";
|
||||
|
||||
public override bool Press( IPressable.Event e )
|
||||
{
|
||||
base.Press( e );
|
||||
|
||||
if ( e.Source.Components.TryGet<Dedugan>( out var dedugan ) )
|
||||
{
|
||||
dedugan.Inventory.AddItem( Components.Get<InventoryItem>() );
|
||||
RpcDestroy();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[Rpc.Broadcast]
|
||||
void RpcDestroy()
|
||||
{
|
||||
GameObject.Destroy();
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,17 @@
|
||||
|
||||
public static class UseSystem
|
||||
{
|
||||
public static void TryUse( IUseContext context )
|
||||
public static bool TryUse( IUseContext context )
|
||||
{
|
||||
foreach ( var useable in context.GetUsables() )
|
||||
{
|
||||
if ( useable.CanUse() )
|
||||
{
|
||||
useable.Use();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,38 @@ public abstract class UseableBase : Component, IUseable
|
||||
{
|
||||
[Property] public float Cooldown { get; set; } = 0.5f;
|
||||
|
||||
private TimeSince _timeSinceUsed;
|
||||
private bool _equipped;
|
||||
|
||||
protected override void OnStart()
|
||||
[Property]
|
||||
public bool Equipped
|
||||
{
|
||||
get => _equipped;
|
||||
set
|
||||
{
|
||||
if ( _equipped != value )
|
||||
{
|
||||
_equipped = value;
|
||||
if ( _equipped )
|
||||
{
|
||||
OnEquip?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private TimeSince _timeSinceUsed;
|
||||
public Action OnEquip { get; set; }
|
||||
|
||||
protected override void OnAwake()
|
||||
{
|
||||
_timeSinceUsed = Cooldown;
|
||||
|
||||
OnEquip += OnEquipped;
|
||||
}
|
||||
|
||||
public virtual void OnEquipped()
|
||||
{
|
||||
Log.Info( $"OnEquip {this}" );
|
||||
}
|
||||
|
||||
public virtual bool CanUse()
|
||||
|
||||
Reference in New Issue
Block a user