sasalka/Code/Weapons/Weapon.cs
2025-06-10 02:09:21 +03:00

104 lines
2.2 KiB
C#

using System.Threading.Tasks;
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;
protected override void OnStart()
{
base.OnStart();
_sound = GameObject.GetComponent<SoundPointComponent>( 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();
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<Dedugan>();
var enemy = components.Get<Enemy>();
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;
}
protected override void OnUse()
{
Attack();
}
}