private static void BGMConfigRefresh()
 {
     lock (staticMutationLock) {
         if (curMusicVol > Config.MusicVolume)
         {
             curMusicVol = Config.MusicVolume;
             AudioModule.SetSoundInstanceVolume(curMusicInstanceID.Value, curMusicVol);
         }
     }
 }
        private static void BGMTick(float deltaTime)
        {
            lock (staticMutationLock) {
                if (deltaTime > 1f)
                {
                    return;
                }
                float cap = Config.MusicVolume;
                float adjustedFadePerSec = MUSIC_FADE_PER_SEC * cap;

                if (curMusicInstanceID != null && curMusicVol < cap)
                {
                    curMusicVol += adjustedFadePerSec * deltaTime;
                    if (curMusicVol > cap)
                    {
                        curMusicVol = cap;
                    }
                    AudioModule.SetSoundInstanceVolume(curMusicInstanceID.Value, curMusicVol);
                }

                if (prevMusicInstanceID != null && prevMusicVol > 0f)
                {
                    prevMusicVol -= adjustedFadePerSec * deltaTime;
                    if (prevMusicVol <= 0f)
                    {
                        prevSound.StopAllInstances();
                    }
                    else
                    {
                        AudioModule.SetSoundInstanceVolume(prevMusicInstanceID.Value, prevMusicVol);
                    }
                }

                if (curMusicVol >= cap && prevMusicVol <= 0f)
                {
                    if (crossfadeComplete != null)
                    {
                        crossfadeComplete();
                    }
                    crossfadeComplete = null;
                }
            }
        }
