OpenBve.Game.UpdateScore C# (CSharp) Method

UpdateScore() static private method

This method should be called once a frame to update the player's score
static private UpdateScore ( double TimeElapsed ) : void
TimeElapsed double The time elapsed since this function was last called
return void
		internal static void UpdateScore(double TimeElapsed) {
			// doors
			{
				bool leftopen = false;
				bool rightopen = false;
				for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++) {
					for (int k = 0; k < TrainManager.PlayerTrain.Cars[j].Specs.Doors.Length; k++) {
						if (TrainManager.PlayerTrain.Cars[j].Specs.Doors[k].State != 0.0) {
							if (TrainManager.PlayerTrain.Cars[j].Specs.Doors[k].Direction == -1) {
								leftopen = true;
							} else if (TrainManager.PlayerTrain.Cars[j].Specs.Doors[k].Direction == 1) {
								rightopen = true;
							}
						}
					}
				}
				bool bad;
				if (leftopen | rightopen) {
					bad = true;
					int j = TrainManager.PlayerTrain.Station;
					if (j >= 0) {
						int p = Game.GetStopIndex(j, TrainManager.PlayerTrain.Cars.Length);
						if (p >= 0) {
							if (Math.Abs(TrainManager.PlayerTrain.Specs.CurrentAverageSpeed) < 0.1) {
								if (leftopen == Stations[j].OpenLeftDoors & rightopen == Stations[j].OpenRightDoors) {
									bad = false;
								}
							}
						}
					}
				} else {
					bad = false;
				}
				if (bad) {
					CurrentScore.OpenedDoorsCounter += (Math.Abs(TrainManager.PlayerTrain.Specs.CurrentAverageSpeed) + 0.25) * TimeElapsed;
				} else if (CurrentScore.OpenedDoorsCounter != 0.0) {
					int x = (int)Math.Ceiling(ScoreFactorOpenedDoors * CurrentScore.OpenedDoorsCounter);
					CurrentScore.Value += x;
					if (x != 0) {
						AddScore(x, ScoreTextToken.DoorsOpened, 5.0);
					}
					CurrentScore.OpenedDoorsCounter = 0.0;
				}
			}
			// overspeed
			double nr = TrainManager.PlayerTrain.CurrentRouteLimit;
			double ns = TrainManager.PlayerTrain.CurrentSectionLimit;
			double n = nr < ns ? nr : ns;
			double a = Math.Abs(TrainManager.PlayerTrain.Specs.CurrentAverageSpeed) - 0.277777777777778;
			if (a > n) {
				CurrentScore.OverspeedCounter += (a - n) * TimeElapsed;
			} else if (CurrentScore.OverspeedCounter != 0.0) {
				int x = (int)Math.Ceiling(ScoreFactorOverspeed * CurrentScore.OverspeedCounter);
				CurrentScore.Value += x;
				if (x != 0) {
					AddScore(x, ScoreTextToken.Overspeed, 5.0);
				}
				CurrentScore.OverspeedCounter = 0.0;
			}
			// toppling
			{
				bool q = false;
				for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++) {
					if (TrainManager.PlayerTrain.Cars[j].Topples) {
						q = true;
						break;
					}
				}
				if (q) {
					CurrentScore.TopplingCounter += TimeElapsed;
				} else if (CurrentScore.TopplingCounter != 0.0) {
					int x = (int)Math.Ceiling(ScoreFactorToppling * CurrentScore.TopplingCounter);
					CurrentScore.Value += x;
					if (x != 0) {
						AddScore(x, ScoreTextToken.Toppling, 5.0);
					}
					CurrentScore.TopplingCounter = 0.0;
				}
			}
			// derailment
			if (!CurrentScore.Derailed) {
				bool q = false;
				for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++) {
					if (TrainManager.PlayerTrain.Cars[j].Derailed) {
						q = true;
						break;
					}
				}
				if (q) {
					int x = ScoreValueDerailment;
					if (CurrentScore.Value > 0) x -= CurrentScore.Value;
					CurrentScore.Value += x;
					if (x != 0) {
						AddScore(x, ScoreTextToken.Derailed, 5.0);
					}
					CurrentScore.Derailed = true;
				}
			}
			// red signal
			{
				if (TrainManager.PlayerTrain.CurrentSectionLimit == 0.0) {
					if (!CurrentScore.RedSignal) {
						int x = ScoreValueRedSignal;
						CurrentScore.Value += x;
						if (x != 0) {
							AddScore(x, ScoreTextToken.PassedRedSignal, 5.0);
						}
						CurrentScore.RedSignal = true;
					}
				} else {
					CurrentScore.RedSignal = false;
				}
			}
			// arrival
			{
				int j = TrainManager.PlayerTrain.Station;
				if (j >= 0 & j < Stations.Length) {
					if (j >= CurrentScore.ArrivalStation & TrainManager.PlayerTrain.StationState == TrainManager.TrainStopState.Boarding) {
						if (j == 0 || Stations[j - 1].StationType != StationType.ChangeEnds) {
							// arrival
							int xa = ScoreValueStationArrival;
							CurrentScore.Value += xa;
							if (xa != 0) {
								AddScore(xa, ScoreTextToken.ArrivedAtStation, 10.0);
							}
							// early/late
							int xb;
							if (Stations[j].ArrivalTime >= 0) {
								double d = SecondsSinceMidnight - Stations[j].ArrivalTime;
								if (d >= -5.0 & d <= 0.0) {
									xb = ScoreValueStationPerfectTime;
									CurrentScore.Value += xb;
									AddScore(xb, ScoreTextToken.PerfectTimeBonus, 10.0);
								} else if (d > 0.0) {
									xb = (int)Math.Ceiling(ScoreFactorStationLate * (d - 1.0));
									CurrentScore.Value += xb;
									if (xb != 0) {
										AddScore(xb, ScoreTextToken.Late, 10.0);
									}
								} else {
									xb = 0;
								}
							} else {
								xb = 0;
							}
							// position
							int xc;
							int p = Game.GetStopIndex(j, TrainManager.PlayerTrain.Cars.Length);
							if (p >= 0) {
								double d = TrainManager.PlayerTrain.StationDistanceToStopPoint;
								double r;
								if (d >= 0) {
									double t = Stations[j].Stops[p].BackwardTolerance;
									r = (Math.Sqrt(d * d + 1.0) - 1.0) / (Math.Sqrt(t * t + 1.0) - 1.0);
								} else {
									double t = Stations[j].Stops[p].ForwardTolerance;
									r = (Math.Sqrt(d * d + 1.0) - 1.0) / (Math.Sqrt(t * t + 1.0) - 1.0);
								}
								if (r < 0.01) {
									xc = ScoreValueStationPerfectStop;
									CurrentScore.Value += xc;
									AddScore(xc, ScoreTextToken.PerfectStopBonus, 10.0);
								} else {
									if (r > 1.0) r = 1.0;
									r = (r - 0.01) * 1.01010101010101;
									xc = (int)Math.Ceiling(ScoreFactorStationStop * r);
									CurrentScore.Value += xc;
									if (xc != 0) {
										AddScore(xc, ScoreTextToken.Stop, 10.0);
									}
								}
							} else {
								xc = 0;
							}
							// sum
							if (Interface.CurrentOptions.GameMode == Interface.GameMode.Arcade) {
								int xs = xa + xb + xc;
								AddScore("", 10.0);
								AddScore(xs, ScoreTextToken.Total, 10.0, false);
								AddScore(" ", 10.0);
							}
							// evaluation
							if (Interface.CurrentOptions.GameMode == Interface.GameMode.Arcade) {
								if (Stations[j].StationType == StationType.Terminal) {
									double y = (double)CurrentScore.Value / (double)CurrentScore.Maximum;
									if (y < 0.0) y = 0.0;
									if (y > 1.0) y = 1.0;
									int k = (int)Math.Floor(y * (double)Interface.RatingsCount);
									if (k >= Interface.RatingsCount) k = Interface.RatingsCount - 1;
									System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
									AddScore(Interface.GetInterfaceString("score_rating"), 20.0);
									AddScore(Interface.GetInterfaceString("rating_" + k.ToString(Culture)) + " (" + (100.0 * y).ToString("0.00", Culture) + "%)", 20.0);
								}
							}
						}
						// finalize
						CurrentScore.DepartureStation = j;
						CurrentScore.ArrivalStation = j + 1;
					}
				}
			}
			// departure
			{
				int j = TrainManager.PlayerTrain.Station;
				if (j >= 0 & j < Stations.Length & j == CurrentScore.DepartureStation) {
					bool q;
					if (Stations[j].OpenLeftDoors | Stations[j].OpenRightDoors) {
						q = TrainManager.PlayerTrain.StationState == TrainManager.TrainStopState.Completed;
					} else {
						q = TrainManager.PlayerTrain.StationState != TrainManager.TrainStopState.Pending & (TrainManager.PlayerTrain.Specs.CurrentAverageSpeed < -1.5 | TrainManager.PlayerTrain.Specs.CurrentAverageSpeed > 1.5);
					}
					if (q) {
						double r = TrainManager.PlayerTrain.StationDepartureTime - SecondsSinceMidnight;
						if (r > 0.0) {
							int x = (int)Math.Ceiling(ScoreFactorStationDeparture * r);
							CurrentScore.Value += x;
							if (x != 0) {
								AddScore(x, ScoreTextToken.PrematureDeparture, 5.0);
							}
						}
						CurrentScore.DepartureStation = -1;
					}
				}
			}
			// passengers
			if (TrainManager.PlayerTrain.Passengers.FallenOver & CurrentScore.PassengerTimer == 0.0) {
				int x = ScoreValuePassengerDiscomfort;
				CurrentScore.Value += x;
				AddScore(x, ScoreTextToken.PassengerDiscomfort, 5.0);
				CurrentScore.PassengerTimer = 5.0;
			} else {
				CurrentScore.PassengerTimer -= TimeElapsed;
				if (CurrentScore.PassengerTimer <= 0.0) {
					if (TrainManager.PlayerTrain.Passengers.FallenOver) {
						CurrentScore.PassengerTimer = 5.0;
					} else {
						CurrentScore.PassengerTimer = 0.0;
					}
				}
			}
		}

