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;
}
}
}
}