namespace SWB.Base; public partial class Weapon { public virtual void Reload() { if ( IsReloading || InBoltBack || IsShooting() ) return; var maxClipSize = BulletCocking ? Primary.ClipSize + 1 : Primary.ClipSize; if ( Primary.Ammo >= maxClipSize || Primary.ClipSize == -1 ) return; var isEmptyReload = ReloadEmptyTime > 0 && Primary.Ammo == 0; TimeSinceReload = -(isEmptyReload ? ReloadEmptyTime : ReloadTime); if ( Owner.AmmoCount( Primary.AmmoType ) <= 0 && Primary.InfiniteAmmo != InfiniteAmmoType.reserve ) return; if ( IsScoping ) OnScopeEnd(); IsReloading = true; // Anim var reloadAnim = ReloadAnim; if ( isEmptyReload && !string.IsNullOrEmpty( ReloadEmptyAnim ) ) { reloadAnim = ReloadEmptyAnim; } WorldModelRenderer?.Set( reloadAnim, true ); // Player anim HandleReloadEffects(); //Boltback if ( !isEmptyReload && Primary.Ammo == 0 && BoltBack ) { TimeSinceReload -= BoltBackTime; AsyncBoltBack( ReloadTime ); } } public virtual void OnReloadFinish() { IsReloading = false; var maxClipSize = BulletCocking && Primary.Ammo > 0 ? Primary.ClipSize + 1 : Primary.ClipSize; if ( Primary.InfiniteAmmo == InfiniteAmmoType.reserve ) { Primary.Ammo = maxClipSize; return; } var ammo = Owner.TakeAmmo( Primary.AmmoType, maxClipSize - Primary.Ammo ); if ( ammo == 0 ) return; Primary.Ammo += ammo; } public virtual void CancelShellReload() { IsReloading = false; WorldModelRenderer.Set( ReloadAnim, false ); } public virtual void OnShellReload() { ReloadTime = ShellReloadStartTime + ShellReloadInsertTime; Reload(); } public virtual void OnShellReloadFinish() { IsReloading = false; var hasInfiniteReserve = Primary.InfiniteAmmo == InfiniteAmmoType.reserve; var ammo = hasInfiniteReserve ? 1 : Owner.TakeAmmo( Primary.AmmoType, 1 ); Primary.Ammo += 1; if ( ammo != 0 && Primary.Ammo < Primary.ClipSize ) { ReloadTime = ShellReloadInsertTime; Reload(); } else { CancelShellReload(); } } async void AsyncBoltBack( float boltBackDelay ) { InBoltBack = true; // Start boltback await GameTask.DelaySeconds( boltBackDelay ); if ( !IsValid ) return; if ( !IsProxy ) WorldModelRenderer?.Set( BoltBackAnim, true ); // Eject shell await GameTask.DelaySeconds( BoltBackEjectDelay ); if ( !IsValid ) return; var scale = Primary.WMParticleScale; CreateParticle( Primary.BulletEjectParticle, "ejection_point", scale ); // Finished await GameTask.DelaySeconds( BoltBackTime - BoltBackEjectDelay ); if ( !IsValid ) return; InBoltBack = false; } [Broadcast] public virtual void HandleReloadEffects() { // Player Owner?.BodyRenderer?.Set( "b_reload", true ); } }