202 lines
5.3 KiB
C#
202 lines
5.3 KiB
C#
using Sandbox.Citizen;
|
||
using Sandbox.Weapons;
|
||
using Sasalka;
|
||
|
||
public sealed partial class Dedugan : Component
|
||
{
|
||
[Property, InlineEditor] public Inventar Inventory { get; private set; } = new();
|
||
|
||
private Dictionary<Inventar.InventorySlot, (GameObject obj, IUseable useable)> _useableCache = new();
|
||
[Sync] private bool InAds { get; set; } = false;
|
||
private AttachmentSlotResolver _resolver;
|
||
|
||
void InventoryStart()
|
||
{
|
||
if ( !Network.IsOwner ) return;
|
||
|
||
_resolver = new AttachmentSlotResolver( Renderer.GetAttachmentObject );
|
||
|
||
Inventory.AddItem( new InventoryItem
|
||
{
|
||
Definition = ResourceLibrary.Get<ClothingItemDefinition>( "Items/cloth_pijama.clitem" )
|
||
} );
|
||
|
||
// Inventory.AddItem( new InventoryItem
|
||
// {
|
||
// Definition = ResourceLibrary.Get<BaseItemDefinition>( "Items/shorts_1.inv" )
|
||
// } );
|
||
|
||
Inventory.AddItem( new InventoryItem
|
||
{
|
||
Definition = ResourceLibrary.Get<WeaponItemDefinition>( "Items/pistol_test.weapon" )
|
||
} );
|
||
|
||
var ammo = new InventoryItem
|
||
{
|
||
Definition = ResourceLibrary.Get<BaseItemDefinition>( "Items/pistol_ammo.inv" )
|
||
};
|
||
ammo.Count = 30;
|
||
ammo.MaxCount = 130;
|
||
|
||
Inventory.AddItem( ammo );
|
||
|
||
Inventory.OnEquipped += OnItemEquipped;
|
||
Inventory.OnUnEquipped += OnItemUnEquipped;
|
||
}
|
||
|
||
private void OnItemEquipped( InventoryItem item )
|
||
{
|
||
// Если это оружие
|
||
if ( item.Definition is WeaponItemDefinition weaponDef && weaponDef.Prefab.IsValid() )
|
||
{
|
||
var go = weaponDef.Prefab.Clone();
|
||
|
||
AnimationHelper.HoldType = weaponDef.HoldType;
|
||
|
||
switch ( weaponDef.Slot )
|
||
{
|
||
case Inventar.InventorySlot.LeftHand | Inventar.InventorySlot.RightHand:
|
||
case Inventar.InventorySlot.RightHand:
|
||
go.Parent = Renderer.GetAttachmentObject( "hold_R" );
|
||
break;
|
||
case Inventar.InventorySlot.LeftHand:
|
||
go.Parent = Renderer.GetAttachmentObject( "hold_L" );
|
||
break;
|
||
default:
|
||
go.Parent = Renderer.GetAttachmentObject( "forward_reference_modelspace" );
|
||
break;
|
||
}
|
||
|
||
go.LocalPosition = weaponDef.WeaponDefinition.Position;
|
||
go.LocalRotation = weaponDef.WeaponDefinition.Rotation;
|
||
|
||
go.NetworkSpawn();
|
||
|
||
var hand = weaponDef.Slot switch
|
||
{
|
||
Inventar.InventorySlot.LeftHand => CitizenAnimationHelper.Hand.Left,
|
||
Inventar.InventorySlot.RightHand => CitizenAnimationHelper.Hand.Right,
|
||
Inventar.InventorySlot.LeftHand | Inventar.InventorySlot.RightHand => CitizenAnimationHelper.Hand.Both,
|
||
_ => CitizenAnimationHelper.Hand.Both
|
||
};
|
||
|
||
AnimationHelper.Handedness = hand;
|
||
|
||
RpcSetHoldAnimation( weaponDef.HoldType, hand );
|
||
|
||
InAds = true;
|
||
}
|
||
// Если это одежда
|
||
else if ( item.Definition is ClothingItemDefinition clothingDef )
|
||
{
|
||
WearWorkshop( new List<string>() { clothingDef.ClothUrl } );
|
||
}
|
||
}
|
||
|
||
|
||
private void OnItemUnEquipped( InventoryItem item )
|
||
{
|
||
if ( item.Definition is WeaponItemDefinition weaponDef && weaponDef.Prefab.IsValid() )
|
||
{
|
||
switch ( weaponDef.Slot )
|
||
{
|
||
case Inventar.InventorySlot.LeftHand | Inventar.InventorySlot.RightHand:
|
||
case Inventar.InventorySlot.RightHand:
|
||
case Inventar.InventorySlot.LeftHand:
|
||
var attachmentName = !weaponDef.Slot.HasFlag( Inventar.InventorySlot.RightHand )
|
||
? "hold_L"
|
||
: "hold_R";
|
||
|
||
Renderer.GetAttachmentObject( attachmentName ).Children.ForEach( child => child.Destroy() );
|
||
RpcSetHoldAnimation( CitizenAnimationHelper.HoldTypes.None, CitizenAnimationHelper.Hand.Both );
|
||
break;
|
||
default:
|
||
Renderer.GetAttachmentObject( "forward_reference_modelspace" ).Children
|
||
.ForEach( child => child.Destroy() );
|
||
break;
|
||
}
|
||
|
||
item.Destroy();
|
||
InAds = false;
|
||
}
|
||
else if ( item.Definition is ClothingItemDefinition clothingDef )
|
||
{
|
||
StripByName( clothingDef.Name );
|
||
}
|
||
}
|
||
|
||
[Rpc.Broadcast]
|
||
public void RpcSetHoldAnimation( CitizenAnimationHelper.HoldTypes HoldType, CitizenAnimationHelper.Hand hand )
|
||
{
|
||
AnimationHelper.HoldType = HoldType;
|
||
AnimationHelper.Handedness = hand;
|
||
}
|
||
|
||
|
||
// AnimationHelper.HoldType = CitizenAnimationHelper.HoldTypes.None;
|
||
// AnimationHelper.Handedness = CitizenAnimationHelper.Hand.Both;
|
||
|
||
|
||
void InventoryUpdate()
|
||
{
|
||
if ( !Network.IsOwner ) return;
|
||
|
||
// InAds = Input.Down( "Attack2" );
|
||
|
||
if ( Input.Pressed( "Attack1" ) )
|
||
{
|
||
UseSystem.TryUse( this );
|
||
Attack();
|
||
}
|
||
}
|
||
|
||
public IEnumerable<IUseable>
|
||
GetUsables() //Допустим, у джетпака слот Body. Просто дописываешь в GetUsables() Inventar.InventorySlot.Body:
|
||
{
|
||
foreach ( var slot in new[] { Inventar.InventorySlot.LeftHand, Inventar.InventorySlot.RightHand } )
|
||
{
|
||
if ( !Inventory.EquippedItems.TryGetValue( slot, out var item ) )
|
||
continue;
|
||
|
||
var holder = _resolver.GetSlotObject( slot );
|
||
var heldObject = holder?.Children.FirstOrDefault();
|
||
|
||
if ( heldObject == null )
|
||
continue;
|
||
|
||
if ( _useableCache.TryGetValue( slot, out var cached ) && cached.obj == heldObject )
|
||
{
|
||
if ( cached.useable != null )
|
||
yield return cached.useable;
|
||
}
|
||
else
|
||
{
|
||
var useable = heldObject.Components.Get<IUseable>();
|
||
_useableCache[slot] = (heldObject, useable);
|
||
|
||
if ( useable != null )
|
||
yield return useable;
|
||
}
|
||
}
|
||
}
|
||
|
||
[Rpc.Broadcast]
|
||
void Attack()
|
||
{
|
||
Renderer.Set( "b_attack", true );
|
||
}
|
||
}
|
||
|
||
|
||
// if ( !Network.IsOwner ) return;
|
||
//
|
||
// InAds = Input.Down( "Attack2" );
|
||
//
|
||
// if ( Input.Pressed( "Attack1" ) && _weapon != null )
|
||
// {
|
||
// _weapon.Attack();
|
||
// Attack();
|
||
// }
|
||
// }
|
||
//
|