172 lines
5.4 KiB
Rust
172 lines
5.4 KiB
Rust
use bevy::prelude::*;
|
|
use crate::grid::{Grid,GridElement};
|
|
use crate::MAX_FLUID_AMOUNT;
|
|
|
|
const FLUID_FULLNES_STAGES: usize = 7;
|
|
|
|
pub struct GameViewPlugin;
|
|
|
|
impl Plugin for GameViewPlugin {
|
|
fn build(&self, app: &mut App) {
|
|
app
|
|
.init_resource::<CubeStages>()
|
|
.init_resource::<TileMaterials>()
|
|
.add_systems(Startup, (setup_building_planes,setup_view_cubes))
|
|
.add_systems(Update, update_cubes);
|
|
}
|
|
}
|
|
|
|
#[derive(Resource, Default)]
|
|
pub struct CubeStages(pub Vec<Handle<Mesh>>);
|
|
|
|
#[derive(Component, Clone, Default)]
|
|
pub struct TileWatch{
|
|
pub index: usize,
|
|
pub previous_element: GridElement
|
|
}
|
|
|
|
#[derive(Resource, Default)]
|
|
pub struct TileMaterials {
|
|
pub solid: Handle<StandardMaterial>,
|
|
pub water: Handle<StandardMaterial>,
|
|
pub drain: Handle<StandardMaterial>,
|
|
pub source: Handle<StandardMaterial>,
|
|
}
|
|
|
|
pub fn setup_building_planes(
|
|
mut commands: Commands,
|
|
mut meshes: ResMut<Assets<Mesh>>,
|
|
grid: Res<Grid>
|
|
) {
|
|
let mut mesh: Mesh = (Cuboid::new(grid.size.x as f32, grid.size.y as f32, grid.size.z as f32).mesh()).into();
|
|
let _ = mesh.invert_winding();
|
|
|
|
|
|
let mesh_handle = meshes.add(mesh);
|
|
let center = (grid.size.as_vec3() - Vec3::ONE)/2.;
|
|
commands.spawn_scene(bsn!{
|
|
Mesh3d(mesh_handle)
|
|
Transform {
|
|
translation: center
|
|
}
|
|
MeshMaterial3d<StandardMaterial>(asset_value(
|
|
StandardMaterial {
|
|
base_color: Color::WHITE,
|
|
..default()
|
|
}
|
|
))
|
|
Visibility::Visible
|
|
});
|
|
|
|
}
|
|
|
|
pub fn setup_view_cubes(
|
|
mut commands: Commands,
|
|
mut meshes: ResMut<Assets<Mesh>>,
|
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
|
mut stages: ResMut<CubeStages>,
|
|
mut tile_materials: ResMut<TileMaterials>,
|
|
grid: Res<Grid>) {
|
|
for i in 0..FLUID_FULLNES_STAGES {
|
|
let tile_height = ((i+1) as f32)/(FLUID_FULLNES_STAGES as f32);
|
|
let mesh = meshes.add(Cuboid::new(1., tile_height, 1.));
|
|
stages.0.push(mesh);
|
|
}
|
|
|
|
*tile_materials = TileMaterials {
|
|
solid: materials.add(StandardMaterial {
|
|
base_color: Color::hsl(268., 0.778, 0.499),
|
|
..default()
|
|
}),
|
|
water: materials.add(StandardMaterial {
|
|
base_color: Color::hsl(172.,0.502,0.571),
|
|
..default()
|
|
}),
|
|
drain: materials.add(StandardMaterial {
|
|
base_color: Color::hsl(342., 0.628, 0.685),
|
|
..default()
|
|
}),
|
|
source: materials.add(StandardMaterial {
|
|
base_color: Color::hsl(172., 0.502, 0.371),
|
|
..default()
|
|
})
|
|
};
|
|
|
|
let mesh = stages.0[FLUID_FULLNES_STAGES-1].clone();
|
|
|
|
for i in 0..grid.cell_amount() {
|
|
commands.spawn_scene(
|
|
cube(
|
|
grid.deindexify(i as u32).as_vec3(),
|
|
i as usize,
|
|
mesh.clone()
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
pub fn cube(position: Vec3,index: usize,mesh: Handle<Mesh>) -> impl Scene {
|
|
bsn! {
|
|
Mesh3d(mesh)
|
|
MeshMaterial3d<StandardMaterial>
|
|
Transform::from_translation(position)
|
|
TileWatch{
|
|
index
|
|
}
|
|
Visibility::Hidden
|
|
|
|
}
|
|
}
|
|
|
|
pub fn update_cubes(query: Query<(&mut Mesh3d,&mut Visibility,&mut MeshMaterial3d<StandardMaterial>,&mut TileWatch, &mut Transform)>, materials: Res<TileMaterials>, stages: Res<CubeStages>, grid: Res<Grid>) {
|
|
if grid.is_changed() == false { return; }
|
|
|
|
for (mut mesh,mut visibility, mut material, mut tile_data, mut transform) in query {
|
|
let state = grid.data[tile_data.index];
|
|
|
|
if tile_data.previous_element == state {
|
|
continue;
|
|
}
|
|
|
|
match state {
|
|
GridElement::Air => {
|
|
*visibility = Visibility::Hidden;
|
|
},
|
|
GridElement::Water { amount } => {
|
|
*visibility = Visibility::Visible;
|
|
material.0 = materials.water.clone();
|
|
let stage = ((amount as f32)/(MAX_FLUID_AMOUNT as f32) * (FLUID_FULLNES_STAGES-1) as f32).ceil() as usize;
|
|
|
|
transform.translation = grid.deindexify(tile_data.index as u32).as_vec3() - vec3(0.,((FLUID_FULLNES_STAGES-1-stage) as f32 / (FLUID_FULLNES_STAGES as f32))/2.,0.);
|
|
|
|
mesh.0 = stages.0[stage].clone();
|
|
},
|
|
GridElement::Solid => {
|
|
*visibility = Visibility::Visible;
|
|
material.0 = materials.solid.clone();
|
|
mesh.0 = stages.0[FLUID_FULLNES_STAGES-1].clone();
|
|
transform.translation = Vec3::ZERO;
|
|
},
|
|
GridElement::Drain => {
|
|
*visibility = Visibility::Visible;
|
|
material.0 = materials.drain.clone();
|
|
mesh.0 = stages.0[FLUID_FULLNES_STAGES-1].clone();
|
|
transform.translation = Vec3::ZERO;
|
|
},
|
|
GridElement::Source { source_amount } => {
|
|
*visibility = Visibility::Visible;
|
|
material.0 = materials.source.clone();
|
|
let stage = ((source_amount as f32)/(MAX_FLUID_AMOUNT as f32) * (FLUID_FULLNES_STAGES-1) as f32).ceil() as usize;
|
|
|
|
transform.translation = grid.deindexify(tile_data.index as u32).as_vec3() - vec3(0.,((FLUID_FULLNES_STAGES-1-stage) as f32 / (FLUID_FULLNES_STAGES as f32))/2.,0.);
|
|
|
|
mesh.0 = stages.0[stage].clone();
|
|
}
|
|
|
|
}
|
|
|
|
tile_data.previous_element = state;
|
|
}
|
|
}
|