diff --git a/dashleague_cast_tool.py b/dashleague_cast_tool.py
index 3f5879e..73d4386 100644
--- a/dashleague_cast_tool.py
+++ b/dashleague_cast_tool.py
@@ -1417,37 +1417,134 @@ class DashLeagueGUI:
from analysis.rookie_leaderboard import rank_rookies_by_tag
season = self.current_season
tag = "slayer"
-
+
rookies = rank_rookies_by_tag(season, tag)
+ # 1. Text display for the GUI window
lines = []
lines.append(f"ROOKIE LEADERBOARD — Season {season}")
lines.append("Rookies: < 50 maps and < 1000 kills.")
lines.append("")
- # Updated Header
lines.append(f"{'Rank':<5} {'Name':<18} {'Team':<12} {'Score':<10} {'KD':<6} {'Maps':<6} {'Kills':<8}")
lines.append("-" * 75)
for r in rookies:
- # Format thousands for score (e.g. 96,107)
score_str = f"{int(r['score']):,}"
kd_str = f"{r['kd']:.2f}"
maps_str = f"{int(r['maps'])}"
kills_str = f"{int(r['kills'])}"
-
lines.append(f"{r['rank']:<5} {r['name']:<18} {r['team']:<12} {score_str:<10} {kd_str:<6} {maps_str:<6} {kills_str:<8}")
text = "\n".join(lines)
win = tk.Toplevel(self.root)
win.title("Rookie Standings")
- win.geometry("800x550")
+ win.geometry("800x600")
output = tk.Text(win, wrap="none", font=("Courier", 10))
output.pack(expand=True, fill="both", padx=10, pady=10)
output.insert(tk.END, text)
output.config(state="disabled")
+ # 2. HTML Export function for OBS Browser Source
+ def export_html():
+ html_rows = ""
+ for r in rookies:
+ html_rows += f"""
+
+ | #{r['rank']} |
+ {r['name']} |
+ {r['team']} |
+ {int(r['score']):,} |
+ {r['kd']:.2f} |
+ {int(r['kills'])} |
+ {int(r['maps'])} |
+
+ """
+
+ html_content = f"""
+
+
+
+
+
+
+ Rookie Leaderboard
+ Season {season} | < 50 maps and < 1000 kills
+
+
+ | Rank |
+ Name |
+ Team |
+ Score |
+ KD |
+ Kills |
+ Maps |
+
+ {html_rows}
+
+
+
+ """
+ # Save to exports folder
+ html_path = os.path.join(OBS_EXPORT_DIR, "rookie_leaderboard.html")
+ with open(html_path, "w", encoding="utf-8") as f:
+ f.write(html_content)
+
+ self.set_status("Exported Rookie HTML (incl. Kills)")
+ messagebox.showinfo("Exported", f"HTML updated\nLocation: {html_path}")
+
+ # Add button to pop-up window
+ ttk.Button(win, text="Export HTML for OBS Browser Source", command=export_html).pack(pady=10)
+
def export_all_obs_files(self):
"""
diff --git a/utils/graphics_engine.py b/utils/graphics_engine.py
index 434c8c1..658b277 100644
--- a/utils/graphics_engine.py
+++ b/utils/graphics_engine.py
@@ -163,7 +163,7 @@ def generate_team_dna(rosterA, rosterB, nameA, nameB):
img.save(DNA_PATH)
def draw_vs_donut(draw, center, radius, valA, valB, colorA, colorB, label):
- """Draws a split donut showing relative strength between two teams."""
+ """Draws a split donut showing relative strength, matching screen sides perfectly."""
cx, cy = center
width = 35
total = valA + valB
@@ -171,23 +171,27 @@ def draw_vs_donut(draw, center, radius, valA, valB, colorA, colorB, label):
valA, valB = 50, 50
total = 100
- # Percentages of the circle
pctA = valA / total
- # Background circle
+ # Draw background circle
draw.ellipse([cx-radius, cy-radius, cx+radius, cy+radius], outline=(40, 40, 45), width=width)
- # Arcs
- start_angle = -90
- split_angle = start_angle + (360 * pctA)
+ # --- SWAP CORRECTION ---
+ # We start at 90 degrees (6 o'clock) and draw clockwise.
+ # This aligns Team A (Blue, Left) with the Left Side of the donut,
+ # and Team B (Red, Right) with the Right Side.
+ startA = 90
+ endA = startA + (360 * pctA)
- # Blue Arc (Team A)
- draw.arc([cx-radius, cy-radius, cx+radius, cy+radius], start=start_angle, end=split_angle, fill=colorA, width=width)
- # Red Arc (Team B)
- draw.arc([cx-radius, cy-radius, cx+radius, cy+radius], start=split_angle, end=start_angle + 360, fill=colorB, width=width)
+ # Blue Arc (Team A - Left side)
+ draw.arc([cx-radius, cy-radius, cx+radius, cy+radius], start=startA, end=endA, fill=colorA, width=width)
+ # Red Arc (Team B - Right side)
+ draw.arc([cx-radius, cy-radius, cx+radius, cy+radius], start=endA, end=startA + 360, fill=colorB, width=width)
# Center Text
- draw.text((cx, cy), f"{int((valA/total)*100)}% | {int((valB/total)*100)}%", font=get_font(45), fill=(255, 255, 255), anchor="mm")
+ pctA_display = int((valA/total)*100)
+ pctB_display = 100 - pctA_display
+ draw.text((cx, cy), f"{pctA_display}% | {pctB_display}%", font=get_font(45), fill=(255, 255, 255), anchor="mm")
draw.text((cx, cy + radius + 60), label, font=get_font(40), fill=(180, 180, 180), anchor="mm")
def generate_win_probability(rosterA, rosterB, nameA, nameB):