update renderer to have cap status also tickets (#1325)

This commit is contained in:
NotSoToothless
2026-06-14 22:36:06 -07:00
committed by GitHub
parent 4b75ce1533
commit deb4e0fb12
4 changed files with 355 additions and 4 deletions
+34 -2
View File
@@ -96,8 +96,8 @@ def replay_data_path(session_id: str | int) -> Path:
# When enabled, the unmodified Spectra payload is stored next to the transformed
# replay (as RAW_replay_data.json.gz) so it can be pulled and re-processed later.
# Toggle off by setting SRE_STORE_RAW_REPLAY=0 in the environment.
STORE_RAW_REPLAY = os.getenv("SRE_STORE_RAW_REPLAY", "1").strip().lower() not in (
"0", "false", "no", "off", "",
STORE_RAW_REPLAY = os.getenv("SRE_STORE_RAW_REPLAY", "0").strip().lower() in (
"1", "true", "yes", "on",
)
@@ -1273,6 +1273,10 @@ def transform_to_local_format(api_data: Dict[str, Any]) -> Optional[Dict[str, An
winner_players: List[Dict[str, Any]] = []
loser_players: List[Dict[str, Any]] = []
# Original Spectra team slots of the winner/loser, captured from the same
# tag match below — used to normalise zones/tickets into winner-first space.
winner_team_slot: Optional[str] = None
loser_team_slot: Optional[str] = None
for uid_str, pdata in players_dict.items():
try:
@@ -1307,8 +1311,12 @@ def transform_to_local_format(api_data: Dict[str, Any]) -> Optional[Dict[str, An
# Assign to winner or loser by comparing tag
if tag == winner_winged:
winner_players.append(player_entry)
if winner_team_slot is None:
winner_team_slot = str(pdata.get("team"))
elif tag == loser_winged:
loser_players.append(player_entry)
if loser_team_slot is None:
loser_team_slot = str(pdata.get("team"))
except (ValueError, TypeError) as e:
logging.warning(f"Skipping bad player UID {uid_str}: {e}")
continue
@@ -1469,6 +1477,26 @@ def transform_to_local_format(api_data: Dict[str, Any]) -> Optional[Dict[str, An
except (ValueError, TypeError):
session_id_hex = ""
# Capture-zone ownership + ticket timelines (Spectra v2+), kept in their
# original team-slot space: cap sign is the owning slot (positive == slot
# "2", negative == slot "1"), and tickets stay keyed by slot ("1"/"2"). Readers decide
# win/loss by comparing the owning slot to `winner_team_slot` — no sign
# flipping or re-keying. center/radius are dropped (geometry comes from
# the mission .blk in resolve_capture_areas()).
raw_zones = replay.get("zones") or {}
raw_tickets = replay.get("tickets") or {}
zones = {
letter: zdata.get("cap", [])
for letter, zdata in raw_zones.items()
if isinstance(zdata, dict)
} if isinstance(raw_zones, dict) else {}
tickets = raw_tickets if isinstance(raw_tickets, dict) else {}
team_slot_names = {}
if winner_team_slot:
team_slot_names[winner_team_slot] = winner_squadron
if loser_team_slot:
team_slot_names[loser_team_slot] = loser_squadron
return {
"winning_team_squadron": winner_squadron,
"losing_team_squadron": loser_squadron,
@@ -1509,6 +1537,10 @@ def transform_to_local_format(api_data: Dict[str, Any]) -> Optional[Dict[str, An
"mission_path": replay.get("mission_path"),
"difficulty": replay.get("difficulty"),
"type": replay.get("type", ""),
"zones": zones,
"tickets": tickets,
"winner_team_slot": winner_team_slot,
"team_slot_names": team_slot_names,
}
except Exception as e: