M crates/unified/src/client/mod.rs => crates/unified/src/client/mod.rs +5 -2
@@ 4,13 4,14 @@ use crate::client::planet::indicators::indicators_plugin;
use crate::client::starfield::starfield_plugin;
use crate::client::ui::ui_plugin;
use crate::client::zoom::zoom_plugin;
+use crate::client::starguide::starguide_plugin;
use crate::ecs::{Hi, Part, Player};
use aeronet_websocket::client::WebSocketClient;
use bevy::dev_tools::picking_debug::DebugPickingMode;
use crate::prelude::*;
use planet::incoming_planets::incoming_planets_plugin;
use crate::client::ship::attachment::client_attachment_plugin;
-use crate::ecs::Me;
+use crate::ecs::{Me, STARGUIDE_LAYER};
pub mod colors;
pub mod key_input;
@@ 24,6 25,7 @@ pub mod zoom;
pub mod ship;
pub mod rendering;
pub mod input;
+pub mod starguide;
pub struct ClientPlugin {
pub server: Option<String>,
@@ 53,6 55,7 @@ impl Plugin for ClientPlugin {
.add_plugins(ui_plugin)
.add_plugins(zoom_plugin)
.add_plugins(client_attachment_plugin)
+ .add_plugins(starguide_plugin)
.insert_resource(DebugPickingMode::Disabled);
// These are only needed if we're actually doing network things
@@ 76,7 79,7 @@ fn find_me(
info!("^^^^^^^^^^^ IGNORE THESE WARNINGS ^^^^^^^^^^^^^^");
info!("they are normal! and are from the world state being replicated as it is sent over the network");
info!(?msg, "finding me: got hello from server");
- commands.entity(msg.you_are).insert(Me);
+ commands.entity(msg.you_are).insert(Me).insert(STARGUIDE_LAYER);
/*let mut heart_sprite =
Sprite::from_image(asset_server.load("sprites/hearty_heart.png"));
M crates/unified/src/client/parts.rs => crates/unified/src/client/parts.rs +2 -1
@@ 3,7 3,7 @@ use std::f32::consts::PI;
use crate::attachment::{Joint, JointOf, Joints, PartInShip, Peer, SnapOf, SnapOfJoint};
use crate::ecs::Me;
use crate::client::colors::GREEN;
-use crate::ecs::{DragRequestEvent, Part};
+use crate::ecs::{DragRequestEvent, Part, MAIN_LAYER};
use crate::client::input::CursorWorldCoordinates;
use bevy::color::palettes::css::{ORANGE, PURPLE, RED, YELLOW};
use crate::client::ship::attachment::AttachmentDebugRes;
@@ 42,6 42,7 @@ fn handle_incoming_parts(
commands
.entity(new_entity)
+ .insert(MAIN_LAYER)
.insert(sprite)
.insert(Pickable::default())
.observe(on_part_click);
M crates/unified/src/client/planet/incoming_planets.rs => crates/unified/src/client/planet/incoming_planets.rs +2 -0
@@ 1,5 1,6 @@
use crate::config::planet::{Planet, SpecialSpriteProperties};
use crate::prelude::*;
+use crate::ecs::{MAIN_STAR_LAYERS};
pub fn incoming_planets_plugin(app: &mut App) {
app.add_systems(Update, (handle_incoming_planets, handle_updated_planets));
@@ 22,6 23,7 @@ fn handle_incoming_planets(
commands
//.insert(AdditionalMassProperties::Mass(new_planet.mass))
+ .insert(MAIN_STAR_LAYERS.clone())
.insert(sprite);
trace!(?new_planet, "prepared new planet");
M crates/unified/src/client/rendering/mod.rs => crates/unified/src/client/rendering/mod.rs +8 -3
@@ 2,7 2,7 @@ use bevy::anti_alias::fxaa::Fxaa;
use bevy::app::{App, Startup};
use bevy::core_pipeline::tonemapping::DebandDither;
use bevy::post_process::bloom::Bloom;
-use crate::ecs::{MainCamera, Me};
+use crate::ecs::{MainCamera, StarguideCamera, Me, MAIN_LAYER};
use crate::prelude::*;
pub fn render_plugin(app: &mut App) {
@@ 12,13 12,14 @@ pub fn render_plugin(app: &mut App) {
}
-fn setup_graphics(mut commands: Commands) {
+pub fn setup_graphics(mut commands: Commands) {
commands
.spawn(Camera2d)
.insert(Camera {
clear_color: ClearColorConfig::Custom(Color::BLACK),
..default()
})
+ .insert(MAIN_LAYER)
.insert(Bloom::default())
.insert(DebandDither::Enabled)
.insert(Fxaa::default())
@@ 27,11 28,15 @@ fn setup_graphics(mut commands: Commands) {
fn follow_camera(
mut camera: Query<&mut Transform, (With<MainCamera>, Without<Me>)>,
+ mut starguide_camera: Query<&mut Transform, (With<StarguideCamera>, Without<MainCamera>, Without<Me>)>,
player: Query<&Transform, With<Me>>,
) {
let mut camera = camera.single_mut().unwrap();
+ let mut starguide_camera = starguide_camera.single_mut().unwrap();
let Ok(player) = player.single() else {
return;
};
camera.translation = player.translation;
-}>
\ No newline at end of file
+ starguide_camera.translation = player.translation;
+
+}
M crates/unified/src/client/starfield.rs => crates/unified/src/client/starfield.rs +4 -1
@@ 18,7 18,7 @@ use bevy::{
use crate::{
ecs::Me,
- ecs::{MainCamera, StarfieldBack, StarfieldFront, StarfieldMid},
+ ecs::{MainCamera, MAIN_LAYER, STARGUIDE_LAYER, StarfieldBack, StarfieldFront, StarfieldMid},
};
pub const BACK_STARFIELD_SIZE: f32 = 256.0;
@@ 54,6 54,7 @@ pub fn set_up_starfield(
},
..Default::default()
})
+ .insert(MAIN_LAYER)
.insert(Transform::from_xyz(0.0, 0.0, 5.0))
.insert(Visibility::Inherited)
.insert(StarfieldBack);
@@ 68,6 69,7 @@ pub fn set_up_starfield(
},
..Default::default()
})
+ .insert(MAIN_LAYER)
.insert(Transform::from_xyz(0.0, 0.0, 4.5))
.insert(Visibility::Inherited)
.insert(StarfieldMid);
@@ 82,6 84,7 @@ pub fn set_up_starfield(
},
..Default::default()
})
+ .insert(MAIN_LAYER)
.insert(Transform::from_xyz(0.0, 0.0, 4.0))
.insert(Visibility::Inherited)
.insert(StarfieldFront);
A crates/unified/src/client/starguide.rs => crates/unified/src/client/starguide.rs +17 -0
@@ 0,0 1,17 @@
+use crate::prelude::*;
+use crate::ecs::{StarguideCamera, STARGUIDE_LAYER};
+use crate::config::planet::SpecialSpriteProperties;
+use crate::config::planet::Planet;
+
+pub fn starguide_plugin(app: &mut App) {
+ app.add_systems(Startup, init_starguide);
+}
+
+pub fn init_starguide(mut commands: Commands) {
+ commands.spawn((Camera2d::default(), Camera {
+ is_active: false,
+ ..default()
+ }))
+ .insert(STARGUIDE_LAYER)
+ .insert(StarguideCamera);
+}
M crates/unified/src/client/ui.rs => crates/unified/src/client/ui.rs +8 -3
@@ 2,21 2,25 @@ use crate::prelude::*;
use crate::{
client::colors,
- ecs::{FuelText, Player, PlayerStorage, PowerText},
+ ecs::{FuelText, Player, PlayerStorage, PowerText, MainCamera, MAIN_LAYER},
};
+use crate::client::rendering::setup_graphics;
pub fn ui_plugin(app: &mut App) {
- app.add_systems(Startup, setup_ui)
+ app.add_systems(Startup, setup_ui.after(setup_graphics))
.add_systems(Update, update_ui);
}
-fn setup_ui(mut commands: Commands) {
+fn setup_ui(camera: Single<Entity, (With<MainCamera>, With<Camera>)>, mut commands: Commands) {
let ui_id = commands.spawn((
+ UiTargetCamera(camera.into_inner()),
Node {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
..Default::default()
},
+ Transform::from_xyz(0.0, 0.0, 25.0),
+ MAIN_LAYER,
children![(
Node {
display: Display::Flex,
@@ 27,6 31,7 @@ fn setup_ui(mut commands: Commands) {
right: Val::Px(5.0),
..Default::default()
},
+ MAIN_LAYER,
BorderRadius::all(Val::Px(5.0)),
BackgroundColor(colors::MANTLE),
children![
M crates/unified/src/client/zoom.rs => crates/unified/src/client/zoom.rs +29 -10
@@ 6,6 6,7 @@ use bevy::{
use crate::{
client::starfield::{BACK_STARFIELD_SIZE, FRONT_STARFIELD_SIZE, MID_STARFIELD_SIZE, StarfieldSize}, ecs::{MainCamera, Me, StarfieldBack, StarfieldFront, StarfieldMid}
};
+use crate::ecs::StarguideCamera;
pub fn zoom_plugin(app: &mut App) {
app.add_systems(Update, on_scroll);
@@ 38,10 39,22 @@ fn on_scroll(
Without<StarfieldMid>,
),
>,
+ mut starguide_camera: Single<
+ (&mut Camera, &mut Transform),
+ (
+ With<StarguideCamera>,
+ Without<MainCamera>,
+ Without<Me>,
+ Without<StarfieldFront>,
+ Without<StarfieldMid>,
+ Without<StarfieldBack>,
+ ),
+ >,
mut camera: Single<
- &mut Transform,
+ (&mut Camera, &mut Transform),
(
With<MainCamera>,
+ Without<StarguideCamera>,
Without<Me>,
Without<StarfieldFront>,
Without<StarfieldMid>,
@@ 68,11 81,15 @@ fn on_scroll(
match event.unit {
MouseScrollUnit::Line | MouseScrollUnit::Pixel => {
if event.y > 0.0 {
- camera.scale *= 0.97;
+ camera.1.scale *= 0.97;
+ starguide_camera.1.scale *= 0.97;
} else {
- camera.scale *= 1.03;
+ camera.1.scale *= 1.03;
+ starguide_camera.1.scale *= 1.03;
}
- if camera.scale.z > 50.0 {
+ if camera.1.scale.z > 30.0 {
+ camera.0.is_active = false;
+ starguide_camera.0.is_active = true;
starfield_back.image_mode = SpriteImageMode::Auto;
starfield_mid.image_mode = SpriteImageMode::Auto;
starfield_front.image_mode = SpriteImageMode::Auto;
@@ 80,6 97,8 @@ fn on_scroll(
*visibility_mid = Visibility::Hidden;
*visibility_front = Visibility::Hidden;
} else {
+ camera.0.is_active = true;
+ starguide_camera.0.is_active = false;
if matches!(*visibility_back, Visibility::Hidden) {
if let Some(size_back) = size_back {
starfield_back.image_mode = SpriteImageMode::Tiled {
@@ 108,15 127,15 @@ fn on_scroll(
*visibility_front = Visibility::Inherited;
}
starfield_back.custom_size =
- Some(window.size() * camera.scale.z + Vec2::splat(BACK_STARFIELD_SIZE * 2.0));
+ Some(window.size() * camera.1.scale.z + Vec2::splat(BACK_STARFIELD_SIZE * 2.0));
starfield_mid.custom_size =
- Some(window.size() * camera.scale.z + Vec2::splat(MID_STARFIELD_SIZE * 2.0));
+ Some(window.size() * camera.1.scale.z + Vec2::splat(MID_STARFIELD_SIZE * 2.0));
starfield_front.custom_size =
- Some(window.size() * camera.scale.z + Vec2::splat(FRONT_STARFIELD_SIZE * 2.0));
+ Some(window.size() * camera.1.scale.z + Vec2::splat(FRONT_STARFIELD_SIZE * 2.0));
starfield_back_pos.translation = player.translation
+ (-player.translation / 3.0) % BACK_STARFIELD_SIZE
+ (Vec3::new(window.resolution.width(), -window.resolution.height(), 0.0)
- * camera.scale.z
+ * camera.1.scale.z
/ 2.0)
% BACK_STARFIELD_SIZE
+ Vec3::new(0.0, BACK_STARFIELD_SIZE, 0.0)
@@ 124,7 143,7 @@ fn on_scroll(
starfield_mid_pos.translation = player.translation
+ (-player.translation / 2.5) % MID_STARFIELD_SIZE
+ (Vec3::new(window.resolution.width(), -window.resolution.height(), 0.0)
- * camera.scale.z
+ * camera.1.scale.z
/ 2.0)
% MID_STARFIELD_SIZE
+ Vec3::new(0.0, MID_STARFIELD_SIZE, 0.0)
@@ 132,7 151,7 @@ fn on_scroll(
starfield_front_pos.translation = player.translation
+ (-player.translation / 2.0) % FRONT_STARFIELD_SIZE
+ (Vec3::new(window.resolution.width(), -window.resolution.height(), 0.0)
- * camera.scale.z
+ * camera.1.scale.z
/ 2.0)
% FRONT_STARFIELD_SIZE
+ Vec3::new(0.0, FRONT_STARFIELD_SIZE, 0.0)
M crates/unified/src/ecs.rs => crates/unified/src/ecs.rs +9 -1
@@ 3,14 3,22 @@ pub mod thruster;
use crate::config::part::PartConfig;
use bevy::ecs::entity::MapEntities;
use bevy::math::{Quat, Vec2};
+use bevy::camera::visibility::RenderLayers;
use crate::prelude::*;
use bevy_replicon::prelude::Replicated;
use serde::{Deserialize, Serialize};
use avian2d::prelude::*;
use crate::thrust::ThrustSolution;
+use std::sync::LazyLock;
+
+pub const MAIN_LAYER: RenderLayers = RenderLayers::layer(0);
+pub const STARGUIDE_LAYER: RenderLayers = RenderLayers::layer(1);
+pub static MAIN_STAR_LAYERS: LazyLock<RenderLayers> = LazyLock::new(|| RenderLayers::from_layers(&[0, 1]));
#[derive(Component)]
pub struct MainCamera;
+#[derive(Component)]
+pub struct StarguideCamera;
#[derive(Component)]
pub struct StarfieldFront;
@@ 80,4 88,4 @@ pub struct Me;
pub struct Hi {
#[entities]
pub you_are: Entity
-}>
\ No newline at end of file
+}