Beispiel #1
0
        override protected void triggerInternal(GameStateData previousGameState, GameStateData currentGameState)
        {
            // if we've crashed hard and are waiting for the player to say they're OK, don't process anything else in this event:
            if (waitingForDriverIsOKResponse)
            {
                if (timeWhenAskedIfDriverIsOK.Add(TimeSpan.FromSeconds(8)) < currentGameState.Now)
                {
                    timeWhenAskedIfDriverIsOK = currentGameState.Now;
                    if (driverIsOKRequestCount == 1)
                    {
                        audioPlayer.playMessageImmediately(new QueuedMessage(folderAreYouOKSecondTry, 0, type: SoundType.CRITICAL_MESSAGE, priority: 15));
                        driverIsOKRequestCount = 2;
                    }
                    else if (driverIsOKRequestCount == 2)
                    {
                        // no response after 3 requests, he's dead, jim.
                        audioPlayer.playMessageImmediately(new QueuedMessage(folderAreYouOKThirdTry, 0, type: SoundType.CRITICAL_MESSAGE, priority: 15));
                        cancelWaitingForDriverIsOK(DriverOKResponseType.NONE);
                    }
                }
                return;
            }

            if (waitingAfterPotentiallyDangerousAcceleration)
            {
                if (currentGameState.PositionAndMotionData.CarSpeed > speedAfterPotentiallyDangerousAcceleration + 5)
                {
                    Console.WriteLine("Car has accelerated, cancelling wait for crash message");
                    waitingAfterPotentiallyDangerousAcceleration       = false;
                    timeToRecheckAfterPotentiallyDangerousAcceleration = DateTime.MaxValue;
                }
                else if (timeToRecheckAfterPotentiallyDangerousAcceleration > currentGameState.Now)
                {
                    waitingAfterPotentiallyDangerousAcceleration       = false;
                    timeToRecheckAfterPotentiallyDangerousAcceleration = DateTime.MaxValue;
                    timeOfDangerousAcceleration = currentGameState.Now;
                    // special case for iRacing: no damage data so we can't hang this off 'destroyed' components
                    triggerCheckDriverIsOKForIRacingAfter = currentGameState.Now.Add(TimeSpan.FromSeconds(2));
                }
                else
                {
                    // suspend the rest of this event
                    return;
                }
            }

            // need to be careful with interval here.
            // Disable these for iRacing, which has some spikes in car speed data that trigger false positives
            if (CrewChief.gameDefinition.gameEnum != GameEnum.IRACING &&
                enableCrashMessages && !playedAreYouOKInThisSession && !currentGameState.PitData.InPitlane &&
                currentGameState.PositionAndMotionData.CarSpeed > 0.001)
            {
                if (previousGameState != null)
                {
                    double interval = (currentGameState.Now - previousGameState.Now).TotalSeconds;
                    if (interval > 0.01)
                    {
                        double calculatedAcceleration = Math.Abs(currentGameState.PositionAndMotionData.CarSpeed - previousGameState.PositionAndMotionData.CarSpeed) / interval;

                        /*Console.WriteLine("Interval = " + interval +
                         *  " Current speed = " + currentGameState.PositionAndMotionData.CarSpeed +
                         *      " previous speed = " + previousGameState.PositionAndMotionData.CarSpeed + " acceleration = " + calculatedAcceleration / 9.8f + "g");*/

                        // if we're subject to > 40G (400m/s2), this is considered dangerous. If we've stopped (or nearly stopped) immediately
                        // after the impact, assume it's a bad 'un. If we're still moving after the impact, track the speed for 3 seconds and
                        // if it doesn't increase in that time, we can assume it's a bad 'un
                        if (calculatedAcceleration > 400)
                        {
                            Console.WriteLine("Massive impact. Current speed = " + currentGameState.PositionAndMotionData.CarSpeed.ToString("0.000") +
                                              " previous speed = " + previousGameState.PositionAndMotionData.CarSpeed.ToString("0.000") + " acceleration = " + (calculatedAcceleration / 9.8f).ToString("0.0000") + "g");
                            if (currentGameState.PositionAndMotionData.CarSpeed < 3)
                            {
                                timeOfDangerousAcceleration = currentGameState.Now;
                                // special case for iRacing: no damage data so we can't hang this off 'destroyed' components
                                triggerCheckDriverIsOKForIRacingAfter = currentGameState.Now.Add(TimeSpan.FromSeconds(4));
                            }
                            else
                            {
                                // massive acceleration but we're still moving
                                timeToRecheckAfterPotentiallyDangerousAcceleration = currentGameState.Now.Add(TimeSpan.FromSeconds(3));
                                waitingAfterPotentiallyDangerousAcceleration       = true;
                                speedAfterPotentiallyDangerousAcceleration         = currentGameState.PositionAndMotionData.CarSpeed;
                            }
                        }
                    }
                }
            }

            Boolean orientationSamplesFull = orientationSamples.Count > orientationSamplesCount;

            if (orientationSamplesFull)
            {
                orientationSamples.RemoveFirst();
            }
            orientationSamples.AddLast(currentGameState.PositionAndMotionData.Orientation);

            // don't check for rolling if we've just had a dangerous acceleration as we don't want both messages to trigger
            if (enableCrashMessages && currentGameState.Now > nextOrientationCheckDue && orientationSamplesFull &&
                currentGameState.Now.Subtract(timeOfDangerousAcceleration) > TimeSpan.FromSeconds(10))
            {
                nextOrientationCheckDue = currentGameState.Now.Add(orientationCheckEvery);
                checkOrientation(currentGameState.PositionAndMotionData.CarSpeed);
            }

            if (currentGameState.CarDamageData.DamageEnabled && currentGameState.SessionData.SessionRunningTime > 10 && currentGameState.Now > nextPunctureCheck)
            {
                nextPunctureCheck = currentGameState.Now + timeToWaitForDamageToSettle;
                CornerData.Corners puncture = getPuncture(currentGameState.TyreData);
                if (puncture != lastReportedPunctureCorner)
                {
                    lastReportedPunctureCorner = puncture;
                    switch (puncture)
                    {
                    case CornerData.Corners.FRONT_LEFT:
                        audioPlayer.playMessage(new QueuedMessage(folderLeftFrontPuncture, 0, abstractEvent: this, priority: 10));
                        break;

                    case CornerData.Corners.FRONT_RIGHT:
                        audioPlayer.playMessage(new QueuedMessage(folderRightFrontPuncture, 0, abstractEvent: this, priority: 10));
                        break;

                    case CornerData.Corners.REAR_LEFT:
                        audioPlayer.playMessage(new QueuedMessage(folderLeftRearPuncture, 0, abstractEvent: this, priority: 10));
                        break;

                    case CornerData.Corners.REAR_RIGHT:
                        audioPlayer.playMessage(new QueuedMessage(folderRightRearPuncture, 0, abstractEvent: this, priority: 10));
                        break;
                    }
                }
            }
            if (currentGameState.CarDamageData.DamageEnabled)
            {
                aeroDamage   = currentGameState.CarDamageData.OverallAeroDamage;
                trannyDamage = currentGameState.CarDamageData.OverallTransmissionDamage;
                engineDamage = currentGameState.CarDamageData.OverallEngineDamage;
                if (currentGameState.CarDamageData.BrakeDamageStatus.hasValueAtLevel(DamageLevel.DESTROYED))
                {
                    maxBrakeDamage     = DamageLevel.DESTROYED;
                    componentDestroyed = Component.BRAKES;
                }
                else if (currentGameState.CarDamageData.BrakeDamageStatus.hasValueAtLevel(DamageLevel.MAJOR))
                {
                    maxBrakeDamage = DamageLevel.MAJOR;
                }
                else if (currentGameState.CarDamageData.BrakeDamageStatus.hasValueAtLevel(DamageLevel.MINOR))
                {
                    maxBrakeDamage = DamageLevel.MINOR;
                }
                else if (currentGameState.CarDamageData.BrakeDamageStatus.hasValueAtLevel(DamageLevel.TRIVIAL))
                {
                    maxBrakeDamage = DamageLevel.TRIVIAL;
                }
                else
                {
                    maxBrakeDamage = DamageLevel.NONE;
                }

                if (currentGameState.CarDamageData.SuspensionDamageStatus.hasValueAtLevel(DamageLevel.DESTROYED))
                {
                    maxSuspensionDamage = DamageLevel.DESTROYED;
                    componentDestroyed  = Component.SUSPENSION;
                }
                else if (currentGameState.CarDamageData.SuspensionDamageStatus.hasValueAtLevel(DamageLevel.MAJOR))
                {
                    maxSuspensionDamage = DamageLevel.MAJOR;
                }
                else if (currentGameState.CarDamageData.SuspensionDamageStatus.hasValueAtLevel(DamageLevel.MINOR))
                {
                    maxSuspensionDamage = DamageLevel.MINOR;
                }
                else if (currentGameState.CarDamageData.SuspensionDamageStatus.hasValueAtLevel(DamageLevel.TRIVIAL))
                {
                    maxSuspensionDamage = DamageLevel.TRIVIAL;
                }
                else
                {
                    maxSuspensionDamage = DamageLevel.NONE;
                }
                isMissingWheel = !currentGameState.PitData.InPitlane && (!currentGameState.TyreData.LeftFrontAttached || !currentGameState.TyreData.RightFrontAttached ||
                                                                         !currentGameState.TyreData.LeftRearAttached || !currentGameState.TyreData.RightRearAttached);

                if (engineDamage < getLastReportedDamageLevel(Component.ENGINE))
                {
                    resetReportedDamage(Component.ENGINE, engineDamage);
                }
                if (trannyDamage < getLastReportedDamageLevel(Component.TRANNY))
                {
                    resetReportedDamage(Component.TRANNY, trannyDamage);
                }
                if (maxSuspensionDamage < getLastReportedDamageLevel(Component.SUSPENSION))
                {
                    resetReportedDamage(Component.SUSPENSION, maxSuspensionDamage);
                }
                if (maxBrakeDamage < getLastReportedDamageLevel(Component.BRAKES))
                {
                    resetReportedDamage(Component.BRAKES, maxBrakeDamage);
                }
                if (aeroDamage < getLastReportedDamageLevel(Component.AERO))
                {
                    resetReportedDamage(Component.AERO, aeroDamage);
                }

                minDamageToReport = (DamageLevel)Math.Max((int)engineDamage, Math.Max((int)trannyDamage, Math.Max((int)maxSuspensionDamage, Math.Max((int)maxBrakeDamage, (int)aeroDamage))));

                Tuple <Component, DamageLevel> worstUnreportedDamage = getWorstUnreportedDamage();
                if (worstUnreportedDamage != null && worstUnreportedDamage.Item2 >= minDamageToReport)
                {
                    if (damageToReportNext == null || worstUnreportedDamage.Item1 != damageToReportNext.Item1 || worstUnreportedDamage.Item2 != damageToReportNext.Item2)
                    {
                        timeWhenDamageLastChanged = currentGameState.Now;
                        damageToReportNext        = worstUnreportedDamage;
                    }
                    else if (timeWhenDamageLastChanged.Add(timeToWaitForDamageToSettle) < currentGameState.Now)
                    {
                        Console.WriteLine("Reporting ...");
                        Console.WriteLine(damageToReportNext.Item1 + ", " + damageToReportNext.Item2);

                        // put *all* the damage levels in the 'reported' set, even though we haven't actually reported them.
                        // This ensure we only ever play the worst damage on the car when damage has just increased
                        // Only do this if the component damage is *less* than the one we just reported
                        if (Component.AERO == damageToReportNext.Item1 || aeroDamage < damageToReportNext.Item2)
                        {
                            addReportedDamage(Component.AERO, aeroDamage);
                        }
                        if (Component.BRAKES == damageToReportNext.Item1 || maxBrakeDamage < damageToReportNext.Item2)
                        {
                            addReportedDamage(Component.BRAKES, maxBrakeDamage);
                        }
                        if (Component.ENGINE == damageToReportNext.Item1 || engineDamage < damageToReportNext.Item2)
                        {
                            addReportedDamage(Component.ENGINE, engineDamage);
                        }
                        if (Component.SUSPENSION == damageToReportNext.Item1 || maxSuspensionDamage < damageToReportNext.Item2)
                        {
                            addReportedDamage(Component.SUSPENSION, maxSuspensionDamage);
                        }
                        if (Component.TRANNY == damageToReportNext.Item1 || trannyDamage < damageToReportNext.Item2)
                        {
                            addReportedDamage(Component.TRANNY, trannyDamage);
                        }
                        if (enableDamageMessages)
                        {
                            playDamageToReport(currentGameState.SessionData.SessionType == SessionType.Race && currentGameState.SessionData.NumCarsOverall > 2, currentGameState.Now);
                        }
                    }
                }
            }
            else if (CrewChief.gameDefinition.gameEnum == GameEnum.IRACING && currentGameState.Now > triggerCheckDriverIsOKForIRacingAfter)
            {
                triggerCheckDriverIsOKForIRacingAfter = DateTime.MaxValue;
                checkIfDriverIsOK(currentGameState.Now);
            }
        }
Beispiel #2
0
        override protected void triggerInternal(GameStateData previousGameState, GameStateData currentGameState)
        {
            if (currentGameState.CarDamageData.DamageEnabled && currentGameState.SessionData.SessionRunningTime > 10 && currentGameState.Now > nextPunctureCheck)
            {
                nextPunctureCheck = currentGameState.Now + timeToWaitForDamageToSettle;
                CornerData.Corners puncture = getPuncture(currentGameState.TyreData);
                if (puncture != lastReportedPunctureCorner)
                {
                    lastReportedPunctureCorner = puncture;
                    switch (puncture)
                    {
                    case CornerData.Corners.FRONT_LEFT:
                        audioPlayer.playMessage(new QueuedMessage(folderLeftFrontPuncture, 0, this));
                        break;

                    case CornerData.Corners.FRONT_RIGHT:
                        audioPlayer.playMessage(new QueuedMessage(folderRightFrontPuncture, 0, this));
                        break;

                    case CornerData.Corners.REAR_LEFT:
                        audioPlayer.playMessage(new QueuedMessage(folderLeftRearPuncture, 0, this));
                        break;

                    case CornerData.Corners.REAR_RIGHT:
                        audioPlayer.playMessage(new QueuedMessage(folderRightRearPuncture, 0, this));
                        break;
                    }
                }
            }
            if (currentGameState.CarDamageData.DamageEnabled)
            {
                aeroDamage   = currentGameState.CarDamageData.OverallAeroDamage;
                trannyDamage = currentGameState.CarDamageData.OverallTransmissionDamage;
                engineDamage = currentGameState.CarDamageData.OverallEngineDamage;
                if (currentGameState.CarDamageData.BrakeDamageStatus.hasValueAtLevel(DamageLevel.DESTROYED))
                {
                    maxBrakeDamage = DamageLevel.DESTROYED;
                }
                else if (currentGameState.CarDamageData.BrakeDamageStatus.hasValueAtLevel(DamageLevel.MAJOR))
                {
                    maxBrakeDamage = DamageLevel.MAJOR;
                }
                else if (currentGameState.CarDamageData.BrakeDamageStatus.hasValueAtLevel(DamageLevel.MINOR))
                {
                    maxBrakeDamage = DamageLevel.MINOR;
                }
                else if (currentGameState.CarDamageData.BrakeDamageStatus.hasValueAtLevel(DamageLevel.TRIVIAL))
                {
                    maxBrakeDamage = DamageLevel.TRIVIAL;
                }

                if (currentGameState.CarDamageData.SuspensionDamageStatus.hasValueAtLevel(DamageLevel.DESTROYED))
                {
                    maxSuspensionDamage = DamageLevel.DESTROYED;
                }
                else if (currentGameState.CarDamageData.SuspensionDamageStatus.hasValueAtLevel(DamageLevel.MAJOR))
                {
                    maxSuspensionDamage = DamageLevel.MAJOR;
                }
                else if (currentGameState.CarDamageData.SuspensionDamageStatus.hasValueAtLevel(DamageLevel.MINOR))
                {
                    maxSuspensionDamage = DamageLevel.MINOR;
                }
                else if (currentGameState.CarDamageData.SuspensionDamageStatus.hasValueAtLevel(DamageLevel.TRIVIAL))
                {
                    maxSuspensionDamage = DamageLevel.TRIVIAL;
                }
                isMissingWheel = !currentGameState.PitData.InPitlane && (!currentGameState.TyreData.LeftFrontAttached || !currentGameState.TyreData.RightFrontAttached ||
                                                                         !currentGameState.TyreData.LeftRearAttached || !currentGameState.TyreData.RightRearAttached);

                if (engineDamage < getLastReportedDamageLevel(Component.ENGINE))
                {
                    resetReportedDamage(Component.ENGINE, engineDamage);
                }
                if (trannyDamage < getLastReportedDamageLevel(Component.TRANNY))
                {
                    resetReportedDamage(Component.TRANNY, trannyDamage);
                }
                if (maxSuspensionDamage < getLastReportedDamageLevel(Component.SUSPENSION))
                {
                    resetReportedDamage(Component.SUSPENSION, maxSuspensionDamage);
                }
                if (maxBrakeDamage < getLastReportedDamageLevel(Component.BRAKES))
                {
                    resetReportedDamage(Component.BRAKES, maxBrakeDamage);
                }
                if (aeroDamage < getLastReportedDamageLevel(Component.AERO))
                {
                    resetReportedDamage(Component.AERO, aeroDamage);
                }

                minDamageToReport = (DamageLevel)Math.Max((int)engineDamage, Math.Max((int)trannyDamage, Math.Max((int)maxSuspensionDamage, Math.Max((int)maxBrakeDamage, (int)aeroDamage))));

                Tuple <Component, DamageLevel> worstUnreportedDamage = getWorstUnreportedDamage();
                if (worstUnreportedDamage != null && worstUnreportedDamage.Item2 >= minDamageToReport)
                {
                    if (damageToReportNext == null || worstUnreportedDamage.Item1 != damageToReportNext.Item1 || worstUnreportedDamage.Item2 != damageToReportNext.Item2)
                    {
                        timeWhenDamageLastChanged = currentGameState.Now;
                        damageToReportNext        = worstUnreportedDamage;
                    }
                    else if (timeWhenDamageLastChanged.Add(timeToWaitForDamageToSettle) < currentGameState.Now)
                    {
                        Console.WriteLine("reporting ...");
                        Console.WriteLine(damageToReportNext.Item1 + ", " + damageToReportNext.Item2);

                        // put *all* the damage levels in the 'reported' set, even though we haven't actually reported them.
                        // This ensure we only ever play the worst damage on the car when damage has just increased
                        // Only do this if the component damage is *less* than the one we just reported
                        if (Component.AERO == damageToReportNext.Item1 || aeroDamage < damageToReportNext.Item2)
                        {
                            addReportedDamage(Component.AERO, aeroDamage);
                        }
                        if (Component.BRAKES == damageToReportNext.Item1 || maxBrakeDamage < damageToReportNext.Item2)
                        {
                            addReportedDamage(Component.BRAKES, maxBrakeDamage);
                        }
                        if (Component.ENGINE == damageToReportNext.Item1 || engineDamage < damageToReportNext.Item2)
                        {
                            addReportedDamage(Component.ENGINE, engineDamage);
                        }
                        if (Component.SUSPENSION == damageToReportNext.Item1 || maxSuspensionDamage < damageToReportNext.Item2)
                        {
                            addReportedDamage(Component.SUSPENSION, maxSuspensionDamage);
                        }
                        if (Component.TRANNY == damageToReportNext.Item1 || trannyDamage < damageToReportNext.Item2)
                        {
                            addReportedDamage(Component.TRANNY, trannyDamage);
                        }
                        if (enableDamageMessages)
                        {
                            playDamageToReport();
                        }
                    }
                }
            }
        }