Buildings Processing

Tile/Chunk updates events
This commit is contained in:
2024-08-03 18:48:47 -04:00
parent 59090fd3fb
commit bde25435ec
18 changed files with 318 additions and 52 deletions

View File

@@ -1,4 +1,6 @@
use bevy::{prelude::*, window::PrimaryWindow};
use std::f32::consts::E;
use bevy::{ecs::world::CommandQueue, prelude::*, window::PrimaryWindow};
use bevy_asset_loader::loading_state::{
config::{ConfigureLoadingState, LoadingStateConfig},
LoadingStateAppExt,
@@ -6,10 +8,13 @@ use bevy_asset_loader::loading_state::{
use bevy_rapier3d::{parry::transformation::utils::transform, pipeline::QueryFilter, plugin::RapierContext};
use shared::{
despawn::Despawn,
events::TileModifiedEvent,
states::{AssetLoadState, GameplayState},
tags::MainCamera,
};
use world_generation::{heightmap, hex_utils::HexCoord, map::map::Map};
use world_generation::{
heightmap, hex_utils::HexCoord, map::map::Map, prelude::GenerationConfig, states::GeneratorState,
};
use crate::{
assets::{
@@ -17,7 +22,8 @@ use crate::{
building_database::BuildingDatabase,
},
build_queue::{BuildQueue, QueueEntry},
buildings_map::BuildingMap,
buildings_map::{BuildingEntry, BuildingMap},
prelude::Building,
};
pub struct BuildingPugin;
@@ -25,7 +31,6 @@ pub struct BuildingPugin;
impl Plugin for BuildingPugin {
fn build(&self, app: &mut App) {
app.insert_resource(BuildQueue::default());
app.init_resource::<BuildingMap>();
app.add_plugins(BuildingAssetPlugin);
app.configure_loading_state(
@@ -34,11 +39,31 @@ impl Plugin for BuildingPugin {
app.add_systems(Update, init.run_if(in_state(AssetLoadState::Loading)));
app.add_systems(Update, hq_placement.run_if(in_state(GameplayState::PlaceHQ)));
app.add_systems(
PreUpdate,
prepare_building_map.run_if(in_state(GeneratorState::SpawnMap)),
);
app.add_systems(Update, regernerate.run_if(in_state(GeneratorState::Regenerate)));
app.add_systems(
PostUpdate,
update_building_heights.run_if(in_state(GeneratorState::Idle)),
);
app.add_systems(PreUpdate, process_build_queue.run_if(in_state(GameplayState::Playing)));
}
}
fn prepare_building_map(mut commands: Commands, cfg: Res<GenerationConfig>) {
commands.insert_resource(BuildingMap::new(cfg.size));
}
fn regernerate(mut commands: Commands, buildings: Query<Entity, With<Building>>, cfg: Res<GenerationConfig>) {
for e in buildings.iter() {
commands.entity(e).despawn();
}
commands.insert_resource(BuildingMap::new(cfg.size));
}
#[derive(Resource)]
struct IndicatorCube(Handle<Mesh>, Handle<StandardMaterial>);
@@ -114,6 +139,7 @@ fn process_build_queue(
mut commands: Commands,
db: Res<BuildingDatabase>,
building_assets: Res<Assets<BuildingAsset>>,
mut building_map: ResMut<BuildingMap>,
heightmap: Res<Map>,
) {
for item in &queue.queue {
@@ -121,12 +147,44 @@ fn process_build_queue(
if let Some(building) = building_assets.get(handle.id()) {
let h = heightmap.sample_height(&item.pos);
println!("Spawning {} at {}", building.name, item.pos);
commands.spawn(SceneBundle {
scene: building.prefab.clone(),
transform: Transform::from_translation(item.pos.to_world(h)),
..Default::default()
});
let e = commands.spawn((
SceneBundle {
scene: building.prefab.clone(),
transform: Transform::from_translation(item.pos.to_world(h)),
..Default::default()
},
Building,
));
building_map.add_building(BuildingEntry::new(item.pos, e.id()));
}
}
queue.queue.clear();
}
fn update_building_heights(
mut tile_updates: EventReader<TileModifiedEvent>,
building_map: Res<BuildingMap>,
mut commands: Commands,
) {
for event in tile_updates.read() {
match event {
TileModifiedEvent::HeightChanged(coord, new_height) => {
if let Some(building) = building_map.get_building(coord) {
let mut queue = CommandQueue::default();
let e = building.entity.clone();
let h = *new_height;
queue.push(move |world: &mut World| {
let mut emut = world.entity_mut(e);
if let Some(mut transform) = emut.get_mut::<Transform>() {
transform.translation.y = h;
}
});
commands.append(&mut queue);
}
}
_ => (),
}
}
}

View File

@@ -1,14 +1,16 @@
use bevy::prelude::*;
use world_generation::hex_utils::HexCoord;
use world_generation::{hex_utils::HexCoord, prelude::Chunk};
#[derive(Resource, Default)]
#[derive(Resource)]
pub struct BuildingMap {
pub chunks: Vec<BuildingChunk>,
pub size: UVec2,
}
impl BuildingMap {
pub fn new(size: UVec2) -> Self {
let mut db = BuildingMap {
size,
chunks: Vec::with_capacity(size.length_squared() as usize),
};
@@ -23,19 +25,39 @@ impl BuildingMap {
return db;
}
pub fn get_buildings_in_range(&self, coord: &HexCoord, radius: usize) -> Option<Vec<&BuildingEntry>> {
pub fn get_buildings_in_range(&self, coord: &HexCoord, radius: usize) -> Vec<&BuildingEntry> {
assert!(radius != 0, "Radius cannot be zero");
todo!();
let w = self.size.x as usize * Chunk::SIZE;
let h = self.size.y as usize * Chunk::SIZE;
let coords = coord.hex_select_bounded(radius, true, h, w);
return self.get_buildings_in_coords(coords);
}
pub fn get_buildings_in_coords(&self, coords: Vec<HexCoord>) -> Vec<&BuildingEntry> {
let mut result = Vec::new();
for coord in &coords {
if let Some(buidling) = self.get_building(coord) {
result.push(buidling);
}
}
return result;
}
pub fn get_building(&self, coord: &HexCoord) -> Option<&BuildingEntry> {
todo!();
let chunk = &self.chunks[coord.to_chunk_index(self.size.x as usize)];
return chunk.get_building(coord);
}
pub fn add_building(&mut self, entry: BuildingEntry) {
let chunk = &mut self.chunks[entry.coord.to_chunk_index(self.size.x as usize)];
chunk.add_building(entry);
}
}
pub struct BuildingChunk {
pub entries: Vec<BuildingChunk>,
pub entries: Vec<BuildingEntry>,
pub index: usize,
pub offset: IVec2,
}
@@ -50,7 +72,11 @@ impl BuildingChunk {
}
pub fn get_building(&self, coord: &HexCoord) -> Option<&BuildingEntry> {
todo!();
return self.entries.iter().find(|b| &b.coord == coord);
}
pub fn add_building(&mut self, entry: BuildingEntry) {
self.entries.push(entry);
}
}

View File

@@ -3,4 +3,5 @@ pub mod build_queue;
pub mod building_plugin;
pub mod buildings_map;
pub mod footprint;
pub mod prelude;
pub use building_plugin::*;

View File

@@ -0,0 +1,3 @@
use bevy::prelude::*;
#[derive(Component)]
pub struct Building;