public static class MyHydrogenEngineExtensions { private static Dictionary _m_lastOutput = new Dictionary(); private static MethodInfo _markforupdate; static MyHydrogenEngineExtensions() { _markforupdate = AccessTools.DeclaredMethod(typeof(MyGasFueledPowerProducer), "MarkForUpdate"); } // When testing, this was run from MyGasFueledPowerProducer.UpdateBeforeSimulation. I'm guessing we'll want it in MyHydrogenEngine. public static void UpdateSoundState(this MyHydrogenEngine _this) { if (!MySandboxGame.IsGameReady || _this.m_soundEmitter == null || !_this.IsWorking) { return; } if (_this.m_soundEmitter.Sound != null && _this.m_soundEmitter.Sound.IsPlaying) { if (!_m_lastOutput.ContainsKey(_this)) _m_lastOutput.Add(_this, 0f); float m_lastOutput = _m_lastOutput[_this]; // This can be removed when m_lastOutput is an instance field float usePercentage = _this.SourceComp.CurrentOutput / _this.SourceComp.MaxOutput; if (true || usePercentage != m_lastOutput) { float mul = (usePercentage > m_lastOutput ? .1f : .02f); float rpm = m_lastOutput + (usePercentage - m_lastOutput) * mul; // These two lines can be merged by assigning directly to m_lastOutput _m_lastOutput[_this] = rpm; float semitones = 8f * rpm - 6f; _this.m_soundEmitter.Sound.FrequencyRatio = MyAudio.Static.SemitonesToFrequencyRatio(semitones); _this.m_soundEmitter.Sound.VolumeMultiplier = .8f + rpm; _this.MarkForUpdate(); } } } // Wrapper for private method private static void MarkForUpdate(this MyGasFueledPowerProducer _this) { _markforupdate.Invoke(_this, null); } }