diff --git a/crates/benilla-app/src/chat_bubble.rs b/crates/benilla-app/src/chat_bubble.rs index 1ccbf48a..9307bbfd 100644 --- a/crates/benilla-app/src/chat_bubble.rs +++ b/crates/benilla-app/src/chat_bubble.rs @@ -25,17 +25,13 @@ use std::collections::HashMap; use bevy::ecs::entity::EntityHashSet; use bevy::prelude::*; -use benilla_ui::layout::Rect as GxRect; -use benilla_ui::script::{inset_atlas_bleed, pieces, Backdrop, Insets}; -use benilla_ui::script::{JustifyH, JustifyV, Outline}; +use benilla_ui::script::{BubbleState, Outline, UiScript}; use crate::entities::StandBoxHeight; use crate::net::{Embodied, Guid, NetEntity, SelfGuid}; use crate::ui_chat::{default_color, ChatEventKind}; -use crate::ui_pass::{overlay_z, UiQuad, UiQuadAppend, UiQuads, UvRect}; -use crate::ui_text::{layout_text_quads, measure_text, FontSpec, Justify, TextSeat, UiFontAtlas}; +use crate::ui_text::{measure_text, FontSpec, UiFontAtlas}; use crate::vplates::{device_snap, gx_px, plate_basis, text_px, VPlateSet, VPlates}; -use benilla_assets::{AssetSet, WorldAssets}; use benilla_world::view::WorldCamera; /// The two bubble CVars (registrar `0x603280`), booting at the reference's defaults. @@ -90,10 +86,9 @@ impl Default for BubbleConfig { } } -/// The bubble art (`0x4b0940`). -const BG_TEXTURE: &str = "Interface\\Tooltips\\ChatBubble-Background"; -const EDGE_TEXTURE: &str = "Interface\\Tooltips\\ChatBubble-Backdrop"; -const TAIL_TEXTURE: &str = "Interface\\Tooltips\\ChatBubble-Tail"; +// The bubble art (`0x4b0940`) moved with the drawing: it now lives on the widgets +// (`benilla_ui::script::chat_bubble`), where the UI pass resolves and tiles it like any other +// frame's, half-texel bleed inset included. /// The 0.7 yd lift over the anchor height (`[0x7ffd7c]`). const LIFT: f32 = 0.7; @@ -110,20 +105,6 @@ const WRAP_W: f32 = 0.2; /// The border unit (edge size, insets, tail side): 16/1024 of the screen width. const BORDER_FRAC: f32 = 16.0 / 1024.0; -/// Paint order inside one bubble's level: the tail covers the bottom edge piece and the text draws -/// last, as the reference's batch drains textures before font strings (`0x76fb00`). -const Z_BG: u64 = 0; -const Z_EDGE: u64 = 1; -const Z_TAIL: u64 = 2; -const Z_TEXT: u64 = 3; - -/// The z base for the bubble at `rank`, farthest first: the reference's per-frame -/// `SetFrameLevel(2 + i)` walk (`0x4b12d5`-`0x4b1312`), one level per bubble, under the V-plates. -fn level_z(rank: usize) -> u64 { - let level = (rank as u64).min(overlay_z::BUBBLE_MAX_LEVEL); - overlay_z::BUBBLE + level * overlay_z::BUBBLE_STRIDE -} - /// The CVar gating this kind's bubble (`0x608b0d`); `None` for a kind that does not bubble. fn bubble_cvar(kind: ChatEventKind, cfg: &BubbleConfig) -> Option { use ChatEventKind as K; @@ -213,14 +194,6 @@ fn sanitize(text: &str) -> String { out } -/// The bleed inset for one border piece; zero texels (no patch chain) leaves the UVs alone. -fn pieces_inset(uvs: [[f32; 2]; 4], texels: Vec2) -> [[f32; 2]; 4] { - if texels.x <= 0.0 || texels.y <= 0.0 { - return uvs; - } - inset_atlas_bleed(uvs, texels.x, texels.y) -} - /// The frame's bottom-left origin, bottom-center on the seat. Deviation: snapped onto the device /// pixel grid ([`device_snap`]) so the border art blits 1:1; the reference seats it fractionally. fn seat_origin(seat: Vec2, w: f32, scale: f32) -> Vec2 { @@ -292,43 +265,6 @@ struct Bubbles(HashMap); #[derive(Resource, Default)] pub(crate) struct BubblesActive(pub(crate) EntityHashSet); -/// The bubble art, loaded at boot. The edge strip tiles UVs past 1 (repeat); bg and tail clamp. -#[derive(Resource)] -struct BubbleArt { - bg: Handle, - edge: Handle, - tail: Handle, - /// The edge atlas's size in texels, for the half-texel bleed inset. - edge_texels: Vec2, -} - -fn load_bubble_art( - mut commands: Commands, - assets: Option>, - mut images: ResMut>, -) { - let Some(mut assets) = assets else { - return; // no game data (a bare test app); `drive_bubbles` tolerates the missing art - }; - let bg = assets.sprite_texture(BG_TEXTURE, &mut images); - let edge = assets.sprite_texture_tiled(EDGE_TEXTURE, &mut images); - let tail = assets.sprite_texture(TAIL_TEXTURE, &mut images); - let (Some(bg), Some(edge), Some(tail)) = (bg, edge, tail) else { - warn!("chat_bubble: bubble art missing from the patch chain — bubbles will not draw"); - return; - }; - let edge_texels = images.get(&edge).map_or(Vec2::ZERO, |i| { - let s = i.texture_descriptor.size; - Vec2::new(s.width as f32, s.height as f32) - }); - commands.insert_resource(BubbleArt { - bg, - edge, - tail, - edge_texels, - }); -} - /// Every frame: drain the queue through the spawn gate (`0x608ac0`), ramp each bubble's fade /// against its lifetime and the 20 yd re-test (`0x4b0c30`), publish [`BubblesActive`], and draw. #[allow(clippy::type_complexity)] // one Bevy system's full input set @@ -342,8 +278,6 @@ fn drive_bubbles( self_q: Query<&Transform, With>, camera: Query<(&Camera, &Transform), With>, mut atlas: Option>, - mut quads: ResMut, - art: Option>, heights: Query<&StandBoxHeight>, time: Res