upd
This commit is contained in:
@@ -39,7 +39,7 @@ public sealed partial class Dedugan
|
||||
Camera.LocalRotation.Backward * MathF.Min( 0f, EyeAngles.pitch ) * 0.8f +
|
||||
Camera.LocalRotation.Right * -anotherPivot;
|
||||
|
||||
if ( AnimationHelper.HoldType == CitizenAnimationHelper.HoldTypes.Pistol )
|
||||
if ( InAds )
|
||||
{
|
||||
pivotOffset = CameraPivot.LocalRotation.Backward * CamOffsetX * 0.5f + CameraPivot.LocalRotation.Up * 8f;
|
||||
}
|
||||
|
||||
206
Code/Player/Dedugan.Inventory.cs
Normal file
206
Code/Player/Dedugan.Inventory.cs
Normal file
@@ -0,0 +1,206 @@
|
||||
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<InventoryItemDefinition>( "Items/Pijama.inv" )
|
||||
} );
|
||||
|
||||
Inventory.AddItem( new InventoryItem
|
||||
{
|
||||
Definition = ResourceLibrary.Get<InventoryItemDefinition>( "Items/pistol.inv" )
|
||||
} );
|
||||
|
||||
var ammo = new InventoryItem
|
||||
{
|
||||
Definition = ResourceLibrary.Get<InventoryItemDefinition>( "Items/pistol_ammo.inv" )
|
||||
};
|
||||
ammo.Count = 30;
|
||||
ammo.MaxCount = 130;
|
||||
|
||||
Inventory.AddItem( ammo );
|
||||
|
||||
Inventory.OnEquipped += OnItemEquipped;
|
||||
Inventory.OnUnEquipped += OnItemUnEquipped;
|
||||
}
|
||||
|
||||
private void OnItemEquipped( InventoryItem item )
|
||||
{
|
||||
var go = item.Definition.Prefab.Clone();
|
||||
|
||||
AnimationHelper.HoldType = item.Definition.HoldType;
|
||||
|
||||
// switch ( item.Definition.Slot )
|
||||
// {
|
||||
// case Inventar.InventorySlot.LeftHand | Inventar.InventorySlot.RightHand:
|
||||
// go.Parent = Renderer.GetAttachmentObject( "hold_R" );
|
||||
// AnimationHelper.Handedness = CitizenAnimationHelper.Hand.Both;
|
||||
// break;
|
||||
// case Inventar.InventorySlot.RightHand:
|
||||
// go.Parent = Renderer.GetAttachmentObject( "hold_R" );
|
||||
// AnimationHelper.Handedness = CitizenAnimationHelper.Hand.Right;
|
||||
// break;
|
||||
// case Inventar.InventorySlot.LeftHand:
|
||||
// go.Parent = Renderer.GetAttachmentObject( "hold_L" );
|
||||
// AnimationHelper.Handedness = CitizenAnimationHelper.Hand.Left;
|
||||
// break;
|
||||
// default:
|
||||
// go.Parent = Renderer.GetAttachmentObject( "forward_reference_modelspace" );
|
||||
// break;
|
||||
// }
|
||||
switch ( item.Definition.Slot )
|
||||
{
|
||||
case Inventar.InventorySlot.LeftHand | Inventar.InventorySlot.RightHand:
|
||||
go.Parent = Renderer.GetAttachmentObject( "hold_R" );
|
||||
break;
|
||||
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 = item.Definition.WeaponDefinition.Position;
|
||||
go.LocalRotation = item.Definition.WeaponDefinition.Rotation;
|
||||
|
||||
go.NetworkSpawn();
|
||||
|
||||
var hand = item.Definition.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.HoldType = item.Definition.HoldType;
|
||||
AnimationHelper.Handedness = hand;
|
||||
|
||||
RpcSetHoldAnimation( item.Definition.HoldType, hand );
|
||||
|
||||
InAds = true;
|
||||
// item.SpawnedObject = go;
|
||||
}
|
||||
|
||||
private void OnItemUnEquipped( InventoryItem item )
|
||||
{
|
||||
switch ( item.Definition.Slot )
|
||||
{
|
||||
case Inventar.InventorySlot.LeftHand | Inventar.InventorySlot.RightHand:
|
||||
case Inventar.InventorySlot.RightHand:
|
||||
case Inventar.InventorySlot.LeftHand:
|
||||
var attachmentName = !item.Definition.Slot.HasFlag( Inventar.InventorySlot.RightHand )
|
||||
? "hold_L"
|
||||
: "hold_R";
|
||||
|
||||
Renderer.GetAttachmentObject( attachmentName ).Children.ForEach( child => child.Destroy() );
|
||||
// AnimationHelper.Handedness = CitizenAnimationHelper.Hand.Both;
|
||||
// AnimationHelper.HoldType = CitizenAnimationHelper.HoldTypes.None;
|
||||
|
||||
RpcSetHoldAnimation( CitizenAnimationHelper.HoldTypes.None, CitizenAnimationHelper.Hand.Both );
|
||||
break;
|
||||
default:
|
||||
Renderer.GetAttachmentObject( "forward_reference_modelspace" ).Children
|
||||
.ForEach( child => child.Destroy() );
|
||||
break;
|
||||
}
|
||||
|
||||
// item.SpawnedObject = null;
|
||||
item.Destroy();
|
||||
|
||||
InAds = false;
|
||||
}
|
||||
|
||||
[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();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
@@ -1,12 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Sandbox;
|
||||
|
||||
partial class Dedugan
|
||||
{
|
||||
[Property] public List<string> WorkshopItems { get; set; }
|
||||
[Property] public ClothingContainer CurrentClothing { get; set; }
|
||||
public static IReadOnlyList<Dedugan> All => InternalPlayers;
|
||||
public static List<Dedugan> InternalPlayers = new List<Dedugan>();
|
||||
|
||||
public List<ClothingContainer.ClothingEntry> Clothings { get; set; }
|
||||
public static Dedugan Local { get; set; }
|
||||
|
||||
private Guid _guid;
|
||||
@@ -47,4 +52,87 @@ partial class Dedugan
|
||||
public static Dedugan GetByID( Guid id )
|
||||
=> InternalPlayers.FirstOrDefault( x => x.ConnectionID == id );
|
||||
|
||||
public void OnNetworkSpawn( Connection owner )
|
||||
{
|
||||
CurrentClothing = ClothingContainer.CreateFromJson( owner.GetUserData( "avatar" ) );
|
||||
|
||||
var allowedCategories = new[]
|
||||
{
|
||||
Clothing.ClothingCategory.Skin, Clothing.ClothingCategory.Facial, Clothing.ClothingCategory.Eyes,
|
||||
Clothing.ClothingCategory.Eyebrows, Clothing.ClothingCategory.Eyelashes,
|
||||
Clothing.ClothingCategory.MakeupLips, Clothing.ClothingCategory.MakeupEyeshadow,
|
||||
Clothing.ClothingCategory.MakeupEyeliner, Clothing.ClothingCategory.MakeupHighlighter,
|
||||
Clothing.ClothingCategory.MakeupBlush, Clothing.ClothingCategory.MakeupSpecial,
|
||||
Clothing.ClothingCategory.ComplexionFreckles, Clothing.ClothingCategory.ComplexionScars,
|
||||
Clothing.ClothingCategory.ComplexionAcne, Clothing.ClothingCategory.FacialHairMustache,
|
||||
Clothing.ClothingCategory.FacialHairBeard, Clothing.ClothingCategory.FacialHairStubble,
|
||||
Clothing.ClothingCategory.FacialHairSideburns, Clothing.ClothingCategory.FacialHairGoatee,
|
||||
Clothing.ClothingCategory.PierceNose, Clothing.ClothingCategory.PierceEyebrow,
|
||||
Clothing.ClothingCategory.PierceSpecial, Clothing.ClothingCategory.Hair,
|
||||
Clothing.ClothingCategory.HairShort, Clothing.ClothingCategory.HairMedium,
|
||||
Clothing.ClothingCategory.HairLong, Clothing.ClothingCategory.HairUpdo,
|
||||
Clothing.ClothingCategory.HairSpecial,
|
||||
};
|
||||
|
||||
CurrentClothing.Clothing.RemoveAll( entry => !allowedCategories.Contains( entry.Clothing.Category ) );
|
||||
CurrentClothing.Apply( Renderer );
|
||||
|
||||
WearWorkshop( WorkshopItems );
|
||||
}
|
||||
|
||||
CancellationTokenSource _cts;
|
||||
|
||||
public async void WearWorkshop( List<string> workshopItems )
|
||||
{
|
||||
_cts = new CancellationTokenSource();
|
||||
var token = _cts.Token;
|
||||
|
||||
// var clothing = new ClothingContainer();
|
||||
// clothing.AddRange( Clothings );
|
||||
|
||||
if ( workshopItems != null && workshopItems.Count > 0 )
|
||||
{
|
||||
var tasks = workshopItems.Select( x => InstallWorkshopClothing( x, token ) );
|
||||
|
||||
foreach ( var task in tasks )
|
||||
{
|
||||
var c = await task;
|
||||
|
||||
if ( c is null )
|
||||
continue;
|
||||
|
||||
CurrentClothing.Add( c );
|
||||
}
|
||||
}
|
||||
|
||||
CurrentClothing.Normalize();
|
||||
CurrentClothing.Apply( Renderer );
|
||||
Renderer.PostAnimationUpdate();
|
||||
|
||||
// foreach ( var clothing in CurrentClothing.Clothing )
|
||||
// {
|
||||
// Log.Info( clothing.Clothing.Title );
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
async Task<Clothing> InstallWorkshopClothing( string ident, CancellationToken ct )
|
||||
{
|
||||
if ( string.IsNullOrEmpty( ident ) ) return default;
|
||||
|
||||
var package = await Package.FetchAsync( ident, false );
|
||||
if ( package is null ) return default;
|
||||
if ( package.TypeName != "clothing" ) return default;
|
||||
if ( ct.IsCancellationRequested ) return default;
|
||||
|
||||
var primaryAsset = package.GetMeta<string>( "PrimaryAsset" );
|
||||
if ( string.IsNullOrWhiteSpace( primaryAsset ) ) return default;
|
||||
|
||||
var fs = await package.MountAsync();
|
||||
if ( fs is null ) return default;
|
||||
if ( ct.IsCancellationRequested ) return default;
|
||||
|
||||
// try to load it
|
||||
return ResourceLibrary.Get<Clothing>( primaryAsset );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
using Sandbox.Citizen;
|
||||
using Sandbox.Weapons;
|
||||
|
||||
public sealed partial class Dedugan
|
||||
{
|
||||
[Property] public GameObject Gun { get; set; }
|
||||
[Sync] private bool InAds { get; set; } = false;
|
||||
|
||||
private Weapon _weapon { get; set; }
|
||||
|
||||
void WeaponStart()
|
||||
{
|
||||
_weapon = Gun.Components.Get<Weapon>(FindMode.EverythingInSelfAndDescendants );
|
||||
|
||||
Log.Info( $"_weapon: {_weapon}, Network.IsOwner: {Network.IsOwner}" );
|
||||
}
|
||||
|
||||
[Rpc.Broadcast]
|
||||
void Attack()
|
||||
{
|
||||
Renderer.Set( "b_attack", true );
|
||||
}
|
||||
|
||||
void WeaponUpdate()
|
||||
{
|
||||
if ( InAds )
|
||||
{
|
||||
AnimationHelper.Handedness = CitizenAnimationHelper.Hand.Right;
|
||||
AnimationHelper.HoldType = CitizenAnimationHelper.HoldTypes.Pistol;
|
||||
|
||||
Gun.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AnimationHelper.Handedness = CitizenAnimationHelper.Hand.Both;
|
||||
AnimationHelper.HoldType = CitizenAnimationHelper.HoldTypes.None;
|
||||
|
||||
Gun.Enabled = false;
|
||||
}
|
||||
|
||||
if ( !Network.IsOwner ) return;
|
||||
|
||||
InAds = Input.Down( "Attack2" );
|
||||
|
||||
if ( Input.Pressed( "Attack1" ) && InAds )
|
||||
{
|
||||
_weapon.Attack();
|
||||
Attack();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
using System;
|
||||
using Sandbox;
|
||||
using Sandbox.Citizen;
|
||||
using Sasalka;
|
||||
using ShrimpleCharacterController;
|
||||
|
||||
public sealed partial class Dedugan : Component
|
||||
public sealed partial class Dedugan : Component, IUseContext, Component.INetworkSpawn
|
||||
{
|
||||
[RequireComponent] public ShrimpleCharacterController.ShrimpleCharacterController Controller { get; set; }
|
||||
[RequireComponent] public CitizenAnimationHelper AnimationHelper { get; set; }
|
||||
// [Property] public SkinnedModelRenderer Anim {get; set;}
|
||||
|
||||
public SkinnedModelRenderer Renderer { get; set; }
|
||||
[Property] public SkinnedModelRenderer Renderer { get; set; }
|
||||
[Property] public GameObject Camera { get; set; }
|
||||
[Property] public GameObject CameraPivot { get; set; }
|
||||
[Property] public GameObject InventoryUI { get; set; }
|
||||
|
||||
[Property] [Range( 1f, 200f, 1f )] public float CamOffsetX { get; set; }
|
||||
[Property] [Range( 50f, 1200f, 10f )] public float WalkSpeed { get; set; } = 100f;
|
||||
@@ -38,21 +38,23 @@ public sealed partial class Dedugan : Component
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
WeaponStart();
|
||||
InventoryStart();
|
||||
|
||||
RagdollController = Components.Get<RagdollController>();
|
||||
Renderer = Components.Get<SkinnedModelRenderer>( FindMode.EverythingInSelfAndDescendants );
|
||||
// Renderer = Components.Get<SkinnedModelRenderer>( FindMode.EverythingInSelfAndDescendants );
|
||||
|
||||
var cameraComponent = Camera.GetComponent<CameraComponent>();
|
||||
var listener = Components.Get<AudioListener>(true);
|
||||
var listener = Components.Get<AudioListener>( true );
|
||||
cameraComponent.Enabled = false;
|
||||
InventoryUI.Enabled = false;
|
||||
listener.Enabled = false;
|
||||
|
||||
if ( !Network.IsOwner ) return;
|
||||
|
||||
|
||||
cameraComponent.Enabled = true;
|
||||
listener.Enabled = true;
|
||||
|
||||
InventoryUI.Enabled = true;
|
||||
|
||||
if ( Renderer is null )
|
||||
return;
|
||||
|
||||
@@ -62,7 +64,7 @@ public sealed partial class Dedugan : Component
|
||||
protected override void OnUpdate()
|
||||
{
|
||||
UpdateCustomAnimations();
|
||||
WeaponUpdate();
|
||||
InventoryUpdate();
|
||||
if ( Network.IsOwner )
|
||||
{
|
||||
EyeAngles += Input.AnalogLook;
|
||||
|
||||
@@ -1,25 +1,34 @@
|
||||
using System;
|
||||
|
||||
namespace Sandbox;
|
||||
|
||||
public class PlayerDresser : Component, Component.INetworkSpawn
|
||||
{
|
||||
[Property]
|
||||
public SkinnedModelRenderer BodyRenderer { get; set; }
|
||||
[Property] public SkinnedModelRenderer BodyRenderer { get; set; }
|
||||
|
||||
[Property] public ClothingContainer currentClothing { get; set; }
|
||||
|
||||
// public void OnNetworkSpawn( Connection owner )
|
||||
// {
|
||||
// Log.Info( $"Hello {owner.Name}" );
|
||||
// var clothing = new ClothingContainer();
|
||||
// clothing.Deserialize( owner.GetUserData( "avatar" ) );
|
||||
// clothing.Apply( BodyRenderer );
|
||||
// }
|
||||
|
||||
public void OnNetworkSpawn( Connection owner )
|
||||
{
|
||||
Log.Info( $"Hello {owner.Name}" );
|
||||
var clothing = ClothingContainer.CreateFromJson( owner.GetUserData( "avatar" ) );
|
||||
clothing.Height = 1;
|
||||
clothing.Apply( BodyRenderer );
|
||||
currentClothing = ClothingContainer.CreateFromJson( owner.GetUserData( "avatar" ) );
|
||||
|
||||
var allowedCategories = new[]
|
||||
{
|
||||
Clothing.ClothingCategory.Skin, Clothing.ClothingCategory.Facial, Clothing.ClothingCategory.Eyes,
|
||||
Clothing.ClothingCategory.Eyebrows, Clothing.ClothingCategory.Eyelashes,
|
||||
Clothing.ClothingCategory.MakeupLips, Clothing.ClothingCategory.MakeupEyeshadow,
|
||||
Clothing.ClothingCategory.MakeupEyeliner, Clothing.ClothingCategory.MakeupHighlighter,
|
||||
Clothing.ClothingCategory.MakeupBlush, Clothing.ClothingCategory.MakeupSpecial,
|
||||
Clothing.ClothingCategory.ComplexionFreckles, Clothing.ClothingCategory.ComplexionScars,
|
||||
Clothing.ClothingCategory.ComplexionAcne, Clothing.ClothingCategory.FacialHairMustache,
|
||||
Clothing.ClothingCategory.FacialHairBeard, Clothing.ClothingCategory.FacialHairStubble,
|
||||
Clothing.ClothingCategory.FacialHairSideburns, Clothing.ClothingCategory.FacialHairGoatee,
|
||||
Clothing.ClothingCategory.PierceNose, Clothing.ClothingCategory.PierceEyebrow,
|
||||
Clothing.ClothingCategory.PierceSpecial, Clothing.ClothingCategory.Hair,
|
||||
Clothing.ClothingCategory.HairShort, Clothing.ClothingCategory.HairMedium,
|
||||
Clothing.ClothingCategory.HairLong, Clothing.ClothingCategory.HairUpdo,
|
||||
Clothing.ClothingCategory.HairSpecial,
|
||||
};
|
||||
|
||||
currentClothing.Clothing.RemoveAll( entry => !allowedCategories.Contains( entry.Clothing.Category ) );
|
||||
currentClothing.Apply( BodyRenderer );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user