Here is the drift scoring calculation from insim "Drive_LFSS"
Take into considaration:
Time,
Speed,
CarTraj -> CarAngle,
TrackTraj->CarTraj,
CarAnlge->TrackTraj,
Counter Correction to keep Drifting,
Stay on track,
LostControl,
360 and more,
internal void Update(Driver car)
{
if(!isOn)
return;
packetReceive++;
double speedKhm = car.GetSpeedKmh();
double angleTotraj = car.GetShorterAngleToReachTraj();
if (!started)
{
if(speedKhm > MIN_SPEED)
{
if (angleTotraj > START_ANGLE && angleTotraj < START_MAX_ANGLE)
Start(car);
}
}
else
{
//Player is Too Slow End without Score
if (speedKhm < MIN_SPEED || isLostControl)
{
End(car);
return;
}
//This will occur when orientation change is direction
//Into a perfect drift this happen only at the complete end and not much.
double oriSpeed = car.GetOrientationSpeed();
if(clockWise != (oriSpeed>0))
{
if(Math.Abs(oriSpeed) > MIN_COUNTER_ANGLE_SPEED)
{//he apply correction
counterCorrection++;
if (Math.Abs(oriSpeed) > MAX_COUNTER_ANGLE_SPEED)
{//This should mean a lost control, since is doing "S"
End(car);
return;
}
}
}
//Record Max Angle
if (maxAngleDiff < angleTotraj)
maxAngleDiff = angleTotraj;
//Process Score
ComputeScore(car);
//Find END
if (angleTotraj < STOP_ANGLE)
{
if (score > 0 && scoreTick > (MIN_DRIFT_TIME_MS / SCORE_TICK_TIME_MS))
Sucess(car);
else
End(car);
}
}
}
private void Start(Driver driver)
{
started = true;
startTime = DateTime.Now;
clockWise = (driver.GetOrientationSpeed() > 0 ? true : false);
maxAngleDiff = 0.0d;
scoreAngle = 0.0d;
startSpeed = driver.GetSpeedKmh();
scoreSpeed = 0;
score = 0;
scoreTick = 0;
counterCorrection = 0;
packetReceive = 0;
/*if(driver.IsAdmin)
{
driver.SendUpdateButton((ushort)Button_Entry.INFO_1, "^2Drift Start "+(clockWise?"":"^7-"));
driver.SendUpdateButton((ushort)Button_Entry.INFO_2, "^7Score ^3" + score);
}*/
}
private void End(Driver driver)
{
started = false;
/*if(driver.IsAdmin)
{
driver.SendUpdateButton((ushort)Button_Entry.INFO_1, "^1Drift End");
}*/
}
private void Sucess(Driver driver)
{
if (maxAngleDiff >= BONUS_ANGLE)
score *= BONUS_ANGLE_SCORE_RATIO;
Log.feature(((IDriver)driver).DriverName + ", Done Drift Score: " + (uint)score + ".\r\n");
End(driver);
//Debug think
/*if(((Driver)driver).IsAdmin)
{
((IButton)driver).SendUpdateButton((ushort)Button_Entry.INFO_2, "^7Score ^2" + score);
}*/
((Driver)driver).driftScoreByTime += (uint)score;
if (((Driver)driver).ISession.Script.CarDriftScoring((ICar)driver, (uint)score))
return;
}
private void ComputeScore(Driver driver)
{
//Scoring calculation occur only at all SCORE_TICK_TIME_MS diff.
TimeSpan timeDiff = DateTime.Now - startTime;
if (timeDiff.TotalMilliseconds / SCORE_TICK_TIME_MS < scoreTick)
return;
//How many time we calculated the score
scoreTick++;
//Calculate correction ratio
double correctionRatio = (100.0d-(counterCorrection * 100.0d/packetReceive))/100.0d;
//Gave point for Angle
double angleToReach = driver.GetAngleToReachTraj(clockWise);
scoreAngle += (360.0d - angleToReach) * SCORE_ANGLE_RATIO;
//If player goes faster then start speed WOW, if not loose a little each time
double _scoreSpeed = ((driver.GetSpeedKmh() * 100.0d / startSpeed) - 100.0d) * SCORE_SPEED_RATIO;
if(_scoreSpeed <0.0d)
_scoreSpeed += (startSpeed / 35.0d) * (double)scoreTick;
scoreSpeed += _scoreSpeed;
//All By Correction %, Can only Lower Score
score = ((scoreAngle + scoreSpeed) * correctionRatio) - ((correctionRatio-1.0d)*40.0d);
//Only for debug purpose
/*if(((Driver)car).IsAdmin)
{
((IButton)car).SendUpdateButton((ushort)Button_Entry.INFO_2, "^7Score ^3"+score);
((IButton)car).SendUpdateButton((ushort)Button_Entry.INFO_3, "^3SA ^7" + scoreAngle);
((IButton)car).SendUpdateButton((ushort)Button_Entry.INFO_4, "^3SS ^7" + scoreSpeed);
((IButton)car).SendUpdateButton((ushort)Button_Entry.INFO_5, "^3CR ^7" + correctionRatio);
}*/
}
public bool IsOn
{
get { return isOn; }
set
{
isOn = value;
started = false;
}
}
}
Here is the LostControl thing, make a difference between a drift and a lost control , really depend on the Track Direction
double tracjectoryDiff = GetAngleDiff(trackOrientation,car.GetTrajectory());
car.SendTrajDisplay(GetTrajectoryDisplay(tracjectoryDiff));
double orientationDiff = GetAngleDiff(trackOrientation, car.GetOrientation());
car.SendOriDisplay( GetOrientationDisplay(orientationDiff) );
double perpenDist = GetPerpendicularDist(car.GetPosX(), car.GetPosY(), node.centreX, node.centreY, node.centreX + node.dirX, node.centreY + node.dirY);
car.SendPathDisplay(GetPathSideDisplay(node.driveLeft,node.driveRight, perpenDist,car));
if (car.GetSpeedMs() > 0.1 && (Math.Abs(tracjectoryDiff) > 16 && Math.Abs(orientationDiff) > 19))
lostControl = true;
else if (car.GetSpeedMs() > 0.1 && Math.Abs(orientationDiff) > 19)
drift = true;
Scoring happen at a static Tick time , me i use 150ms , so each 150ms i calculate your drift score until i detect your no more into a drift or you completely lost control.
P.S. a sucess 360 into a drift can be real good if you keep on the Track.
All this code is very old and was made before i complete Map System, so it can be a lot better.
Let say i don't have motivation or help needed to update that code , but hope gave you idea to build your own or anyone else
bye bye!