feat: editor paint undone
This commit is contained in:
parent
a3752a6496
commit
fb0e374f17
4 changed files with 144 additions and 13 deletions
72
src/view/editor.rs
Normal file
72
src/view/editor.rs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy::picking::backend::ray::RayMap;
|
||||
|
||||
use crate::grid::{Grid, GridElement};
|
||||
|
||||
pub struct EditorPlugin;
|
||||
|
||||
impl Plugin for EditorPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<EditorTools>().add_observer(apply_tool).add_systems(Update, calculate_tools);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, PartialEq, Eq,Resource)]
|
||||
pub enum EditorTools {
|
||||
#[default]
|
||||
None,
|
||||
Paint{ position: UVec3, block: GridElement },
|
||||
}
|
||||
|
||||
|
||||
#[derive(Component,Default,Clone)]
|
||||
pub struct ViewCube;
|
||||
|
||||
#[derive(Event)]
|
||||
pub struct ApplyTool(EditorTools);
|
||||
|
||||
pub fn calculate_tools(
|
||||
mut commands: Commands,
|
||||
mouse_button: Res<ButtonInput<MouseButton>>,
|
||||
ray_map: Res<RayMap>,
|
||||
mut raycast: MeshRayCast,
|
||||
mut tool: ResMut<EditorTools>,
|
||||
mut gizmos: Gizmos
|
||||
) {
|
||||
let new_tool: Option<EditorTools> = match tool.clone() {
|
||||
EditorTools::None => None,
|
||||
EditorTools::Paint{position: _, block} => {
|
||||
let mut new_position: Option<UVec3> = None;
|
||||
for (_, ray) in ray_map.iter() {
|
||||
let Some((_, hit)) = raycast.cast_ray(*ray, &MeshRayCastSettings::default()).first() else {continue;};
|
||||
gizmos.sphere(hit.point.round(), 0.5, Color::BLACK);
|
||||
new_position = Some(hit.point.floor().as_uvec3());
|
||||
}
|
||||
|
||||
new_position.map(|pos|{
|
||||
EditorTools::Paint { position: pos , block }}
|
||||
)
|
||||
},
|
||||
};
|
||||
if let Some(new_tool) = new_tool {
|
||||
*tool = new_tool;
|
||||
}
|
||||
if mouse_button.just_pressed(MouseButton::Left) {
|
||||
match tool.clone() {
|
||||
EditorTools::None => {},
|
||||
EditorTools::Paint { position, block } => {
|
||||
commands.trigger(ApplyTool(EditorTools::Paint { position, block }));
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_tool(params: On<ApplyTool>, mut grid: ResMut<Grid>) {
|
||||
match params.0 {
|
||||
EditorTools::None => {},
|
||||
EditorTools::Paint { position, block } => {
|
||||
let index = grid.indexify(position).unwrap();
|
||||
grid.data[index] = block;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -8,10 +8,10 @@ pub struct GameViewPlugin;
|
|||
|
||||
impl Plugin for GameViewPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(PreStartup, debug_setup_grid)
|
||||
app
|
||||
.init_resource::<CubeStages>()
|
||||
.init_resource::<TileMaterials>()
|
||||
.add_systems(Startup, setup_view_cubes)
|
||||
.add_systems(Startup, (setup_building_planes,setup_view_cubes))
|
||||
.add_systems(Update, update_cubes);
|
||||
}
|
||||
}
|
||||
|
|
@ -33,14 +33,31 @@ pub struct TileMaterials {
|
|||
pub source: Handle<StandardMaterial>,
|
||||
}
|
||||
|
||||
pub fn debug_setup_grid(mut grid: ResMut<Grid>) {
|
||||
use crate::grid::GridElement;
|
||||
let mut tool = grid.manipulate();
|
||||
tool.fill_xyz(5, 0, 1, 5, 0, 14, GridElement::Solid);
|
||||
//tool.fill_xyz(0, 0, 0, 4, 0, 15, GridElement::Water { amount: MAX_FLUID_AMOUNT });
|
||||
//tool.set_xyz(0, 0, 6, GridElement::Source { source_amount: MAX_FLUID_AMOUNT });
|
||||
tool.set_xyz(0, 8, 6, GridElement::Source { source_amount: MAX_FLUID_AMOUNT });
|
||||
//tool.set_xyz(15,0, 6, GridElement::Drain);
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -2,15 +2,16 @@ use bevy::prelude::*;
|
|||
|
||||
use game::GameViewPlugin;
|
||||
|
||||
use crate::view::ui::UIPlugin;
|
||||
use crate::view::{editor::EditorPlugin, ui::UIPlugin};
|
||||
|
||||
pub mod ui;
|
||||
pub mod game;
|
||||
pub mod editor;
|
||||
|
||||
pub struct ViewPlugin;
|
||||
|
||||
impl Plugin for ViewPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins((GameViewPlugin,UIPlugin));
|
||||
app.add_plugins((GameViewPlugin,UIPlugin,EditorPlugin));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use bevy::prelude::*;
|
|||
|
||||
use crate::grid::{Grid, GridElement};
|
||||
use crate::simulation::SimulationStatus;
|
||||
use crate::view::editor::EditorTools;
|
||||
|
||||
pub struct UIPlugin;
|
||||
|
||||
|
|
@ -22,6 +23,9 @@ struct WaterLabel;
|
|||
#[derive(Component, Clone, Default)]
|
||||
struct SpeedLabel;
|
||||
|
||||
#[derive(Component, Clone, Default)]
|
||||
struct ToolLabel;
|
||||
|
||||
const MAX_FREQUENCY: u32 = 512;
|
||||
const MIN_FREQUENCY: u32 = 1;
|
||||
|
||||
|
|
@ -52,6 +56,7 @@ fn ui() -> impl Scene {
|
|||
}
|
||||
Children [
|
||||
debug_column()
|
||||
editor_column()
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -79,6 +84,42 @@ fn debug_column() -> impl Scene {
|
|||
}
|
||||
}
|
||||
|
||||
fn editor_column() -> impl Scene {
|
||||
bsn! {
|
||||
Node {
|
||||
display: Display::Flex,
|
||||
flex_direction: FlexDirection::Column,
|
||||
align_items: AlignItems::Stretch,
|
||||
justify_content: JustifyContent::Start,
|
||||
padding: px(8),
|
||||
row_gap: px(8),
|
||||
width: px(256),
|
||||
min_width: px(256),
|
||||
}
|
||||
pane()
|
||||
pane_header()
|
||||
pane_body()
|
||||
Children [
|
||||
label("Tools")
|
||||
ToolLabel,
|
||||
@FeathersButton {
|
||||
@caption: bsn!{label("None")}
|
||||
}
|
||||
on(|_activate: On<Activate>, mut tool: ResMut<EditorTools>, mut label: Single<&mut Text, With<ToolLabel>>| {
|
||||
*tool = EditorTools::None;
|
||||
label.0 = "Current tool: None".to_string();
|
||||
}),
|
||||
@FeathersButton {
|
||||
@caption: bsn!{label("Paint")}
|
||||
}
|
||||
on(|_activate: On<Activate>, mut tool: ResMut<EditorTools>, mut label: Single<&mut Text, With<ToolLabel>>| {
|
||||
*tool = EditorTools::Paint { position: UVec3::default(), block: GridElement::Solid };
|
||||
label.0 = "Current tool: Paint".to_string();
|
||||
}),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn water_amount_label() -> impl Scene {
|
||||
bsn! {
|
||||
Node {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue