diff --git a/Cargo.lock b/Cargo.lock index 2129af5..0ed034d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,22 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "ab_glyph" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" + [[package]] name = "accesskit" version = "0.18.0" @@ -67,6 +83,19 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.3", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -389,7 +418,7 @@ dependencies = [ "bevy_utils", "blake3", "derive_more", - "downcast-rs", + "downcast-rs 2.0.1", "either", "petgraph", "ron", @@ -416,7 +445,7 @@ dependencies = [ "cfg-if", "console_error_panic_hook", "ctrlc", - "downcast-rs", + "downcast-rs 2.0.1", "log", "thiserror 2.0.12", "variadics_please", @@ -447,7 +476,7 @@ dependencies = [ "crossbeam-channel", "derive_more", "disqualified", - "downcast-rs", + "downcast-rs 2.0.1", "either", "futures-io", "futures-lite", @@ -993,7 +1022,7 @@ dependencies = [ "bevy_utils", "derive_more", "disqualified", - "downcast-rs", + "downcast-rs 2.0.1", "erased-serde", "foldhash", "glam", @@ -1049,7 +1078,7 @@ dependencies = [ "bytemuck", "codespan-reporting", "derive_more", - "downcast-rs", + "downcast-rs 2.0.1", "encase", "fixedbitset", "futures-lite", @@ -1530,6 +1559,18 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "calloop-wayland-source" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop", + "rustix", + "wayland-backend", + "wayland-client", +] + [[package]] name = "cc" version = "1.2.22" @@ -1939,6 +1980,12 @@ dependencies = [ "rayon", ] +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "downcast-rs" version = "2.0.1" @@ -3450,6 +3497,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "owned_ttf_parser" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" +dependencies = [ + "ttf-parser 0.25.1", +] + [[package]] name = "parking" version = "2.2.1" @@ -3675,6 +3731,15 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" +[[package]] +name = "quick-xml" +version = "0.37.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.40" @@ -4046,12 +4111,31 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sctk-adwaita" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" +dependencies = [ + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit", + "tiny-skia", +] + [[package]] name = "self_cell" version = "1.2.0" @@ -4169,6 +4253,31 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +dependencies = [ + "bitflags 2.9.0", + "calloop", + "calloop-wayland-source", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix", + "thiserror 1.0.69", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + [[package]] name = "smol_str" version = "0.2.2" @@ -4214,6 +4323,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" + [[package]] name = "strum" version = "0.26.3" @@ -4387,6 +4502,31 @@ dependencies = [ "weezl", ] +[[package]] +name = "tiny-skia" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + [[package]] name = "tinyvec" version = "1.9.0" @@ -4535,6 +4675,12 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" +[[package]] +name = "ttf-parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" + [[package]] name = "twox-hash" version = "2.1.0" @@ -4761,6 +4907,114 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wayland-backend" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" +dependencies = [ + "cc", + "downcast-rs 1.2.1", + "rustix", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61" +dependencies = [ + "bitflags 2.9.0", + "rustix", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.9.0", + "cursor-icon", + "wayland-backend", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65317158dec28d00416cb16705934070aef4f8393353d41126c54264ae0f182" +dependencies = [ + "rustix", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "779075454e1e9a521794fed15886323ea0feda3f8b0fc1390f5398141310422a" +dependencies = [ + "bitflags 2.9.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fd38cdad69b56ace413c6bcc1fbf5acc5e2ef4af9d5f8f1f9570c0c83eae175" +dependencies = [ + "bitflags 2.9.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cb6cdc73399c0e06504c437fe3cf886f25568dd5454473d565085b36d6a8bbf" +dependencies = [ + "bitflags 2.9.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbcebb399c77d5aa9fa5db874806ee7b4eba4e73650948e8f93963f128896615" +dependencies = [ + "dlib", + "log", + "pkg-config", +] + [[package]] name = "web-sys" version = "0.3.77" @@ -5441,6 +5695,7 @@ version = "0.30.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0d05bd8908e14618c9609471db04007e644fd9cce6529756046cfc577f9155e" dependencies = [ + "ahash", "android-activity", "atomic-waker", "bitflags 2.9.0", @@ -5455,6 +5710,7 @@ dependencies = [ "dpi", "js-sys", "libc", + "memmap2", "ndk 0.9.0", "objc2", "objc2-app-kit", @@ -5466,11 +5722,17 @@ dependencies = [ "raw-window-handle", "redox_syscall 0.4.1", "rustix", + "sctk-adwaita", + "smithay-client-toolkit", "smol_str", "tracing", "unicode-segmentation", "wasm-bindgen", "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-plasma", "web-sys", "web-time", "windows-sys 0.52.0", @@ -5529,6 +5791,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" +[[package]] +name = "xcursor" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" + [[package]] name = "xkbcommon-dl" version = "0.4.2" diff --git a/Cargo.toml b/Cargo.toml index 0324bc5..7da3eeb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -bevy = { version = "0.16" } +bevy = { version = "0.16", features = ["wayland"] } noise = "0.9.0" rand = "0.9.1" image = "0.25.6" diff --git a/src/camera.rs b/src/camera.rs index af355e6..a63217a 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -3,7 +3,6 @@ use bevy::input::mouse::{MouseScrollUnit, MouseWheel}; use bevy::prelude::*; use bevy::render::camera::{OrthographicProjection, Projection}; -use crate::constants::TILE_SIZE; use crate::{game, tilemap}; #[derive(Component)] @@ -81,10 +80,10 @@ pub fn spawn_panning_camera(mut commands: Commands) { } pub fn scroll_events(mut evr_scroll: EventReader, mut query: Query<&mut Projection>) { - const ZOOM_SENSITIVITY: f32 = 0.035; + const LINE_SENSITIVITY: f32 = 0.035; const PIXEL_SENSITIVITY: f32 = 0.001; - const MIN_SCALE: f32 = 0.2; - const MAX_SCALE: f32 = 2.0; + const MIN_SCALE: f32 = 0.3; + const MAX_SCALE: f32 = 1.75; for ev in evr_scroll.read() { for mut projection_component in query.iter_mut() { @@ -97,14 +96,14 @@ pub fn scroll_events(mut evr_scroll: EventReader, mut query: Query<& }; let new_scale = match ev.unit { - MouseScrollUnit::Line => current_scale + ev.y * ZOOM_SENSITIVITY, - MouseScrollUnit::Pixel => current_scale + ev.y * PIXEL_SENSITIVITY, + MouseScrollUnit::Line => current_scale + ev.y * LINE_SENSITIVITY, // win, x11 + MouseScrollUnit::Pixel => current_scale + ev.y * PIXEL_SENSITIVITY, // macos, wayland }; - + *projection_component = Projection::Orthographic(OrthographicProjection { scale: new_scale.max(MIN_SCALE).min(MAX_SCALE), ..OrthographicProjection::default_2d() }); } } -} \ No newline at end of file +} diff --git a/src/citizen.rs b/src/citizen.rs index d202c3d..10aa471 100644 --- a/src/citizen.rs +++ b/src/citizen.rs @@ -435,13 +435,13 @@ pub fn spawn_citizens(mut commands: Commands, asset_server: Res) { let mut rng = rand::rng(); // Spawn a handful of citizens - for _ in 0..100 { + for _ in 0..10 { let cit = commands .spawn(Citizen::new( &asset_server, Vec3::new( - rng.random_range(-25.0f32..25.0f32).round(), - rng.random_range(-25.0f32..25.0f32).round(), + rng.random_range(-8.0f32..8.0f32).round(), + rng.random_range(-8.0f32..8.0f32).round(), 35.0, ) * TILE_SIZE, )) diff --git a/src/tilemap.rs b/src/tilemap.rs index acf65ef..2345ebc 100644 --- a/src/tilemap.rs +++ b/src/tilemap.rs @@ -25,7 +25,7 @@ pub const SEED: u32 = 420; #[derive(Resource)] pub struct ChunkMap { - pub loaded_chunks: HashMap, + pub loaded_chunks: HashMap, } impl Default for ChunkMap { @@ -193,18 +193,44 @@ pub fn generate_surface_terrain(x: i32, y: i32) -> f32 { (noise_value * 2.5) as f32 } +fn chunkmap_despawn_timer_system( + mut chunk_map: ResMut, + mut cwss: ResMut, +) { + for (_, (is_loaded, timer)) in chunk_map.loaded_chunks.iter_mut() { + if !*is_loaded { + continue; + } + if *timer > 0 { + *timer -= 1; + } else { + //TODO - remove chunk from chunkmap + + *is_loaded = false; + cwss.state = TerrainSpriteState::WaitingForRender; + } + } +} + fn handle_chunk_events( mut chunk_events: EventReader, + mut chunk_map: ResMut, mut terrain_event_writer: EventWriter, mut weathering_event_writer: EventWriter, mut foliage_event_writer: EventWriter, mut fauna_event_writer: EventWriter, mut cwss: ResMut, ) { - let count = chunk_events.len(); - // Fire each terrain pass. They will all fire sequentially. - for event in chunk_events.read() { - let chunk_pos = event.chunk_position; + let mut any = false; + for event in chunk_events.par_read() { + let chunk_pos = event.0.chunk_position; + if let Some((true, _)) = chunk_map.loaded_chunks.get(&chunk_pos) { + continue; + } + any = true; + let chunk_map_updates: Mutex> = Mutex::new(HashMap::new()); + // Mark chunk as loaded in our thread-safe collection + chunk_map_updates.lock().unwrap().insert(chunk_pos, true); terrain_event_writer.write(ChunkTerrainEvent { chunk_position: chunk_pos, }); @@ -217,8 +243,12 @@ fn handle_chunk_events( fauna_event_writer.write(ChunkFaunaEvent { chunk_position: chunk_pos, }); + // Apply all collected updates to the actual resources + for (chunk_pos, value) in chunk_map_updates.into_inner().unwrap() { + chunk_map.loaded_chunks.insert(chunk_pos, (value, 1800)); + } } - if count > 0 { + if any { cwss.state = TerrainSpriteState::WaitingForRender; } } @@ -226,36 +256,23 @@ fn handle_chunk_events( fn generate_chunk_terrain( commands: ParallelCommands<'_, '_>, // Use ParallelCommands for parallel spawning mut events: EventReader, - mut chunk_map: ResMut, mut tilemap: ResMut, mut forrestry_event_writer: EventWriter, mut occlusion_event_writer: EventWriter, ) { let is_empty = events.is_empty(); let start = Instant::now(); - let count = events.len(); + let count: usize = events.len(); let cave_noise = Perlin::new(SEED); // Create mutexes for our shared resources - let chunk_map_updates = Mutex::new(HashMap::new()); let tilemap_updates = Mutex::new(HashMap::new()); let forrestry_events = Mutex::new(Vec::new()); events.par_read().for_each(|event| { let chunk_pos = event.chunk_position; - // Check if chunk is already loaded - using a local check first to avoid locking - { - let chunk_map_guard = chunk_map.loaded_chunks.get(&chunk_pos); - if let Some(true) = chunk_map_guard { - return; - } - } - - // Mark chunk as loaded in our thread-safe collection - chunk_map_updates.lock().unwrap().insert(chunk_pos, true); - let start_x = chunk_pos.x * CHUNK_SIZE; let start_y = chunk_pos.y * CHUNK_SIZE; @@ -356,11 +373,6 @@ fn generate_chunk_terrain( }); }); - // Apply all collected updates to the actual resources - for (chunk_pos, value) in chunk_map_updates.into_inner().unwrap() { - chunk_map.loaded_chunks.insert(chunk_pos, value); - } - for (pos, data) in tilemap_updates.into_inner().unwrap() { tilemap.floor_tiles.insert(pos, data); occlusion_event_writer.write(TileOcclusionEvent { tile_position: pos }); @@ -623,14 +635,17 @@ impl Plugin for TilemapPlugin { .add_systems( FixedUpdate, ( - handle_chunk_events, - generate_chunk_terrain, - generate_chunk_weathering_and_precipitation, - generate_chunk_forrestry, - generate_chunk_foliage, - generate_chunk_fauna, - ) - .chain(), + ( + handle_chunk_events, + generate_chunk_terrain, + generate_chunk_weathering_and_precipitation, + generate_chunk_forrestry, + generate_chunk_foliage, + generate_chunk_fauna, + ) + .chain(), + chunkmap_despawn_timer_system, + ), ) .add_systems( Update,