Skip to content
This repository has been archived by the owner on Jul 24, 2022. It is now read-only.

Commit

Permalink
added flags and gained/lost positions mode in the leaderboard
Browse files Browse the repository at this point in the history
  • Loading branch information
3ximus committed Jun 21, 2020
1 parent af75591 commit 4d7ac94
Show file tree
Hide file tree
Showing 16 changed files with 116 additions and 45 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ Can be tweaked for other championships using the "teams.ini" file.

During the race a file is saved, that will be read by the app during a race replay to be able to load the whole UI again. However currently **it only saves different files for each combination of track and car**.

## STILL A WORK IN PROGRESS!!


## teams.ini configuration

Each line contains the following information about each driver in order separated by a colon "`:`"
Expand All @@ -32,3 +29,11 @@ QUALIFYING
FASTEST LAP

![im2](/screenshots/screen2.png)

DRIVER TIME GAP COMPARISON (sort of useless)

![im4](/screenshots/screen4.png)

GAINED LOST POSITIONS (click on the information panel to switch between time games and this mode)

![im5](/screenshots/screen5.png)
91 changes: 60 additions & 31 deletions apps/python/F12020Leaderboard/F12020Leaderboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from utils import get_image_size, time_to_string
from DriverWidget import DriverWidget
from DriverComparisonWidget import DriverComparisonWidget
from LeaderboardRow import LeaderboardRow
from LeaderboardRow import LeaderboardRow, INFO_TYPE
from FastestLapBanner import FastestLapBanner


Expand All @@ -37,8 +37,6 @@
replay_started = False
quali_started = False

leaderboard_displayed = False

qualify_session_time = 0

# REPLAY FILE
Expand All @@ -57,6 +55,7 @@
leaderboardBaseLabel = None
leaderboardInfoBackgroundLabel = None
leaderboardBackgroundLabel = None
flagLabel = None

class Driver: # class to hold driver information
def __init__(self, id, n_splits):
Expand Down Expand Up @@ -87,6 +86,7 @@ def acMain(ac_version):
# LABELS
global leaderboard
global lapCountTimerLabel, leaderboardBaseLabel, leaderboardInfoBackgroundLabel, leaderboardBackgroundLabel
global flagLabel

totalDrivers = ac.getCarsCount()
n_splits = ac.getTrackLength(0) / FC.TRACK_SECTION_LENGTH
Expand All @@ -113,7 +113,7 @@ def acMain(ac_version):
ac.setPosition(leaderboardBackgroundLabel, 0, h)
ac.setSize(leaderboardBackgroundLabel, w, totalDrivers*LeaderboardRow.ROW_HEIGHT + 2)
ac.setBackgroundTexture(leaderboardBackgroundLabel, FC.LEADERBOARD_BACKGROUND);

# ===============================
# Lap Counter / Time
lapCountTimerLabel = ac.addLabel(leaderboardWindow, "")
Expand All @@ -123,13 +123,27 @@ def acMain(ac_version):
ac.setFontAlignment(lapCountTimerLabel, "center")
ac.setFontColor(lapCountTimerLabel, 0.86, 0.86, 0.86, 1)

# ===============================
# Flags
flagLabel = ac.addLabel(leaderboardWindow, "")
ac.setPosition(flagLabel, w, 8)
ac.setSize(flagLabel, 110, h-8)
ac.setVisible(flagLabel, 0)

# ===============================
# Info Background
leaderboardInfoBackgroundLabel = ac.addLabel(leaderboardWindow, "")
ac.setPosition(leaderboardInfoBackgroundLabel, w, h)
ac.setSize(leaderboardInfoBackgroundLabel, 110, totalDrivers*LeaderboardRow.ROW_HEIGHT + 2)
ac.setBackgroundTexture(leaderboardInfoBackgroundLabel, FC.LEADERBOARD_INFO_BACKGROUNG)

info_button = ac.addButton(leaderboardWindow, "")
ac.setPosition(info_button, w, h)
ac.setSize(info_button, 110, totalDrivers*LeaderboardRow.ROW_HEIGHT + 2)
ac.addOnClickedListener(info_button, on_click_info)
ac.setBackgroundOpacity(info_button, 0)
ac.drawBorder(info_button, 0)

