mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-01 05:33:49 +08:00
Visuals - Custom Themes - Random Events
Enjoy a bit of unpredictability with random events that can occur during certain driving conditions. This is purely cosmetic and has no impact on driving controls!
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import math
|
||||
import random
|
||||
import time
|
||||
import threading
|
||||
from typing import SupportsFloat
|
||||
@@ -194,19 +195,25 @@ class Controls:
|
||||
|
||||
self.always_on_lateral_active = False
|
||||
self.drive_added = False
|
||||
self.fcw_random_event_triggered = False
|
||||
self.holiday_theme_alerted = False
|
||||
self.onroad_distance_pressed = False
|
||||
self.openpilot_crashed_triggered = False
|
||||
self.previous_traffic_mode = False
|
||||
self.previously_enabled = False
|
||||
self.random_event_triggered = False
|
||||
self.speed_check = False
|
||||
self.speed_limit_changed = False
|
||||
self.update_toggles = False
|
||||
self.vCruise69_alert_played = False
|
||||
|
||||
self.display_timer = 0
|
||||
self.drive_distance = 0
|
||||
self.drive_time = 0
|
||||
self.max_acceleration = 0
|
||||
self.previous_speed_limit = 0
|
||||
self.previous_v_cruise = 0
|
||||
self.random_event_timer = 0
|
||||
self.speed_limit_timer = 0
|
||||
|
||||
def set_initial_state(self):
|
||||
@@ -410,6 +417,11 @@ class Controls:
|
||||
planner_fcw = self.sm['longitudinalPlan'].fcw and self.enabled
|
||||
if (planner_fcw or model_fcw) and not (self.CP.notCar and self.joystick_mode):
|
||||
self.events.add(EventName.fcw)
|
||||
self.fcw_random_event_triggered = not self.random_event_triggered
|
||||
elif self.fcw_random_event_triggered and self.frogpilot_toggles.random_events:
|
||||
self.events.add(EventName.yourFrogTriedToKillMe)
|
||||
self.fcw_random_event_triggered = False
|
||||
self.random_event_triggered = True
|
||||
|
||||
for m in messaging.drain_sock(self.log_sock, wait_for_one=False):
|
||||
try:
|
||||
@@ -664,8 +676,18 @@ class Controls:
|
||||
turning = abs(lac_log.desiredLateralAccel) > 1.0
|
||||
good_speed = CS.vEgo > 5
|
||||
max_torque = abs(self.sm['carOutput'].actuatorsOutput.steer) > 0.99
|
||||
if undershooting and turning and good_speed and max_torque:
|
||||
lac_log.active and self.events.add(EventName.goatSteerSaturated if self.frogpilot_toggles.goat_scream else EventName.steerSaturated)
|
||||
if undershooting and turning and good_speed and max_torque and not self.random_event_triggered:
|
||||
event_choices = [1, 2]
|
||||
if self.sm.frame % (10000 // len(event_choices)) == 0 and self.frogpilot_toggles.random_events:
|
||||
event_choice = random.choice(event_choices)
|
||||
if event_choice == 1:
|
||||
lac_log.active and self.events.add(EventName.firefoxSteerSaturated)
|
||||
self.params_memory.put_int("CurrentRandomEvent", 1)
|
||||
elif event_choice == 2:
|
||||
lac_log.active and self.events.add(EventName.goatSteerSaturated)
|
||||
self.random_event_triggered = True
|
||||
else:
|
||||
lac_log.active and self.events.add(EventName.goatSteerSaturated if self.frogpilot_toggles.goat_scream else EventName.steerSaturated)
|
||||
elif lac_log.saturated:
|
||||
# TODO probably should not use dpath_points but curvature
|
||||
dpath_points = model_v2.position.y
|
||||
@@ -926,9 +948,56 @@ class Controls:
|
||||
self.events.add(EventName.leadDeparting)
|
||||
|
||||
if not self.openpilot_crashed_triggered and os.path.isfile(os.path.join(sentry.CRASHES_DIR, 'error.txt')):
|
||||
self.events.add(EventName.openpilotCrashed)
|
||||
if self.frogpilot_toggles.random_events:
|
||||
self.events.add(EventName.openpilotCrashedRandomEvents)
|
||||
else:
|
||||
self.events.add(EventName.openpilotCrashed)
|
||||
self.openpilot_crashed_triggered = True
|
||||
|
||||
if self.frogpilot_toggles.random_events:
|
||||
acceleration = CS.aEgo
|
||||
|
||||
if not CS.gasPressed:
|
||||
self.max_acceleration = max(acceleration, self.max_acceleration)
|
||||
else:
|
||||
self.max_acceleration = 0
|
||||
|
||||
if 3.5 > self.max_acceleration >= 3.0 and acceleration < 1.5:
|
||||
self.events.add(EventName.accel30)
|
||||
self.params_memory.put_int("CurrentRandomEvent", 2)
|
||||
self.random_event_triggered = True
|
||||
self.max_acceleration = 0
|
||||
|
||||
elif 4.0 > self.max_acceleration >= 3.5 and acceleration < 1.5:
|
||||
self.events.add(EventName.accel35)
|
||||
self.params_memory.put_int("CurrentRandomEvent", 3)
|
||||
self.random_event_triggered = True
|
||||
self.max_acceleration = 0
|
||||
|
||||
elif self.max_acceleration >= 4.0 and acceleration < 1.5:
|
||||
self.events.add(EventName.accel40)
|
||||
self.params_memory.put_int("CurrentRandomEvent", 4)
|
||||
self.random_event_triggered = True
|
||||
self.max_acceleration = 0
|
||||
|
||||
if self.sm['frogpilotPlan'].takingCurveQuickly:
|
||||
self.events.add(EventName.dejaVuCurve)
|
||||
self.params_memory.put_int("CurrentRandomEvent", 5)
|
||||
self.random_event_triggered = True
|
||||
|
||||
conversion = 1 if self.is_metric else CV.KPH_TO_MPH
|
||||
v_cruise = max(self.v_cruise_helper.v_cruise_kph, self.v_cruise_helper.v_cruise_cluster_kph) * conversion
|
||||
|
||||
if 70 > v_cruise >= 69:
|
||||
if self.sm.frame % 25 == 0:
|
||||
if v_cruise == self.previous_v_cruise and not self.vCruise69_alert_played:
|
||||
self.events.add(EventName.vCruise69)
|
||||
self.vCruise69_alert_played = True
|
||||
self.previous_v_cruise = v_cruise
|
||||
else:
|
||||
self.vCruise69_alert_played = False
|
||||
self.previous_v_cruise = v_cruise
|
||||
|
||||
if self.frogpilot_toggles.speed_limit_alert and self.speed_limit_changed:
|
||||
self.events.add(EventName.speedLimitChanged)
|
||||
|
||||
@@ -990,6 +1059,13 @@ class Controls:
|
||||
self.previously_enabled |= (self.enabled or self.always_on_lateral_active) and CS.vEgo > CRUISING_SPEED
|
||||
self.previously_enabled &= driving_gear
|
||||
|
||||
if self.random_event_triggered:
|
||||
self.random_event_timer += DT_CTRL
|
||||
if self.random_event_timer >= 4:
|
||||
self.random_event_triggered = False
|
||||
self.random_event_timer = 0
|
||||
self.params_memory.remove("CurrentRandomEvent")
|
||||
|
||||
self.speed_check = CS.vEgo >= self.frogpilot_toggles.pause_lateral_below_speed
|
||||
self.speed_check |= self.frogpilot_toggles.pause_lateral_below_signal and not (CS.leftBlinker or CS.rightBlinker)
|
||||
self.speed_check |= CS.standstill
|
||||
|
||||
@@ -1109,6 +1109,71 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .1, alert_rate=0.75),
|
||||
},
|
||||
|
||||
# Random Events
|
||||
EventName.accel30: {
|
||||
ET.WARNING: Alert(
|
||||
"UwU u went a bit fast there!",
|
||||
"(⁄ ⁄•⁄ω⁄•⁄ ⁄)",
|
||||
AlertStatus.frogpilot, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.uwu, 4.),
|
||||
},
|
||||
|
||||
EventName.accel35: {
|
||||
ET.WARNING: Alert(
|
||||
"I ain't giving you no tree-fiddy",
|
||||
"you damn Loch Ness monsta!",
|
||||
AlertStatus.frogpilot, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.nessie, 4.),
|
||||
},
|
||||
|
||||
EventName.accel40: {
|
||||
ET.WARNING: Alert(
|
||||
"Great Scott!",
|
||||
"🚗💨",
|
||||
AlertStatus.frogpilot, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.doc, 4.),
|
||||
},
|
||||
|
||||
EventName.dejaVuCurve: {
|
||||
ET.WARNING: Alert(
|
||||
"♬♪ Deja Vu! ᕕ(⌐■_■)ᕗ ♪♬",
|
||||
"🏎️",
|
||||
AlertStatus.frogpilot, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.dejaVu, 4.),
|
||||
},
|
||||
|
||||
EventName.firefoxSteerSaturated: {
|
||||
ET.WARNING: Alert(
|
||||
"Turn Exceeds Steering Limit",
|
||||
"IE Has Stopped Responding...",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.firefox, 4.),
|
||||
},
|
||||
|
||||
EventName.openpilotCrashedRandomEvents: {
|
||||
ET.PERMANENT: Alert(
|
||||
"openpilot crashed 💩",
|
||||
"Please post the error log in the FrogPilot Discord!",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.HIGHEST, VisualAlert.none, AudibleAlert.fart, 10.),
|
||||
},
|
||||
|
||||
EventName.vCruise69: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Lol 69",
|
||||
"",
|
||||
AlertStatus.frogpilot, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.noice, 2.),
|
||||
},
|
||||
|
||||
EventName.yourFrogTriedToKillMe: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Your frog tried to kill me...",
|
||||
"👺",
|
||||
AlertStatus.frogpilot, AlertSize.mid,
|
||||
Priority.MID, VisualAlert.none, AudibleAlert.angry, 5.),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 940 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 515 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 445 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 123 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -49,6 +49,7 @@ class FrogPilotPlanner:
|
||||
self.override_force_stop = False
|
||||
self.override_slc = False
|
||||
self.slower_lead = False
|
||||
self.taking_curve_quickly = False
|
||||
self.tracking_lead = False
|
||||
|
||||
self.acceleration_jerk = 0
|
||||
@@ -103,6 +104,9 @@ class FrogPilotPlanner:
|
||||
self.model_length = modelData.position.x[TRAJECTORY_SIZE - 1]
|
||||
self.road_curvature = abs(float(calculate_road_curvature(modelData, v_ego)))
|
||||
|
||||
if frogpilot_toggles.random_events:
|
||||
self.taking_curve_quickly = v_ego > (1 / self.road_curvature)**0.5 * 2 > CRUISING_SPEED * 2 and abs(carState.steeringAngleDeg) > 30
|
||||
|
||||
if v_ego > CRUISING_SPEED:
|
||||
self.override_force_stop = False
|
||||
self.tracking_lead = self.lead_one.status
|
||||
@@ -321,6 +325,8 @@ class FrogPilotPlanner:
|
||||
frogpilotPlan.slcSpeedLimitOffset = SpeedLimitController.offset
|
||||
frogpilotPlan.unconfirmedSlcSpeedLimit = SpeedLimitController.desired_speed_limit
|
||||
|
||||
frogpilotPlan.takingCurveQuickly = bool(self.taking_curve_quickly)
|
||||
|
||||
frogpilotPlan.vCruise = float(self.v_cruise)
|
||||
|
||||
pm.send('frogpilotPlan', frogpilot_plan_send)
|
||||
|
||||
@@ -19,6 +19,18 @@ void drawIcon(QPainter &p, const QPoint ¢er, const QPixmap &img, const QBrus
|
||||
p.restore();
|
||||
}
|
||||
|
||||
void drawIconGif(QPainter &p, const QPoint ¢er, const QMovie &img, const QBrush &bg, float opacity) {
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setOpacity(1.0); // bg dictates opacity of ellipse
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(bg);
|
||||
p.drawEllipse(center.x() - btn_size / 2, center.y() - btn_size / 2, btn_size, btn_size);
|
||||
p.setOpacity(opacity);
|
||||
QPixmap currentFrame = img.currentPixmap();
|
||||
p.drawPixmap(center - QPoint(currentFrame.width() / 2, currentFrame.height() / 2), currentFrame);
|
||||
p.setOpacity(1.0);
|
||||
}
|
||||
|
||||
// ExperimentalButton
|
||||
ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(false), engageable(false), QPushButton(parent) {
|
||||
setFixedSize(btn_size, btn_size);
|
||||
@@ -36,6 +48,13 @@ ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(fals
|
||||
{5, loadPixmap("../frogpilot/assets/wheel_images/hyundai.png", {img_size, img_size})},
|
||||
{6, loadPixmap("../frogpilot/assets/wheel_images/stalin.png", {img_size, img_size})},
|
||||
};
|
||||
|
||||
wheelImagesGif = {
|
||||
{0, new QMovie("../frogpilot/assets/random_events/images/firefox.gif", QByteArray(), this)},
|
||||
{1, new QMovie("../frogpilot/assets/random_events/images/weeb_wheel.gif", QByteArray(), this)},
|
||||
{2, new QMovie("../frogpilot/assets/random_events/images/tree_fiddy.gif", QByteArray(), this)},
|
||||
{3, new QMovie("../frogpilot/assets/random_events/images/great_scott.gif", QByteArray(), this)},
|
||||
};
|
||||
}
|
||||
|
||||
void ExperimentalButton::changeMode() {
|
||||
@@ -67,13 +86,33 @@ void ExperimentalButton::updateState(const UIState &s) {
|
||||
conditionalExperimental = scene.conditional_experimental;
|
||||
conditionalStatus = scene.conditional_status;
|
||||
navigateOnOpenpilot = scene.navigate_on_openpilot;
|
||||
randomEvent = scene.current_random_event;
|
||||
rotatingWheel = scene.rotating_wheel;
|
||||
trafficModeActive = scene.traffic_mode_active;
|
||||
wheelIcon = scene.wheel_icon;
|
||||
wheelIconGif = 0;
|
||||
|
||||
if (rotatingWheel && steeringAngleDeg != scene.steering_angle_deg) {
|
||||
if (randomEvent == 0 && gifLabel) {
|
||||
delete gifLabel;
|
||||
gifLabel = nullptr;
|
||||
} else if (randomEvent == 1 || randomEvent == 2 || randomEvent == 3 || randomEvent == 4) {
|
||||
if (!gifLabel) {
|
||||
gifLabel = new QLabel(this);
|
||||
QMovie *movie = wheelImagesGif[randomEvent - 1];
|
||||
if (movie) {
|
||||
gifLabel->setMovie(movie);
|
||||
gifLabel->setFixedSize(img_size, img_size);
|
||||
gifLabel->move((width() - gifLabel->width()) / 2, (height() - gifLabel->height()) / 2);
|
||||
gifLabel->movie()->start();
|
||||
}
|
||||
}
|
||||
|
||||
gifLabel->show();
|
||||
wheelIconGif = randomEvent - 1;
|
||||
update();
|
||||
} else if (rotatingWheel && steeringAngleDeg != scene.steering_angle_deg) {
|
||||
steeringAngleDeg = scene.steering_angle_deg;
|
||||
update();
|
||||
} else if (!rotatingWheel) {
|
||||
steeringAngleDeg = 0;
|
||||
}
|
||||
@@ -87,6 +126,7 @@ void ExperimentalButton::paintEvent(QPaintEvent *event) {
|
||||
QPainter p(this);
|
||||
engage_img = wheelImages[wheelIcon];
|
||||
QPixmap img = wheelIcon != 0 ? engage_img : (experimental_mode ? experimental_img : engage_img);
|
||||
QMovie *gif = wheelImagesGif[wheelIconGif];
|
||||
|
||||
QColor background_color = wheelIcon != 0 && !isDown() && engageable ?
|
||||
(alwaysOnLateralActive ? bg_colors[STATUS_ALWAYS_ON_LATERAL_ACTIVE] :
|
||||
@@ -96,7 +136,11 @@ void ExperimentalButton::paintEvent(QPaintEvent *event) {
|
||||
(navigateOnOpenpilot ? bg_colors[STATUS_NAVIGATION_ACTIVE] : QColor(0, 0, 0, 166)))))) :
|
||||
QColor(0, 0, 0, 166);
|
||||
|
||||
drawIcon(p, QPoint(btn_size / 2, btn_size / 2), img, QColor(0, 0, 0, 166), (isDown() || !engageable) ? 0.6 : 1.0, steeringAngleDeg);
|
||||
if (wheelIconGif != 0) {
|
||||
drawIconGif(p, QPoint(btn_size / 2, btn_size / 2), *gif, background_color, 1.0);
|
||||
} else {
|
||||
drawIcon(p, QPoint(btn_size / 2, btn_size / 2), img, background_color, (isDown() || !engageable) ? 0.6 : 1.0, steeringAngleDeg);
|
||||
}
|
||||
}
|
||||
|
||||
// MapSettingsButton
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <QLabel>
|
||||
#include <QMovie>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "selfdrive/ui/ui.h"
|
||||
@@ -32,10 +34,15 @@ private:
|
||||
bool trafficModeActive;
|
||||
|
||||
int conditionalStatus;
|
||||
int randomEvent;
|
||||
int steeringAngleDeg;
|
||||
int wheelIcon;
|
||||
int wheelIconGif;
|
||||
|
||||
QLabel *gifLabel;
|
||||
|
||||
QMap<int, QPixmap> wheelImages;
|
||||
QMap<int, QMovie*> wheelImagesGif;
|
||||
|
||||
Params paramsMemory{"/dev/shm/params"};
|
||||
};
|
||||
|
||||
+33
-4
@@ -41,6 +41,16 @@ sound_list: dict[int, tuple[str, int | None, float]] = {
|
||||
AudibleAlert.warningSoft: ("warning_soft.wav", None, MAX_VOLUME),
|
||||
AudibleAlert.warningImmediate: ("warning_immediate.wav", None, MAX_VOLUME),
|
||||
|
||||
# Random Events
|
||||
AudibleAlert.angry: ("angry.wav", 1, MAX_VOLUME),
|
||||
AudibleAlert.dejaVu: ("dejaVu.wav", 1, MAX_VOLUME),
|
||||
AudibleAlert.doc: ("doc.wav", 1, MAX_VOLUME),
|
||||
AudibleAlert.fart: ("fart.wav", 1, MAX_VOLUME),
|
||||
AudibleAlert.firefox: ("firefox.wav", 1, MAX_VOLUME),
|
||||
AudibleAlert.nessie: ("nessie.wav", 1, MAX_VOLUME),
|
||||
AudibleAlert.noice: ("noice.wav", 1, MAX_VOLUME),
|
||||
AudibleAlert.uwu: ("uwu.wav", 1, MAX_VOLUME),
|
||||
|
||||
# Other
|
||||
AudibleAlert.goat: ("goat.wav", None, MAX_VOLUME),
|
||||
}
|
||||
@@ -69,6 +79,19 @@ class Soundd:
|
||||
self.frogpilot_toggles = FrogPilotVariables.toggles
|
||||
|
||||
self.previous_sound_directory = None
|
||||
self.random_events_directory = BASEDIR + "/selfdrive/frogpilot/assets/random_events/sounds/"
|
||||
|
||||
self.random_events_map = {
|
||||
AudibleAlert.angry: MAX_VOLUME,
|
||||
AudibleAlert.dejaVu: MAX_VOLUME,
|
||||
AudibleAlert.doc: MAX_VOLUME,
|
||||
AudibleAlert.fart: MAX_VOLUME,
|
||||
AudibleAlert.firefox: MAX_VOLUME,
|
||||
AudibleAlert.goat: MAX_VOLUME,
|
||||
AudibleAlert.nessie: MAX_VOLUME,
|
||||
AudibleAlert.noice: MAX_VOLUME,
|
||||
AudibleAlert.uwu: MAX_VOLUME,
|
||||
}
|
||||
|
||||
self.update_toggles = False
|
||||
|
||||
@@ -81,12 +104,15 @@ class Soundd:
|
||||
for sound in sound_list:
|
||||
filename, play_count, volume = sound_list[sound]
|
||||
|
||||
try:
|
||||
if sound in self.random_events_map:
|
||||
wavefile = wave.open(self.random_events_directory + filename, 'r')
|
||||
else:
|
||||
if sound == AudibleAlert.goat and not self.frogpilot_toggles.goat_scream:
|
||||
continue
|
||||
wavefile = wave.open(self.sound_directory + filename, 'r')
|
||||
except FileNotFoundError:
|
||||
wavefile = wave.open(BASEDIR + "/selfdrive/assets/sounds/" + filename, 'r')
|
||||
try:
|
||||
wavefile = wave.open(self.sound_directory + filename, 'r')
|
||||
except FileNotFoundError:
|
||||
wavefile = wave.open(BASEDIR + "/selfdrive/assets/sounds/" + filename, 'r')
|
||||
|
||||
assert wavefile.getnchannels() == 1
|
||||
assert wavefile.getsampwidth() == 2
|
||||
@@ -172,6 +198,9 @@ class Soundd:
|
||||
elif self.frogpilot_toggles.alert_volume_control and self.current_alert in self.volume_map:
|
||||
self.current_volume = self.volume_map[self.current_alert] / 100.0
|
||||
|
||||
elif self.current_alert in self.random_events_map:
|
||||
self.current_volume = self.random_events_map[self.current_alert]
|
||||
|
||||
self.get_audible_alert(sm)
|
||||
|
||||
rk.keep_time()
|
||||
|
||||
@@ -335,6 +335,7 @@ void ui_update_frogpilot_params(UIState *s) {
|
||||
scene.custom_icons = custom_theme ? params.getInt("CustomIcons") : 0;
|
||||
scene.custom_signals = custom_theme ? params.getInt("CustomSignals") : 0;
|
||||
scene.holiday_themes = custom_theme && params.getBool("HolidayThemes");
|
||||
scene.random_events = custom_theme && params.getBool("RandomEvents");
|
||||
|
||||
scene.disable_smoothing_mtsc = params.getBool("MTSCEnabled") && params.getBool("DisableMTSCSmoothing");
|
||||
scene.disable_smoothing_vtsc = params.getBool("VisionTurnControl") && params.getBool("DisableVTSCSmoothing");
|
||||
@@ -447,6 +448,7 @@ void UIState::update() {
|
||||
// FrogPilot variables that need to be constantly updated
|
||||
scene.conditional_status = scene.conditional_experimental && scene.enabled ? paramsMemory.getInt("CEStatus") : 0;
|
||||
scene.current_holiday_theme = scene.holiday_themes ? paramsMemory.getInt("CurrentHolidayTheme") : 0;
|
||||
scene.current_random_event = scene.random_events ? paramsMemory.getInt("CurrentRandomEvent") : 0;
|
||||
}
|
||||
|
||||
void UIState::setPrimeType(PrimeType type) {
|
||||
|
||||
@@ -144,6 +144,7 @@ typedef struct UIScene {
|
||||
bool onroad_distance_button;
|
||||
bool parked;
|
||||
bool pedals_on_ui;
|
||||
bool random_events;
|
||||
bool reverse;
|
||||
bool reverse_cruise;
|
||||
bool reverse_cruise_ui;
|
||||
@@ -186,6 +187,7 @@ typedef struct UIScene {
|
||||
int conditional_speed_lead;
|
||||
int conditional_status;
|
||||
int current_holiday_theme;
|
||||
int current_random_event;
|
||||
int custom_colors;
|
||||
int custom_icons;
|
||||
int custom_signals;
|
||||
|
||||
Reference in New Issue
Block a user