def WritePreset(): global Car, FixBody, FixEngine, FixSuspen, Preset, Tires, Gas PresetConfig = configparser.ConfigParser() PresetConfig.read('apps\python\BoxRadio\BoxRadio.ini') Car = PresetConfig['PRESET' + str(Preset) + '_' + ac.getCarName(0)]['car'] if Tires != 'NoChange' or Gas != 0 or FixBody != 'no' or FixEngine != 'no' or FixSuspen != 'no' or Car != ac.getCarName( 0): PresetConfig.set('PRESET' + str(Preset) + '_' + str(Car), 'car', ac.getCarName(0)) PresetConfig.set('PRESET' + str(Preset) + '_' + str(Car), 'tyre', Tires) PresetConfig.set('PRESET' + str(Preset) + '_' + str(Car), 'fuel', str(Gas)) PresetConfig.set('PRESET' + str(Preset) + '_' + str(Car), 'body', FixBody) PresetConfig.set('PRESET' + str(Preset) + '_' + str(Car), 'engine', FixEngine) PresetConfig.set('PRESET' + str(Preset) + '_' + str(Car), 'suspen', FixSuspen) with open('apps\python\BoxRadio\BoxRadio.ini', 'w') as configfile: configfile.write( ';Set "FUEL / add" to "1" to ADD the fuel to the amount already in the tank or set to "0" to fill the tank up to the amount selected on the app.' + '\n') configfile.write( ';UI Size example: Set "UI / sizemultiplier" to "1.2" in order to increase UI size in 20% (min: 1.0, max: 3.0)' + '\n' + '\n') PresetConfig.write(configfile)
def updateSharedMemory(): global sharedMem sharedmem = sharedMem.getsharedmem() sharedmem.numVehicles = ac.getCarsCount() sharedmem.focusVehicle = ac.getFocusedCar() #now we'll build the slots, so we later know every single (possible) car carIds = range(0, ac.getCarsCount(), 1) for carId in carIds: #first we'll check wether there is a car for this id; as soon it returns -1 #it's over if str(ac.getCarName(carId)) == '-1': break else: sharedmem.vehicleInfo[carId].carId = carId sharedmem.vehicleInfo[carId].driverName = ac.getDriverName(carId).encode('utf-8') sharedmem.vehicleInfo[carId].carModel = ac.getCarName(carId).encode('utf-8') sharedmem.vehicleInfo[carId].speedMS = ac.getCarState(carId, acsys.CS.SpeedMS) sharedmem.vehicleInfo[carId].bestLapMS = ac.getCarState(carId, acsys.CS.BestLap) sharedmem.vehicleInfo[carId].lapCount = ac.getCarState(carId, acsys.CS.LapCount) sharedmem.vehicleInfo[carId].currentLapInvalid = ac.getCarState(carId, acsys.CS.LapInvalidated) sharedmem.vehicleInfo[carId].currentLapTimeMS = ac.getCarState(carId, acsys.CS.LapTime) sharedmem.vehicleInfo[carId].lastLapTimeMS = ac.getCarState(carId, acsys.CS.LastLap) sharedmem.vehicleInfo[carId].worldPosition = ac.getCarState(carId, acsys.CS.WorldPosition) sharedmem.vehicleInfo[carId].isCarInPitline = ac.isCarInPitline(carId) sharedmem.vehicleInfo[carId].isCarInPit = ac.isCarInPit(carId) sharedmem.vehicleInfo[carId].carLeaderboardPosition = ac.getCarLeaderboardPosition(carId) sharedmem.vehicleInfo[carId].carRealTimeLeaderboardPosition = ac.getCarRealTimeLeaderboardPosition(carId) sharedmem.vehicleInfo[carId].spLineLength= ac.getCarState(carId, acsys.CS.NormalizedSplinePosition) sharedmem.vehicleInfo[carId].isConnected = ac.isConnected(carId)
def ReadPreset(): global Car, FixBody, FixEngine, FixSuspen, Preset, Tires, Gas PresetConfig = configparser.ConfigParser() PresetConfig.read('apps\python\BoxRadio\BoxRadio.ini') if not 'PRESET' + str(Preset) + '_' + ac.getCarName(0) in PresetConfig: WriteSection() Car = PresetConfig['PRESET' + str(Preset) + '_' + ac.getCarName(0)]['car'] if Car == ac.getCarName(0): ac.setValue( FuelSelection, int(PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['fuel'])) if PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['body'] == 'no': FixBody = 'yes' else: FixBody = 'no' if PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['engine'] == 'no': FixEngine = 'yes' else: FixEngine = 'no' if PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['suspen'] == 'no': FixSuspen = 'yes' else: FixSuspen = 'no' if PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['tyre'] == 'NoChange': NoChangeEvent('name', 0) elif PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['tyre'] == 'Option1': Option1Event('name', 0) elif PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['tyre'] == 'Option2': Option2Event('name', 0) elif PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['tyre'] == 'Option3': Option3Event('name', 0) elif PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['tyre'] == 'Option4': Option4Event('name', 0) elif PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['tyre'] == 'Option5': Option5Event('name', 0) else: ac.setValue(FuelSelection, 0) NoChangeEvent('name', 0) FixBody = 'yes' FixEngine = 'yes' FixSuspen = 'yes' BodyEvent('name', 0) EngineEvent('name', 0) SuspensionEvent('name', 0) FuelEvent(0)
def NewSection(NewPreset): PresetConfig = configparser.ConfigParser() PresetConfig.read('apps\python\BoxRadio\BoxRadio.ini') PresetConfig.add_section('PRESET' + str(NewPreset) + '_' + ac.getCarName(0)) PresetConfig.set('PRESET' + str(NewPreset) + '_' + ac.getCarName(0), 'car', ac.getCarName(0)) PresetConfig.set('PRESET' + str(NewPreset) + '_' + ac.getCarName(0), 'tyre', Tires) PresetConfig.set('PRESET' + str(NewPreset) + '_' + ac.getCarName(0), 'fuel', str(Gas)) PresetConfig.set('PRESET' + str(NewPreset) + '_' + ac.getCarName(0), 'body', FixBody) PresetConfig.set('PRESET' + str(NewPreset) + '_' + ac.getCarName(0), 'engine', FixEngine) PresetConfig.set('PRESET' + str(NewPreset) + '_' + ac.getCarName(0), 'suspen', FixSuspen) with open('apps\python\BoxRadio\BoxRadio.ini', 'w') as configfile: configfile.write( ';Set "FUEL / add" to "1" to ADD the fuel to the amount already in the tank or set to "0" to fill the tank up to the amount selected on the app.' + '\n') configfile.write( ';UI Size example: Set "UI / sizemultiplier" to "1.2" in order to increase UI size in 20% (min: 1.0, max: 3.0)' + '\n' + '\n') PresetConfig.write(configfile)
def reinitialize_app(self): self.track = Track() # Avoid a "sector change" until it actually changes. self.last_sector = sim_info.info.graphics.currentSectorIndex # Note AC_PRACTICE/AC_QUALIFY/AC_RACE transitions. self.last_session = sim_info.info.graphics.session if not hasattr(self.data, 'sectors_available'): # Yes, keep this in self.data, so we can hot reload and still know it. self.data.sectors_available = False # auto-set to True when available # Only one sector? We know what sector you are in. if self.track.sector_count == 1: self.data.sectors_available = True track = self.track.name if not hasattr(self.data, 'config'): self.data.config = config.load() if 'bar_mode' in self.data.config: self.bar_mode = self.data.config['bar_mode'] if 'bar_moves' in self.data.config: self.bar_moves = self.data.config['bar_moves'] if 'bar_smooth' in self.data.config: self.label_tracker.bar_smooth = self.data.config['bar_smooth'] if ('sectors' in self.data.config and track in self.data.config['sectors']): self.sector_lookup = self.data.config['sectors'][track] if not hasattr(self.data, 'fastest_lap'): rlap = lap_serialize.load(track, ac.getCarName(0), 'best', sector_count=self.track.sector_count) if rlap is not None: self.data.fastest_lap = rlap if not hasattr(self.data, 'fastest_splits'): self.data.fastest_splits = [] for sector_number in range(self.track.sector_count): rlap = lap_serialize.load(track, ac.getCarName(0), 'q{}'.format(sector_number + 1), sector_count=self.track.sector_count) self.data.fastest_splits.append(rlap) # May be None if not hasattr(self.data, 'session_splits'): self.data.session_splits = [None] * self.track.sector_count
def ReadPreset(): global Car, FixBody, FixEngine, FixSuspen, Preset, Tires, Gas PresetConfig = configparser.ConfigParser() PresetConfig.read('apps\python\BoxRadio\BoxRadio.ini') if not 'PRESET' + str(Preset) + '_' + ac.getCarName(0) in PresetConfig: WriteSection() Car = PresetConfig['PRESET' + str(Preset) + '_' + ac.getCarName(0)]['car'] if Car == ac.getCarName(0): ac.setValue(FuelSelection, int(PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['fuel'])) if PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['body'] == 'no': FixBody = 'yes' else: FixBody = 'no' if PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['engine'] == 'no': FixEngine = 'yes' else: FixEngine = 'no' if PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['suspen'] == 'no': FixSuspen = 'yes' else: FixSuspen = 'no' if PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['tyre'] == 'NoChange': NoChangeEvent('name', 0) elif PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['tyre'] == 'Option1': Option1Event('name', 0) elif PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['tyre'] == 'Option2': Option2Event('name', 0) elif PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['tyre'] == 'Option3': Option3Event('name', 0) elif PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['tyre'] == 'Option4': Option4Event('name', 0) elif PresetConfig['PRESET' + str(Preset) + '_' + str(Car)]['tyre'] == 'Option5': Option5Event('name', 0) else: ac.setValue(FuelSelection, 0) NoChangeEvent('name', 0) FixBody = 'yes' FixEngine = 'yes' FixSuspen = 'yes' BodyEvent('name', 0) EngineEvent('name', 0) SuspensionEvent('name', 0) FuelEvent(0)
def __init__(self, app, x, y): self.AverageFuelPerLap = 0.0 self.FuelLastLap = 0.0 self.completedLaps = 0.0 self.fuelAtLapStart = 0.0 self.distanceTraveledAtStart = 0.0 self.fuelAtStart = 0.0 self.lastFuelMeasurement = 0.0 self.lastDistanceTraveled = 0.0 self.counter = 0 self.updatecounter = 0 self.inifilepath = inidir + self.getValidFileName(ac.getCarName(0)) +"_" + self.getValidFileName(ac.getTrackName(0)) + self.getValidFileName(ac.getTrackConfiguration(0)) + ".ini" ##initialize labels self.remainingLabel = ac.addLabel(app, "remainingLabel") self.averageFuelPerLapLabel = ac.addLabel(app, "averageFuelPerLapLabel") self.lapsLeftLabel = ac.addLabel(app, "lapsLeftLabel") self.averageFuelPer100kmLabel = ac.addLabel(app, "averageFuelPer100km") self.instFuelLabel = ac.addLabel(app, "instFuel") ##set label positions ac.setPosition(self.remainingLabel, x, y) ac.setPosition(self.averageFuelPerLapLabel, x + 208, y) ac.setPosition(self.lapsLeftLabel, 150 - x, y) ac.setPosition(self.averageFuelPer100kmLabel, x + 208, y + 19) ac.setPosition(self.instFuelLabel, 150 - x, y + 19) ##set label alignments ac.setFontAlignment(self.remainingLabel, "left") ac.setFontAlignment(self.averageFuelPerLapLabel, "left") ac.setFontAlignment(self.lapsLeftLabel, "right") ac.setFontAlignment(self.averageFuelPer100kmLabel, "left") ac.setFontAlignment(self.instFuelLabel, "right") ##set font size ac.setFontSize(self.remainingLabel, 32) ac.setFontSize(self.averageFuelPerLapLabel, 16) ac.setFontSize(self.lapsLeftLabel, 16) ac.setFontSize(self.averageFuelPer100kmLabel, 16) ac.setFontSize(self.instFuelLabel, 16) if os.path.exists(self.inifilepath): f = open(self.inifilepath, "r") self.AverageFuelPerLap = float(f.readline()[6:]) f.close() ac.setText(self.remainingLabel, "--- l") ac.setText(self.averageFuelPerLapLabel, "--- l/lap") ac.setText(self.lapsLeftLabel, "--- laps") if milesPerGallon: ac.setText(self.averageFuelPer100kmLabel, "--- mpg") else: ac.setText(self.averageFuelPer100kmLabel, "--- l/100km") ac.setText(self.instFuelLabel, "--- inst.")
def acMain(ac_version): """Main function that is invoked by Assetto Corsa.""" global NOTIFICATION, LAPTIME_LABELS app = ac.newApp("AC-Ranking") ac.setSize(app, 400, 300) NOTIFICATION = ac.addLabel(app, '') ac.setPosition(NOTIFICATION, 15, 20) ac.setSize(NOTIFICATION, 190, 20) auth = read_auth() validate_token(auth['user'], auth['token']) validate_token_button = ac.addButton(app, 'Validate token') ac.setPosition(validate_token_button, 20, 40) ac.setSize(validate_token_button, 120, 20) ac.addOnClickedListener(validate_token_button, validate_token_button_func) refresh_button = ac.addButton(app, '\u21BB') ac.setPosition(refresh_button, 300, 5) ac.setSize(refresh_button, 15, 18) ac.addOnClickedListener(refresh_button, refresh_button_func) LAPTIME_LABELS = tuple(ac.addLabel(app, '#' + str(i)) for i in range(10)) for index, label in enumerate(LAPTIME_LABELS): ac.setSize(label, 120, 20) ac.setPosition(label, 200, (index * 20) + 50) get_laptimes(ac.getCarName(0), ac.getTrackName(0), ac.getTrackConfiguration(0) or None) return "ACR"
def acMain(ac_version): global TYREINFO, optimal_spinner_id, optimal_spinner_shown appWindow = ac.newApp("Tyre Temperatures") ac.drawBackground(appWindow, background) ac.drawBorder(appWindow, background) ac.setBackgroundOpacity(appWindow, background) ac.setSize(appWindow, x_app_size, y_app_size) TYREINFO = Tyre_Info(appWindow, x_start, y_start) ac.addRenderCallback(appWindow, onFormRender) TYREINFO.optimal_temp = d_optimal_temp TYREINFO.carinifilepath = inidir + getValidFileName(ac.getCarName(0)) + ".ini" TYREINFO.needwriteini = 1 if os.path.exists(TYREINFO.carinifilepath): f = open(TYREINFO.carinifilepath, "r") TYREINFO.optimal_temp = int(f.readline()[8:]) f.close() TYREINFO.needwriteini = 0 optimal_spinner_id = ac.addSpinner(appWindow, "optimal") ac.setPosition(optimal_spinner_id, 0, y_app_size + 28) ac.setStep(optimal_spinner_id, 1) if inFahrenheit: ac.setRange(optimal_spinner_id, int(CelsiusToFahrenheit(50)), int(CelsiusToFahrenheit(150))) ac.setValue(optimal_spinner_id, int(CelsiusToFahrenheit(TYREINFO.optimal_temp))) else: ac.setRange(optimal_spinner_id, 50, 150) ac.setValue(optimal_spinner_id, TYREINFO.optimal_temp) ac.addOnValueChangeListener(optimal_spinner_id, onValueChanged) optimal_spinner_shown = 1 ac.log("Danny Giusa Tyre Temperatures loaded") return "Danny Giusa Tyre Temperatures"
def loadCarData(): global CarData carName = ac.getCarName(0) try: carsFile = os.path.join(os.path.dirname(__file__), "cardata.json") with open(carsFile, "r") as f: jsonData = json.load(f) except OSError: ac.log("Reventach ERROR: loadCarData cardata.json not found") else: try: CarData["totalGears"] = jsonData[carName]["gears"] CarData["maxRPM"] = jsonData[carName]["maxRPM"] ac.console("Car data found for " + carName) except KeyError: # Doesn't exist in official, look for custom data try: carsFile = os.path.join(os.path.dirname(__file__), "cardata-custom.json") with open(carsFile, "r") as f: jsonData = json.load(f) CarData["totalGears"] = jsonData[carName]["gears"] CarData["maxRPM"] = jsonData[carName]["maxRPM"] except (OSError, KeyError) as e: ac.log( "Reventach ERROR: loadCarData: No custom car data found for this car" ) else: ac.console("Custom car data found for " + carName)
def marshall(self): """Simple comma seperated transmission, client will need to be aware of positions of various data items Add any new data items to the end so existing apps are not affected """ try: data = ["x02"] #start token data.extend(ac.getCarState(0, acsys.CS.CurrentTyresCoreTemp)) #0-3 - Core tyre temperatures, Degrees celcius data.extend(info.physics.tyreWear) #4-7 #tyre wear data.extend(ac.getCarState(0, acsys.CS.DynamicPressure)) #8-11 pressure of each tyre in PSI data.extend(ac.getCarState(0, acsys.CS.TyreDirtyLevel)) #12-15 amount of dirt on each tyre data.append(ac.getCarState(0, acsys.CS.SpeedMS)) #16 speed in metres/sec data.append(ac.getCarState(0, acsys.CS.Gear)) #17 gear number data.append(ac.getCarState(0, acsys.CS.BestLap)) #18 best lap time in ms data.append(ac.getCarState(0, acsys.CS.RPM)) #19 rpm data.append(ac.getCarState(0, acsys.CS.LapCount)) #20 lap count data.append(ac.getCarState(0, acsys.CS.LapInvalidated)) #21 is lap invalid? 0-no, 1-yes data.append(ac.getCarState(0, acsys.CS.LapTime)) #22 current lap time in ms data.append(ac.getCarState(0, acsys.CS.LastLap)) #23 last lap in ms data.append(ac.getCarState(0, acsys.CS.PerformanceMeter)) #24 delta time in ms from best lap?? (haven't checked) data.append(ac.getCarState(0, acsys.CS.Steer)) #25 steering rotation in radians data.append(ac.getCarName(0)) #26 name of car being driven by player data.append(ac.getTrackName(0)) #27 track name data.append("x04") #end token except Exception as e: ac.console("{}".format(e)) return ",".join(str(v) for v in data).encode()
def acMain(ac_version): global DRIVER, TRACK, CAR, WINDOW, LAP_LABELS, LAP_VALID_INDICATOR DRIVER = ac.getDriverName(DRIVER_ID_SELF) TRACK = '%s-%s' % (ac.getTrackName(DRIVER_ID_SELF), ac.getTrackConfiguration(DRIVER_ID_SELF)) CAR = ac.getCarName(DRIVER_ID_SELF) ac.console('Initialize %s: driver %s on %s in %s' % (NAME, DRIVER, TRACK, CAR)) WINDOW = ac.newApp(NAME) ac.setSize(WINDOW, *SIZE) ac.setTitle(NAME) if ac.addOnAppActivatedListener(WINDOW, onActivate) == -1: ac.console('Failed to add listener activate') if ac.addOnAppDismissedListener(WINDOW, onDeactivate) == -1: ac.console('Failed to add listener deactivate') i = 0 while i < LAP_COUNT: label = ac.addLabel(WINDOW, 'Waiting for lap time...') LAP_LABELS.append(label) i += 1 LAP_VALID_INDICATOR = ac.addLabel(WINDOW, 'Clean') refreshLapDisplay() return NAME
def updateSharedMemory(): global sharedMem sharedmem = sharedMem.getsharedmem() sharedmem.numVehicles = ac.getCarsCount() sharedmem.focusVehicle = ac.getFocusedCar() #now we'll build the slots, so we later know every single (possible) car carIds = range(0, ac.getCarsCount(), 1) for carId in carIds: #first we'll check wether there is a car for this id; as soon it returns -1 #it's over if str(ac.getCarName(carId)) == '-1': break else: sharedmem.vehicleInfo[carId].carId = carId sharedmem.vehicleInfo[carId].driverName = ac.getDriverName( carId).encode('utf-8') sharedmem.vehicleInfo[carId].carModel = ac.getCarName( carId).encode('utf-8') sharedmem.vehicleInfo[carId].speedMS = ac.getCarState( carId, acsys.CS.SpeedMS) sharedmem.vehicleInfo[carId].bestLapMS = ac.getCarState( carId, acsys.CS.BestLap) sharedmem.vehicleInfo[carId].lapCount = ac.getCarState( carId, acsys.CS.LapCount) sharedmem.vehicleInfo[carId].currentLapInvalid = ac.getCarState( carId, acsys.CS.LapInvalidated) sharedmem.vehicleInfo[carId].currentLapTimeMS = ac.getCarState( carId, acsys.CS.LapTime) sharedmem.vehicleInfo[carId].lastLapTimeMS = ac.getCarState( carId, acsys.CS.LastLap) sharedmem.vehicleInfo[carId].worldPosition = ac.getCarState( carId, acsys.CS.WorldPosition) sharedmem.vehicleInfo[carId].isCarInPitline = ac.isCarInPitline( carId) sharedmem.vehicleInfo[carId].isCarInPit = ac.isCarInPit(carId) sharedmem.vehicleInfo[ carId].carLeaderboardPosition = ac.getCarLeaderboardPosition( carId) sharedmem.vehicleInfo[ carId].carRealTimeLeaderboardPosition = ac.getCarRealTimeLeaderboardPosition( carId) sharedmem.vehicleInfo[carId].spLineLength = ac.getCarState( carId, acsys.CS.NormalizedSplinePosition) sharedmem.vehicleInfo[carId].isConnected = ac.isConnected(carId) sharedmem.vehicleInfo[carId].finishStatus = ac.getCarState( carId, acsys.CS.RaceFinished)
def setup_replay_file(drivers, nLaps): filename = "replay_%s_%s.txt" % (ac.getCarName(0), ac.getTrackName(0)) replay_file = open(FC.REPLAY_DIR + filename, "w") data = "START %d %d " % (len(drivers), nLaps) for d in drivers: data += "%d;%s " % (d.starting_position, d.tyre) replay_file.write(data+'\n') return replay_file
def acMain(ac_version): try: global multiLapsApp, configApp, config global showHeader, fontSize, opacity, showBorder global lapDisplayedCount, showDelta, deltaColor, redAt, greenAt global reference, showCurrent, showReference, showTotal global updateTime, logLaps, logBest, lockBest global trackName, trackConf, carName, bestLapFile global nurbTourist if ac_version < 1.0: return "MultiLaps" config = configparser.ConfigParser() config.read("apps/python/MultiLaps/MultiLaps_config/config.ini") showHeader = config.getint("SETTINGS", "showHeader") fontSize = config.getint("SETTINGS", "fontSize") opacity = config.getint("SETTINGS", "opacity") showBorder = config.getint("SETTINGS", "showBorder") lapDisplayedCount = config.getint("SETTINGS", "lapDisplayedCount") showDelta = config.getint("SETTINGS", "showDelta") deltaColor = config.get("SETTINGS", "deltaColor") redAt = config.getint("SETTINGS", "redAt") greenAt = config.getint("SETTINGS", "greenAt") reference = config.get("SETTINGS", "reference") showCurrent = config.getint("SETTINGS", "showCurrent") showTotal = config.getint("SETTINGS", "showTotal") showReference = config.getint("SETTINGS", "showReference") updateTime = config.getint("SETTINGS", "updateTime") logLaps = config.getint("SETTINGS", "logLaps") logBest = config.get("SETTINGS", "logBest") lockBest = config.getint("SETTINGS", "lockBest") trackName = ac.getTrackName(0) trackConf = ac.getTrackConfiguration(0) carName = ac.getCarName(0) if trackConf == "": bestLapFile = "apps/python/MultiLaps/MultiLaps_bestlap/{0} - {1}.ini".format( trackName, carName) else: bestLapFile = "apps/python/MultiLaps/MultiLaps_bestlap/{0} [{1}] - {2}.ini".format( trackName, trackConf, carName) if trackName == "ks_nordschleife" and trackConf == "touristenfahrten": nurbTourist = True multiLapsApp = MultiLaps("MultiLaps", "Laps") multiLapsApp.refreshParameters() ac.addRenderCallback(multiLapsApp.window, onRenderCallback) configApp = MultiLaps_config("MultiLaps_config", "MultiLaps config", fontSizeConfig, 0) configApp.updateView() return "MultiLaps" except Exception as e: ac.log("MultiLaps: Error in acMain: %s" % e)
def onStartup(self, ac_version): self.steam_id = steamID() self.ac_version = ac_version driver = ac.getDriverName(0) car = ac.getCarName(0) track = ac.getTrackName(0) track_config = ac.getTrackConfiguration(0) self.session = Session(ac_version, driver, car, track, track_config) self.latestPos = getCoords() self.latestUpdate = datetime.datetime.now()
def get_delta_file_path(self): track_file_path = Config.get_user_documents_path( ) + "plugins/actv_deltas/default" if not os.path.exists(track_file_path): os.makedirs(track_file_path) track_file_path += "/" + ac.getTrackName(0) if ac.getTrackConfiguration(0) != "": track_file_path += "_" + ac.getTrackConfiguration(0) track_file_path += "_" + ac.getCarName(0) + ".delta" return track_file_path
def get_delta_file_path(self): track_file_path = os.path.join(os.path.expanduser("~"), "Documents", "Assetto Corsa", "plugins", "actv_deltas", "default") if not os.path.exists(track_file_path): os.makedirs(track_file_path) track_file_path += "/" + ac.getTrackName(0) if ac.getTrackConfiguration(0) != "": track_file_path += "_" + ac.getTrackConfiguration(0) track_file_path += "_" + ac.getCarName(0) + ".delta" return track_file_path
def getDeltaFilePath(self): trackFilePath = os.path.join( os.path.expanduser("~"), "Documents", "Assetto Corsa", "plugins", "actv_deltas", "default" ) if not os.path.exists(trackFilePath): os.makedirs(trackFilePath) trackFilePath += "/" + ac.getTrackName(0) if ac.getTrackConfiguration(0) != "": trackFilePath += "_" + ac.getTrackConfiguration(0) trackFilePath += "_" + ac.getCarName(0) + ".delta" return trackFilePath
def startTelemetry(): global logPrefix, telemetrySession telemetrySession = TelemetrySession() trackName = ac.getTrackName(0) trackConfig = ac.getTrackConfiguration(0) trackLength = ac.getTrackLength(0) carName = ac.getCarName(0) telemetrySession.start(carName=carName, trackName=trackName, trackConfig=trackConfig, trackLength=trackLength)
def init(): """Add the info window/app.""" global info_telemetry window_info = ac.newApp("Info") ac.setSize(window_info, 160, 205) ac.addRenderCallback(window_info, render_app) info_telemetry = TelemetryProvider() compound_label = CompoundLabel(info_telemetry) optimum_temps_label = OptimumTempsLabel(info_telemetry) abs_label = ABSLabel(info_telemetry) tc_label = TractionControlLabel(info_telemetry) lateral_force_label = LateralForceLabel(info_telemetry) transverse_force_label = TransverseForceLabel(info_telemetry) drs_image_label = DRSImageLabel(info_telemetry) abs_image_label = ABSImageLabel(info_telemetry) tc_image_label = TCImageLabel(info_telemetry) background_label = BackgroundLabel() for label in (compound_label, optimum_temps_label, abs_label, tc_label, lateral_force_label, transverse_force_label, drs_image_label, abs_image_label, tc_image_label, background_label): label.window = window_info # Prepei na mpei teleytaio gia na fortwnei meta to prasino eikonidio gia na # kratietai to diafano... car_name = ac.getCarName(0) car_upgrade = '' if car_name.endswith(('_s1', '_s2', '_s3', '_drift', '_dtm')): car_upgrade = car_name.split('_')[-1] car_upgrade_img_path = os.path.join( APP_DIR, "Images/Info{}.png".format(car_upgrade or 'STD')) background_label.bg_texture = car_upgrade_img_path image_arrow_left = LeftLateralForceImage( info_telemetry, pos_x=131, pos_y=147, width=20, height=20, color=(1, 1, 0, 1), filename='arrowLeft.png') image_arrow_right = RightLateralForceImage( info_telemetry, pos_x=132, pos_y=147, width=20, height=20, color=(1, 1, 0, 1), filename='arrowRight.png') image_arrow_up = PositiveTransverseForceImage( info_telemetry, pos_x=104, pos_y=119, width=20, height=20, color=(1, 1, 0, 1), filename='arrowUp.png') image_arrow_down = NegativeTransverseForceImage( info_telemetry, pos_x=104, pos_y=120, width=20, height=20, color=(1, 1, 0, 1), filename='arrowDown.png')
def prepare(self): self.track = ac.getTrackName(0) #now we'll build the slots, so we later know every single (possible) car carIds = range(0, ac.getCarsCount(), 1) for carId in carIds: #first we'll check wether there is a car for this id; as soon it returns -1 #it's over carModel = str(ac.getCarName(carId)) if carModel == '-1': break else: maxSlotId = carId driverName = ac.getDriverName(carId) self.cars.append(helipicapewcar.HeliPicaPewCar(carId, driverName, carModel))
def getLeaderCarId(): global raceTotalSessionTime, raceCrossedStartLine if raceTotalSessionTime != -1 and raceCrossedStartLine: numberOfCars = ac.getCarsCount() carIds = range(0, ac.getCarsCount(), 1) for carId in carIds: if str(ac.getCarName(carId)) == '-1': break else: carPosition = ac.getCarRealTimeLeaderboardPosition(carId) if carPosition == 0: return carId return -1
def load_replay_file(drivers): '''Load replay data into a dictionary that follows the following structure {'LAP_NUMBER': [[TIME [UPDATE DATA]], [TIME [UPDATE DATA]], ... ] 'FL' : {'LAP_NUMBER' : [[TIME, DRIVER_ID, FASTEST_LAP], [TIME, DRIVER_ID, FASTEST_LAP]...] } } ''' try: filename = "replay_%s_%s.txt" % (ac.getCarName(0), ac.getTrackName(0)) with open(FC.REPLAY_DIR + filename, "r") as rf: data = {} line = next(rf).split() if line[0] != "START": ac.log("Replay file doesnt start with 'START' tag.") return totalDrivers = int(line[1]) data['totalDrivers'] = totalDrivers data['nLaps'] = int(line[2]) for i in range(3, 3+totalDrivers): line[i] = line[i].split(';') drivers[i-3].starting_position = int(line[i][0]) drivers[i-3].tyre = line[i][1] for line in rf: line = line.split() if line[0] == "U": # normal update update = [float(line[2])] for i in range(3, 3+totalDrivers): line[i] = line[i].split(';') update.append([int(line[i][0]), float(line[i][1]), line[i][2], int(line[i][3]), bool(int(line[i][4])), int(line[i][5])]) if int(line[1]) not in data: data[int(line[1])] = [] data[int(line[1])].append(update) elif line[0] == "FL": laps, time = line[1].split(';') id, fastest_lap = line[2].split(';') if 'FL' not in data: data['FL'] = {} if int(laps) not in data['FL']: data['FL'][int(laps)] = [] data['FL'][int(laps)].append([float(time), int(id), float(fastest_lap)]) else: ac.log("Replay file has wrong tag '%s'." % line[0]) return return data except FileNotFoundError: ac.log("Replay File not found.")
def loadTireData(): global Options try: tyresFile = os.path.join(os.path.dirname(__file__), "tyres-data.json") with open(tyresFile, "r") as f: tyreData = json.load(f) except OSError: ac.log("CamberExtravaganza ERROR: loadTireData tyres-data.json not found") else: try: carName = ac.getCarName(0) tyreCompound = ac.getCarTyreCompound(0) Options["tireRadius"] = tyreData[carName][tyreCompound]["radius"] dcamber0 = tyreData[carName][tyreCompound]["dcamber0"] dcamber1 = tyreData[carName][tyreCompound]["dcamber1"] Options["targetCamber"] = math.degrees(dcamber0 / (2 * dcamber1)) Options["dcamber0"] = dcamber0 Options["dcamber1"] = dcamber1 Options["LS_EXPY"] = tyreData[carName][tyreCompound]["ls_expy"] ac.console("Tyre data found for " + carName + " " + tyreCompound) except KeyError: # Doesn't exist in official, look for custom data try: tyresFile = os.path.join(os.path.dirname(__file__), "tyres-data-custom.json") with open(tyresFile, "r") as f: tyreData = json.load(f) Options["tireRadius"] = tyreData[carName][tyreCompound]["radius"] dcamber0 = tyreData[carName][tyreCompound]["dcamber0"] dcamber1 = tyreData[carName][tyreCompound]["dcamber1"] Options["targetCamber"] = math.degrees(dcamber0 / (2 * dcamber1)) Options["dcamber0"] = dcamber0 Options["dcamber1"] = dcamber1 Options["LS_EXPY"] = tyreData[carName][tyreCompound]["ls_expy"] except (OSError, KeyError) as e: Options["tireRadius"] = 1 Options["targetCamber"] = 999 Options["dcamber0"] = 999 Options["dcamber1"] = -999 Options["LS_EXPY"] = 1 ac.log("CamberExtravaganza ERROR: loadTireData: No custom tyre data found for this car") else: ac.console("Custom tyre data found for " + carName + " " + tyreCompound)
def SendCurrentScore(): global highscore, storeDriftScore if highscore < storeDriftScore: highscore = storeDriftScore data = { "name": ac.getDriverName(0), "track": ac.getTrackName(0) + "-" + ac.getTrackConfiguration(0), "mode": "drift", "score": str(storeDriftScore), "car": ac.getCarName(0) } t = threading.Thread(target=SendScore, args=(data, )) #t.daemon = True t.start() resetDriftScoring() #ac.console("current score sent: "+str(storeDriftScore)) return
def startLogging(self): if self.outputFile != None: return ac.console('Start') tmpFile = open('D:\logger_' + datetime.now().strftime('%Y%m%d_%H%M') + '.log', mode = 'w') tmpFile.write('Course : {}\n'.format(ac.getTrackName(self.carId))) tmpFile.write('Layout : {}\n'.format(ac.getTrackConfiguration(self.carId))) tmpFile.write('Car Id : {}\n'.format(self.carId)) tmpFile.write('Driver : {}\n'.format(ac.getDriverName(self.carId))) tmpFile.write('Driver : {}\n'.format(ac.getCarName(self.carId))) tmpFile.write('\n') tmpFile.write('\t'.join(['lapCount', 'lapTime', 'distance', 'speed', 'throttle', \ 'brake', 'gear', 'RPM', 'steer', 'x', 'y', 'z\n'])) self.outputFile = tmpFile
def loadTireData(): global Options tyreDataPath = os.path.join(os.path.dirname(__file__), "tyres_data") tyreData = {} for td in os.listdir(tyreDataPath): if td.endswith('.json'): with open(os.path.join(tyreDataPath, td), 'r') as f: try: newData = json.load(f) except ValueError as e: ac.log("CamberExtravaganza ERROR: Invalid JSON: " + td) else: tyreData.update(newData) carName = ac.getCarName(0) tyreCompound = ac.getCarTyreCompound(0) parseTyreData(carName, tyreCompound, tyreData)
def SendLapScore(): global lastLapCumulativeScore, cumulativescore, driftScoreAtStartLine currentDrift = round(ac.getCarState(0, acsys.CS.InstantDrift)) lapscore = cumulativescore - lastLapCumulativeScore + currentDrift - driftScoreAtStartLine # + currentDrift - driftScoreAtStartLine driftScoreAtStartLine = currentDrift lastLapCumulativeScore = cumulativescore data = { "name": ac.getDriverName(0), "track": ac.getTrackName(0) + "-" + ac.getTrackConfiguration(0), "mode": "OneLapDrifting", "car": ac.getCarName(0), "score": str(lapscore), "laptime": str(ac.getCarState(0, acsys.CS.LastLap)) } t = threading.Thread(target=SendScore, args=(data, )) t.start() #SendScore(data); return
def acMain(ac_version): """Main function that is invoked by Assetto Corsa.""" global app_window app_window = ac.newApp("") ac.setSize(app_window, 343, 78) ac.drawBorder(app_window, 0) app_dir = os.path.dirname(os.path.realpath(__file__)) ac.setBackgroundTexture(app_window, app_dir + "/Images/Dashboard.png") ac.addRenderCallback(app_window, render_app) CAR.name = ac.getCarName(0) dashboard_elements.init(MAIN_APP_TELEMETRY, app_window, CAR.name) tyre_apps.init(MAIN_APP_TELEMETRY) info_app.init() threading.Thread(target=read_static_shared_memory).start() return "AC Dashboard"
def SendSessionData(): #send cumulatice score global cumulativescore, server_connection_ok, sessionDataSent if sessionDataSent > 0: return sessionDataSent = sessionDataSent + 1 if server_connection_ok == 0: return session = info.graphics.session session_string = "other" laps = ac.getCarState(0, acsys.CS.LapCount) if laps < 1: laps = 1 if session == 0: session_string = "practise" if session == 1: session_string = "qualify" if session == 2: session_string = "race" data = { "name": ac.getDriverName(0), "track": ac.getTrackName(0) + "-" + ac.getTrackConfiguration(0), "mode": session_string, "car": ac.getCarName(0), "score": str(cumulativescore), "laps": str(laps), "bestlap": str(info.graphics.iBestTime), "average_score_per_lap": str(cumulativescore / laps), "score_per_km": str(cumulativescore / (info.graphics.distanceTraveled / 1000)) } SendScore(data) return
def save_delta(self): reference_lap = list(self.referenceLap) reference_lap_time = self.referenceLapTime.value if len(reference_lap) > 0: try: times = [] for l in reference_lap: times.append((l.sector, l.time)) data_file = { 'lap': reference_lap_time, 'times': times, 'track': ac.getTrackName(0), 'config': ac.getTrackConfiguration(0), 'car': ac.getCarName(0), 'user': ac.getDriverName(0) } file = self.get_delta_file_path() with gzip.open(file, 'wt') as outfile: json.dump(data_file, outfile) except: Log.w("Error tower")
def acMain(ac_version): global appWindow, trackname, tracklength, l_lapcount, l_distance, l_fuel, conn, c appWindow = ac.newApp("acOdometer") ac.setSize(appWindow, 142, 142) l_lapcount = ac.addLabel(appWindow, "Laps: Outlap") ac.setPosition(l_lapcount, 3, 30) l_distance = ac.addLabel(appWindow, "Kilometers: Outlap") ac.setPosition(l_distance, 3, 45) l_fuel = ac.addLabel(appWindow, "Fuel used: 0") ac.setPosition(l_fuel, 3, 60) trackname = ac.getTrackName(0) carname = ac.getCarName(0) t = int(time.time()) c.execute("INSERT INTO session('date', 'track', 'car') values (?, ?, ?)", (t, trackname, carname)) # Commited atomically at end of session ac.log("*************************** NEW SESSION\n********* " + trackname) ac.log("acOdometer loaded, racing {} which has {:.3f} miles per lap".format(trackname, tracklength[trackname])) ac.console("acOdometer loaded, racing {} which has {:.3f} kilometers per lap.".format(trackname, tracklength[trackname])) return "acOdometer"
def acMain(ac_version): global session # Create session object session = Session(ac, acsys) session.app_size_x = app_size_x session.app_size_y = app_size_y session.freq = FREQ session.trackname = ac.getTrackName(0) session.carname = ac.getCarName(0) # Initialise UI: ui = UI(session) session.ui = ui # Load best lap time if it exists for current track and car session.load_best_lap() # Create first lap session.new_lap(ac.getCarState(0, acsys.CS.LapCount)) return "Racing Line"
def __init__(self, carId): self.carId = carId # ID - номер машины в списке self.driverName = ac.getDriverName(carId) # имя игрока self.carName = getCarName(ac.getCarName(carId)) # машина # TODO: брать название машины из конфигов: например, вместо ks_bmw_m235i_racing будет BMW M235i Racing self.lapsCompleted = 0 # завершено кругов self.lastLap = ac.getCarState( self.carId, acsys.CS.LastLap) # время последнего пройденного круга в мс self.bestLap = ac.getCarState( self.carId, acsys.CS.BestLap) # время лучшего круга сессии в мс self.qualifiedTime = 0 # время, поставленное в квалификации (сохраняется для сортировки пилотов на старте) self.totalTime = 0 # суммарное время кругов (время гонки, в остальных сессиях не имеет смысла) self.totalDistance = 0 # суммарная дистанция (для сортировки в гонке) self.isInPitlane = ac.isCarInPitlane(carId) # машина на пит-лейне self.isInPit = ac.isCarInPit(carId) # машина в боксах self.lapPostTime = 0 # момент времени (по session_time), когда было поставлено время в практике/квалификации self.connected = False self.leaderboardPosition = 0 self.realTimeLeaderboardPosition = 0 self.isTimedRace = 0 # гонка ограничена временем, а не кругами self.hasExtraLap = 0 # дополнительный круг в гонке по времени self.isFinished = 0 # гонщик завершил сессию
def saveDelta(self): # ac.log(str(time.time())+" saveDelta start:") referenceLap = list(self.referenceLap) # referenceLap=self.referenceLap referenceLapTime = self.referenceLapTime.value if len(referenceLap) > 0: try: times = [] for l in referenceLap: times.append((l.sector, l.time)) data_file = { "lap": referenceLapTime, "times": times, "track": ac.getTrackName(0), "config": ac.getTrackConfiguration(0), "car": ac.getCarName(0), "user": ac.getDriverName(0), } file = self.getDeltaFilePath() with gzip.open(file, "wt") as outfile: json.dump(data_file, outfile) except: Log.w("Error tower")
def acMain(ac_version): global TYREINFO, optimal_spinner_id, optimal_spinner_shown appWindow = ac.newApp("Tyre Temperatures") ac.drawBackground(appWindow, background) ac.drawBorder(appWindow, background) ac.setBackgroundOpacity(appWindow, background) ac.setSize(appWindow, x_app_size, y_app_size) TYREINFO = Tyre_Info(appWindow, x_start, y_start) ac.addRenderCallback(appWindow, onFormRender) TYREINFO.optimal_temp = d_optimal_temp TYREINFO.carinifilepath = inidir + getValidFileName( ac.getCarName(0)) + ".ini" TYREINFO.needwriteini = 1 if os.path.exists(TYREINFO.carinifilepath): f = open(TYREINFO.carinifilepath, "r") TYREINFO.optimal_temp = int(f.readline()[8:]) f.close() TYREINFO.needwriteini = 0 optimal_spinner_id = ac.addSpinner(appWindow, "optimal") ac.setPosition(optimal_spinner_id, 0, y_app_size + 28) ac.setStep(optimal_spinner_id, 1) if inFahrenheit: ac.setRange(optimal_spinner_id, int(CelsiusToFahrenheit(50)), int(CelsiusToFahrenheit(150))) ac.setValue(optimal_spinner_id, int(CelsiusToFahrenheit(TYREINFO.optimal_temp))) else: ac.setRange(optimal_spinner_id, 50, 150) ac.setValue(optimal_spinner_id, TYREINFO.optimal_temp) ac.addOnValueChangeListener(optimal_spinner_id, onValueChanged) optimal_spinner_shown = 1 ac.log("Danny Giusa Tyre Temperatures loaded") return "Danny Giusa Tyre Temperatures"
def acUpdate(deltaT): global timer0, timer1 global tyreLabels, tyrePressureLabels global drsLabel, ersLabel, ersModeLabel, ersRecoveryLabel, fuelLabel, drsPenaltyLabel, drsPenaltyBackgroundLabel global carValue, trackConfigValue, trackValue global currentLapValue, lapValue, previousLapValue, carWasInPit global totalDrivers, trackLength, driversList, totalPenalty, soundPlaying, drsAvailableZones, currentDrsZone, drsPenaltyAwardedInZone, lastTime global tyreCompoundShort, tyreCompoundCleaned, previousTyreCompoundValue, minimumOptimalTemperature, maximumOptimalTemperature, idealPressureFront, idealPressureRear global tyreTemperatureValue, tyreTemperatureValueI, tyreTemperatureValueM, tyreTemperatureValueO, tyrePressureValue, tyreCompoundValue global temperatureTransitionRange, tyrePracticalTemperatureValue global fuelAmountValue, fuelStartValue, relevantLapsNumber, fuelSpentValue, fuelPerLapValue global compounds, modCompounds timer0 += deltaT timer1 += deltaT # Once per second if timer0 > 1: timer0 = 0 # ================================================================================================================= # GET A BUNCH OF INFO # ================================================================================================================= tyreCompoundValue = info.graphics.tyreCompound tyreTemperatureValue = info.physics.tyreCoreTemperature tyreTemperatureValueI = info.physics.tyreTempI tyreTemperatureValueM = info.physics.tyreTempM tyreTemperatureValueO = info.physics.tyreTempO tyrePressureValue = info.physics.wheelsPressure fuelAmountValue = info.physics.fuel if ac.isCarInPitline(0): carWasInPit = 1 # ================================================================================================================= # SET IDEAL TYRE PRESSURES AND TEMPERATURES # ================================================================================================================= if previousTyreCompoundValue != tyreCompoundValue: previousTyreCompoundValue = tyreCompoundValue tyreCompoundShort = tyreCompoundValue[tyreCompoundValue.find("(") + 1:tyreCompoundValue.find(")" )] tyreCompoundCleaned = re.sub( '\_+$', '', re.sub(r'[^\w]+', '_', tyreCompoundValue)).lower() if compounds.has_section(carValue + "_" + tyreCompoundCleaned): try: idealPressureFront = int( compounds.get(carValue + "_" + tyreCompoundCleaned, "IDEAL_PRESSURE_F")) idealPressureRear = int( compounds.get(carValue + "_" + tyreCompoundCleaned, "IDEAL_PRESSURE_R")) minimumOptimalTemperature = int( compounds.get(carValue + "_" + tyreCompoundCleaned, "MIN_OPTIMAL_TEMP")) maximumOptimalTemperature = int( compounds.get(carValue + "_" + tyreCompoundCleaned, "MAX_OPTIMAL_TEMP")) except: ac.console("Error loading tyre data.") elif modCompounds.has_section(carValue + "_" + tyreCompoundCleaned): try: idealPressureFront = int( modCompounds.get(carValue + "_" + tyreCompoundCleaned, "IDEAL_PRESSURE_F")) idealPressureRear = int( modCompounds.get(carValue + "_" + tyreCompoundCleaned, "IDEAL_PRESSURE_R")) minimumOptimalTemperature = int( float( modCompounds.get( carValue + "_" + tyreCompoundCleaned, "MIN_OPTIMAL_TEMP"))) maximumOptimalTemperature = int( float( modCompounds.get( carValue + "_" + tyreCompoundCleaned, "MAX_OPTIMAL_TEMP"))) # ac.console("Tyres: {}, {}psi/{}psi, {}°C-{}°C".format(tyreCompoundValue, idealPressureFront, idealPressureRear, minimumOptimalTemperature, maximumOptimalTemperature)) except: ac.console("Error loading mod tyre data.") else: ac.console( "Tyres: {}, no data found".format(tyreCompoundValue)) # 10 times per second if timer1 > 0.1: timer1 = 0 currentLapValue = info.graphics.iCurrentTime lapValue = ac.getCarState(0, acsys.CS.LapCount) lapProgressValue = ac.getCarState(0, acsys.CS.NormalizedSplinePosition) # ================================================================================================================= # DRS # ================================================================================================================= drsAvailableValue = ac.getCarState(0, acsys.CS.DrsAvailable) drsEnabledValue = ac.getCarState(0, acsys.CS.DrsEnabled) # ================================================================================================================= # DRS SIMPLE (not races) # ================================================================================================================= if info.graphics.session != 2 and ac.getCarName(0) in DRS_ALLOWED_CARS: if drsEnabledValue: set_drs_good() elif drsAvailableValue: set_drs_available() if not soundPlaying and SOUND_ON: # use this variable to control drs beep at begining of drs sound_player.play(audio) sound_player.stop() soundPlaying = True else: soundPlaying = False ac.setVisible(drsLabel, 0) # ================================================================================================================= # DRS DATA COLLECTION # ================================================================================================================= if info.graphics.session == 2 and ac.getCarName(0) in DRS_ALLOWED_CARS: crossedDetectionZone = -1 crossedEndZone = -1 crossedStartZone = -1 curTime = time.time() for i in range(totalDrivers): spline = ac.getCarState(i, acsys.CS.NormalizedSplinePosition) for zid, zone in enumerate(drsZones): if driver_crossed_zone(driversList[i].last_pos, zone['detection'], spline): driversList[i].drs_detection_times[zid] = curTime if i == 0: # current driver crossedDetectionZone = zid # mark zone crossed by driver (not possible to cross multiple zone) if i == 0 and driver_crossed_zone(driversList[i].last_pos, zone['end'], spline): crossedEndZone = zid if i == 0 and driver_crossed_zone(driversList[i].last_pos, zone['start'], spline): crossedStartZone = zid driversList[i].last_pos = spline # ================================================================================================================= # DRS ALLOWANCE MANAGEMENT # ================================================================================================================= # Race Restart if info.graphics.completedLaps == 0 and info.graphics.iCurrentTime == 0: totalPenalty = 0 # reset penalty set_drs_penalty(0) # DRS DETECTION Zone crossed if crossedDetectionZone != -1: if info.graphics.completedLaps + 1 >= DRS_STARTS_ON_LAP: # if this is a valid lap ac.log("Checking Detection Zone: " + str(crossedDetectionZone) + " on lap: " + str(info.graphics.completedLaps)) # check if there is any driver within DRS_GAP if any(driversList[0]. drs_detection_times[crossedDetectionZone] - driver.drs_detection_times[crossedDetectionZone] <= DRS_GAP and driversList[0]. drs_detection_times[crossedDetectionZone] - driver. drs_detection_times[crossedDetectionZone] >= 0 for driver in driversList[1:]): set_drs_possible() drsAvailableZones[crossedDetectionZone] = True # DRS END Zone crossed if crossedEndZone != -1: drsAvailableZones[crossedEndZone] = False currentDrsZone = -1 drsPenaltyAwardedInZone = False # if next zone allows for drs already -- for cases where 1 DRS detection is used in 2 zones if drsAvailableZones[(crossedEndZone + 1) % len(drsAvailableZones)]: set_drs_possible() set_drs_hidden() # DRS START Zone crossed if crossedStartZone != -1: currentDrsZone = crossedStartZone # IN DRS ZONE if drsAvailableValue: if drsAvailableZones[currentDrsZone]: if drsEnabledValue: set_drs_good() else: set_drs_available() if totalPenalty > 0: totalPenalty -= curTime - lastTime set_drs_penalty(totalPenalty) else: if drsEnabledValue: set_drs_bad() if not drsPenaltyAwardedInZone: drsPenaltyAwardedInZone = True announcePenalty( ac.getDriverName(0), info.graphics.completedLaps + 1, "Illegal DRS use, Zone %d" % (currentDrsZone)) # Add penalty amount if abs(curTime - lastTime) < 1: totalPenalty += curTime - lastTime set_drs_penalty(totalPenalty) else: set_drs_hidden() # end of drs update save current values into lasts lastTime = curTime # ================================================================================================================= # ERS LABEL # ================================================================================================================= ersRecoveryLevel = info.physics.ersRecoveryLevel ersMode = info.physics.ersPowerLevel ac.setText(ersModeLabel, "🗲{}".format(ersMode)) ac.setText(ersRecoveryLabel, "↺{}".format(ersRecoveryLevel)) ac.setFontColor(ersModeLabel, *ERS_COLORS[ersMode]) ac.setFontColor(ersLabel, *ERS_COLORS[ersMode]) ac.setFontColor(ersRecoveryLabel, *ERS_COLORS[ersMode]) # ================================================================================================================= # FUEL LABEL # ================================================================================================================= if fuelPerLapValue: ac.setText( fuelLabel, "💧 {:.1f} Laps".format(fuelAmountValue / fuelPerLapValue)) # ================================================================================================================= # TYRE TEMPERATURES # ================================================================================================================= for i in range(4): tyrePracticalTemperatureValue[i] = 0.25 * ( (tyreTemperatureValueI[i] + tyreTemperatureValueM[i] + tyreTemperatureValueO[i]) / 3) + 0.75 * tyreTemperatureValue[i] for i, label in enumerate(tyreLabels): # ac.setText(label, "{:.0f}".format(tyrePracticalTemperatureValue[i])) if minimumOptimalTemperature and maximumOptimalTemperature: if int(round(tyrePracticalTemperatureValue[i]) ) >= minimumOptimalTemperature and int( round(tyrePracticalTemperatureValue[i]) ) <= maximumOptimalTemperature: ac.setBackgroundColor(label, 0.17, 1, 0) elif int(round(tyrePracticalTemperatureValue[i]) ) < minimumOptimalTemperature: idealTemperatureDifference = min( temperatureTransitionRange, minimumOptimalTemperature - tyrePracticalTemperatureValue[i] ) / temperatureTransitionRange ac.setBackgroundColor( label, max(0, 0.17 - idealTemperatureDifference / 5.88), max(0.51, 1 - idealTemperatureDifference / 1.96), min(1, 0 + idealTemperatureDifference)) elif int(round(tyrePracticalTemperatureValue[i]) ) > maximumOptimalTemperature: idealTemperatureDifference = min( temperatureTransitionRange, tyrePracticalTemperatureValue[i] - maximumOptimalTemperature) / temperatureTransitionRange ac.setBackgroundColor( label, min(1, 0.17 + idealTemperatureDifference / 0.83), max(0.17, 1 - idealTemperatureDifference / 0.83), 0) else: ac.setBackgroundOpacity(label, 0) ac.setBackgroundOpacity( label, 1 ) # background colors start to hyde for some reason so this is needed for i, label in enumerate(tyrePressureLabels): if idealPressureFront and idealPressureRear: if i < 2: # front ac.setText( label, "{:+.1f}".format(tyrePressureValue[i] - idealPressureFront)) else: # rear ac.setText( label, "{:+.1f}".format(tyrePressureValue[i] - idealPressureRear)) else: ac.setText(label, "{:.0f}".format(tyrePressureValue[i])) # ================================================================================================================= # CALCULATE AT LAP ENDING OR LAP START # ================================================================================================================= #Display/calculate on lap start if currentLapValue > 500 and currentLapValue < 1000: carWasInPit = 0 fuelStartValue = fuelAmountValue #Display/calculate on lap finish if previousLapValue < lapValue: # announce any penalty at the end of a lap if totalPenalty > 0: announceTotalPenalty(ac.getDriverName(0), info.graphics.completedLaps + 1) previousLapValue = lapValue #Fuel per lap if fuelAmountValue < fuelStartValue and not carWasInPit: relevantLapsNumber += 1 fuelSpentValue += fuelStartValue - fuelAmountValue fuelPerLapValue = fuelSpentValue / relevantLapsNumber
def acMain(ac_version): global DRS_ALLOWED_CARS, SOUND_ON, SERVERS global tyreLabels, tyrePressureLabels global drsLabel, ersLabel, ersModeLabel, ersRecoveryLabel, fuelLabel, drsPenaltyLabel, drsPenaltyBackgroundLabel global drsZones, totalDrivers, trackLength, drsAvailableZones, driversList global carValue, trackConfigValue, trackValue global compounds, modCompounds carValue = ac.getCarName(0) trackValue = ac.getTrackName(0) trackConfigValue = ac.getTrackConfiguration(0) settings = configparser.ConfigParser() settings.read("apps/python/%s/config.ini" % APP_NAME) if settings.has_section('CARS'): DRS_ALLOWED_CARS.extend( [c for c in settings['CARS'] if settings['CARS'][c] == '1']) if settings.has_section('SETTINGS'): SOUND_ON = True if 'sound' in settings['SETTINGS'] and settings[ 'SETTINGS']['sound'] == '1' else False if settings.has_section('SERVERS'): SERVERS = list(settings['SERVERS'].values()) drsZones = loadDRSZones() totalDrivers = ac.getCarsCount() trackLength = getTrackLength() driversList = [Driver(i, len(drsZones)) for i in range(totalDrivers)] drsAvailableZones = [False] * len(drsZones) compounds = configparser.ConfigParser() compounds.read(COMPOUNDSPATH + "compounds.ini") modCompounds = configparser.ConfigParser() modCompounds.read(COMPOUNDSPATH + carValue + ".ini") ac.initFont(0, FONT_NAME, 0, 0) appWindow = ac.newApp(APP_NAME) ac.setTitle(appWindow, "") ac.drawBorder(appWindow, 0) ac.setIconPosition(appWindow, 0, -10000) ac.setSize(appWindow, 280, 70) ac.setBackgroundOpacity(appWindow, 0.2) # ================================================================================================================= # TYRE LABELS # ================================================================================================================= tyreLabelFL = ac.addLabel(appWindow, "") tyreLabelFR = ac.addLabel(appWindow, "") tyreLabelRL = ac.addLabel(appWindow, "") tyreLabelRR = ac.addLabel(appWindow, "") tyreLabels = [tyreLabelFL, tyreLabelFR, tyreLabelRL, tyreLabelRR] for label in tyreLabels: ac.setFontSize(label, 15) ac.setFontColor(label, 0, 0, 0, 1) ac.setFontAlignment(label, "center") ac.setSize(label, 15, 23) tyrePressureLabelFL = ac.addLabel(appWindow, "PFL") tyrePressureLabelFR = ac.addLabel(appWindow, "PFR") tyrePressureLabelRL = ac.addLabel(appWindow, "PRL") tyrePressureLabelRR = ac.addLabel(appWindow, "PRR") tyrePressureLabels = [ tyrePressureLabelFL, tyrePressureLabelFR, tyrePressureLabelRL, tyrePressureLabelRR ] for label in tyrePressureLabels: ac.setFontSize(label, 15) ac.setFontColor(label, 0.86, 0.86, 0.86, 1) ac.setCustomFont(label, FONT_NAME, 0, 0) ac.setFontAlignment(tyrePressureLabels[0], "right") ac.setFontAlignment(tyrePressureLabels[1], "left") ac.setFontAlignment(tyrePressureLabels[2], "right") ac.setFontAlignment(tyrePressureLabels[3], "left") #position all the labels tlpx = 180 tlpy = 10 ac.setPosition(tyreLabels[0], tlpx + 5, tlpy + 0) ac.setPosition(tyreLabels[1], tlpx + 25, tlpy + 0) ac.setPosition(tyreLabels[2], tlpx + 5, tlpy + 28) ac.setPosition(tyreLabels[3], tlpx + 25, tlpy + 28) ac.setPosition(tyrePressureLabels[0], tlpx, tlpy + 2) ac.setPosition(tyrePressureLabels[1], tlpx + 43, tlpy + 2) ac.setPosition(tyrePressureLabels[2], tlpx, tlpy + 30) ac.setPosition(tyrePressureLabels[3], tlpx + 43, tlpy + 30) # ================================================================================================================= # ERS MODES LABELS # ================================================================================================================= elpx = 15 elpy = 10 ersModeLabel = ac.addLabel(appWindow, "🗲0") ac.setPosition(ersModeLabel, elpx + 50, elpy) ac.setFontSize(ersModeLabel, 18) ac.setCustomFont(ersModeLabel, FONT_NAME, 0, 0) ac.setFontColor(ersModeLabel, 1.0, 1.0, 0.2, 1) ac.setFontAlignment(ersModeLabel, "left") ersRecoveryLabel = ac.addLabel(appWindow, "") ac.setPosition(ersRecoveryLabel, elpx + 85, elpy) ac.setFontSize(ersRecoveryLabel, 18) ac.setCustomFont(ersRecoveryLabel, FONT_NAME, 0, 0) ac.setFontColor(ersRecoveryLabel, 1.0, 1.0, 0.2, 1) ac.setFontAlignment(ersRecoveryLabel, "left") ersLabel = ac.addLabel(appWindow, "ERS:") ac.setPosition(ersLabel, elpx, elpy) ac.setFontSize(ersLabel, 18) ac.setCustomFont(ersLabel, FONT_NAME, 0, 0) ac.setFontColor(ersLabel, 1.0, 1.0, 0.2, 1) ac.setFontAlignment(ersLabel, "left") # ================================================================================================================= # FUEL LABEL # ================================================================================================================= fuelLabel = ac.addLabel(appWindow, "💧 --.- Laps") ac.setPosition(fuelLabel, 15, 36) ac.setFontSize(fuelLabel, 18) ac.setCustomFont(fuelLabel, FONT_NAME, 0, 0) ac.setFontColor(fuelLabel, 0.86, 0.86, 0.86, 1) ac.setFontAlignment(fuelLabel, "left") # ================================================================================================================= # DRS LABELS # ================================================================================================================= drsLabel = ac.addLabel(appWindow, "") ac.setPosition(drsLabel, -70, 0) ac.setSize(drsLabel, 70, 70) ac.setVisible(drsLabel, 0) drsPenaltyBackgroundLabel = ac.addLabel(appWindow, "") ac.setPosition(drsPenaltyBackgroundLabel, 0, 70) ac.setSize(drsPenaltyBackgroundLabel, 280, 25) ac.setBackgroundTexture(drsPenaltyBackgroundLabel, DRS_PENALTY_TEXTURE) ac.setVisible(drsPenaltyBackgroundLabel, 0) drsPenaltyLabel = ac.addLabel(appWindow, "") ac.setPosition(drsPenaltyLabel, 150, 70) ac.setFontSize(drsPenaltyLabel, 18) ac.setCustomFont(drsPenaltyLabel, FONT_NAME, 0, 1) ac.setFontColor(drsPenaltyLabel, 0.86, 0.86, 0.86, 1) ac.setFontAlignment(drsPenaltyLabel, "center") ac.setVisible(drsPenaltyLabel, 0) # Announce Start timer = threading.Timer(10, announceStart) timer.start() return APP_NAME
def acUpdate(deltaT): global window_width, have_setup, indicated_max_rpm, max_rpm, indicated_max_speed global rpm_pivot_x, rpm_pivot_y, speed_pivot_x, speed_pivot_y, tach_radius, speedo_radius, max_fuel global fuel_warning_label, dt_ratio global draw_boost_gauge global rpms_file ac.setBackgroundOpacity(window,0) if have_setup: telemetry_client.tick() if debug_mode: ac.setText(debug_label,"%2.2f" % (ac.getCarState(0,acsys.CS.DriveTrainSpeed)/ac.getCarState(0,acsys.CS.SpeedKMH))) if have_setup == 0: max_rpm = sim_info.static.maxRpm ac.console("Maximum RPM for car %s: %d" %(ac.getCarName(0),max_rpm)) if max_rpm < 500: if rpms_file.has_section(ac.getCarName(0)): max_rpm = int(rpms_file[ac.getCarName(0)]['max_rpm']) else: ac.console("Don't know max RPMs for this car, go play with it in practice mode first!") max_rpm = 20000 else: if not rpms_file.has_section(ac.getCarName(0)): rpms_file.add_section(ac.getCarName(0)) rpms_file[ac.getCarName(0)]['max_rpm'] = str(max_rpm) with open('apps/python/AnalogInstruments/rpms.ini','w') as file: rpms_file.write(file) ac.console("Learned max RPM for this car") telemetry_client.connect() ac.log("Opening car info file") carinfo_file = configparser.ConfigParser() carinfo_file.read("apps/python/AnalogInstruments/carinfo.ini") ac.log("Got car info file") if carinfo_file.has_section(ac.getCarName(0)): ac.log("Found car in file") dt_ratio = float(carinfo_file[ac.getCarName(0)]['ratio']) ac.log("Got ratio") indicated_max_speed = int(carinfo_file[ac.getCarName(0)]['top_speed']) ac.log("Got top speed") has_turbo = carinfo_file[ac.getCarName(0)].getboolean('has_turbo') ac.log("Got turbo") else: ac.console("Car %s isn't in carinfo.ini!" % ac.getCarName(0)) dt_ratio = 1 indicated_max_speed = 320 has_turbo = True if (not has_turbo or not draw_boost_gauge) and draw_background: ac.setBackgroundTexture(window,background_image_path_noboost) draw_boost_gauge = False # Max fuel ac.log("Getting things from SHM") max_fuel = sim_info.static.maxFuel car_model = sim_info.static.carModel compound = str(sim_info.graphics.tyreCompound)#FIXME ac.log("Got things from SHM") # Optimal tyre temp range as taken from that forum post if "exos_125_s1" in car_model: if "SuperSoft" in compound: tyre_optimal_temp = range(85,111) elif "Soft" in compound: tyre_optimal_temp = range(105,126) elif "Medium" in compound: tyre_optimal_temp = range(90,116) elif "Hard" in compound: tyre_optimal_temp = range(110,136) elif "exos_125" in car_model: tyre_optimal_temp = range(90,121) elif "Semislick" in compound: tyre_optimal_temp = range(75,101) elif "Street" in compound: tyre_optimal_temp = range(75,86) elif "_gt2" in car_model: if "SuperSoft" in compound: tyre_optimal_temp = range(90,106) elif "Soft" in compound: tyre_optimal_temp = range(90,106) elif "Medium" in compound: tyre_optimal_temp = range(85,106) elif "Hard" in compound: tyre_optimal_temp = range(80,101) elif "SuperHard" in compound: tyre_optimal_temp = range(80,101) elif "70F1" in compound: tyre_optimal_temp = range(50,91) elif "Soft" in compound: tyre_optimal_temp = range(80,111) elif "Medium" in compound: tyre_optimal_temp = range(75,106) elif "Hard" in compound: tyre_optimal_temp = range(70,101) ac.log("Setting up tach") if draw_tachometer: # Tach setup indicated_max_rpm = max_rpm + 1000 - (max_rpm % 1000) # Tach labels for i in range(0,indicated_max_rpm+1,1000): r = abs(tach_min_angle - tach_max_angle) rad = math.radians(tach_max_angle - (i/indicated_max_rpm)*r) label = ac.addLabel(window," ") ac.setText(label,"%d" % (i/1000)) x_offset = 0 y_offset = 0 if rad < math.pi/2: x_offset = 15 - math.sin(rad)*15 y_offset = math.cos(rad)*5 ac.setPosition(label,math.cos(rad)*(tach_radius*4/5)+rpm_pivot_x-x_offset,rpm_pivot_y - math.sin(rad)*(tach_radius*4/5)-y_offset) ac.log("Setting up speedo") if draw_speedometer: # Speedo setup if imperial: indicated_max_speed = int(indicated_max_speed/1.6) #TODO: round up to multiple of 20 # Speedo labels for i in range(0,indicated_max_speed+1,20): r = abs(speedo_min_angle - speedo_max_angle) rad = math.radians(speedo_max_angle - (i/indicated_max_speed)*r) label = ac.addLabel(window," ") ac.setText(label,"%d" % i) x_offset = 0 y_offset = 0 if rad < math.pi/2: x_offset = 23 - math.sin(rad)*23 y_offset = math.cos(rad)*5 ac.setPosition(label,math.cos(rad)*speedo_radius*4/5+speed_pivot_x-x_offset,speed_pivot_y - math.sin(rad)*speedo_radius*4/5-y_offset) have_setup = 1
def acMain(ac_version: str) -> None: """ Initiates the program. """ global ACD_OBJ global CONFIGS global LT_VERSION log("Starting Live Telemetry {} on AC Python API version {}...".format( LT_VERSION, ac_version)) log("Loading configs...") CONFIGS = Config(LT_VERSION) log("Loading {} info...".format(ac.getCarName(0))) ACD_OBJ = ACD("content/cars/{}".format(ac.getCarName(0))) log("Loaded correctly") log("Loading options window...") global OPTIONS_INFO OPTIONS_INFO = OptionsInfo(CONFIGS) ac.addOnClickedListener( OPTIONS_INFO.get_button_id("Camber"), on_click_camber) ac.addOnClickedListener(OPTIONS_INFO.get_button_id("Dirt"), on_click_dirt) ac.addOnClickedListener( OPTIONS_INFO.get_button_id("Height"), on_click_height) ac.addOnClickedListener(OPTIONS_INFO.get_button_id("Load"), on_click_load) ac.addOnClickedListener(OPTIONS_INFO.get_button_id("Lock"), on_click_lock) ac.addOnClickedListener( OPTIONS_INFO.get_button_id("Logging"), on_click_logging) ac.addOnClickedListener(OPTIONS_INFO.get_button_id( "Pressure"), on_click_pressure) ac.addOnClickedListener( OPTIONS_INFO.get_button_id("RPMPower"), on_click_rpm) ac.addOnClickedListener(OPTIONS_INFO.get_button_id("Size"), on_click_size) ac.addOnClickedListener(OPTIONS_INFO.get_button_id( "Suspension"), on_click_suspension) ac.addOnClickedListener( OPTIONS_INFO.get_button_id("Temps"), on_click_temps) ac.addOnClickedListener(OPTIONS_INFO.get_button_id("Tire"), on_click_tire) ac.addOnClickedListener(OPTIONS_INFO.get_button_id("Wear"), on_click_wear) log("Loading engine window...") global ENGINE_INFO ENGINE_INFO = EngineInfo(ACD_OBJ, CONFIGS) window_id = ENGINE_INFO.get_window_id() ac.addOnAppActivatedListener(window_id, on_activation) ac.addOnAppDismissedListener(window_id, on_dismiss) ac.addRenderCallback(ENGINE_INFO.get_window_id(), on_render_engine) log("Loading wheel windows...") global WHEEL_INFOS for index in range(4): info = WheelInfo(ACD_OBJ, CONFIGS, index) window_id = info.get_window_id() ac.addOnAppActivatedListener(window_id, on_activation) ac.addOnAppDismissedListener(window_id, on_dismiss) WHEEL_INFOS[info.get_id()] = info ac.addRenderCallback(WHEEL_INFOS["FL"].get_window_id(), on_render_fl) ac.addRenderCallback(WHEEL_INFOS["FR"].get_window_id(), on_render_fr) ac.addRenderCallback(WHEEL_INFOS["RL"].get_window_id(), on_render_rl) ac.addRenderCallback(WHEEL_INFOS["RR"].get_window_id(), on_render_rr) log("Live Telemetry started.") return "Live Telemetry"
def init_lap(self): self.lap.track = self.track.name self.lap.car = ac.getCarName(0) self.lap.lap_number = ac.getCarState(0, acsys.CS.LapCount) self.lap.splits = [0] * self.track.sector_count self.lap.invalid_sectors = [False] * self.track.sector_count
def onUpdate(self, sim_info, fl): self.session.setValue(sim_info.graphics.session) self.manageWindow() self.animate() if self.carsCount==0: self.carsCount = ac.getCarsCount() sessionTimeLeft=sim_info.graphics.sessionTimeLeft sim_info_status=sim_info.graphics.status self.currentVehicule.setValue(ac.getFocusedCar()) backupLaptime=0 backupLastLapInPits=0 if len(self.lapTimesArray) < self.carsCount: for x in range(self.carsCount): c = ac.getCarState(x,acsys.CS.LapCount) self.driversLap.append(Value(c)) self.lapTimesArray.append(lapTimeStart(c,sessionTimeLeft,0)) else: for x in range(self.carsCount): c = ac.getCarState(x,acsys.CS.LapCount) self.driversLap[x].setValue(c) if self.driversLap[x].hasChanged(): self.lapTimesArray[x].lap=self.driversLap[x].value self.lapTimesArray[x].time=sessionTimeLeft if bool(ac.isCarInPitline(x)) or bool(ac.isCarInPit(x)): self.lapTimesArray[x].lastpit=c if x == self.currentVehicule.value: backupLaptime=self.lapTimesArray[x].time-sessionTimeLeft self.lastLapStart = self.lapTimesArray[x].time backupLastLapInPits = self.lapTimesArray[x].lastpit currentVehiculeChanged=self.currentVehicule.hasChanged() if currentVehiculeChanged or (self.fastestLapBorderActive and sessionTimeLeft < self.visible_end-2000): self.fastestLapBorderActive = False car = ac.getCarName(self.currentVehicule.value) self.lbl_border.setBgColor(Colors.colorFromCar(car)) if sim_info_status == 2: #LIVE strOffset = " " #self.nameOffset=14 if self.session.value != 2 : #NOT RACE #qtime self.fastestLap.setValue(fl) bestlap = ac.getCarState(self.currentVehicule.value,acsys.CS.BestLap) isInPit = (bool(ac.isCarInPitline(self.currentVehicule.value)) or bool(ac.isCarInPit(self.currentVehicule.value))) LapCount = ac.getCarState(self.currentVehicule.value,acsys.CS.LapCount) if self.lastLap != LapCount: self.lastLap = LapCount self.firstLapStarted=False if self.currentVehicule.value==0: self.lastLapStart = sessionTimeLeft curLapTime = ac.getCarState(self.currentVehicule.value, acsys.CS.LapTime) if curLapTime == 0 and backupLaptime > 0 and self.minLapCount > 0: curLapTime = backupLaptime if curLapTime > 0: self.firstLapStarted=True #if self.minLapCount == 0 and self.firstLapStarted and ((self.lastLapTime > curLapTime and curLapTime < 1000) or self.lastLapStart==10000): # self.lastLapStart = sessionTimeLeft self.lastLapTime = curLapTime if isInPit : self.lastLapInPit = LapCount self.lastTimeInPit = sessionTimeLeft if self.currentVehicule.value==0 and sim_info.physics.numberOfTyresOut >= 4 and self.lapCanBeInvalidated: self.lastLapInvalidated = LapCount if isInPit and self.minLapCount == 0: self.lastLapInvalidated = -1 if self.sectorCount < 0: self.sectorCount = sim_info.static.sectorCount if self.fastestLap.value > 0: for x in range(self.carsCount): c = ac.getCarState(x,acsys.CS.BestLap) if self.fastestLap2.value == 0 or (c > 0 and c < self.fastestLap2.value): self.fastestLap2.setValue(c) self.fastestLapSectors = ac.getLastSplits(x) else: self.fastestLapSectors = [0,0,0,0,0,0] #lapInvalidated = bool(ac.getCarState(0, acsys.CS.LapInvalidated)) lapInvalidated = bool(self.lastLapInvalidated==LapCount) if currentVehiculeChanged or self.lbl_driver_name_text.value=="": self.lbl_driver_name_text.setValue(self.format_name(ac.getDriverName(self.currentVehicule.value))) #sector_delay = 5000 # live or info #ac.console("("+str(self.lastLapInPit)+" < "+str(LapCount)+" or "+str(self.minLapCount)+"==0) and not "+str(lapInvalidated)+" and ("+str(self.lastTimeInPit)+"==0 or "+str(self.lastTimeInPit)+" > "+str(self.lastLapStart)+")") if ((self.lastLapStart < 0 and self.minLapCount > 0) or (self.minLapCount == 0 and lapInvalidated)) and self.session.value != 0: self.lbl_driver_name_visible.setValue(0) self.lbl_timing_visible.setValue(0) self.lbl_split.hideText() self.info_position.hide() self.info_position_lead.hide() elif (self.lastLapInPit < LapCount or self.minLapCount==0) and not lapInvalidated and (self.lastTimeInPit==0 or self.lastTimeInPit > self.lastLapStart or self.minLapCount==0) : if self.currentVehicule.value == 0: sector = sim_info.graphics.currentSectorIndex else: sector = self.getSector() self.lbl_driver_name_visible.setValue(1) self.lbl_timing_visible.setValue(1) #lapTime = ac.getCarState(self.currentVehicule.value, acsys.CS.LapTime) if self.currentVehicule.value == 0: lastLap = sim_info.graphics.iLastTime else: lastLap=0 lastSplits = ac.getLastSplits(self.currentVehicule.value) for c in lastSplits: lastLap+=c if lastLap==0: lastLap=ac.getCarState(self.currentVehicule.value, acsys.CS.LastLap) traite=False cur_splits = ac.getCurrentSplits(self.currentVehicule.value) timeSplit=0 fastestSplit=0 i=0 showSplit=False for c in cur_splits: if c > 0: timeSplit+=c fastestSplit+=self.fastestLapSectors[i] i+=1 fastestSplit_fin=fastestSplit if i < self.sectorCount: fastestSplit_fin+=self.fastestLapSectors[i] #Situation for s in range(0,self.sectorCount): if self.fastestLap.value > 0 and curLapTime > fastestSplit_fin - self.sector_delay: #LAST_SECONDS_OF_SECTOR_X, sector == s and self.info_position.hide() self.nameOffset=self.rowHeight*14/36 #14 if self.sectorCount-1 == sector: #LAST_SECONDS_OF_SECTOR_LAP, self.lbl_split.setText(self.time_splitting(self.fastestLap.value,"yes")).setColor(Colors.white()).showText() self.info_position_lead.show() showSplit=True elif fastestSplit_fin > 0: self.lbl_split.setText(self.time_splitting(fastestSplit_fin,"yes")).setColor(Colors.white()).showText() self.info_position_lead.show() showSplit=True break if sector == s + 1 and s + 1 <= self.sectorCount and curLapTime - timeSplit <= self.sector_delay and fastestSplit > 0 : #SECTOR_X_FINISHED_BEGIN_SECTOR_Y self.nameOffset=self.rowHeight*14/36 #14 self.lbl_timing_text.setValue(strOffset + self.time_splitting(timeSplit,"yes")) if fastestSplit < timeSplit: self.lbl_split.setText("+"+self.time_splitting(timeSplit-fastestSplit,"yes")).setColor(Colors.yellow()).showText() else: self.lbl_split.setText("-"+self.time_splitting(fastestSplit-timeSplit,"yes")).setColor(Colors.green()).showText() self.info_position_lead.show() self.info_position.hide() traite=True break if not traite: if self.sectorCount-1 == sector and self.fastestLap.value > 0 and curLapTime > self.fastestLap.value - self.sector_delay: #LAST_SECONDS_OF_SECTOR_LAP, self.nameOffset=self.rowHeight*14/36 #14 self.lbl_timing_text.setValue(strOffset + self.time_splitting(curLapTime)) self.info_position.hide() #self.lbl_split.setText(self.time_splitting(self.fastestLap,"yes") + strOffset).setVisible(1) elif self.lastLapInvalidated!=LapCount-1 and ((self.lastLapInPit!=LapCount-1 and sector == 0) or (self.minLapCount==0)) and curLapTime <= self.sector_delay and lastLap > 0: #LAP_FINISHED_BEGIN_NEW_LAP, pos = ac.getCarLeaderboardPosition(self.currentVehicule.value) if pos == -1: pos = self.getStandingsPosition(self.currentVehicule.value) if pos > 1: self.info_position.setColor(Colors.white()).setBgColor(Colors.grey(bg = True)).setBgOpacity(0.8) else: self.info_position.setColor(Colors.white()).setBgColor(Colors.red(bg = True)).setBgOpacity(0.8) self.info_position.setText(str(pos)) self.info_position.show() self.nameOffset=self.rowHeight*49/36 #49 self.lbl_timing_text.setValue(strOffset + self.time_splitting(lastLap,"yes")) if self.fastestLap.value < lastLap: self.lbl_split.setText("+"+self.time_splitting(lastLap-self.fastestLap.value,"yes")).setColor(Colors.yellow()).showText() else: self.lbl_split.setText("-"+self.time_splitting(self.getBestLap()-lastLap,"yes")).setColor(Colors.green()).showText() self.info_position_lead.show() else: #OTHER self.nameOffset=self.rowHeight*14/36 #14 self.lbl_timing_text.setValue(strOffset + self.time_splitting(curLapTime)) self.info_position.hide() if not showSplit: self.lbl_split.hideText() self.info_position_lead.hide() self.fastestLap.changed=False else : self.info_position_lead.hide() normalizedSplinePosition = ac.getCarState(self.currentVehicule.value,acsys.CS.NormalizedSplinePosition) if normalizedSplinePosition <= 0.001: normalizedSplinePosition=1 if sessionTimeLeft > 0 and self.minLapCount==1 and normalizedSplinePosition > 0.95 and not isInPit : self.lbl_driver_name_visible.setValue(1) self.nameOffset=self.rowHeight*14/36 #14 self.lbl_timing_visible.setValue(1) self.lbl_split.hideText() self.info_position.hide() self.lbl_timing_text.setValue(strOffset + "0.0") elif lapInvalidated and self.lastLapInPit < LapCount and self.minLapCount > 0 : self.lbl_driver_name_visible.setValue(0) self.lbl_timing_visible.setValue(0) self.lbl_split.hideText() self.info_position.hide() elif bestlap > 0 : self.lbl_driver_name_visible.setValue(1) self.lbl_timing_visible.setValue(1) if self.fastestLap.value < bestlap: self.lbl_split.setText("+"+self.time_splitting(bestlap-self.fastestLap.value,"yes")).setColor(Colors.yellow()).showText() else: self.lbl_split.hideText() self.lbl_timing_text.setValue(strOffset + self.time_splitting(bestlap,"yes")) self.nameOffset=self.rowHeight*49/36 #49 #pos = sim_info.graphics.position pos = ac.getCarLeaderboardPosition(self.currentVehicule.value) if pos == -1: pos = self.getStandingsPosition(self.currentVehicule.value) if pos > 1: self.info_position.setColor(Colors.white()).setBgColor(Colors.grey(bg = True)).setBgOpacity(1) else: self.info_position.setColor(Colors.white()).setBgColor(Colors.red(bg = True)).setBgOpacity(1) self.info_position.setText(str(pos)).show() self.lbl_position_text.setValue(str(pos)) elif isInPit : self.lbl_driver_name_visible.setValue(0) self.lbl_timing_visible.setValue(0) self.lbl_split.hideText() self.info_position.hide() else : self.nameOffset=self.rowHeight*14/36 #14 self.lbl_driver_name_visible.setValue(1) self.lbl_timing_visible.setValue(1) if self.currentVehicule.value==0: self.lbl_timing_text.setValue(strOffset + self.format_tire(sim_info.graphics.tyreCompound)) else: self.lbl_timing_text.setValue(strOffset + "Out Lap") self.lbl_split.hideText() self.info_position.hide() if curLapTime <= self.sector_delay and ac.getCarState(self.currentVehicule.value, acsys.CS.LastLap) > 0 and backupLastLapInPits + 1 < ac.getCarState(x,acsys.CS.LapCount) and sessionTimeLeft < 0: self.nameOffset=self.rowHeight*49/36 #49 self.lbl_driver_name_visible.setValue(1) self.lbl_timing_visible.setValue(1) self.lbl_split.showText() self.info_position.show() #time vis self.visibilityQualif() else: ################ Race ################ self.info_position_lead.hide() self.lbl_split.hideText() #fastest lap completed=0 for x in range(self.carsCount): c = ac.getCarState(x,acsys.CS.LapCount) if c > completed: completed=c if completed <=1: self.race_fastest_lap.setValue(0) else: for i in range(self.carsCount): bl=ac.getCarState(i,acsys.CS.BestLap) l = ac.getCarState(i,acsys.CS.LapCount) if bl > 0 and l > self.minLapCount and (self.race_fastest_lap.value == 0 or bl < self.race_fastest_lap.value): self.race_fastest_lap.setValue(bl) self.race_fastest_lap_driver.setValue(i) if self.race_fastest_lap.hasChanged() and self.race_fastest_lap.value > 0: self.fastestLapBorderActive = True car = ac.getCarName(self.race_fastest_lap_driver.value) self.lbl_border.setBgColor(Colors.colorFromCar(car)) self.visible_end = sessionTimeLeft - 8000 self.lbl_driver_name_visible.setValue(1) self.lbl_driver_name_text.setValue(self.format_name(ac.getDriverName(self.race_fastest_lap_driver.value))) self.nameOffset=self.rowHeight*14/36 #14 self.lbl_timing_text.setValue(strOffset + "Fastest Lap") self.lbl_timing_visible.setValue(1) self.info_position.hide() self.lbl_fastest_split.setText(self.time_splitting(self.race_fastest_lap.value,"yes")).showText() elif currentVehiculeChanged: #driver info self.visible_end = sessionTimeLeft - 8000 self.lbl_driver_name_visible.setValue(1) self.lbl_driver_name_text.setValue(self.format_name(ac.getDriverName(self.currentVehicule.value))) self.nameOffset=self.rowHeight*49/36 #49 #pos = ac.getCarLeaderboardPosition(self.currentVehicule.value) pos = ac.getCarRealTimeLeaderboardPosition(self.currentVehicule.value) + 1 if pos > 1: self.info_position.setColor(Colors.white()).setBgColor(Colors.grey(bg = True)).setBgOpacity(1) else: self.info_position.setColor(Colors.white()).setBgColor(Colors.red(bg = True)).setBgOpacity(1) self.info_position.setText(str(pos)).show() self.lbl_timing_visible.setValue(0) self.lbl_fastest_split.hideText() elif self.visible_end == 0 or sessionTimeLeft < self.visible_end or sessionTimeLeft > 1800000: self.lbl_driver_name_visible.setValue(0) self.info_position.hide() self.lbl_timing_visible.setValue(0) self.lbl_fastest_split.hideText() self.visibilityRace() elif sim_info_status == 1 and self.session.value != 2: #Replay Qualif strOffset = " " showSplit=False LapCount = ac.getCarState(self.currentVehicule.value,acsys.CS.LapCount) curLapTime = ac.getCarState(self.currentVehicule.value, acsys.CS.LapTime) isInPit = (bool(ac.isCarInPitline(self.currentVehicule.value)) or bool(ac.isCarInPit(self.currentVehicule.value))) if currentVehiculeChanged or self.lbl_driver_name_text.value=="": self.lbl_driver_name_text.setValue(self.format_name(ac.getDriverName(self.currentVehicule.value))) if isInPit: self.lbl_driver_name_visible.setValue(0) self.lbl_timing_visible.setValue(0) self.lbl_split.hideText() self.info_position.hide() elif curLapTime <= self.sector_delay and LapCount > 1: #show last lap self.lbl_driver_name_visible.setValue(1) self.lbl_timing_visible.setValue(1) if self.currentVehicule.value == 0: lastLap = sim_info.graphics.iLastTime else: lastLap=0 lastSplits = ac.getLastSplits(self.currentVehicule.value) for c in lastSplits: lastLap+=c if lastLap==0: lastLap=ac.getCarState(self.currentVehicule.value, acsys.CS.LastLap) pos = ac.getCarLeaderboardPosition(self.currentVehicule.value) if pos == -1: pos = self.getStandingsPosition(self.currentVehicule.value) if pos > 1: self.info_position.setColor(Colors.white()).setBgColor(Colors.grey(bg = True)).setBgOpacity(0.8) else: self.info_position.setColor(Colors.white()).setBgColor(Colors.red(bg = True)).setBgOpacity(0.8) self.info_position.setText(str(pos)) self.info_position.show() self.nameOffset=self.rowHeight*49/36 #49 self.lbl_timing_text.setValue(strOffset + self.time_splitting(lastLap,"yes")) if self.fastestLap.value < lastLap: self.lbl_split.setText("+"+self.time_splitting(lastLap-self.fastestLap.value,"yes")).setColor(Colors.yellow()).showText() else: self.lbl_split.setText("-"+self.time_splitting(self.fastestLap.old-lastLap,"yes")).setColor(Colors.green()).showText() self.info_position_lead.show() self.fastestLap.changed=False elif LapCount > self.minLapCount: #showTiming self.lbl_driver_name_visible.setValue(1) self.lbl_timing_visible.setValue(1) self.info_position_lead.hide() self.nameOffset=self.rowHeight*14/36 #14 self.lbl_timing_text.setValue(strOffset + self.time_splitting(curLapTime)) self.info_position.hide() if not showSplit: self.lbl_split.hideText() self.info_position_lead.hide() else: #showTireInfo self.info_position_lead.hide() self.nameOffset=self.rowHeight*14/36 #14 self.lbl_driver_name_visible.setValue(1) self.lbl_timing_visible.setValue(1) if self.currentVehicule.value==0: self.lbl_timing_text.setValue(strOffset + self.format_tire(sim_info.graphics.tyreCompound)) else: self.lbl_timing_text.setValue(strOffset + "Out Lap") self.lbl_split.hideText() self.info_position.hide() self.visibilityQualif() elif sim_info_status == 1 and self.session.value == 2: #Replay Race todo=1 ''' if currentVehiculeChanged: self.visible_end = sessionTimeLeft - 8000 self.lbl_driver_name_visible.setValue(1) self.lbl_driver_name_text.setValue(self.format_name(ac.getDriverName(self.currentVehicule.value))) self.nameOffset=self.rowHeight*49/36 #49 pos = ac.getCarRealTimeLeaderboardPosition(self.currentVehicule.value) + 1 if pos > 1: self.info_position.setColor(Colors.white()).setBgColor(Colors.grey(bg = True)).setBgOpacity(1) else: self.info_position.setColor(Colors.white()).setBgColor(Colors.red(bg = True)).setBgOpacity(1) self.info_position.setText(str(pos)).show() self.lbl_timing_visible.setValue(0) self.lbl_fastest_split.hideText() if self.lbl_driver_name_visible.hasChanged(): if self.lbl_driver_name_visible.value == 0: self.lbl_driver_name.hide() self.lbl_border.hide() else: self.lbl_driver_name.show() self.lbl_border.show() if self.lbl_timing_visible.hasChanged(): if self.lbl_timing_visible.value == 0: self.lbl_timing.hide() else: self.lbl_timing.show() if self.lbl_driver_name_text.hasChanged(): self.lbl_driver_name.setText(self.lbl_driver_name_text.value) if self.lbl_timing_text.hasChanged(): self.lbl_timing.setText(self.lbl_timing_text.value,hidden=bool(self.lbl_timing_height < 30)) ''' else: #REPLAY self.resetVisibility()
def __init__(self): self.rowHeight=36 self.lastLapInPit = 0 self.lastLapInvalidated = 0 self.situation = 0 self.carsCount=0 self.lbl_timing_height = 0 self.lbl_position_height = 0 self.lbl_position_text=Value("") self.currentVehicule=Value(-1) self.ui_row_height = Value(-1) self.cursor=Value(False) self.fastestLap=Value(0) self.fastestLap2=Value(0) self.fastestPos=1 self.lastLap=0 self.lastLapStart=10000 self.sector_delay = 5000 self.lastTimeInPit=0 self.visible_end = 0 self.lastLapTime = 0 self.nameOffset=0 self.nameOffsetValue=Value(0) self.lapCanBeInvalidated=True self.fastestLapBorderActive = False self.firstLapStarted=False self.minLapCount=1 self.sectorCount=-1 self.lapTimesArray = [] self.driversLap = [] track=ac.getTrackName(0) config=ac.getTrackConfiguration(0) if track.find("ks_nordschleife")>=0 and config.find("touristenfahrten")>=0: self.minLapCount=0 self.lastLapInvalidated = -1 elif track.find("drag1000")>=0 or track.find("drag400")>=0: self.minLapCount=0 self.lastLapInvalidated = -1 self.fastestLapSectors = [0,0,0,0,0,0] self.session=Value(-1) #self.session.setValue() self.window = Window(name="ACTV Info", icon=False, width=332, height=self.rowHeight*2, texture="") self.lbl_driver_name=Label(self.window.app,"").setSize(284, self.rowHeight).setPos(0, 0).setBgColor(rgb([20, 20, 20], bg = True)).setBgOpacity(0.8).setVisible(0) self.lbl_driver_name2=Label(self.window.app,"Loading").setSize(284, self.rowHeight).setPos(14, 0).setFontSize(26).setAlign("left").setVisible(0) self.lbl_driver_name_visible=Value() self.lbl_driver_name_visible_fin=Value(0) self.lbl_driver_name_text=Value("") self.lbl_position_visible=Value(0) self.lbl_timing_text=Value() self.race_fastest_lap=Value(0) #self.race_fastest_lap.setValue(0) self.race_fastest_lap_driver=Value() self.lbl_timing_visible=Value(0) self.lbl_timing=Label(self.window.app,"Loading").setSize(284, self.rowHeight).setPos(0, self.rowHeight).setFontSize(26).setAlign("left").setBgColor(rgb([55, 55, 55], bg = True)).setBgOpacity(0.64).setVisible(0) self.lbl_split=Label(self.window.app,"Loading").setSize(220, self.rowHeight).setPos(10, self.rowHeight).setFontSize(26).setAlign("right").setVisible(0) self.lbl_fastest_split=Label(self.window.app,"Loading").setSize(220, self.rowHeight).setPos(48, self.rowHeight).setFontSize(26).setAlign("right").setVisible(0) self.info_position=Label(self.window.app,"0").setSize(self.rowHeight, self.rowHeight).setPos(0, 0).setFontSize(26).setAlign("center").setBgColor(Colors.red(bg = True)).setBgOpacity(1).setVisible(0) self.info_position_lead=Label(self.window.app,"1").setSize(self.rowHeight, self.rowHeight).setPos(246, self.rowHeight).setFontSize(26).setAlign("center").setBgColor(Colors.red(bg = True)).setBgOpacity(1).setVisible(0) car = ac.getCarName(0) self.lbl_border=Label(self.window.app,"").setSize(284, 1).setPos(0, self.rowHeight).setBgColor(Colors.colorFromCar(car)).setBgOpacity(0.7).setVisible(0) self.loadCFG() self.info_position.setAnimationSpeed("o", 0.1) self.info_position_lead.setAnimationSpeed("o", 0.1) self.lbl_split.setAnimationSpeed("a", 0.1) self.lbl_fastest_split.setAnimationSpeed("a", 0.1)
os.remove('apps\python\BoxRadio\AClog.txt') else: ac.log('BoxRadio: ks_tyres.ini method') with open('server\manager\ks_tyres.ini', 'r') as g: content = g.read() g.close() with open('apps\python\BoxRadio\ks_tyres_adj.ini', 'w') as j: j.write(';') j.write(content) j.close() config = configparser.ConfigParser() config.read('apps\python\BoxRadio\ks_tyres_adj.ini') if ac.getCarName(0) in config: for key in config[ac.getCarName(0)]: OptionLabel[i] = key ac.log('BoxRadio: Tyre short: ' + key) i = i + 1 ac.log('BoxRadio: Tyres obtained from ks_tyres.ini') else: OptionLabel = ['', 'T1', 'T2', 'T3', 'T4', 'T5'] ac.log('BoxRadio: Mod tyres not found on ks_tyres.ini') os.remove('apps\python\BoxRadio\ks_tyres_adj.ini') ac.log('BoxRadio: Found AC log location: ' + logfound) # Read Config File configini = configparser.ConfigParser()