~starkingdoms/starkingdoms

ref: 4f93bd075f25550e5b28733e07efa96c6bed0a5c starkingdoms/crates/unified/src/client/mod.rs -rw-r--r-- 4.3 KiB
4f93bd07ghostly_zsh scaling added, along with fixes to sampling 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
mod colors;
mod incoming_particles;
mod incoming_parts;
mod key_input;
mod net;
mod starfield;
mod ui;
mod planet;
mod zoom;
mod particles;

use crate::client::incoming_particles::replicated_particles_plugin;
use crate::client::incoming_parts::incoming_parts_plugin;
use planet::incoming_planets::incoming_planets_plugin;
use crate::client::key_input::key_input_plugin;
use crate::client::starfield::starfield_plugin;
use crate::client::ui::ui_plugin;
use crate::client::zoom::zoom_plugin;
use crate::ecs::{CursorWorldCoordinates, MainCamera, Part, Player};
use aeronet_websocket::client::WebSocketClient;
use bevy::core_pipeline::bloom::Bloom;
use bevy::core_pipeline::fxaa::Fxaa;
use bevy::core_pipeline::tonemapping::DebandDither;
use bevy::prelude::*;
use bevy::window::PrimaryWindow;
use bevy_replicon::shared::server_entity_map::ServerEntityMap;
use crate::client::net::set_config;
use crate::client::planet::indicators::indicators_plugin;

pub struct ClientPlugin {
    pub server: String,
}
impl Plugin for ClientPlugin {
    fn build(&self, app: &mut App) {
        let server = self.server.clone();
        app.insert_resource(CursorWorldCoordinates(None))
            .add_systems(Startup, move |mut commands: Commands| {
                let config = net::websocket_config();

                commands
                    .spawn(Name::new("default-session"))
                    .queue(WebSocketClient::connect(config, server.clone()));
            })
            .add_observer(net::on_connecting)
            .add_observer(net::on_connected)
            .add_observer(net::on_disconnected)
            .add_systems(Startup, setup_graphics)
            .add_systems(Update, update_cursor_position)
            .add_systems(Update, follow_camera)
            .add_systems(Update, find_me)
            .add_systems(Update, set_config)
            .add_plugins((incoming_planets_plugin, indicators_plugin))
            .add_plugins(incoming_parts_plugin)
            .add_plugins(key_input_plugin)
            .add_plugins(starfield_plugin)
            .add_plugins(ui_plugin)
            .add_plugins(replicated_particles_plugin)
            .add_plugins(zoom_plugin);
    }
}

#[derive(Component)]
pub struct Me;

fn find_me(
    mut commands: Commands,
    q_clients: Query<(Entity, &Player, &Part), Added<Player>>,
    entity_map: Res<ServerEntityMap>,
    asset_server: Res<AssetServer>,
) {
    for (entity, player, part) in q_clients.iter() {
        let this_id_clientside = entity_map.to_client().get(&player.client).unwrap();
        if *this_id_clientside == entity {
            info!("hi! i've been found!");
            commands.entity(entity).insert(Me);
            let mut heart_sprite = Sprite::from_image(asset_server.load("sprites/heart_sprite.png"));
            heart_sprite.custom_size = Some(Vec2::new(part.width, part.height));
            heart_sprite.color = Color::srgb(20.0, 0.0, 0.0);

            commands.spawn((
                    ChildOf(entity),
                    heart_sprite,
                    Transform::from_xyz(0.0, 0.0, 10.0)
                ));
        }
    }
}

fn setup_graphics(mut commands: Commands) {
    commands
        .spawn(Camera2d)
        .insert(Camera {
            hdr: true,
            clear_color: ClearColorConfig::Custom(Color::BLACK),
            ..default()
        })
        .insert(Bloom::default())
        .insert(DebandDither::Enabled)
        .insert(Fxaa::default())
        .insert(MainCamera);
}

fn follow_camera(
    mut camera: Query<&mut Transform, (With<MainCamera>, Without<Me>)>,
    player: Query<&Transform, With<Me>>,
) {
    let mut camera = camera.single_mut().unwrap();
    let Ok(player) = player.single() else {
        return;
    };
    camera.translation = player.translation;
}

fn update_cursor_position(
    q_windows: Query<&Window, With<PrimaryWindow>>,
    q_camera: Query<(&Camera, &GlobalTransform), With<MainCamera>>,
    mut coords: ResMut<CursorWorldCoordinates>,
) {
    let (camera, camera_transform) = q_camera.single().unwrap();
    let window = q_windows.single().unwrap();

    if let Some(world_position) = window
        .cursor_position()
        .and_then(|cursor| camera.viewport_to_world(camera_transform, cursor).ok())
        .map(|ray| ray.origin.truncate())
    {
        coords.0 = Some(world_position);
    } else {
        coords.0 = None;
    }
}