/// <summary> /// Based on FireMode enum, perform the expected behaviours. /// Assuming fireRate as Rate-Per-Minute, convert to adequate deylay between shots, given by fD = 1/(fR/60) /// </summary> /// <param name="TrackedFire">A function delegated from the weapon to be called for each "shot". This function is expected to return a bool representing if the shot was successful.</param> /// <param name="TriggerPressed">A function delegated from the weapon to return a bool representing if the weapon trigger is currently pressed</param> /// <param name="fireSelector">FireMode enum, used to determine the behaviour of the method</param> /// <param name="fireRate">Determines the delay between calls to `TrackedFire`, given as a Rounds-Per-Minunte value</param> /// <param name="burstNumber">The number of calls made to `TrackedFire`, if `fireSelector` is set to `FireMode.Burst`</param> /// <param name="emptySoundDriver">If `TrackedFire` returns a false, this AudioSource is played</param> /// <param name="WeaponIsFiring">A function delegated from the weapon to determine if the coroutine is running</param> /// <returns></returns> public static IEnumerator GeneralFire(TrackFiredDelegate TrackedFire, TriggerPressedDelegate TriggerPressed, FireMode fireSelector = FireMode.Single, int fireRate = 60, int burstNumber = 3, AudioSource emptySoundDriver = null, IsFiringDelegate WeaponIsFiring = null, IsSpawningDelegate ProjectileIsSpawning = null) { WeaponIsFiring?.Invoke(true); float fireDelay = 60.0f / (float)fireRate; if (fireSelector == FireMode.Safe) { if (emptySoundDriver != null) { emptySoundDriver.Play(); } yield return(null); } else if (fireSelector == FireMode.Single) { if (ProjectileIsSpawning != null) { do { yield return(null); }while (ProjectileIsSpawning()); } if (!TrackedFire()) { if (emptySoundDriver != null) { emptySoundDriver.Play(); } yield return(null); } yield return(new WaitForSeconds(fireDelay)); } else if (fireSelector == FireMode.Burst) { for (int i = 0; i < burstNumber; i++) { if (ProjectileIsSpawning != null) { do { yield return(null); }while (ProjectileIsSpawning()); } if (!TrackedFire()) { if (emptySoundDriver != null) { emptySoundDriver.Play(); } yield return(null); break; } yield return(new WaitForSeconds(fireDelay)); } yield return(null); } else if (fireSelector == FireMode.Auto) { // triggerPressed is handled in OnHeldAction(), so stop firing once the trigger/weapon is released while (TriggerPressed()) { if (ProjectileIsSpawning != null) { do { yield return(null); }while (ProjectileIsSpawning()); } if (!TrackedFire()) { if (emptySoundDriver != null) { emptySoundDriver.Play(); } yield return(null); break; } yield return(new WaitForSeconds(fireDelay)); } } WeaponIsFiring?.Invoke(false); yield return(null); }
public static IEnumerator AnimationLinkedFire(Animator Animator, string Animation, float flintlockDelay, int remainingAmmo, TrackFiredDelegate TrackedFire, TriggerPressedDelegate TriggerPressed, IsSpawningDelegate ProjectileIsSpawning = null, AudioSource emptySoundDriver = null, AudioSource secondaryFireSound = null, ParticleSystem secondaryMuzzleFlash = null) { if (remainingAmmo >= 1) { Animate(Animator, Animation); do { yield return(null); }while (IsAnimationPlaying(Animator, Animation)); } // wait for any previous projectiles do { yield return(null); }while (ProjectileIsSpawning()); // Fire Success if (TrackedFire()) { yield return(new WaitForSeconds(flintlockDelay)); if (secondaryFireSound != null) { secondaryFireSound.Play(); } if (secondaryMuzzleFlash != null) { secondaryMuzzleFlash.Play(); } } // Fire Failure else { if (emptySoundDriver != null) { emptySoundDriver.Play(); } yield return(null); } yield return(null); }