private static LayeredAudio GetLayeredAudio(LocoAudioShunter locoAudio)
            {
                var engineTransform = locoAudio.transform.Find("Engine");
                var coolingFanGO    = engineTransform.Find("CoolingFan")?.gameObject;

                if (coolingFanGO == null)
                {
                    coolingFanGO = new GameObject("CoolingFan");
                    coolingFanGO.transform.parent        = engineTransform;
                    coolingFanGO.transform.localPosition = Vector3.zero;
                    coolingFanGO.transform.localRotation = Quaternion.identity;

                    var source = coolingFanGO.AddComponent <AudioSource>();
                    source.loop         = true;
                    source.clip         = FileAudio.Load("Ventilation Fan drone 2.mp3");
                    source.spatialBlend = 1f;
                    source.pitch        = 1f;

                    var layer = new LayeredAudio.Layer()
                    {
                        name          = "CoolingFan",
                        volumeCurve   = AnimationCurve.Linear(0, 0, 1, 2),
                        inertia       = 2f,
                        inertialPitch = true,
                        source        = source,
                    };

                    var layered = coolingFanGO.AddComponent <LayeredAudio>();
                    layered.layers          = new LayeredAudio.Layer[] { layer };
                    layered.linearPitchLerp = true;
                    layered.minPitch        = 0f;
                }
                return(coolingFanGO.GetComponent <LayeredAudio>());
            }
        private static void SetHorn(LocoAudioShunter audio, SoundSet soundSet)
        {
            var hornHitSource = audio.hornAudio.transform.Find("train_horn_01_hit").GetComponent <AudioSource>();

            AudioUtils.Apply(TrainCarType.LocoShunter, SoundType.HornHit, soundSet[SoundType.HornHit], hornHitSource);
            AudioUtils.Apply(TrainCarType.LocoShunter, SoundType.HornLoop, soundSet[SoundType.HornLoop], audio.hornAudio);
        }
            private static void SetupBell(LocoAudioShunter __instance)
            {
                var originalHornLoop =
                    __instance.transform.Find("Horn/Horn_Layered/train_horn_01_loop").GetComponent <AudioSource>();
                var bellSource = GameObject.Instantiate(originalHornLoop, __instance.transform.Find("Horn"));

                bellSource.name         = "ZSounds bell";
                bellSource.loop         = false;
                bellSource.volume       = 1f;
                bellSource.spatialBlend = 1f;
            }
            private static IEnumerator CoolingFanCoro(LocoAudioShunter locoAudio)
            {
                var sim     = locoAudio.GetComponentInParent <ShunterLocoSimulation>();
                var layered = GetLayeredAudio(locoAudio);

                while (true)
                {
                    yield return(null);

                    layered.Set(ShunterPower.IsFanRunning(sim) ? 1f : 0f);
                }
            }
        private static void SetEngine(LocoAudioShunter audio, SoundSet soundSet)
        {
            soundSet.sounds.TryGetValue(SoundType.EngineStartup, out var startup);
            AudioUtils.Apply(TrainCarType.LocoShunter, SoundType.EngineStartup, startup, ref audio.engineOnClip);
            soundSet.sounds.TryGetValue(SoundType.EngineShutdown, out var shutdown);
            AudioUtils.Apply(TrainCarType.LocoShunter, SoundType.EngineShutdown, shutdown, ref audio.engineOffClip);
            EngineFade.SetFadeSettings(audio, new EngineFade.Settings
            {
                fadeInStart     = startup?.fadeStart ?? 0.15f * audio.engineOnClip.length,
                fadeOutStart    = shutdown?.fadeStart ?? 0.10f * audio.engineOffClip.length,
                fadeInDuration  = startup?.fadeDuration ?? 2f,
                fadeOutDuration = shutdown?.fadeDuration ?? 1f,
            });

            AudioUtils.Apply(TrainCarType.LocoShunter, SoundType.EngineLoop, soundSet[SoundType.EngineLoop], audio.engineAudio);
            AudioUtils.Apply(TrainCarType.LocoShunter, SoundType.EngineLoadLoop, soundSet[SoundType.EngineLoadLoop], audio.enginePistonAudio);
            AudioUtils.Apply(TrainCarType.LocoShunter, SoundType.TractionMotors, soundSet[SoundType.TractionMotors], audio.electricMotorAudio);
        }
 static void Postfix(TrainCar car, LocoAudioShunter __instance)
 {
     __instance.gameObject.AddComponent <LocoAudioShunterCustom>();
 }
 public static void Postfix(LocoAudioShunter __instance)
 {
     __instance.StartCoroutine(CoolingFanCoro(__instance));
 }
 public static void Postfix(LocoAudioShunter __instance)
 {
     SetupBell(__instance);
 }
        private static void SetBell(LocoAudioShunter audio, SoundSet soundSet)
        {
            var audioSource = audio.transform.Find("Horn/ZSounds bell").GetComponent <AudioSource>();

            AudioUtils.Apply(TrainCarType.LocoShunter, SoundType.Bell, soundSet[SoundType.Bell], audioSource);
        }