Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,18 @@ promoted to stable releases (see [docs/VERSIONING.md](docs/VERSIONING.md)); the
(`ailists_#user.cfg` and `car_use/!openomsi-ai-lists-*.ocu` of the map's folder, the format OMSI
itself reads), a group or a line can be reset on its own, and *Reset the map* deletes them, which
gives the map's defaults back. Translated into every language of the launcher.
- **Interface themes**: a mod or a plugin can give the game's own screens a look of their own,
chosen in Options › Interface › Theme pack ([docs/THEMES.md](docs/THEMES.md)). A theme is a
folder with a `theme.json` (`Themes/<id>/` of a content folder, or a plugin's own folder): the
colours of the pause menu, its settings windows and lists, the photo mode, the developer tools
and the plugins' panels and notifications; the corners of the panels; the panels as frosted
glass over the game's picture (blurred on the graphics card every frame the menu is open); the
logo and the name at the top of the pause menu; and the
loading screen's colours and logo, which can itself be the loading bar - its path
`id="progress"` drawn along, or the logo filled from the left, as far as the loading is - and
parts of the logo marked `data-at` pop up (or, `data-blink`, flash) as the loading reaches them.
openOMSI's own look is unchanged and stays the default. Plugins see the themes with
`ui.themes` and `ui.theme` and can switch to one with `ui.set_theme` (`omsi.ui.version` 7).
- **LAN protocol 15**: a game of this version cannot join a session of an older one, nor the
other way round (the AI traffic goes as a table, see below). Update the game on both sides.
- **Every light casts a shadow** (Enhanced and Enhanced+): the lamps' shadow maps were four, now
Expand Down
60 changes: 60 additions & 0 deletions crates/omsi-app/locales/app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52894,6 +52894,66 @@ _version: 2
sv: "Hastigheter, avstånd och temperaturer i spelets texter"
sr: "Brzine, udaljenosti i temperature u sopstvenim tekstovima igre"
ka: "სიჩქარეები, მანძილები და ტემპერატურები თამაშის ტექსტებში"
"Theme pack":
ca: "Paquet de tema"
ru: "Пакет оформления"
de: "Designpaket"
fr: "Pack de thème"
uk: "Пакет оформлення"
be: "Пакет афармлення"
kk: "Безендіру жинағы"
pl: "Pakiet motywu"
cs: "Balíček motivu"
hu: "Témacsomag"
es: "Paquete de tema"
pt: "Pacote de tema"
pt-pt: "Pacote de tema"
it: "Pacchetto tema"
nl: "Themapakket"
tr: "Tema paketi"
ja: "テーマパック"
zh: "主题包"
hi: "थीम पैक"
zh-tw: "主題包"
ko: "테마 팩"
th: "แพ็กธีม"
vi: "Gói giao diện"
id: "Paket tema"
ms: "Pek tema"
tl: "Theme pack"
sv: "Temapaket"
sr: "Paket teme"
ka: "თემის პაკეტი"
"The look of the menus, the panels and the loading screen: openOMSI's own, or one a mod or plugin brings":
ca: "L'aspecte dels menús, dels panells i de la pantalla de càrrega: el d'openOMSI, o un que porti un mod o un connector"
ru: "Вид меню, панелей и экрана загрузки: собственный вид openOMSI или тема из мода или плагина"
de: "Das Aussehen der Menüs, der Tafeln und des Ladebildschirms: das von openOMSI oder eines, das ein Mod oder Plugin mitbringt"
fr: "L'apparence des menus, des panneaux et de l'écran de chargement : celle d'openOMSI, ou celle qu'apporte un mod ou un plugin"
uk: "Вигляд меню, панелей і екрана завантаження: власний вигляд openOMSI або тема з мода чи плагіна"
be: "Выгляд меню, панэляў і экрана загрузкі: уласны выгляд openOMSI або тэма з мода ці плагіна"
kk: "Мәзірлердің, панельдердің және жүктеу экранының көрінісі: openOMSI-дің өз көрінісі немесе мод не плагин әкелген тақырып"
pl: "Wygląd menu, paneli i ekranu ładowania: własny wygląd openOMSI albo motyw z moda lub wtyczki"
cs: "Vzhled nabídek, panelů a načítací obrazovky: vlastní vzhled openOMSI, nebo motiv z modu či pluginu"
hu: "A menük, a panelek és a betöltőképernyő megjelenése: az openOMSI sajátja, vagy egy mod vagy bővítmény által hozott téma"
es: "El aspecto de los menús, los paneles y la pantalla de carga: el propio de openOMSI o uno que traiga un mod o un plugin"
pt: "A aparência dos menus, dos painéis e da tela de carregamento: a do próprio openOMSI ou uma trazida por um mod ou plugin"
pt-pt: "O aspeto dos menus, dos painéis e do ecrã de carregamento: o do próprio openOMSI ou um trazido por um mod ou plugin"
it: "L'aspetto dei menu, dei pannelli e della schermata di caricamento: quello di openOMSI o uno portato da una mod o da un plugin"
nl: "Hoe de menu's, de panelen en het laadscherm eruitzien: zoals in openOMSI zelf, of een look die een mod of plugin meebrengt"
tr: "Menülerin, panellerin ve yükleme ekranının görünümü: openOMSI'nin kendi görünümü ya da bir mod veya eklentinin getirdiği bir tema"
ja: "メニュー、パネル、ロード画面の見た目:openOMSI 標準のもの、または Mod やプラグインが提供するもの"
zh: "菜单、面板和加载画面的外观:openOMSI 自带的,或由模组或插件提供的"
hi: "मेनू, पैनल और लोडिंग स्क्रीन का रूप: openOMSI का अपना, या किसी मॉड या प्लगइन द्वारा लाया गया"
zh-tw: "選單、面板和載入畫面的外觀:openOMSI 內建的,或由模組或外掛提供的"
ko: "메뉴, 패널, 로딩 화면의 모양: openOMSI 기본 모양 또는 모드나 플러그인이 제공하는 테마"
th: "หน้าตาของเมนู แผง และหน้าจอโหลด: แบบของ openOMSI เอง หรือแบบที่ม็อดหรือปลั๊กอินนำมา"
vi: "Giao diện của menu, bảng điều khiển và màn hình tải: của chính openOMSI, hoặc do một mod hay plugin mang lại"
id: "Tampilan menu, panel, dan layar pemuatan: bawaan openOMSI, atau yang dibawa oleh mod atau plugin"
ms: "Rupa menu, panel dan skrin pemuatan: rupa openOMSI sendiri, atau yang dibawa oleh mod atau pemalam"
tl: "Ang itsura ng mga menu, mga panel at ng loading screen: ang sariling itsura ng openOMSI, o isang dala ng mod o plugin"
sv: "Utseendet på menyerna, panelerna och laddningsskärmen: openOMSI:s eget, eller ett som en mod eller ett tillägg har med sig"
sr: "Izgled menija, panela i ekrana za učitavanje: sopstveni izgled openOMSI-ja ili tema koju donosi mod ili dodatak"
ka: "მენიუების, პანელების და ჩატვირთვის ეკრანის იერსახე: openOMSI-ის საკუთარი, ან მოდის ან დანამატის მიერ მოტანილი"
"Metric (km/h, km, °C)":
ca: "Mètric (km/h, km, °C)"
ru: "Метрические (км/ч, км, °C)"
Expand Down
1 change: 1 addition & 0 deletions crates/omsi-app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,7 @@ impl App {
/// One loading screen picture (the map, or our bus going to the server): `title`, bar at `shown`.
fn loading_frame(&mut self, renderer: omsi_render::Renderer, mut scene: Scene, title: &str, shown: f32) {
let mut reconfigure = false;
crate::themes::sync(&self.settings.ui_theme_pack, self.settings.is_light_theme());
if let (Some(ui), Some(s), Some(win)) = (
self.ui.as_mut(),
self.gfx.surface.as_ref(),
Expand Down
29 changes: 28 additions & 1 deletion crates/omsi-app/src/app_events/frame/integrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ impl App {
steam.client.run_callbacks();
}
// the plugins' frame, with the bus's scripts done
let mut plugins = self.integrations.plugins.take().unwrap_or_else(crate::plugins::load);
// (their main chunk already knows the interface themes: `ui.themes`, `ui.theme`)
let mut plugins = self.integrations.plugins.take().unwrap_or_else(|| {
omsi_plugin::ui::themes_for_load(theme_infos(), &self.settings.ui_theme_pack);
crate::plugins::load()
});
self.sync_vehicle_scripts(&mut plugins);
if !self.paused && !omsi_cfg::flags::OMSI_NO_PLUGINS.is_set() {
crate::plugin_io::object::drive(self, &mut plugins, dt);
Expand All @@ -54,6 +58,16 @@ impl App {
// the mouse on the plugins' script textures since their frame, and which those are now
plugins.pointer = std::mem::take(&mut self.integrations.plugin_pointer.pending);
self.integrations.plugin_pointer.pages = plugins.pointer_textures();
if !plugins.is_empty() {
// the interface themes there are, and the one in use (`ui.themes`, `ui.theme`)
let mut ui = plugins.ui.borrow_mut();
if ui.themes().is_empty() {
ui.set_themes(theme_infos(), &self.settings.ui_theme_pack);
} else if ui.theme() != self.settings.ui_theme_pack {
let list = ui.themes().to_vec();
ui.set_themes(list, &self.settings.ui_theme_pack);
}
}
if !plugins.is_empty() && !self.paused {
let keys = std::mem::take(&mut self.integrations.plugin_keys);
let events = std::mem::take(&mut self.integrations.plugin_events);
Expand Down Expand Up @@ -101,7 +115,15 @@ impl App {
}
// the passengers report their tickets only while a plugin hears of them
let hear_tickets = plugins.hear_tickets();
// a plugin switched the interface theme (`ui.set_theme`): the player's setting, as if
// chosen in Options › Interface
let theme_ask = plugins.ui.borrow_mut().take_theme_ask();
self.integrations.plugins = Some(plugins);
if let Some(id) = theme_ask.filter(|id| *id != self.settings.ui_theme_pack) {
log::info!("plugins: the interface theme \"{id}\" asked for");
let value = if id.is_empty() { crate::themes::OWN.to_string() } else { id };
crate::game_lists::store_with(self, |v| v["ui_theme_pack"] = serde_json::json!(value));
}
// OMSI_WATCH_VARS=a,b: every change of those variables of the player's bus
if let (Some(p), Some(list)) = (self.player.as_ref(), omsi_cfg::flags::OMSI_WATCH_VARS.var()) {
thread_local!(static LAST: std::cell::RefCell<std::collections::HashMap<String, f32>> = Default::default());
Expand Down Expand Up @@ -143,3 +165,8 @@ impl App {
}
}
}

/// The game's interface themes as the plugins see them (`ui.themes`).
fn theme_infos() -> Vec<omsi_plugin::ui::ThemeInfo> {
crate::themes::choices().iter().map(|(id, name)| omsi_plugin::ui::ThemeInfo { id: id.clone(), name: name.clone() }).collect()
}
2 changes: 1 addition & 1 deletion crates/omsi-app/src/app_events/frame/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ impl App {
cursor: self.input.cursor,
dt,
backdrop: ui::backdrop(settings.ui_opacity),
light: settings.is_light_theme(),
palette: crate::themes::palette(settings.is_light_theme()),
navigator: self.menus.navigator.as_ref().and_then(|n| n.screen_rect()),
dock: self.menus.navigator.as_ref().and_then(|n| n.dock_slot).map(|(r, scale, placed, frame)| crate::plugin_ui::Dock { width: r[2], room: r[3], scale, at: placed.then(|| glam::Vec2::new(r[0], r[1])), frame }),
};
Expand Down
15 changes: 15 additions & 0 deletions crates/omsi-app/src/app_events/frame/present.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ impl App {
) {
let mut finish = false;
let mut reconfigure = false;
crate::themes::sync(&self.settings.ui_theme_pack, self.settings.is_light_theme());
if let (Some(s), Some(r)) = (self.gfx.surface.as_mut(), self.renderer.as_ref()) {
s.set_glass(r, omsi_ui::theme::th().glass.is_some());
}
let shot = self.perf.shot.take();
if let Some(s) = self.gfx.surface.as_ref() {
let (w, h) = (s.config.width, s.config.height);
Expand Down Expand Up @@ -348,6 +352,17 @@ impl App {
lighting,
);
}
// a glass theme's pause menu: the picture under it, as the scene left it, blurred on the
// graphics card for its panels (where the window's picture can be copied)
match omsi_ui::theme::th().glass.filter(|_| self.menus.game_menu.is_some() && !photo && !mirrored) {
Some(glass) if self.shell.glass_due(self.paused) => {
if let Some(picture) = frame.as_ref().and_then(|f| s.picture(f)) {
self.shell.capture_backdrop(r, &picture, glass.blur * self.shell.scale);
}
}
Some(_) => {}
None => self.shell.glass_closed(),
}
// the pause menu and the photo mode's panel
self.shell.render(r, &view, s.config.width, s.config.height);
// the on-screen controls over the picture (a phone)
Expand Down
2 changes: 1 addition & 1 deletion crates/omsi-app/src/app_impl/shell_link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl App {
keys: !crate::platform::touch_controls(),
summary: self.pause_summary(),
};
self.shell.set_theme(self.settings.is_light_theme());
crate::themes::sync(&self.settings.ui_theme_pack, self.settings.is_light_theme());
self.shell.begin(w, h, scale, dt);
crate::shell::pause::draw(&mut self.shell, &view);
self.shell.finish();
Expand Down
2 changes: 1 addition & 1 deletion crates/omsi-app/src/devtools/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ impl App {
self.devtools = Some(Box::new(d));
}
self.shell.opaque = false;
self.shell.set_theme(self.settings.is_light_theme());
crate::themes::sync(&self.settings.ui_theme_pack, self.settings.is_light_theme());
self.shell.begin(w, h, scale, dt);
let size = Vec2::new(w, h) / self.shell.scale;
let requests = {
Expand Down
Loading
Loading