using SWB.Base.Attachments; namespace SWB.Base; public partial class Weapon { public virtual SkinnedModelRenderer GetEffectRenderer() { SkinnedModelRenderer effectModel = WorldModelRenderer; return effectModel; } /// /// Gets the info on where to show the muzzle effect /// public virtual Transform? GetMuzzleTransform() { var activeAttachment = GetActiveAttachmentForCategory( AttachmentCategory.Muzzle ); var effectRenderer = GetEffectRenderer(); var effectAttachment = "muzzle"; if ( activeAttachment is not null ) { effectAttachment = activeAttachment.EffectAttachmentOrBone; Transform? effectBoneTransform = null; // Custom models will not use attachments but bones instead to position effects if (activeAttachment.WorldModelRenderer is not null ) { effectBoneTransform = activeAttachment.WorldModelRenderer.SceneModel.GetBoneWorldTransform( effectAttachment ); } if ( effectBoneTransform.HasValue ) return effectBoneTransform.Value; } return effectRenderer?.GetAttachment( effectAttachment ); } /// /// Gets the correct shoot animation /// /// Info used for the current attack /// public virtual string GetShootAnimation( ShootInfo shootInfo ) { if ( IsAiming && (!string.IsNullOrEmpty( shootInfo.ShootAimedAnim )) ) { return shootInfo.ShootAimedAnim; } else if ( shootInfo.Ammo == 0 && !string.IsNullOrEmpty( shootInfo.ShootEmptyAnim ) ) { return shootInfo.ShootEmptyAnim; } return shootInfo.ShootAnim; } /// /// If there is usable ammo left /// public bool HasAmmo() { if ( Primary.InfiniteAmmo == InfiniteAmmoType.clip ) return true; if ( Primary.ClipSize == -1 ) { return Owner.AmmoCount( Primary.AmmoType ) > 0; } if ( Primary.Ammo == 0 ) return false; return true; } public ShootInfo GetShootInfo( bool isPrimary ) { return isPrimary ? Primary : Secondary; } public bool IsShooting() { if ( Secondary is null ) return GetRealRPM( Primary.RPM ) > TimeSincePrimaryShoot; return GetRealRPM( Primary.RPM ) > TimeSincePrimaryShoot || GetRealRPM( Secondary.RPM ) > TimeSinceSecondaryShoot; } public static float GetRealRPM( int rpm ) { return 60f / rpm; } public virtual float GetRealSpread( float baseSpread = -1 ) { if ( !Owner.IsValid() ) return 0; float spread = baseSpread != -1 ? baseSpread : Primary.Spread; float floatMod = 1f; // Aiming if ( IsAiming && Primary.Bullets == 1 ) floatMod /= 4; // if ( !Owner.IsOnGround ) // { // // Jumping // floatMod += 0.75f; // } // else if ( Owner.Velocity.Length > 100 ) // { // // Moving // floatMod += 0.25f; // } return spread * floatMod; } public virtual Angles GetRecoilAngles( ShootInfo shootInfo ) { var recoilX = IsAiming ? -shootInfo.Recoil * 0.4f : -shootInfo.Recoil; var recoilY = Game.Random.NextFloat( -0.2f, 0.2f ) * recoilX; var recoilAngles = new Angles( recoilX, recoilY, 0 ); return recoilAngles; } }