This commit is contained in:
Oscar
2025-06-26 01:56:08 +03:00
parent 5c9be94aba
commit 8b61aa1d7b
89 changed files with 7072 additions and 333 deletions

View File

@@ -6,9 +6,14 @@ public class BaseItemDefinition : GameResource
public string Name { get; set; }
public string Description { get; set; }
[ResourceType( "prefab" )] public GameObject Prefab { get; set; }
[ResourceType( "prefab" )]
public GameObject Prefab { get; set; } = GameObject.GetPrefab( "prefabs/item_parcel.prefab" );
public Texture ImageTexture { get; set; }
public string ImageUrl { get; set; }
public int MaxCount { get; set; } = 1;
public virtual Inventar.InventorySlot? GetSlot() => null;
}

View File

@@ -5,4 +5,5 @@ public class ClothingItemDefinition : BaseItemDefinition, IEquipable
{
[Property] public string ClothUrl { get; set; }
public Inventar.InventorySlot Slot { get; set; }
public override Inventar.InventorySlot? GetSlot() => Slot;
}

View File

@@ -6,6 +6,8 @@ namespace Sasalka;
public class WeaponItemDefinition : BaseItemDefinition, IEquipable
{
public Inventar.InventorySlot Slot { get; set; }
public override Inventar.InventorySlot? GetSlot() => Slot;
public CitizenAnimationHelper.HoldTypes HoldType { get; set; } = CitizenAnimationHelper.HoldTypes.None;
[InlineEditor, Space] public WeaponDefinition WeaponDefinition { get; set; }
}

View File

@@ -60,23 +60,28 @@ public class Inventar
// Экипировать новый предмет
EquippedItems[equipable.Slot] = item;
item.Equipped = true;
OnEquipped?.Invoke( item );
}
public void DropItem( InventoryItem item, Vector3 position )
{
var gO = item.Definition.Prefab.Clone( position );
GameObject gO = item.Definition.Prefab.Clone( position );
if ( gO.Components.TryGet<InventoryItem>( out var inventoryItem ) )
{
inventoryItem.Count = item.Count;
if ( inventoryItem.Definition == null )
{
inventoryItem.Definition = item.Definition;
}
}
gO.NetworkSpawn( null );
RemoveItem( item );
// Items.Remove( item );
// OnChanged?.Invoke();
Items.Remove( item );
OnChanged?.Invoke();
}
@@ -87,6 +92,7 @@ public class Inventar
EquippedItems.Remove( kvp.Key );
}
item.Equipped = false;
OnUnEquipped?.Invoke( item );
}
}

View File

@@ -1,4 +1,5 @@
using Sandbox;
using Sandbox.UI;
namespace Sasalka;
@@ -6,4 +7,13 @@ public class InventoryItem : Component
{
[Property] public BaseItemDefinition Definition { get; set; }
[Property] public int Count { get; set; } = 1;
[Property] public bool Equipped { get; set; } = false;
protected override void OnStart()
{
if ( GameObject.Components.TryGet<PickupItem>( out var item ) ) //FindMode.EverythingInSelf
{
item.Label = Definition.Name;
}
}
}

View File

