cargo fmt

main
Elijah C. Voigt 2 years ago
parent 609ae8ebb9
commit fe2e023036

@ -1,11 +1,9 @@
use gltf::*; use gltf::*;
fn main() -> gltf::Result<()> { fn main() -> gltf::Result<()> {
let g = Gltf::open("assets/models/Martian Chess.glb")?; let g = Gltf::open("assets/models/Martian Chess.glb")?;
g.animations() g.animations().into_iter().for_each(|x| {
.into_iter() println!("{:?}", x.name());
.for_each(|x| { });
println!("{:?}", x.name()); Ok(())
});
Ok(())
} }

@ -1,95 +1,93 @@
use bevy::pbr::OpaqueRendererMethod;
use bevy::prelude::*;
use bevy::pbr::ExtendedMaterial; use bevy::pbr::ExtendedMaterial;
use bevy::pbr::MaterialExtension; use bevy::pbr::MaterialExtension;
use bevy::pbr::MaterialMeshBundle; use bevy::pbr::MaterialMeshBundle;
use bevy::pbr::OpaqueRendererMethod;
use bevy::prelude::*;
use bevy::render::render_resource::*; use bevy::render::render_resource::*;
type MyMat = ExtendedMaterial<StandardMaterial, MatExt>; type MyMat = ExtendedMaterial<StandardMaterial, MatExt>;
fn main() { fn main() {
App::new() App::new()
.add_plugins(( .add_plugins((
DefaultPlugins.set(ImagePlugin::default_nearest()), DefaultPlugins.set(ImagePlugin::default_nearest()),
MaterialPlugin::<MyMat>::default(), MaterialPlugin::<MyMat>::default(),
)) ))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, rotate) .add_systems(Update, rotate)
.add_systems(Update, setup_material) .add_systems(Update, setup_material)
.run(); .run();
} }
fn setup( fn setup(mut commands: Commands, assets: Res<AssetServer>) {
mut commands: Commands, commands.spawn(SceneBundle {
assets: Res<AssetServer>, scene: assets.load("models/Martian Chess.glb#Scene0"),
) { ..default()
commands.spawn(SceneBundle { });
scene: assets.load("models/Martian Chess.glb#Scene0"),
..default()
});
commands.spawn(PointLightBundle { commands.spawn(PointLightBundle {
point_light: PointLight { point_light: PointLight {
intensity: 10.0, intensity: 10.0,
..default() ..default()
}, },
transform: Transform::from_xyz(-1.0, 4.5, 4.0).looking_at(Vec3::ZERO, Vec3::Y), transform: Transform::from_xyz(-1.0, 4.5, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
..default() ..default()
}); });
commands.spawn(Camera3dBundle { commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-1.0, 1.5, 4.0).looking_at(Vec3::ZERO, Vec3::Y), transform: Transform::from_xyz(-1.0, 1.5, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
..default() ..default()
}); });
} }
#[derive(Asset, AsBindGroup, Reflect, Debug, Clone)] #[derive(Asset, AsBindGroup, Reflect, Debug, Clone)]
struct MatExt { struct MatExt {
#[uniform(100)] #[uniform(100)]
cutoff: f32, cutoff: f32,
} }
impl MaterialExtension for MatExt { impl MaterialExtension for MatExt {
fn fragment_shader() -> ShaderRef { fn fragment_shader() -> ShaderRef {
"examples/shaders/dissolve.wgsl".into() "examples/shaders/dissolve.wgsl".into()
} }
} }
fn setup_material( fn setup_material(
events: Query<(Entity, &Handle<StandardMaterial>), Added<Handle<StandardMaterial>>>, events: Query<(Entity, &Handle<StandardMaterial>), Added<Handle<StandardMaterial>>>,
standard_materials: Res<Assets<StandardMaterial>>, standard_materials: Res<Assets<StandardMaterial>>,
mut materials: ResMut<Assets<MyMat>>, mut materials: ResMut<Assets<MyMat>>,
mut commands: Commands, mut commands: Commands,
) { ) {
events.iter().for_each(|(entity, handle)| { events.iter().for_each(|(entity, handle)| {
// Extension we will add to existing gltf-sourced materials // Extension we will add to existing gltf-sourced materials
let extension = MatExt { cutoff: 1.0 }; let extension = MatExt { cutoff: 1.0 };
// Base material we will extend for the duration of the dissolve effect // Base material we will extend for the duration of the dissolve effect
let mut base = standard_materials.get(handle).expect("Resolve material data").clone(); let mut base = standard_materials
.get(handle)
.expect("Resolve material data")
.clone();
base.opaque_render_method = OpaqueRendererMethod::Auto; base.opaque_render_method = OpaqueRendererMethod::Auto;
base.alpha_mode = AlphaMode::Mask(0.5); base.alpha_mode = AlphaMode::Mask(0.5);
commands.entity(entity).insert( commands
materials.add(ExtendedMaterial { .entity(entity)
base, .insert(materials.add(ExtendedMaterial { base, extension }))
extension, .remove::<Handle<StandardMaterial>>();
}) })
).remove::<Handle<StandardMaterial>>();
})
} }
fn rotate( fn rotate(
mut query: Query<&mut Transform, With<Handle<Mesh>>>, mut query: Query<&mut Transform, With<Handle<Mesh>>>,
time: Res<Time>, time: Res<Time>,
mut materials: ResMut<Assets<MyMat>>, mut materials: ResMut<Assets<MyMat>>,
) { ) {
query.iter_mut().for_each(|mut t| { query.iter_mut().for_each(|mut t| {
t.rotate_local_y(time.delta_seconds() / 2.0); t.rotate_local_y(time.delta_seconds() / 2.0);
// t.rotate_local_z(time.delta_seconds() / 2.0); // t.rotate_local_z(time.delta_seconds() / 2.0);
// t.rotate_local_x(time.delta_seconds() / 2.0); // t.rotate_local_x(time.delta_seconds() / 2.0);
}); });
materials.iter_mut().for_each(|(_id, m)| { materials.iter_mut().for_each(|(_id, m)| {
m.extension.cutoff = time.elapsed_seconds().sin().abs(); m.extension.cutoff = time.elapsed_seconds().sin().abs();
}) })
} }

