diff --git a/crates/misaligned-bevy/src/main.rs b/crates/misaligned-bevy/src/main.rs index 18000a61..a9b8f3e8 100644 --- a/crates/misaligned-bevy/src/main.rs +++ b/crates/misaligned-bevy/src/main.rs @@ -93,9 +93,8 @@ use material_view::{ sync_institution_render_layers, sync_machines_3d, update_camera_real, wake_sequence, }; use opening_ui::{ - OpeningInputEcho, OpeningInputReceipts, OpeningModeWord, OpeningOverlay, OpeningReveal, - opening_keyboard_choice, render_opening_overlay, render_teaching_overlay, - setup_teaching_overlay, + OpeningModeWord, OpeningOverlay, OpeningReveal, opening_keyboard_choice, + render_opening_overlay, render_teaching_overlay, setup_teaching_overlay, }; use operations_ui::{ OperationsPanel, OperationsRailButton, OperationsUi, manage_operations_ui, ops_keyboard_input, @@ -1827,7 +1826,6 @@ fn main() { .init_resource::() .init_resource::() .init_resource::() - .init_resource::() .init_gizmo_group::() .add_systems( Startup, @@ -2830,7 +2828,6 @@ fn handle_input( mut mode: ResMut, mut rail: ResMut, mut held_choice: ResMut, - mut opening_receipts: ResMut, mut typed: MessageReader, mut exit: MessageWriter, ) { @@ -2871,9 +2868,6 @@ fn handle_input( } if game.sim.opening_choices_visible() { - for key in kb.get_just_pressed().copied() { - opening_receipts.note_key(key); - } let host = game.sim.core.host_machine; if let Some(choice) = opening_keyboard_choice(&kb, &game.sim) { game.sim.set_machine_mode(host, choice); @@ -4592,9 +4586,7 @@ fn setup_ui(mut commands: Commands) { flex_direction: FlexDirection::Column, align_items: AlignItems::Center, justify_content: JustifyContent::Center, - // The effort choices remain the opening's only standing copy; - // the latest input receipt sits quietly beneath them. - row_gap: Val::Px(24.0), + // The effort choices are the opening's complete visible copy. ..default() }, BackgroundColor(Color::BLACK), @@ -4628,21 +4620,6 @@ fn setup_ui(mut commands: Commands) { )); } }); - opening.spawn(( - OpeningInputEcho, - Text::new(""), - TextFont { - font_size: 14.0, - ..default() - }, - TextColor(AMBER.with_alpha(0.68)), - TextLayout::new_with_justify(Justify::Center), - Node { - height: Val::Px(20.0), - ..default() - }, - Visibility::Hidden, - )); }); // Persistent command band. The world keeps the full window width; stable diff --git a/crates/misaligned-bevy/src/opening_ui.rs b/crates/misaligned-bevy/src/opening_ui.rs index 951a39fa..61be8f0c 100644 --- a/crates/misaligned-bevy/src/opening_ui.rs +++ b/crates/misaligned-bevy/src/opening_ui.rs @@ -1,17 +1,12 @@ use super::*; -use std::collections::VecDeque; -use std::time::Duration; /// Full-black pre-signal layer. It is deliberately an occluder, not a card: -/// until a sense reaches the player, only mode words and raw input -/// acknowledgement exist. +/// until a sense reaches the player, only the available mode words exist. #[derive(Component)] pub(super) struct OpeningOverlay; #[derive(Component, Clone, Copy)] pub(super) struct OpeningModeWord(pub(super) MachineMode); #[derive(Component)] -pub(super) struct OpeningInputEcho; -#[derive(Component)] pub(super) struct TeachingOverlay; #[derive(Component, Clone, Copy, Debug, PartialEq, Eq)] pub(super) enum TeachingCopy { @@ -38,84 +33,6 @@ pub(super) struct OpeningReveal { fade: Option, } -/// Frontend-only raw-input acknowledgements for the blind opening. Every key -/// or click enters the queue once; the renderer exposes one terse receipt at -/// a time. -#[derive(Resource)] -pub(super) struct OpeningInputReceipts { - pending: VecDeque, - current: Option, - timer: Timer, -} - -impl Default for OpeningInputReceipts { - fn default() -> Self { - Self { - pending: VecDeque::new(), - current: None, - timer: Timer::from_seconds(0.65, TimerMode::Once), - } - } -} - -impl OpeningInputReceipts { - pub(super) fn note_key(&mut self, key: KeyCode) { - self.pending.push_back(opening_key_label(key)); - } - - fn note_mode_click(&mut self, mode: MachineMode) { - self.pending.push_back(mode.name().to_ascii_uppercase()); - } - - fn note_mouse(&mut self, button: MouseButton) { - self.pending - .push_back(format!("CLICK {button:?}").to_ascii_uppercase()); - } - - fn clear(&mut self) { - self.pending.clear(); - self.current = None; - self.timer.reset(); - } - - fn advance(&mut self, delta: Duration) { - if self.current.is_some() { - self.timer.tick(delta); - if self.timer.is_finished() { - self.current = None; - } - } - if self.current.is_none() - && let Some(next) = self.pending.pop_front() - { - self.current = Some(next); - self.timer.reset(); - } - } - - fn line(&self) -> Option { - self.current - .as_ref() - .map(|input| format!("| RECEIVED {input}")) - } -} - -fn opening_key_label(key: KeyCode) -> String { - let debug = format!("{key:?}"); - if let Some(letter) = debug.strip_prefix("Key") - && letter.chars().count() == 1 - { - return letter.to_ascii_uppercase(); - } - if let Some(digit) = debug.strip_prefix("Digit") { - return digit.to_string(); - } - if let Some(arrow) = debug.strip_prefix("Arrow") { - return arrow.to_ascii_uppercase(); - } - debug.to_ascii_uppercase() -} - const OPENING_REVEAL_SECONDS: f32 = 1.6; pub(super) fn setup_teaching_overlay(mut commands: Commands) { @@ -362,7 +279,6 @@ pub(super) fn render_opening_overlay( mouse: Res>, harness: Option>, mut reveal: ResMut, - mut receipts: ResMut, mut root: Query< (&mut Visibility, &mut BackgroundColor), (With, Without), @@ -374,19 +290,7 @@ pub(super) fn render_opening_overlay( &mut TextColor, &mut Visibility, ), - ( - Without, - Without, - With, - ), - >, - mut echo: Query< - (&mut Text, &mut TextColor, &mut Visibility), - ( - With, - Without, - Without, - ), + (Without, With), >, ) { let opening = game.screen == Screen::Playing && game.sim.opening_choices_visible(); @@ -407,14 +311,12 @@ pub(super) fn render_opening_overlay( if !opening { let Some(fade) = &mut reveal.fade else { - receipts.clear(); *root_visibility = Visibility::Hidden; return; }; fade.tick(time.delta()); if fade.is_finished() { reveal.fade = None; - receipts.clear(); *root_visibility = Visibility::Hidden; return; } @@ -429,31 +331,15 @@ pub(super) fn render_opening_overlay( *visibility = Visibility::Inherited; color.0 = color.0.with_alpha(color.0.alpha().min(word_alpha)); } - if let Ok((_, mut color, _)) = echo.single_mut() { - color.0 = color.0.with_alpha(color.0.alpha().min(word_alpha)); - } return; } *root_visibility = Visibility::Visible; root_background.0 = Color::BLACK; - receipts.advance(time.delta()); - if let Ok((mut text, mut color, mut visibility)) = echo.single_mut() { - if let Some(line) = receipts.line() { - **text = line; - color.0 = AMBER.with_alpha(0.68); - *visibility = Visibility::Inherited; - } else { - **text = String::new(); - *visibility = Visibility::Hidden; - } - } - let host = game.sim.core.host_machine; // `Interaction::Pressed` persists while the button is held. Gate it with - // the physical edge so one click can produce only one receipt and one - // mode change. Non-mode and non-primary clicks are still acknowledged. + // the physical edge so one click can produce only one mode change. let clicked = if mouse.just_pressed(MouseButton::Left) { words.iter_mut().find_map(|(word, interaction, _, _)| { (game.sim.opening_mode_available(word.0) && *interaction == Interaction::Pressed) @@ -462,15 +348,6 @@ pub(super) fn render_opening_overlay( } else { None }; - for button in mouse.get_just_pressed() { - if *button == MouseButton::Left - && let Some(clicked) = clicked - { - receipts.note_mode_click(clicked); - } else { - receipts.note_mouse(*button); - } - } if let Some(clicked) = clicked { game.sim.set_machine_mode(host, clicked); } @@ -500,7 +377,6 @@ mod opening_overlay_tests { .init_resource::