using System.Threading.Tasks; using Sandbox.UI; using Sasalka; namespace Sandbox.Weapons; public sealed class Weapon : AmmoUseableBase { [Property] public SkinnedModelRenderer GunRenderer { get; private set; } [Property] public GameObject MuzzleLight { get; private set; } [Property] public GameObject particlePrefab { get; set; } [Property] public GameObject bloodParticle { get; set; } private SoundPointComponent _sound; private Rigidbody _rigidbody; protected override void OnStart() { base.OnStart(); _sound = GameObject.GetComponent( true ); } public override void OnEquipped() { _rigidbody = GameObject.Components.Get(); _rigidbody.Enabled = false; GameObject.Components.Get().Enabled = false; } public void Attack() { AttackEffects(); Vector3 startPos = Scene.Camera.WorldPosition; Vector3 dir = Scene.Camera.WorldRotation.Forward; float maxDistance = 1000f; var tr = Scene.Trace .Ray( startPos, startPos + dir * maxDistance ) .IgnoreGameObjectHierarchy( Dedugan.Local.GameObject ) .WithoutTags( "weapon" ) .UseHitboxes() .Run(); if ( tr.Hit && tr.Hitbox != null ) { var components = tr.GameObject.Components; var boneIndex = tr.Hitbox.Bone.Index; // Log.Info($"{tr.GameObject.Name} attacked"); var dedugan = components.Get(); var enemy = components.Get(); if ( dedugan.IsValid() || enemy.IsValid() ) { CreateHitEffects( tr.EndPosition, tr.Normal, true ); } if ( dedugan.IsValid() ) { dedugan.ReportHit( dir, boneIndex ); } if ( enemy.IsValid() ) { enemy.ReportHit( dir, boneIndex ); Log.Info( boneIndex ); } } else if ( tr.Hitbox == null ) { CreateHitEffects( tr.EndPosition, tr.Normal ); } } [Rpc.Broadcast] private void CreateHitEffects( Vector3 position, Vector3 normal, bool blood = false ) { var rot = Rotation.LookAt( normal ); DestroyAsync( blood ? bloodParticle.Clone( position, rot ) : particlePrefab.Clone( position, rot ), 0.5f ); } async void DestroyAsync( GameObject go, float delay ) { await GameTask.DelaySeconds( delay ); go.Destroy(); } [Rpc.Broadcast] public void AttackEffects() { _sound?.StartSound(); MuzzleLight.Enabled = true; GunRenderer.Set( "Fire", true ); GameTask.DelaySeconds( 0.05f ).ContinueWith( ( _ ) => { MuzzleLight.Enabled = false; } ); } protected override void OnUse() { Attack(); } }