# ===============================
# Driver Widget
driverWidget = DriverWidget(FC.APP_NAME+" Driver")
Expand Down Expand Up @@ -175,6 +189,7 @@ def acUpdate(deltaT):
# LABELS
global leaderboard
global lapCountTimerLabel, leaderboardBaseLabel, leaderboardInfoBackgroundLabel, leaderboardBackgroundLabel
global flagLabel

# ============================
# UPDATE TIMERS
Expand Down Expand Up @@ -260,6 +275,20 @@ def acUpdate(deltaT):
fastest_lap_banner.timer -= timer1
fastest_lap_banner.hide()

# ============================
# FLAGS
if info.graphics.flag == 1:
ac.setBackgroundTexture(flagLabel, FC.BLUE_FLAG)
ac.setVisible(flagLabel, 1)
elif info.graphics.flag == 2:
ac.setBackgroundTexture(flagLabel, FC.YELLOW_FLAG)
ac.setVisible(flagLabel, 1)
elif info.graphics.flag == 5:
ac.setBackgroundTexture(flagLabel, FC.CHECKERED_FLAG)
ac.setVisible(flagLabel, 1)
elif info.graphics.flag == 0:
ac.setVisible(flagLabel, 0)

timer1 = 0

# Once per second
Expand All @@ -284,17 +313,22 @@ def acUpdate(deltaT):
# ===========================
# CALCULATE TIME DIFERENCES
dPosition = sorted(drivers, key=lambda x: x.position)
for i in range(1, len(dPosition)):
driver_ahead, driver = dPosition[i-1], dPosition[i]
timeDiff = driver.split_times[driver.current_split - 1] - driver_ahead.split_times[driver.current_split - 1]
if timeDiff < 0: continue # ignore these times, happens on overtakes
if driver.position > totalDrivers: continue # might try to update before it is possible
driver.timeDiff = timeDiff
if timeDiff > 60:
leaderboard[driver.position].update_time("+1 MIN")
else:
leaderboard[driver.position].update_time("+" + time_to_string(timeDiff*1000))
leaderboard[0].update_time("Interval") # Force it
if LeaderboardRow.update_type == INFO_TYPE.GAPS:
for i in range(1, len(dPosition)):
driver_ahead, driver = dPosition[i-1], dPosition[i]
timeDiff = driver.split_times[driver.current_split - 1] - driver_ahead.split_times[driver.current_split - 1]
if timeDiff < 0: continue # ignore these times, happens on overtakes
if driver.position > totalDrivers: continue # might try to update before it is possible
driver.timeDiff = timeDiff
if timeDiff > 60:
leaderboard[driver.position].update_time("+1 MIN")
else:
leaderboard[driver.position].update_time("+" + time_to_string(timeDiff*1000))
leaderboard[0].update_time("Interval") # Force it
elif LeaderboardRow.update_type == INFO_TYPE.POSITIONS:
for d in dPosition:
posDiff = d.starting_position - d.position - 1
leaderboard[d.position].update_positions(posDiff)

# ============================
# MARK FASTEST LAP
Expand Down Expand Up @@ -561,9 +595,13 @@ def acUpdate(deltaT):
# UPDATE TIMES
if replay_data:
for row in leaderboard:
row.update_time("+" + time_to_string(drivers[row.driverId].timeDiff*1000))
if row.row == 0:
row.update_time("Interval") # Force it
if LeaderboardRow.update_type == INFO_TYPE.GAPS:
row.update_time("+" + time_to_string(drivers[row.driverId].timeDiff*1000))
if row.row == 0:
row.update_time("Interval") # Force it
elif LeaderboardRow.update_type == INFO_TYPE.POSITIONS:
posDiff = drivers[row.driverId].starting_position - drivers[row.driverId].position - 1
row.update_positions(posDiff)

# END UPDATE

Expand All @@ -572,18 +610,6 @@ def acShutdown():
if replay_file:
replay_file.close()