Beispiel #3
0
        private static void TickSound(float deltaTime)
        {
            Vector3 ballVelo       = egg.Velocity;
            float   ballSpeed      = ballVelo.Length;
            float   speedLastFrame = velocityLastFrame.Length;

            const int TICK_SOUND_EARLINESS_MS = 200;

            // Tick
            int adjustedTimeRemainingMs = timeRemainingMs - TICK_SOUND_EARLINESS_MS;
            int timeRemainingSecs       = adjustedTimeRemainingMs / 1000;

            if (timeRemainingSecs != 0 && timeRemainingSecs != (int)(adjustedTimeRemainingMs + deltaTime * 1000f) / 1000)
            {
                int instanceId = AudioModule.CreateSoundInstance(AssetLocator.TickSound);
                AudioModule.PlaySoundInstance(
                    instanceId,
                    false,
                    0.2f * Config.SoundEffectVolume,
                    adjustedTimeRemainingMs > Config.TimePitchRaiseMs ? 1f : (adjustedTimeRemainingMs > Config.TimeWarningMs ? 1.1f : 1.2f)
                    );
            }

            // Bounce
            if (velocityLastFrame != Vector3.ZERO && ballSpeed >= MIN_SPEED_FOR_DIFFERENTIAL_ANGLE_BOUNCE_SOUND && Vector3.AngleBetween(ballVelo, velocityLastFrame) >= MIN_VELO_DIFFERENTIAL_ANGLE_FOR_BOUNCE_SOUND)
            {
                if (lastBounceSoundTime - timeRemainingMs >= BOUNCE_SOUND_MIN_INTERVAL)
                {
                    int instanceId = AudioModule.CreateSoundInstance(AssetLocator.ObtuseBounceSound);
                    AudioModule.PlaySoundInstance(
                        instanceId,
                        false,
                        BOUNCE_VOLUME * Config.SoundEffectVolume,
                        RandomProvider.Next(BOUNCE_PITCH_MIN, BOUNCE_PITCH_MAX)
                        );
                    instanceId = AudioModule.CreateSoundInstance(AssetLocator.ImpactSounds[RandomProvider.Next(0, AssetLocator.ImpactSounds.Length)]);
                    AudioModule.PlaySoundInstance(
                        instanceId,
                        false,
                        IMPACT_VOLUME * Config.SoundEffectVolume,
                        RandomProvider.Next(IMPACT_PITCH_MIN, IMPACT_PITCH_MAX)
                        );
                    lastBounceSoundTime = timeRemainingMs;
                }

                float speedDiff     = Math.Abs(speedLastFrame - ballSpeed);
                int   baseBitsCount = 3;
                if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 10f)
                {
                    baseBitsCount = 13;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 8f)
                {
                    baseBitsCount = 11;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 6f)
                {
                    baseBitsCount = 7;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 4f)
                {
                    baseBitsCount = 5;
                }
                CollisionBitPool.DisseminateBits(egg.Transform.Translation, -boardDownDir.WithLength(speedDiff * 0.65f), baseBitsCount * (int)Config.PhysicsLevel);
                MaybePlayAllBounce(speedDiff);
            }
            else if (Math.Abs(ballSpeed - speedLastFrame) >= MIN_SPEED_CHANGE_FOR_BOUNCE_SOUND)               // bounce in same direction
            {
                if (lastBounceSoundTime - timeRemainingMs >= BOUNCE_SOUND_MIN_INTERVAL)
                {
                    int instanceId = AudioModule.CreateSoundInstance(AssetLocator.AcuteBounceSound);
                    AudioModule.PlaySoundInstance(
                        instanceId,
                        false,
                        BOUNCE_VOLUME * Config.SoundEffectVolume,
                        RandomProvider.Next(BOUNCE_PITCH_MIN, BOUNCE_PITCH_MAX)
                        );
                    instanceId = AudioModule.CreateSoundInstance(AssetLocator.ImpactSounds[RandomProvider.Next(0, AssetLocator.ImpactSounds.Length)]);
                    AudioModule.PlaySoundInstance(
                        instanceId,
                        false,
                        IMPACT_VOLUME * Config.SoundEffectVolume,
                        RandomProvider.Next(IMPACT_PITCH_MIN, IMPACT_PITCH_MAX)
                        );
                    lastBounceSoundTime = timeRemainingMs;
                }

                float speedDiff     = Math.Abs(speedLastFrame - ballSpeed);
                int   baseBitsCount = 2;
                if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 10f)
                {
                    baseBitsCount = 13;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 8f)
                {
                    baseBitsCount = 11;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 6f)
                {
                    baseBitsCount = 7;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 4f)
                {
                    baseBitsCount = 3;
                }
                CollisionBitPool.DisseminateBits(egg.Transform.Translation, -boardDownDir.WithLength(speedDiff * 0.65f), baseBitsCount * (int)Config.PhysicsLevel);
                MaybePlayAllBounce(speedDiff);
            }

            // Roll
            float   rollVolFraction  = (ballSpeed - GameplayConstants.EGG_SPEED_FOR_MIN_ROLL_VOL) / (GameplayConstants.EGG_SPEED_FOR_MAX_ROLL_VOL - GameplayConstants.EGG_SPEED_FOR_MIN_ROLL_VOL);
            float   rollFreqFraction = (ballSpeed - GameplayConstants.EGG_SPEED_FOR_MIN_ROLL_FREQ) / (GameplayConstants.EGG_SPEED_FOR_MAX_ROLL_FREQ - GameplayConstants.EGG_SPEED_FOR_MIN_ROLL_FREQ);
            Vector3 eggPos           = egg.Transform.Translation;
            Ray     rollTestRay      = Ray.FromStartAndEndPoint(
                eggPos,
                eggPos + boardDownDir.WithLength(GameplayConstants.EGG_COLLISION_RADIUS + ROLL_MARGIN)
                );

            EntityModule.RayTestAllLessGarbage(rollTestRay, reusableRayTestResultsList);
            bool isRolling = false;

            for (int i = 0; i < reusableRayTestResultsList.Count; ++i)
            {
                if (reusableRayTestResultsList[i].Entity != egg)
                {
                    isRolling = true;
                    break;
                }
            }
            if (isRolling)
            {
                if (unbrokenRollTime == 0)
                {
                    unbrokenRollTime = (int)(deltaTime * 1000f);
                }
                else
                {
                    unbrokenRollTime += lastRollTime - timeRemainingMs;
                }
                lastRollTime = timeRemainingMs;
            }
            else
            {
                if (unbrokenRollTime < UNBROKEN_ROLL_TIME_BEFORE_ROLL_SOUND ||
                    lastRollTime - timeRemainingMs > ROLL_RAY_FAIL_MAX_TIME_BEFORE_UNBROKEN_ROLL_RESET)
                {
                    unbrokenRollTime = 0;
                }
            }

            if (unbrokenRollTime < UNBROKEN_ROLL_TIME_BEFORE_ROLL_SOUND ||
                lastRollTime - timeRemainingMs > ROLL_RAY_FAIL_MAX_TIME_BEFORE_NO_SOUND_MS ||
                rollVolFraction <= 0f ||
                rollFreqFraction <= 0f)
            {
                AudioModule.SetSoundInstanceVolume(AssetLocator.RollSound.SoundInstanceIds.First(), 0f);
            }
            else
            {
                if (rollVolFraction > 1f)
                {
                    rollVolFraction = 1f;
                }
                if (rollFreqFraction > 1f)
                {
                    rollFreqFraction = 1f;
                }
                AudioModule.SetSoundInstanceFrequency(AssetLocator.RollSound.SoundInstanceIds.First(), ROLL_FREQ_MIN + (ROLL_FREQ_MAX - ROLL_FREQ_MIN) * rollFreqFraction);
                AudioModule.SetSoundInstanceVolume(AssetLocator.RollSound.SoundInstanceIds.First(), ROLL_VOLUME_MIN + (ROLL_VOLUME_MAX - ROLL_VOLUME_MIN) * rollVolFraction * Config.SoundEffectVolume);
            }

            // Highspeed
            if (ballSpeed >= HIGHSPEED_SOUND_MIN_SPEED)
            {
                float angleToUp   = Vector3.AngleBetween(ballVelo, -boardDownDir);
                float angleToDown = Vector3.AngleBetween(ballVelo, boardDownDir);

                if (angleToUp <= MathUtils.PI_OVER_TWO * 0.5f)
                {
                    if (highspeedUpMetadata.TimeAtLastSound - timeRemainingMs >= MIN_INTERVAL_BETWEEN_HIGHSPEED_SOUNDS_MS &&
                        highspeedUpMetadata.CollidedSinceLastSound && highspeedUpMetadata.SlowedSinceLastSound)
                    {
                        int instanceId = AudioModule.CreateSoundInstance(AssetLocator.HighSpeedUpSounds[RandomProvider.Next(0, AssetLocator.HighSpeedUpSounds.Length)]);
                        AudioModule.PlaySoundInstance(
                            instanceId,
                            false,
                            HIGHSPEED_VOLUME * Config.SoundEffectVolume,
                            RandomProvider.Next(HIGHSPEED_PITCH_MIN, HIGHSPEED_PITCH_MAX)
                            );
                        highspeedUpMetadata.CollidedSinceLastSound = highspeedUpMetadata.SlowedSinceLastSound = false;
                        highspeedUpMetadata.TimeAtLastSound        = timeRemainingMs;
                    }
                }
                else if (angleToDown <= MathUtils.PI_OVER_TWO * 0.5f)
                {
                    Ray  downRay          = Ray.FromStartAndEndPoint(eggPos, eggPos + boardDownDir.WithLength(PARALLEL_HIGHSPEED_DOWN_BUFFER));
                    bool somethingBeneath = EntityModule.RayTestAll(downRay).Any(rtc => rtc.Entity != egg);
                    if (highspeedDownMetadata.TimeAtLastSound - timeRemainingMs >= MIN_INTERVAL_BETWEEN_HIGHSPEED_SOUNDS_MS &&
                        highspeedDownMetadata.CollidedSinceLastSound && highspeedDownMetadata.SlowedSinceLastSound &&
                        !somethingBeneath)
                    {
                        int instanceId = AudioModule.CreateSoundInstance(AssetLocator.HighSpeedDownSounds[RandomProvider.Next(0, AssetLocator.HighSpeedDownSounds.Length)]);
                        AudioModule.PlaySoundInstance(
                            instanceId,
                            false,
                            HIGHSPEED_VOLUME * Config.SoundEffectVolume,
                            RandomProvider.Next(HIGHSPEED_PITCH_MIN, HIGHSPEED_PITCH_MAX)
                            );
                        highspeedDownMetadata.CollidedSinceLastSound = highspeedDownMetadata.SlowedSinceLastSound = false;
                        highspeedDownMetadata.TimeAtLastSound        = timeRemainingMs;
                    }
                }
                else if (ballSpeed >= HIGHSPEED_SOUND_MIN_SPEED + HIGHSPEED_SOUND_ADDITIONAL_SPEED_FOR_PARALLEL)
                {
                    if (highspeedParallelMetadata.TimeAtLastSound - timeRemainingMs >= MIN_INTERVAL_BETWEEN_HIGHSPEED_SOUNDS_MS &&
                        highspeedParallelMetadata.CollidedSinceLastSound && highspeedParallelMetadata.SlowedSinceLastSound)
                    {
                        int instanceId = AudioModule.CreateSoundInstance(AssetLocator.HighSpeedParallelSounds[RandomProvider.Next(0, AssetLocator.HighSpeedParallelSounds.Length)]);
                        AudioModule.PlaySoundInstance(
                            instanceId,
                            false,
                            HIGHSPEED_VOLUME * Config.SoundEffectVolume,
                            RandomProvider.Next(HIGHSPEED_PITCH_MIN, HIGHSPEED_PITCH_MAX)
                            );
                        highspeedParallelMetadata.CollidedSinceLastSound = highspeedParallelMetadata.SlowedSinceLastSound = false;
                        highspeedParallelMetadata.TimeAtLastSound        = timeRemainingMs;
                    }
                }
            }
            else
            {
                highspeedUpMetadata.SlowedSinceLastSound = highspeedDownMetadata.SlowedSinceLastSound = highspeedParallelMetadata.SlowedSinceLastSound = true;
            }

            // Countdown Timer
            if (!playingCountdownTimer && timeRemainingMs <= COUNTDOWN_TIMER_START_TIME_MS)
            {
                int instanceId = AudioModule.CreateSoundInstance(AssetLocator.CountdownLoopSound.File);
                AssetLocator.CountdownLoopSound.AddInstance(instanceId);
                AudioModule.PlaySoundInstance(instanceId, true, COUNTDOWN_VOLUME);
                playingCountdownTimer = true;
            }

            velocityLastFrame = ballVelo;
        }