refactor file locations for readability

This commit is contained in:
2025-09-11 18:23:53 +01:00
parent e58f6804bf
commit ee7ac39ad5
25 changed files with 1103 additions and 1052 deletions
+174
View File
@@ -0,0 +1,174 @@
use bevy::prelude::*;
use bevy_platform::collections::HashMap;
use bevy_platform::sync::Mutex;
use bevy_platform::time::Instant;
use noise::{NoiseFn, Perlin};
use crate::{
constants::{SEED, TILE_SIZE},
world::{
tiles::TileMap, ChunkForrestryEvent, ChunkTerrainEvent, FloorTilePrefab,
TileOcclusionEvent, CHUNK_SIZE, Z_ABOVE, Z_BELOW,
},
};
pub fn generate_surface_terrain(x: i32, y: i32) -> f32 {
let noise = Perlin::new(SEED);
let mut noise_value = 0.0;
let mut amplitude = 1.0;
let mut frequency = 0.008;
for _ in 0..6 {
noise_value += noise.get([x as f64 * frequency, y as f64 * frequency]) * amplitude;
amplitude *= 0.6;
frequency *= 1.8;
}
(noise_value * 2.5) as f32
}
pub fn generate_chunk_terrain(
commands: ParallelCommands<'_, '_>, // Use ParallelCommands for parallel spawning
mut events: EventReader<ChunkTerrainEvent>,
mut tilemap: ResMut<TileMap>,
mut forrestry_event_writer: EventWriter<ChunkForrestryEvent>,
mut occlusion_event_writer: EventWriter<TileOcclusionEvent>,
) {
let is_empty = events.is_empty();
let start = Instant::now();
let count: usize = events.len();
let cave_noise = Perlin::new(SEED);
// Create mutexes for our shared resources
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;
let start_x = chunk_pos.x * CHUNK_SIZE;
let start_y = chunk_pos.y * CHUNK_SIZE;
let mut surface_positions: Vec<(Vec3, String)> = Vec::new();
let mut local_tilemap_updates: HashMap<IVec3, (i32, bool, bool, bool, i32, [u32; 8])> =
HashMap::new();
// Generate tiles for this chunk
for local_y in 0..CHUNK_SIZE {
for local_x in 0..CHUNK_SIZE {
let world_x = start_x + local_x;
let world_y = start_y + local_y;
let noise_position = Vec3::new(
(world_x as f32 * TILE_SIZE).round(),
(world_y as f32 * TILE_SIZE).round(),
(generate_surface_terrain(world_x, world_y) * TILE_SIZE).round(),
);
// Spawn tiles and add them to tilemap
for z in -Z_BELOW as isize..=Z_ABOVE as isize {
let position = Vec3::new(
(world_x as f32 * TILE_SIZE).round(),
(world_y as f32 * TILE_SIZE).round(),
(z as f32 * TILE_SIZE).round(),
);
let pos_ivec = position.as_ivec3();
if z < -5 {
let cave_value = cave_noise.get([
world_x as f64 * 0.05,
world_y as f64 * 0.05,
z as f64 * 0.05,
]);
if cave_value < -0.75 {
commands.command_scope(|mut cmd| {
FloorTilePrefab::air(position).spawn(&mut cmd);
});
local_tilemap_updates
.insert(pos_ivec, (0, true, false, true, 0, [0; 8]));
// Air tile
} else if cave_value < 0.8 {
commands.command_scope(|mut cmd| {
FloorTilePrefab::rock(position).spawn(&mut cmd);
});
local_tilemap_updates
.insert(pos_ivec, (2, false, true, false, 50, [0; 8]));
// Rock tile
} else {
commands.command_scope(|mut cmd| {
FloorTilePrefab::dirt(position).spawn(&mut cmd);
});
local_tilemap_updates
.insert(pos_ivec, (1, false, true, false, 85, [0; 8]));
// Dirt tile
}
} else if noise_position.z > position.z {
if (generate_surface_terrain(world_x, world_y) * TILE_SIZE).round()
<= position.z + TILE_SIZE
{
commands.command_scope(|mut cmd| {
FloorTilePrefab::grass(position).spawn(&mut cmd);
});
local_tilemap_updates
.insert(pos_ivec, (1, false, true, false, 100, [0; 8])); // Dirt tile (grass)
surface_positions.push((position, ("grass").to_string()));
} else {
commands.command_scope(|mut cmd| {
FloorTilePrefab::dirt(position).spawn(&mut cmd);
});
local_tilemap_updates
.insert(pos_ivec, (1, false, true, false, 85, [0; 8]));
// Dirt tile
}
} else {
commands.command_scope(|mut cmd| {
FloorTilePrefab::air(position).spawn(&mut cmd);
});
local_tilemap_updates.insert(pos_ivec, (0, true, false, true, 0, [0; 8]));
// Air tile
}
}
}
}
// Add our local updates to the global mutexes
{
let mut tilemap_guard = tilemap_updates.lock().unwrap();
for (pos, data) in local_tilemap_updates {
tilemap_guard.insert(pos, data);
}
}
// Store forrestry event for this chunk
forrestry_events.lock().unwrap().push(ChunkForrestryEvent {
chunk_position: chunk_pos,
floor_tiles: surface_positions,
});
});
for (pos, data) in tilemap_updates.into_inner().unwrap() {
tilemap.floor_tiles.insert(pos, data);
occlusion_event_writer.write(TileOcclusionEvent { tile_position: pos });
}
// Send all forrestry events
for event in forrestry_events.into_inner().unwrap() {
forrestry_event_writer.write(event);
}
if !is_empty {
println!("{} terrain chunks loaded in {:.2?}", count, start.elapsed());
}
}
pub fn generate_chunk_weathering_and_precipitation(// mut commands: Commands,
// mut events: EventReader<GenerateChunkEvent>,
// mut chunk_map: ResMut<ChunkMap>,
// mut tilemap: ResMut<TileMap>,
) {
// TODO: Generate weathering and precipitation
// Temperature and humidity
// Erosion
// Hadley lines/cells etc
// Biomes
}