/** * Copyright (C) 2009-2014 Cars and Tracks Development Project (CTDP). * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package net.ctdp.rfdynhud.gamedata; import java.util.List; class LaptimesRecorder implements ScoringInfo.ScoringInfoUpdateListener { @Override public void onSessionStarted( LiveGameData gameData, boolean isEditorMode ) {} @Override public void onCockpitEntered( LiveGameData gameData, boolean isEditorMode ) {} private static List<Laptime> addLaptime( VehicleScoringInfo vsi, int lapsCompleted, Laptime laptime ) { List<Laptime> laps = vsi.laptimes; for ( int i = laps.size(); i < lapsCompleted; i++ ) laps.add( null ); laps.add( laptime ); return ( laps ); } static void calcAvgLaptime( VehicleScoringInfo vsi ) { if ( vsi._getFastestLaptime() == null ) { vsi.oldAverageLaptime = null; vsi.averageLaptime = null; return; } float fastest = vsi._getFastestLaptime().getLapTime(); float accepted = fastest * 1.06f; float sumS1 = 0f; float sumS2 = 0f; float sumS3 = 0f; float sumL = 0f; int count = 0; for ( int i = 0; i < vsi.laptimes.size(); i++ ) { Laptime lt = vsi.laptimes.get( i ); if ( ( lt != null ) && lt.finished && !lt.isOutLap && ( lt.isInLap == Boolean.FALSE ) ) { float ltt = lt.getLapTime(); if ( ltt <= accepted ) { sumS1 += lt.getSector1(); sumS2 += lt.getSector2(); sumS3 += lt.getSector3(); sumL += ltt; count++; } } } if ( count == 0 ) { vsi.oldAverageLaptime = null; vsi.averageLaptime = null; } else { if ( vsi.averageLaptime == null ) { vsi.oldAverageLaptime = null; vsi.averageLaptime = new Laptime( vsi.getDriverId(), 0 ); vsi.averageLaptime.isInLap = false; vsi.averageLaptime.isOutLap = false; vsi.averageLaptime.finished = true; } else { if ( vsi.oldAverageLaptime == null ) { vsi.oldAverageLaptime = new Laptime( vsi.getDriverId(), vsi.averageLaptime.lap ); vsi.oldAverageLaptime.isInLap = false; vsi.oldAverageLaptime.isOutLap = false; vsi.oldAverageLaptime.finished = true; vsi.oldAverageLaptime.sector1 = vsi.averageLaptime.sector1; vsi.oldAverageLaptime.sector2 = vsi.averageLaptime.sector2; vsi.oldAverageLaptime.sector3 = vsi.averageLaptime.sector3; vsi.oldAverageLaptime.laptime = vsi.averageLaptime.laptime; } else if ( count != vsi.oldAverageLaptime.lap ) { vsi.oldAverageLaptime.lap = vsi.averageLaptime.lap; vsi.oldAverageLaptime.sector1 = vsi.averageLaptime.sector1; vsi.oldAverageLaptime.sector2 = vsi.averageLaptime.sector2; vsi.oldAverageLaptime.sector3 = vsi.averageLaptime.sector3; vsi.oldAverageLaptime.laptime = vsi.averageLaptime.laptime; } } vsi.averageLaptime.lap = count; vsi.averageLaptime.sector1 = sumS1 / count; vsi.averageLaptime.sector2 = sumS2 / count; vsi.averageLaptime.sector3 = sumS3 / count; vsi.averageLaptime.laptime = sumL / count; } } @Override public void onScoringInfoUpdated( LiveGameData gameData, boolean isEditorMode ) { final ScoringInfo scoringInfo = gameData.getScoringInfo(); int n = scoringInfo.getNumVehicles(); for ( int i = 0; i < n; i++ ) { VehicleScoringInfo vsi = scoringInfo.getVehicleScoringInfo( i ); int lapsCompleted = vsi.getLapsCompleted(); if ( vsi.isLapJustStarted() ) { Laptime laptime = new Laptime( vsi.getDriverId(), lapsCompleted + 1 ); List<Laptime> laps = addLaptime( vsi, lapsCompleted, laptime ); Laptime last = ( lapsCompleted == 0 ) ? null : laps.get( lapsCompleted - 1 ); if ( last != null ) { last.sector1 = vsi.getLastSector1(); last.sector2 = vsi.getLastSector2( false ); SessionType sessionType = scoringInfo.getSessionType(); if ( !sessionType.isRace() && ( last.isInLap == Boolean.TRUE ) ) last.sector3 = -1f; else last.sector3 = vsi.getLastSector3(); last.updateLaptimeFromSectors(); if ( last.getLapTime() < 0f ) { laps.set( lapsCompleted - 1, null ); } else { Laptime fastestLaptime = vsi._getFastestLaptime(); if ( ( fastestLaptime == null ) || ( fastestLaptime.getLapTime() < 0f ) || ( last.getLapTime() < fastestLaptime.getLapTime() ) ) { vsi.setFastestLaptime( last ); } } if ( sessionType.isRace() ) last.setType( Laptime.LapType.RACE ); else if ( sessionType.isQualifying() ) last.setType( Laptime.LapType.QUALIFY ); else if ( Laptime.isHotlap( gameData ) ) last.setType( Laptime.LapType.HOTLAP ); else last.setType( Laptime.LapType.NORMAL ); last.finished = true; if ( ( last.isInLap != Boolean.TRUE ) && !last.isOutLap && ( last.getLapTime() > 0f ) ) { DataCache.INSTANCE.addLaptime( scoringInfo, gameData.getProfileInfo().getTeamName(), last ); } } } else if ( vsi.getFinishStatus() == FinishStatus.NONE ) { Laptime laptime = vsi.laptimes.isEmpty() ? null : vsi.laptimes.get( lapsCompleted ); if ( laptime == null ) { laptime = new Laptime( vsi.getDriverId(), lapsCompleted + 1 ); addLaptime( vsi, lapsCompleted, laptime ); } switch ( vsi.getSector() ) { case 1: laptime.sector1 = vsi.getCurrentSector1(); laptime.sector2 = -1f; laptime.sector3 = -1f; break; case 2: laptime.sector1 = vsi.getLastSector1(); laptime.sector2 = vsi.getCurrentSector2( false ); laptime.sector3 = -1f; break; case 3: laptime.sector1 = vsi.getLastSector1(); laptime.sector2 = vsi.getLastSector2( false ); if ( !scoringInfo.getSessionType().isRace() && ( laptime.isInLap == Boolean.TRUE ) ) laptime.sector3 = -1f; else laptime.sector3 = scoringInfo.getSessionTime() - vsi.getLapStartTime() - laptime.sector1 - laptime.sector2; break; } laptime.updateLaptimeFromSectors(); } if ( vsi.isInPits() ) { Laptime laptime = vsi.getLaptime( lapsCompleted + 1 ); if ( laptime == null ) { laptime = new Laptime( vsi.getDriverId(), lapsCompleted + 1 ); addLaptime( vsi, lapsCompleted, laptime ); } if ( vsi.getNormalizedLapDistance() > 0.5f ) { if ( vsi.getStintStartLap() != lapsCompleted + 1 ) laptime.isInLap = true; } else { laptime.isOutLap = true; Laptime lastLap = vsi.getLaptime( lapsCompleted ); if ( lastLap != null ) { lastLap.isInLap = true; if ( !scoringInfo.getSessionType().isRace() ) { lastLap.sector3 = -1f; lastLap.updateLaptimeFromSectors(); } } } } else if ( vsi.getStintLength() > 2.0f ) { Laptime lastLap = vsi.getLaptime( lapsCompleted ); if ( ( lastLap != null ) && ( lastLap.isInLap == null ) ) { lastLap.isInLap = false; } } if ( vsi.isLapJustStarted() ) { calcAvgLaptime( vsi ); } } } @Override public void onPlayerJoined( LiveGameData gameData, VehicleScoringInfo joinedVSI, boolean rejoined ) {} @Override public void onPlayerLeft( LiveGameData gameData, Integer vsiID ) {} @Override public void onGamePauseStateChanged( LiveGameData gameData, boolean isEditorMode, boolean isPaused ) {} @Override public void onCockpitExited( LiveGameData gameData, boolean isEditorMode ) {} private LaptimesRecorder() { } static final LaptimesRecorder INSTANCE = new LaptimesRecorder(); }