def hide_leaderboard():
global leaderboard_displayed
global leaderboard
global lapCountTimerLabel, leaderboardBaseLabel, leaderboardInfoBackgroundLabel, leaderboardBackgroundLabel
if not leaderboard_displayed: return

def show_leaderboard():
global leaderboard_displayed
global leaderboard
global lapCountTimerLabel, leaderboardBaseLabel, leaderboardInfoBackgroundLabel, leaderboardBackgroundLabel
if leaderboard_displayed: return

def write_driver_info(replay_file, laps, time, drivers):
data = "U %d %d " % (laps, time)
for d in drivers:
Expand Down Expand Up @@ -676,5 +702,8 @@ def lookup_fastest_lap(lap, time, replay_data):
return replay_data['FL'][lap][it-1]
return None


def on_click_info(*args):
# cycle through types
LeaderboardRow.update_type += 1
LeaderboardRow.update_type %= INFO_TYPE.N_TYPES

54 changes: 45 additions & 9 deletions apps/python/F12020Leaderboard/LeaderboardRow.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,22 @@

from constants import FC

class INFO_TYPE:
GAPS = 0
POSITIONS = 1

# amount of types, used to cycle between them
N_TYPES = 2

class LeaderboardRow:
X_BASE = 5
Y_BASE = 84
ROW_HEIGHT = 37
FASTEST_LAP_ID = -1
HIGHLIGHT_ID = -1

update_type = INFO_TYPE.GAPS # false for timings, true for positions lost or gained

def __init__(self, leaderboardWindow, row):
# SET SOME VARIABLES
self.row = row
Expand Down Expand Up @@ -56,19 +66,24 @@ def __init__(self, leaderboardWindow, row):
ac.setFontColor(self.infoLabel, 0.86, 0.86, 0.86, 1)
ac.setFontAlignment(self.infoLabel, "right")

self.positionChangeLabel = ac.addLabel(leaderboardWindow, "")
ac.setPosition(self.positionChangeLabel, 205, py + 4)
ac.setSize(self.positionChangeLabel, 18, 18)
ac.setVisible(self.positionChangeLabel, 0)

self.fastestLapLabel = ac.addLabel(leaderboardWindow, "")
ac.setPosition(self.fastestLapLabel, px-41, py-6)
ac.setSize(self.fastestLapLabel, 37, 37)
ac.setBackgroundTexture(self.fastestLapLabel, FC.LEADERBOARD_FASTEST_LAP);
ac.setVisible(self.fastestLapLabel, 0)

self.button = ac.addButton(leaderboardWindow, "")
ac.setPosition(self.button, px, py-7)
ac.setSize(self.button, 140, 38)
self.on_click_func = functools.partial(self.on_click, row=self)
ac.addOnClickedListener(self.button, self.on_click_func)
ac.setBackgroundOpacity(self.button, 0)
ac.drawBorder(self.button, 0)
self.focus_button = ac.addButton(leaderboardWindow, "")
ac.setPosition(self.focus_button, px, py-7)
ac.setSize(self.focus_button, 140, 38)
self.on_click_focus_func = functools.partial(self.on_click_focus, row=self)
ac.addOnClickedListener(self.focus_button, self.on_click_focus_func)
ac.setBackgroundOpacity(self.focus_button, 0)
ac.drawBorder(self.focus_button, 0)

def update_name(self, id):
if id == ac.getFocusedCar():
Expand All @@ -87,7 +102,21 @@ def update_name(self, id):

def update_time(self, time):
if self.out or self.pit: return # no need to update
ac.setText(self.infoLabel, time)
if self.update_type == INFO_TYPE.GAPS:
ac.setVisible(self.positionChangeLabel, 0)
ac.setText(self.infoLabel, time)

def update_positions(self, pos_diff):
if self.out or self.pit: return # no need to update
if self.update_type == INFO_TYPE.POSITIONS:
ac.setVisible(self.positionChangeLabel, 1)
if pos_diff > 0:
ac.setBackgroundTexture(self.positionChangeLabel, FC.POSITION_GAINED)
elif pos_diff < 0:
ac.setBackgroundTexture(self.positionChangeLabel, FC.POSITION_LOST)
else:
ac.setBackgroundTexture(self.positionChangeLabel, FC.POSITION_MAINTAINED)
ac.setText(self.infoLabel, str(abs(pos_diff)))

