using System.Threading.Tasks; namespace Sandbox.Weapons; public sealed class Weapon : Component { [Property] public SkinnedModelRenderer GunRenderer { get; private set; } [Property] public GameObject BulletOut { get; private set; } [Property] public GameObject MuzzleLight { get; private set; } [Property] public GameObject particlePrefab { get; set; } [Property] public GameObject bloodParticle { get; set; } [Property] public DecalDefinition ImpactDecal { get; set; } [Property] public SoundEvent ImpactSound { get; set; } private SoundPointComponent _sound; protected override void OnStart() { _sound = GameObject.GetComponent( true ); } 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(); Log.Info( Dedugan.Local.GameObject ); 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 ); _ = AttackEffectsAsync(); } private async Task AttackEffectsAsync() { await GameTask.DelaySeconds( 0.05f ); MuzzleLight.Enabled = false; } }