@@ -2,7 +2,7 @@
@inherits PanelComponent
@namespace Sasalka.Ui
<root class="@( Inventar.IsInventoryOpen ? "" : "hidden" )">
<root class="inventory @( Inventar.IsInventoryOpen ? "" : "hidden" )">
<div class="inventory-panel">
@if ( PlayerInventory.Items.Count > 0 )
{

View File

@@ -1,34 +1,30 @@
Inventory {
display: flex;
flex-direction: column;
height: 96vh;
width: 30%;
position: absolute;
top: 20px;
right: 20px;
padding: 24px;
background: linear-gradient(135deg, #0a1a2b 0%, #08111f 100%);
border: 3px solid #2a3d54;
border-radius: 14px;
font-family: 'Orbitron', 'Poppins', sans-serif;
position: absolute;
width: 30%;
height: 96vh;
right: 20px;
top: 20px;
padding: 24px;
display: flex;
flex-direction: column;
gap: 20px;
transition: all 0.2s ease;
z-index: 100;
overflow: hidden;
pointer-events: all;
&.hidden {
opacity: 0;
}
}
.inventory-panel {
overflow-y: scroll;
display: flex;
flex-direction: column;
gap: 12px;
//background-color: rgba(255, 0, 0, 0.1);
}
.hidden {
opacity: 0;
}

View File

@@ -3,24 +3,33 @@
@inherits Sandbox.UI.Panel
@namespace Sasalka.Ui
<root class="inventory-item @( Equipped ? "equipped" : "" )" @onclick="@(() => OnItemClick?.Invoke( Item ))" @onrightclick=@( () => OnItemRightClick?.Invoke( Item ) )>
@{
var definition = Item?.Definition;
var name = definition?.Name;
var slot = Item?.Equipped == true ? definition?.GetSlot() : null;
var imageUrl = definition?.ImageTexture.IsValid() == true
? definition.ImageTexture.ResourcePath
: !string.IsNullOrWhiteSpace( definition?.ImageUrl )
? definition.ImageUrl
: null;
}
@* <input type="checkbox" class="equipped-checkbox" checked="@Equipped" disabled/> *@
@if ( Item.Definition.ImageTexture.IsValid() )
<root class="inventory-item @( Item.Equipped ? "equipped" : "" )" @onclick="@(() => OnItemClick?.Invoke( Item ))" @onrightclick=@( () => OnItemRightClick?.Invoke( Item ) )>
@if ( slot is not null )
{
<img src="@Item.Definition.ImageTexture.ResourcePath" alt="@Item.Definition.Name"/>
}
else if ( Item.Definition.ImageUrl.Length > 0 )
{
<img src="@Item.Definition.ImageUrl" alt="@Item.Definition.Name">
<div class="inventory-item__slot">@slot</div>
}
<div class="inventory-item__name">@Item?.Definition.Name</div>
@if ( Item?.Definition.MaxCount > 1 )
@if ( !string.IsNullOrEmpty( imageUrl ) )
{
<div class="inventory-item__count">@Item?.Count / @Item?.Definition.MaxCount</div>
<img src="@imageUrl" alt="@name"/>
}
<div class="inventory-item__name">@name</div>
@if ( definition?.MaxCount > 1 )
{
<div class="inventory-item__count">@Item?.Count / @definition.MaxCount</div>
}
</root>
@@ -29,16 +38,11 @@
public Action<Sasalka.InventoryItem> OnItemClick { get; set; }
public Action<Sasalka.InventoryItem> OnItemRightClick { get; set; }
public bool Equipped { get; set; }
protected override int BuildHash()
{
base.BuildHash();
var hash = new HashCode();
hash.Add( Item.Count );
hash.Add( Item?.Count );
return hash.ToHashCode();
}

View File

@@ -1,16 +1,16 @@
InventoryItem {
flex-shrink: 0;
width: 100%;
//height: 64px;
background: #2a3d53;
display: flex;
gap: 24px;
align-items: center;
justify-content: flex-start;
border: 1px solid #666;
cursor: pointer;
transition: background 0.2s;
border-radius: 12px;
padding: 12px 24px;
cursor: pointer;
transition: background 0.2s ease;
position: relative;
&:hover {
@@ -20,22 +20,30 @@ InventoryItem {
img {
width: 32px;
height: 32px;
object-fit: contain;
}
&.name {
.inventory-item__name {
font-size: 20px;
font-weight: 500;
}
.inventory-item__count {
margin-left: auto;
font-size: 14px;
color: #ccc;
}
.inventory-item__slot {
font-size: 12px;
color: #8fc98f;
background: rgba(0, 0, 0, 0.3);
padding: 2px 6px;
border-radius: 4px;
}
&.equipped {
border: 2px solid #4caf50;
background: #2e3e2e;
}
.equipped-checkbox {
position: absolute;
top: 6px;
left: 6px;
pointer-events: none;
accent-color: #4caf50;
}
}