def mark_red_position(self):
if self.out or self.positionLabelId == 1: return # no need to update
Expand All @@ -107,6 +136,8 @@ def mark_white_position(self):
def mark_in(self):
if not self.out: return
self.out = False
if LeaderboardRow.update_type == INFO_TYPE.POSITIONS:
ac.setVisible(self.positionChangeLabel, 1)
ac.setVisible(self.positionLabel, 1)
ac.setPosition(self.teamLabel, self.px + 47, self.py + 2)
ac.setPosition(self.nameLabel, self.px + 65, self.py+4)
Expand All @@ -117,6 +148,7 @@ def mark_out(self):
if self.out: return
self.out = True
ac.setVisible(self.positionLabel, 0)
ac.setVisible(self.positionChangeLabel, 0)
ac.setPosition(self.teamLabel, self.px + 12, self.py + 2)
ac.setPosition(self.nameLabel, self.px + 30, self.py+4)
ac.setFontColor(self.nameLabel, .58,.53,.53, 1)
Expand All @@ -126,12 +158,15 @@ def mark_out(self):
def mark_enter_pits(self):
if self.out or self.pit: return
self.pit = True
ac.setVisible(self.positionChangeLabel, 0)
ac.setText(self.infoLabel, "IN PIT")
ac.setFontColor(self.infoLabel, 0,.84,1, 1)

def mark_left_pits(self):
if self.out or not self.pit: return
self.pit = False
if LeaderboardRow.update_type == INFO_TYPE.POSITIONS:
ac.setVisible(self.positionChangeLabel, 1)
if self.driverId == 0:
ac.setText(self.infoLabel, "Interval")
ac.setFontColor(self.infoLabel, 0.86, 0.86, 0.86, 1)
Expand All @@ -143,6 +178,7 @@ def mark_fastest_lap(self):
ac.setVisible(self.fastestLapLabel, 0)

@staticmethod
def on_click(*args, row=None):
def on_click_focus(*args, row=None):
if row:
ac.focusCar(row.driverId)

5 changes: 3 additions & 2 deletions apps/python/F12020Leaderboard/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ class FC:

# FLAGS
YELLOW_FLAG = "apps/python/%s/ui/yellow_flag.png" % APP_NAME
BLUE_FLAG = "apps/python/%s/ui/blue_flag.png" % APP_NAME
YELLOW_FLAG_SECTOR1 = "apps/python/%s/ui/yellow_flag_s1.png" % APP_NAME
YELLOW_FLAG_SECTOR2 = "apps/python/%s/ui/yellow_flag_s2.png" % APP_NAME
YELLOW_FLAG_SECTOR3 = "apps/python/%s/ui/yellow_flag_s3.png" % APP_NAME
GREEN_FLAG = "apps/python/%s/ui/green_flag.png" % APP_NAME
RACE_FLAG = "apps/python/%s/ui/race_flag.png" % APP_NAME
# GREEN_FLAG = "apps/python/%s/ui/green_flag.png" % APP_NAME
CHECKERED_FLAG = "apps/python/%s/ui/race_flag.png" % APP_NAME

# POSITION CHANGED INDICATOR
POSITION_GAINED = "apps/python/%s/ui/position_gained.png" % APP_NAME
Expand Down
Binary file added apps/python/F12020Leaderboard/ui/blue_flag.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed apps/python/F12020Leaderboard/ui/green_flag.png
Binary file not shown.
Binary file modified apps/python/F12020Leaderboard/ui/position_maintained.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/python/F12020Leaderboard/ui/race_flag.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed apps/python/F12020Leaderboard/ui/safety_car.png
Binary file not shown.
Binary file not shown.
Binary file modified apps/python/F12020Leaderboard/ui/yellow_flag.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/python/F12020Leaderboard/ui/yellow_flag_s1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/python/F12020Leaderboard/ui/yellow_flag_s2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/python/F12020Leaderboard/ui/yellow_flag_s3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/screen4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/screen5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 4d7ac94

Please sign in to comment.