@ -76,7 +76,9 @@ fn audio_trigger(
AudioEvent::MenuSelect => tweak.get::<String>("audio_menu_select").unwrap(), AudioEvent::MenuSelect => tweak.get::<String>("audio_menu_select").unwrap(),
AudioEvent::PickUp => tweak.get::<String>("audio_display3d_pick_up").unwrap(), AudioEvent::PickUp => tweak.get::<String>("audio_display3d_pick_up").unwrap(),
AudioEvent::PutDown => tweak.get::<String>("audio_display3d_put_down").unwrap(), AudioEvent::PutDown => tweak.get::<String>("audio_display3d_put_down").unwrap(),
AudioEvent::Idle | AudioEvent::StopIdle => tweak.get::<String>("audio_display3d_idle").unwrap(), AudioEvent::Idle | AudioEvent::StopIdle => {
tweak.get::<String>("audio_display3d_idle").unwrap()
}
AudioEvent::Invalid => tweak.get::<String>("audio_display3d_invalid").unwrap(), AudioEvent::Invalid => tweak.get::<String>("audio_display3d_invalid").unwrap(),
}; };
// There is an event, play an audio // There is an event, play an audio

@ -19,20 +19,20 @@ impl Plugin for DebugPlugin {
SystemInformationDiagnosticsPlugin::default(), SystemInformationDiagnosticsPlugin::default(),
)) ))
.init_resource::<DebugInfo>() .init_resource::<DebugInfo>()
.insert_resource( .insert_resource(GizmoConfig {
GizmoConfig { depth_bias: -0.1,
depth_bias: -0.1, ..default()
..default() })
}, .add_systems(Update, (aabb_gizmo,))
)
.add_systems(Update, (
aabb_gizmo,
))
// Systems that run in the editor mode // Systems that run in the editor mode
.add_systems(Update, ( .add_systems(
selected_gizmo.run_if(any_with_component::<game::Selected>()), Update,
selected_position.run_if(any_with_component::<game::Selected>()), (
).run_if(resource_exists::<DebugEnabled>())) selected_gizmo.run_if(any_with_component::<game::Selected>()),
selected_position.run_if(any_with_component::<game::Selected>()),
)
.run_if(resource_exists::<DebugEnabled>()),
)
.add_systems(Startup, init_debug_ui) .add_systems(Startup, init_debug_ui)
.add_systems( .add_systems(
Update, Update,
@ -156,47 +156,50 @@ fn camera_info(mut debug_infos: ResMut<DebugInfo>, cameras: Query<(&Camera, &Nam
} }
fn aabb_gizmo( fn aabb_gizmo(
added: Query<Entity, Added<game::Selected>>, added: Query<Entity, Added<game::Selected>>,
mut removed: RemovedComponents<game::Selected>, mut removed: RemovedComponents<game::Selected>,
selected: Query<Entity, With<game::Selected>>, selected: Query<Entity, With<game::Selected>>,
active: Option<Res<DebugEnabled>>, active: Option<Res<DebugEnabled>>,
mut commands: Commands, mut commands: Commands,
) { ) {
added.iter().for_each(|e| { added.iter().for_each(|e| {
commands.entity(e).insert(AabbGizmo { color: Some(Color::RED) }); commands.entity(e).insert(AabbGizmo {
}); color: Some(Color::RED),
removed.read().for_each(|e| { });
commands.entity(e).remove::<AabbGizmo>(); });
}); removed.read().for_each(|e| {
match active { commands.entity(e).remove::<AabbGizmo>();
Some(_) => selected.iter().for_each(|e| { });
commands.entity(e).insert(AabbGizmo { color: Some(Color::RED) }); match active {
}), Some(_) => selected.iter().for_each(|e| {
None => selected.iter().for_each(|e| { commands.entity(e).insert(AabbGizmo {
commands.entity(e).remove::<AabbGizmo>(); color: Some(Color::RED),
}), });
} }),
None => selected.iter().for_each(|e| {
commands.entity(e).remove::<AabbGizmo>();
}),
}
} }
/// Draw a gizmo showing cardinal directions for a selected object /// Draw a gizmo showing cardinal directions for a selected object
fn selected_gizmo( fn selected_gizmo(selected: Query<&GlobalTransform, With<game::Selected>>, mut gizmos: Gizmos) {
selected: Query<&GlobalTransform, With<game::Selected>>, selected.iter().for_each(|g| {
mut gizmos: Gizmos, let s = g.translation();
) { gizmos.ray(s, Vec3::X, Color::RED);
selected.iter().for_each(|g| { gizmos.ray(s, Vec3::Y, Color::GREEN);
let s = g.translation(); gizmos.ray(s, Vec3::Z, Color::BLUE);
gizmos.ray(s, Vec3::X, Color::RED); });
gizmos.ray(s, Vec3::Y, Color::GREEN);
gizmos.ray(s, Vec3::Z, Color::BLUE);
});
} }
fn selected_position( fn selected_position(
selected: Query<(Entity, &GlobalTransform), With<game::Selected>>, selected: Query<(Entity, &GlobalTransform), With<game::Selected>>,
mut debug_info: ResMut<debug::DebugInfo>, mut debug_info: ResMut<debug::DebugInfo>,
) { ) {
let val = selected.iter().map(|(e, gt)| { let val = selected
format!("\n{:?} {:?}", e, gt.translation()) .iter()
}).collect::<Vec<String>>().join(""); .map(|(e, gt)| format!("\n{:?} {:?}", e, gt.translation()))
debug_info.set("Position".into(), val); .collect::<Vec<String>>()
.join("");
debug_info.set("Position".into(), val);
} }

@ -12,9 +12,12 @@ use bevy::{
Skybox, Skybox,
}, },
input::mouse::{MouseButtonInput, MouseMotion, MouseScrollUnit, MouseWheel}, input::mouse::{MouseButtonInput, MouseMotion, MouseScrollUnit, MouseWheel},
pbr::{ScreenSpaceAmbientOcclusionBundle, ScreenSpaceAmbientOcclusionSettings, MaterialExtension, ExtendedMaterial, OpaqueRendererMethod}, pbr::{
ExtendedMaterial, MaterialExtension, OpaqueRendererMethod,
ScreenSpaceAmbientOcclusionBundle, ScreenSpaceAmbientOcclusionSettings,
},
render::{ render::{
render_resource::{TextureViewDescriptor, TextureViewDimension, ShaderRef,AsBindGroup}, render_resource::{AsBindGroup, ShaderRef, TextureViewDescriptor, TextureViewDimension},
view::ColorGrading, view::ColorGrading,
}, },
window::PrimaryWindow, window::PrimaryWindow,
@ -27,81 +30,89 @@ impl Plugin for Display3dPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_plugins(( app.add_plugins((
TemporalAntiAliasPlugin, TemporalAntiAliasPlugin,
MaterialPlugin::<DissolveMaterial>::default(), MaterialPlugin::<DissolveMaterial>::default(),
)) ))
.insert_resource(Msaa::Off) .insert_resource(Msaa::Off)
.add_systems( .add_systems(
OnExit(GameState::Loading), OnExit(GameState::Loading),
(initialize, fix_skybox.before(initialize), update_tweaks.run_if(resource_exists::<tweak::GameTweaks>()),), (
) initialize,
.add_systems( fix_skybox.before(initialize),
Update, update_tweaks.run_if(resource_exists::<tweak::GameTweaks>()),
( ),
load_assets )
.run_if(in_state(GameState::Loading)) .add_systems(
.run_if(on_event::<AssetEvent<Tweaks>>()), Update,
hydrate_camera.run_if(any_component_added::<Camera3d>), (
set_piece_model.run_if(any_component_added::<Piece>), load_assets
set_board_model.run_if(any_component_added::<game::BoardComponent>), .run_if(in_state(GameState::Loading))
set_board_model.run_if(any_component_added::<TilesComponent>), .run_if(on_event::<AssetEvent<Tweaks>>()),
set_valid_move_model.run_if(any_component_added::<game::ValidMove>), hydrate_camera.run_if(any_component_added::<Camera3d>),
set_tile_hitbox.run_if(any_component_added::<game::Tile>), set_piece_model.run_if(any_component_added::<Piece>),
set_piece_position.run_if(any_component_changed::<BoardIndex>), set_board_model.run_if(any_component_added::<game::BoardComponent>),
set_piece_texture.run_if(any_component_changed::<Side>).run_if(resource_exists::<tweak::GameTweaks>()), set_board_model.run_if(any_component_added::<TilesComponent>),
select set_valid_move_model.run_if(any_component_added::<game::ValidMove>),
.run_if(in_state(GameState::Play)) set_tile_hitbox.run_if(any_component_added::<game::Tile>),
.run_if(in_state(DisplayState::Display3d)) set_piece_position.run_if(any_component_changed::<BoardIndex>),
.run_if(on_event::<MouseButtonInput>()), set_piece_texture
pick_up.run_if(any_component_added::<game::Selected>), .run_if(any_component_changed::<Side>)
put_down.run_if(any_component_removed::<game::Selected>()), .run_if(resource_exists::<tweak::GameTweaks>()),
switch_sides select
.run_if(in_state(GameState::Play))
.run_if(state_changed::<game::TurnState>()),
update_tweaks.run_if(on_event::<AssetEvent<Tweaks>>()).run_if(resource_exists::<tweak::GameTweaks>()),
scale_lighting.run_if(
any_component_added::<DirectionalLight>
.or_else(any_component_added::<SpotLight>)
.or_else(any_component_added::<PointLight>)
.or_else(on_event::<AssetEvent<Tweaks>>()),
),
capture_piece.run_if(any_with_component::<game::Captured>()),
),
)
.add_systems(
Update,
(
move_camera.run_if(on_event::<MouseMotion>()),
mouse_zoom.run_if(on_event::<MouseWheel>()),
gizmo_system,
selected_gizmo,
moves_gizmo,
)
.run_if(resource_exists::<debug::DebugEnabled>())
.run_if(in_state(GameState::Play)) .run_if(in_state(GameState::Play))
.run_if(in_state(DisplayState::Display3d)), .run_if(in_state(DisplayState::Display3d))
) .run_if(on_event::<MouseButtonInput>()),
.add_systems( pick_up.run_if(any_component_added::<game::Selected>),
OnEnter(DisplayState::Display3d), put_down.run_if(any_component_removed::<game::Selected>()),
( switch_sides
activate::<Display3d>, .run_if(in_state(GameState::Play))
set_piece_texture.run_if(resource_exists::<tweak::GameTweaks>()), .run_if(state_changed::<game::TurnState>()),
opening_animation update_tweaks
.run_if(run_once()) .run_if(on_event::<AssetEvent<Tweaks>>())
.run_if(in_state(GameState::Play)), .run_if(resource_exists::<tweak::GameTweaks>()),
scale_lighting.run_if(
any_component_added::<DirectionalLight>
.or_else(any_component_added::<SpotLight>)
.or_else(any_component_added::<PointLight>)
.or_else(on_event::<AssetEvent<Tweaks>>()),
), ),
capture_piece.run_if(any_with_component::<game::Captured>()),
),
)
.add_systems(
Update,
(
move_camera.run_if(on_event::<MouseMotion>()),
mouse_zoom.run_if(on_event::<MouseWheel>()),
gizmo_system,
selected_gizmo,
moves_gizmo,
) )
.add_systems(OnExit(DisplayState::Display3d), deactivate::<Display3d>) .run_if(resource_exists::<debug::DebugEnabled>())
.add_systems( .run_if(in_state(GameState::Play))
OnEnter(GameState::Play), .run_if(in_state(DisplayState::Display3d)),
( )
activate::<Display3d>.run_if(in_state(DisplayState::Display3d)), .add_systems(
set_piece_texture, OnEnter(DisplayState::Display3d),
update_tweaks.run_if(resource_exists::<tweak::GameTweaks>()), (
opening_animation activate::<Display3d>,
.run_if(run_once()) set_piece_texture.run_if(resource_exists::<tweak::GameTweaks>()),
.run_if(in_state(DisplayState::Display3d)), opening_animation
), .run_if(run_once())
); .run_if(in_state(GameState::Play)),
),
)
.add_systems(OnExit(DisplayState::Display3d), deactivate::<Display3d>)
.add_systems(
OnEnter(GameState::Play),
(
activate::<Display3d>.run_if(in_state(DisplayState::Display3d)),
set_piece_texture,
update_tweaks.run_if(resource_exists::<tweak::GameTweaks>()),
opening_animation
.run_if(run_once())
.run_if(in_state(DisplayState::Display3d)),
),
);
} }
} }
@ -280,10 +291,9 @@ fn hydrate_camera(
.unwrap() .unwrap()
.as_str(), .as_str(),
), ),
}.expect("Camera Startup"); }
player .expect("Camera Startup");
.play(animation.clone()) player.play(animation.clone()).pause();
.pause();
} }
}); });
} }
@ -738,7 +748,11 @@ fn select(
meshes: Res<Assets<Mesh>>, meshes: Res<Assets<Mesh>>,
cameras: Query<(&Camera, &GlobalTransform)>, cameras: Query<(&Camera, &GlobalTransform)>,
windows: Query<&Window, With<PrimaryWindow>>, windows: Query<&Window, With<PrimaryWindow>>,
selectable: Query<(Entity, &BoardIndex, &Side, Option<&Piece>), (With<game::Selectable>, With<Display3d>)>, selectable: Query<
(Entity, &BoardIndex, &Side),
(With<game::Selectable>, With<Display3d>),
>,
selected: Query<Entity, With<game::Selected>>,
children: Query<&Children>, children: Query<&Children>,
mut selections: EventWriter<game::Selection>, mut selections: EventWriter<game::Selection>,
state: Res<State<game::TurnState>>, state: Res<State<game::TurnState>>,
@ -760,20 +774,24 @@ fn select(
hit::intersects3d(&ray, mesh, &gt).and_then(|_hit| { hit::intersects3d(&ray, mesh, &gt).and_then(|_hit| {
selectable selectable
.iter() .iter()
.find_map(|(e, &board_index, &side, piece_ish)| { .find_map(|(e, &board_index, &side)| {
// Check if this piece is on the active side // Check the side of the selection if no piece is selected
let side_check = piece_ish.is_some() && *state.get() == side; // Otherwise this is fine, select away
let side_check = !selected.is_empty() || *state.get() == side;
// This entity was hit (tile hitboxes) let hit_check = {
let primary = entity == e; // This entity was hit (tile hitboxes)
let primary = entity == e;
// A child was hit (pieces) // A child was hit (pieces)
let secondary = children let secondary = children
.iter_descendants(e) .iter_descendants(e)
.any(|child| child == entity); .any(|child| child == entity);
(side_check && (primary || secondary)).then_some(board_index) primary || secondary
};
(side_check && hit_check).then_some(board_index)
}) })
.iter() .iter()
.for_each(|&board_index| { .for_each(|&board_index| {
@ -816,7 +834,10 @@ fn moves_gizmo(
} }
fn set_valid_move_model( fn set_valid_move_model(
mut events: Query<(&mut Handle<Scene>, &mut Visibility), (With<Display3d>, Added<game::ValidMove>)>, mut events: Query<
(&mut Handle<Scene>, &mut Visibility),
(With<Display3d>, Added<game::ValidMove>),
>,
gltfs: Res<Assets<Gltf>>, gltfs: Res<Assets<Gltf>>,
tweaks: Res<Assets<Tweaks>>, tweaks: Res<Assets<Tweaks>>,
tweaks_file: Res<tweak::GameTweaks>, tweaks_file: Res<tweak::GameTweaks>,
@ -874,20 +895,28 @@ fn pick_up(
info!(" Child: {:?}", child); info!(" Child: {:?}", child);
if let Ok((name, mut player)) = players.get_mut(child) { if let Ok((name, mut player)) = players.get_mut(child) {
info!("Picking up {:?} ({:?}) {:?}", name, entity, piece); info!("Picking up {:?} ({:?}) {:?}", name, entity, piece);
let pickup_animation = format!("display3d_models_animations_pick_up_{:?}", piece).to_ascii_lowercase(); let pickup_animation =
let pickup_handle = gltf.named_animations.get( format!("display3d_models_animations_pick_up_{:?}", piece).to_ascii_lowercase();
tweak let pickup_handle = gltf
.get::<String>(pickup_animation.as_str()) .named_animations
.unwrap() .get(
.as_str(), tweak
).expect("Pickup Animation"); .get::<String>(pickup_animation.as_str())
let idle_animation = format!("display3d_models_animations_idle_{:?}", piece).to_ascii_lowercase(); .unwrap()
let idle_handle = gltf.named_animations.get( .as_str(),
tweak )
.get::<String>(idle_animation.as_str()) .expect("Pickup Animation");
.unwrap() let idle_animation =
.as_str(), format!("display3d_models_animations_idle_{:?}", piece).to_ascii_lowercase();
).expect("Idle animation"); let idle_handle = gltf
.named_animations
.get(
tweak
.get::<String>(idle_animation.as_str())
.unwrap()
.as_str(),
)
.expect("Idle animation");
if let Some(pickup_clip) = clips.get(pickup_handle) { if let Some(pickup_clip) = clips.get(pickup_handle) {
if let Some(idle_clip) = clips.get(idle_handle) { if let Some(idle_clip) = clips.get(idle_handle) {
if pickup_clip.compatible_with(name) && idle_clip.compatible_with(name) { if pickup_clip.compatible_with(name) && idle_clip.compatible_with(name) {
@ -931,13 +960,18 @@ fn put_down(
children.iter_descendants(entity).for_each(|child| { children.iter_descendants(entity).for_each(|child| {
if let Ok((name, mut player)) = players.get_mut(child) { if let Ok((name, mut player)) = players.get_mut(child) {
info!("Putting down {:?}", entity); info!("Putting down {:?}", entity);
let putdown_animation = format!("display3d_models_animations_put_down_{:?}", piece).to_ascii_lowercase(); let putdown_animation =
let putdown_handle = gltf.named_animations.get( format!("display3d_models_animations_put_down_{:?}", piece)
tweak .to_ascii_lowercase();
.get::<String>(putdown_animation.as_str()) let putdown_handle = gltf
.unwrap() .named_animations
.as_str(), .get(
).expect("PutDown Animation"); tweak
.get::<String>(putdown_animation.as_str())
.unwrap()
.as_str(),
)
.expect("PutDown Animation");
if let Some(putdown_clip) = clips.get(putdown_handle) { if let Some(putdown_clip) = clips.get(putdown_handle) {
if putdown_clip.compatible_with(name) { if putdown_clip.compatible_with(name) {
player player
@ -1006,7 +1040,11 @@ fn switch_sides(
} }
fn scale_lighting( fn scale_lighting(
mut directional: Query<(Entity, &mut DirectionalLight, Option<&Original<DirectionalLight>>)>, mut directional: Query<(
Entity,
&mut DirectionalLight,
Option<&Original<DirectionalLight>>,
)>,
mut spot: Query<(Entity, &mut SpotLight, Option<&Original<SpotLight>>)>, mut spot: Query<(Entity, &mut SpotLight, Option<&Original<SpotLight>>)>,
mut point: Query<(Entity, &mut PointLight, Option<&Original<PointLight>>)>, mut point: Query<(Entity, &mut PointLight, Option<&Original<PointLight>>)>,
mut commands: Commands, mut commands: Commands,
@ -1017,18 +1055,24 @@ fn scale_lighting(
.get(tweaks_file.handle.clone()) .get(tweaks_file.handle.clone())
.expect("Load tweakfile"); .expect("Load tweakfile");
let directional_tweak = tweak.get::<f32>("display3d_lights_scaling_directional").expect("Directional lighting scalar"); let directional_tweak = tweak
directional.iter_mut().for_each(|(entity, mut val, original)| { .get::<f32>("display3d_lights_scaling_directional")
debug!("Scaling directional light {:?}", entity); .expect("Directional lighting scalar");
if let Some(Original(v)) = original { directional
val.illuminance = v.illuminance * directional_tweak; .iter_mut()
} else { .for_each(|(entity, mut val, original)| {
commands.entity(entity).insert(Original(val.clone())); debug!("Scaling directional light {:?}", entity);
val.illuminance *= directional_tweak; if let Some(Original(v)) = original {
} val.illuminance = v.illuminance * directional_tweak;
}); } else {
commands.entity(entity).insert(Original(val.clone()));
val.illuminance *= directional_tweak;
}
});
let spot_tweak = tweak.get::<f32>("display3d_lights_scaling_spot").expect("Spot lighting scalar"); let spot_tweak = tweak
.get::<f32>("display3d_lights_scaling_spot")
.expect("Spot lighting scalar");
spot.iter_mut().for_each(|(entity, mut val, original)| { spot.iter_mut().for_each(|(entity, mut val, original)| {
debug!("Scaling spot light {:?}", entity); debug!("Scaling spot light {:?}", entity);
if let Some(Original(v)) = original { if let Some(Original(v)) = original {
@ -1039,7 +1083,9 @@ fn scale_lighting(
} }
}); });
let point_tweak = tweak.get::<f32>("display3d_lights_scaling_point").expect("Point lighting scalar"); let point_tweak = tweak
.get::<f32>("display3d_lights_scaling_point")
.expect("Point lighting scalar");
point.iter_mut().for_each(|(entity, mut val, original)| { point.iter_mut().for_each(|(entity, mut val, original)| {
debug!("Scaling point light {:?}", entity); debug!("Scaling point light {:?}", entity);
if let Some(Original(v)) = original { if let Some(Original(v)) = original {
@ -1224,14 +1270,14 @@ type DissolveMaterial = ExtendedMaterial<StandardMaterial, DissolveExtension>;
/// Material extension for dissolving effect /// Material extension for dissolving effect
#[derive(Asset, AsBindGroup, Reflect, Debug, Clone)] #[derive(Asset, AsBindGroup, Reflect, Debug, Clone)]
struct DissolveExtension { struct DissolveExtension {
#[uniform(100)] #[uniform(100)]
percentage: f32, percentage: f32,
} }
impl MaterialExtension for DissolveExtension { impl MaterialExtension for DissolveExtension {
fn fragment_shader() -> ShaderRef { fn fragment_shader() -> ShaderRef {
"shaders/dissolve.wgsl".into() "shaders/dissolve.wgsl".into()
} }
} }
// Component for 'backing up' components which are temporarily not used // Component for 'backing up' components which are temporarily not used
@ -1245,10 +1291,13 @@ struct Backup<T: Component>(T);
/// The animation is like a 'beam me up scotty' sorta thing. /// The animation is like a 'beam me up scotty' sorta thing.
fn capture_piece( fn capture_piece(
events: Query<Entity, (With<Display3d>, Added<game::Captured>)>, events: Query<Entity, (With<Display3d>, Added<game::Captured>)>,
mut query: Query<(&mut Visibility, &mut Transform, &Side), (With<Display3d>, With<game::Captured>)>, mut query: Query<
(&mut Visibility, &mut Transform, &Side),
(With<Display3d>, With<game::Captured>),
>,
mut state: Local<Option<game::CaptureFlow>>, mut state: Local<Option<game::CaptureFlow>>,
standard_materials: ResMut<Assets<StandardMaterial>>, standard_materials: ResMut<Assets<StandardMaterial>>,
mut dissolve_materials: ResMut<Assets<DissolveMaterial>>, mut dissolve_materials: ResMut<Assets<DissolveMaterial>>,
object_standard_materials: Query<&Handle<StandardMaterial>>, object_standard_materials: Query<&Handle<StandardMaterial>>,
object_dissolve_materials: Query<&Handle<DissolveMaterial>>, object_dissolve_materials: Query<&Handle<DissolveMaterial>>,
backup_material: Query<&Backup<Handle<StandardMaterial>>>, backup_material: Query<&Backup<Handle<StandardMaterial>>>,
@ -1270,31 +1319,32 @@ fn capture_piece(
// Play fade-out animation // Play fade-out animation
{ {
object_dissolve_materials object_dissolve_materials.iter().for_each(|handle| {
.iter() let extended_material = dissolve_materials
.for_each(|handle| { .get_mut(handle)
let extended_material = dissolve_materials .expect("Get the dissolve material");
.get_mut(handle)
.expect("Get the dissolve material");
// Calculate how much of the animation has passed // Calculate how much of the animation has passed
let delta = time.delta_seconds() / duration; let delta = time.delta_seconds() / duration;
// Change the material's value to create animation // Change the material's value to create animation
extended_material.extension.percentage -= delta; // TODO: Tweak this timing extended_material.extension.percentage -= delta; // TODO: Tweak this timing
debug!("Play fade out animation {:?} {:?}", delta, extended_material.extension.percentage); debug!(
"Play fade out animation {:?} {:?}",
delta, extended_material.extension.percentage
);
if extended_material.extension.percentage <= 0.0 { if extended_material.extension.percentage <= 0.0 {
// Set to exactly 0 for simplicity // Set to exactly 0 for simplicity
extended_material.extension.percentage = 0.0; extended_material.extension.percentage = 0.0;
// Move to next state now that animation is done // Move to next state now that animation is done
*state = s.next(); *state = s.next();
} }
}); });
} }
}, }
game::CaptureFlow::Store(entity) => { game::CaptureFlow::Store(entity) => {
let (mut v, mut t, side) = query let (mut v, mut t, side) = query
.get_mut(entity) .get_mut(entity)
@ -1306,7 +1356,7 @@ fn capture_piece(
t.translation = capture_translation(side, score.get(*side)); t.translation = capture_translation(side, score.get(*side));
*state = s.next(); *state = s.next();
}, }
game::CaptureFlow::FadeIn(entity) => { game::CaptureFlow::FadeIn(entity) => {
let (mut v, _, _) = query let (mut v, _, _) = query
.get_mut(entity) .get_mut(entity)
@ -1317,67 +1367,69 @@ fn capture_piece(
// Play fade-in animation // Play fade-in animation
{ {
object_dissolve_materials object_dissolve_materials.iter().for_each(|handle| {
.iter() let extended_material = dissolve_materials
.for_each(|handle| { .get_mut(handle)
let extended_material = dissolve_materials .expect("Get the dissolve material");
.get_mut(handle)
.expect("Get the dissolve material"); // Calculate how much of the animation has passed
let delta = time.delta_seconds() / duration;
// Calculate how much of the animation has passed
let delta = time.delta_seconds() / duration; // Change the material's value to create animation
extended_material.extension.percentage += delta; // TODO: Tweak this timing
// Change the material's value to create animation
extended_material.extension.percentage += delta; // TODO: Tweak this timing debug!(
"Play fade in animation {:?} {:?}",
debug!("Play fade in animation {:?} {:?}", delta, extended_material.extension.percentage); delta, extended_material.extension.percentage
);
if extended_material.extension.percentage >= 1.0 {
// Move to next state now that animation is done if extended_material.extension.percentage >= 1.0 {
*state = s.next(); // Move to next state now that animation is done
*state = s.next();
// Remove the captured component for bookkeeping
commands.entity(entity).remove::<game::Captured>(); // Remove the captured component for bookkeeping
commands.entity(entity).remove::<game::Captured>();
// Remove the dissolve material
commands.entity(entity).remove::<Handle<DissolveMaterial>>(); // Remove the dissolve material
commands.entity(entity).remove::<Handle<DissolveMaterial>>();
// Re-add the original material
if let Ok(Backup(orig)) = backup_material.get(entity) { // Re-add the original material
commands.entity(entity).insert(orig.clone()); if let Ok(Backup(orig)) = backup_material.get(entity) {
commands.entity(entity).remove::<Backup<Handle<StandardMaterial>>>(); commands.entity(entity).insert(orig.clone());
} else { commands
warn!("Entity {:?} does not have original material", entity) .entity(entity)
} .remove::<Backup<Handle<StandardMaterial>>>();
} else {
warn!("Entity {:?} does not have original material", entity)
} }
}); }
});
} }
} }
} }
}, }
None => { None => {
*state = events.iter().next().map(|entity| { *state = events.iter().next().map(|entity| {
children children
.iter_descendants(entity) .iter_descendants(entity)
.filter_map(|e| { .filter_map(|e| object_standard_materials.get(e).ok().map(|h| (e, h)))
object_standard_materials.get(e).ok().map(|h| (e, h))
})
.for_each(|(child, handle)| { .for_each(|(child, handle)| {
// Extension we will add to existing gltf-sourced materials // Extension we will add to existing gltf-sourced materials
let extension = DissolveExtension { percentage: 1.0 }; let extension = DissolveExtension { percentage: 1.0 };
// Base material we will extend for the duration of the dissolve effect // Base material we will extend for the duration of the dissolve effect
let mut base = standard_materials.get(handle).expect("Resolve material data").clone(); let mut base = standard_materials
.get(handle)
base.opaque_render_method = OpaqueRendererMethod::Auto; .expect("Resolve material data")
base.alpha_mode = AlphaMode::Mask(0.5); .clone();
commands.entity(child).insert( base.opaque_render_method = OpaqueRendererMethod::Auto;
dissolve_materials.add(ExtendedMaterial { base.alpha_mode = AlphaMode::Mask(0.5);
base,
extension, commands
}) .entity(child)
).insert(Backup(handle.clone())) .insert(dissolve_materials.add(ExtendedMaterial { base, extension }))
.remove::<Handle<StandardMaterial>>(); .insert(Backup(handle.clone()))
.remove::<Handle<StandardMaterial>>();
}); });
// Set the next state to start fading out // Set the next state to start fading out

@ -32,7 +32,9 @@ impl Plugin for GamePlugin {
) )
.add_systems( .add_systems(
PreUpdate, PreUpdate,
asserts::<display3d::Display3d>.run_if(in_state(DisplayState::Display3d)).run_if(in_state(GameState::Play)), asserts::<display3d::Display3d>
.run_if(in_state(DisplayState::Display3d))
.run_if(in_state(GameState::Play)),
) )
.add_systems( .add_systems(
PostUpdate, PostUpdate,
@ -70,7 +72,6 @@ impl PartialEq<Side> for TurnState {
} }
} }
#[derive(Debug, Component, Clone, PartialEq, Copy, Hash)] #[derive(Debug, Component, Clone, PartialEq, Copy, Hash)]
pub(crate) enum Piece { pub(crate) enum Piece {
Pawn, Pawn,
@ -190,8 +191,8 @@ impl CaptureFlow {
pub(crate) fn next(&self) -> Option<Self> { pub(crate) fn next(&self) -> Option<Self> {
match self { match self {
Self::FadeOut(e) => Some(Self::Store(e.clone())), Self::FadeOut(e) => Some(Self::Store(e.clone())),
Self::Store(e) => Some(Self::FadeIn(e.clone())), Self::Store(e) => Some(Self::FadeIn(e.clone())),
Self::FadeIn(_) => None, Self::FadeIn(_) => None,
} }
} }
} }
@ -517,7 +518,7 @@ pub(crate) fn update_board(
audio_events.send(audio::AudioEvent::StopIdle); audio_events.send(audio::AudioEvent::StopIdle);
*played = true; *played = true;
if *from != *to_idx { if *from != *to_idx {
let ns = !*curr_state.get() ; let ns = !*curr_state.get();
info!("Piece moved, switching sides: {:?}", ns); info!("Piece moved, switching sides: {:?}", ns);
next_state.set(ns); next_state.set(ns);
} }
@ -700,9 +701,7 @@ fn show_valid_moves(
} }
/// Hide "Valid Move" indicators when a piece is de-selected /// Hide "Valid Move" indicators when a piece is de-selected
fn hide_valid_moves( fn hide_valid_moves(mut indicators: Query<&mut Visibility, With<ValidMove>>) {
mut indicators: Query<&mut Visibility, With<ValidMove>>,
) {
indicators.iter_mut().for_each(|mut visibility| { indicators.iter_mut().for_each(|mut visibility| {
*visibility = Visibility::Hidden; *visibility = Visibility::Hidden;
}); });

@ -2,7 +2,6 @@
#![feature(iter_intersperse)] // used in debug.rs #![feature(iter_intersperse)] // used in debug.rs
#![feature(async_closure)] // Loading tweakfiles #![feature(async_closure)] // Loading tweakfiles
mod audio; mod audio;
mod credits; mod credits;
mod debug; mod debug;
@ -101,7 +100,14 @@ fn toggle_display_camera(
} }
fn activate<Marker: Component>( fn activate<Marker: Component>(
mut entities: Query<&mut Visibility, (With<Marker>, Without<game::Captured>, Without<game::ValidMove>)>, mut entities: Query<
&mut Visibility,
(
With<Marker>,
Without<game::Captured>,
Without<game::ValidMove>,
),
>,
) { ) {
entities.iter_mut().for_each(|mut visibility| { entities.iter_mut().for_each(|mut visibility| {
*visibility = Visibility::Visible; *visibility = Visibility::Visible;

@ -50,16 +50,14 @@ fn init_menu_ui(mut commands: Commands) {
}, },
)) ))
.with_children(|parent| { .with_children(|parent| {
parent.spawn( parent.spawn(TextBundle::from_section(
TextBundle::from_section( "M A R T I A N C H E S S",
"M A R T I A N C H E S S", TextStyle {
TextStyle { font_size: 48.0,
font_size: 48.0, color: Color::ORANGE_RED,
color: Color::ORANGE_RED, ..default()
..default() },
}, ));
)
);
parent parent
.spawn(( .spawn((
GameState::Play, GameState::Play,

@ -54,9 +54,9 @@ impl Tweaks {
} else { } else {
None None
} }
}).flatten().map(|h| { })
(k.clone(), h) .flatten()
}), .map(|h| (k.clone(), h)),
_ => None, _ => None,
}) })
.collect(); .collect();
@ -78,11 +78,10 @@ impl Tweaks {
} }
pub fn get<'de, T: Deserialize<'de>>(&self, key: &str) -> Option<T> { pub fn get<'de, T: Deserialize<'de>>(&self, key: &str) -> Option<T> {
Tweaks::locate(&self.table, key) Tweaks::locate(&self.table, key).map(|val| match val.try_into() {
.map(|val| match val.try_into() { Ok(val) => val,
Ok(val) => val, Err(e) => panic!("{}", e.message()),
Err(e) => panic!("{}", e.message()) })
})
} }
fn iter_all(t: &toml::Table, key: &str) -> Vec<(String, toml::Value)> { fn iter_all(t: &toml::Table, key: &str) -> Vec<(String, toml::Value)> {

Loading…
Cancel
Save