Usage Example

示例#1
0
        protected override void OnUpdateFrame(FrameEventArgs e)
        {
            TimeFactor = MainLoop.TimeFactor;
            // timer
            double RealTimeElapsed;
            double TimeElapsed;

            if (Game.SecondsSinceMidnight >= Game.StartupTime)
            {
                RealTimeElapsed = CPreciseTimer.GetElapsedTime();
                TimeElapsed     = RealTimeElapsed * (double)TimeFactor;
                if (loadComplete && !firstFrame)
                {
                    //Our current in-game time is equal to or greater than the startup time, but the first frame has not yet been processed
                    //Therefore, reset the timer to zero as time consuming texture loads may cause us to be late at the first station
                    RealTimeElapsed = 0.0;
                    TimeElapsed     = 0.0;
                    firstFrame      = true;
                }
            }
            else
            {
                RealTimeElapsed = 0.0;
                TimeElapsed     = Game.StartupTime - Game.SecondsSinceMidnight;
            }

            //We only want to update the simulation if we aren't in a menu
            if (Game.CurrentInterface == Game.InterfaceType.Normal)
            {
#if DEBUG
                //If we're in debug mode and a frame takes greater than a second to render, we can safely assume that VS has hit a breakpoint
                //Check this and the sim no longer barfs because the update time was too great
                if (RealTimeElapsed > 1)
                {
                    RealTimeElapsed = 0.0;
                    TimeElapsed     = 0.0;
                }
#endif
                TotalTimeElapsedForInfo          += TimeElapsed;
                TotalTimeElapsedForSectionUpdate += TimeElapsed;


                if (TotalTimeElapsedForSectionUpdate >= 1.0)
                {
                    if (Game.Sections.Length != 0)
                    {
                        Game.UpdateSection(Game.Sections.Length - 1);
                    }
                    TotalTimeElapsedForSectionUpdate = 0.0;
                }

                // events

                // update simulation in chunks
                {
                    const double chunkTime = 1.0 / 2.0;
                    if (TimeElapsed <= chunkTime)
                    {
                        Game.SecondsSinceMidnight += TimeElapsed;
                        TrainManager.UpdateTrains(TimeElapsed);
                    }
                    else
                    {
                        const int maxChunks = 2;
                        int       chunks    = Math.Min((int)Math.Round(TimeElapsed / chunkTime), maxChunks);
                        double    time      = TimeElapsed / (double)chunks;
                        for (int i = 0; i < chunks; i++)
                        {
                            Game.SecondsSinceMidnight += time;
                            TrainManager.UpdateTrains(time);
                        }
                    }
                }
                Game.UpdateScore(TimeElapsed);
                Game.UpdateMessages();
                Game.UpdateScoreMessages(TimeElapsed);
            }
            RenderTimeElapsed     += TimeElapsed;
            RenderRealTimeElapsed += RealTimeElapsed;
        }