|
|
|
@ -1,5 +1,6 @@
|
|
|
|
#![allow(clippy::type_complexity)]
|
|
|
|
#![allow(clippy::type_complexity)]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use bevy::color::palettes::css::{DARK_GREY, DARK_ORANGE, GREY, ORANGE};
|
|
|
|
use games::*;
|
|
|
|
use games::*;
|
|
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
fn main() {
|
|
|
|
@ -15,9 +16,11 @@ fn main() {
|
|
|
|
(
|
|
|
|
(
|
|
|
|
dialog_engine.run_if(input_just_pressed(KeyCode::KeyN)),
|
|
|
|
dialog_engine.run_if(input_just_pressed(KeyCode::KeyN)),
|
|
|
|
mouse_wheel_scroll.run_if(on_event::<MouseWheel>),
|
|
|
|
mouse_wheel_scroll.run_if(on_event::<MouseWheel>),
|
|
|
|
auto_scroll.run_if(any_component_added::<DialogOption>)
|
|
|
|
auto_scroll.run_if(any_component_added::<DialogOption>),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
.add_observer(add_dialog_option)
|
|
|
|
|
|
|
|
.add_observer(add_dialog_line)
|
|
|
|
.run();
|
|
|
|
.run();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -132,6 +135,37 @@ fn position_camera(mut query: Query<&mut Transform, (With<Camera>, With<Camera3d
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Allows user to scroll (with mouse whell) through old dialog
|
|
|
|
|
|
|
|
fn mouse_wheel_scroll(
|
|
|
|
|
|
|
|
mut events: EventReader<MouseWheel>,
|
|
|
|
|
|
|
|
mut scroll_position: Query<&mut ScrollPosition>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
events.read().for_each(|MouseWheel { unit, y, .. }| {
|
|
|
|
|
|
|
|
let offset_y = match unit {
|
|
|
|
|
|
|
|
MouseScrollUnit::Line => 10.0 * y,
|
|
|
|
|
|
|
|
MouseScrollUnit::Pixel => 1.0 * y,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
scroll_position
|
|
|
|
|
|
|
|
.iter_mut()
|
|
|
|
|
|
|
|
.for_each(|mut pos| pos.offset_y += offset_y);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Automatically scrolls dialog when a new batch of options are added
|
|
|
|
|
|
|
|
fn auto_scroll(
|
|
|
|
|
|
|
|
added: Query<Entity, Added<DialogOption>>,
|
|
|
|
|
|
|
|
mut scroll_positions: Query<&mut ScrollPosition>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
debug_assert!(
|
|
|
|
|
|
|
|
!added.is_empty(),
|
|
|
|
|
|
|
|
"Should only scroll when dialog options are added"
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
scroll_positions.iter_mut().for_each(|mut sp| {
|
|
|
|
|
|
|
|
sp.offset_y = f32::MAX;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// A possible line of dialog the user can choose
|
|
|
|
/// A possible line of dialog the user can choose
|
|
|
|
#[derive(Component)]
|
|
|
|
#[derive(Component)]
|
|
|
|
struct DialogOption;
|
|
|
|
struct DialogOption;
|
|
|
|
@ -159,9 +193,7 @@ fn dialog_engine(
|
|
|
|
commands.entity(*dialog_box).with_children(|parent| {
|
|
|
|
commands.entity(*dialog_box).with_children(|parent| {
|
|
|
|
if let Some(options) = dialog.get(*idx) {
|
|
|
|
if let Some(options) = dialog.get(*idx) {
|
|
|
|
options.iter().for_each(|option| {
|
|
|
|
options.iter().for_each(|option| {
|
|
|
|
parent
|
|
|
|
parent.spawn((Text::new(*option), DialogOption));
|
|
|
|
.spawn((Text::new(*option), Button, DialogOption))
|
|
|
|
|
|
|
|
.observe(choose_dialog);
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
@ -170,42 +202,68 @@ fn dialog_engine(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// When a dialog option is chosen (clicked on) we do the following:
|
|
|
|
/// When a dialog option is chosen (clicked on) we do the following:
|
|
|
|
/// 1. Remove the Button and DialogOption components from that entity
|
|
|
|
fn choose_dialog_option(
|
|
|
|
/// 2. Insert the DialogLine component to that entity
|
|
|
|
trigger: Trigger<Pointer<Click>>,
|
|
|
|
/// 3. Remove all other DialogOptions from the DialogBox
|
|
|
|
mut commands: Commands,
|
|
|
|
fn choose_dialog(trigger: Trigger<Pointer<Click>>, mut commands: Commands) {
|
|
|
|
texts: Query<&Text>,
|
|
|
|
|
|
|
|
options: Query<Entity, With<DialogOption>>,
|
|
|
|
|
|
|
|
dialog_box: Single<Entity, With<DialogBox>>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
info!("Choosing dialog {:?}", trigger.target());
|
|
|
|
info!("Choosing dialog {:?}", trigger.target());
|
|
|
|
commands
|
|
|
|
|
|
|
|
.entity(trigger.target())
|
|
|
|
info!("Despawning dialog options");
|
|
|
|
.remove::<Button>()
|
|
|
|
options.iter().for_each(|e| {
|
|
|
|
.remove::<DialogOption>()
|
|
|
|
commands.entity(e).despawn();
|
|
|
|
.insert(DialogLine);
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
info!("Inserting dialog line");
|
|
|
|
|
|
|
|
if let Ok(t) = texts.get(trigger.target()) {
|
|
|
|
|
|
|
|
commands.entity(*dialog_box).with_children(|parent| {
|
|
|
|
|
|
|
|
parent.spawn((t.clone(), DialogLine));
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Allows user to scroll (with mouse whell) through old dialog
|
|
|
|
fn hover_dialog_option_over(
|
|
|
|
fn mouse_wheel_scroll(
|
|
|
|
trigger: Trigger<Pointer<Over>>,
|
|
|
|
mut events: EventReader<MouseWheel>,
|
|
|
|
mut query: Query<(&mut TextColor, &mut BackgroundColor)>,
|
|
|
|
mut scroll_position: Query<&mut ScrollPosition>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
events.read().for_each(|MouseWheel { unit, y, .. }| {
|
|
|
|
if let Ok((mut tc, mut bg)) = query.get_mut(trigger.target()) {
|
|
|
|
let offset_y = match unit {
|
|
|
|
*tc = TextColor(DARK_ORANGE.into());
|
|
|
|
MouseScrollUnit::Line => 10.0 * y,
|
|
|
|
bg.0.set_alpha(0.9);
|
|
|
|
MouseScrollUnit::Pixel => 1.0 * y,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
scroll_position
|
|
|
|
|
|
|
|
.iter_mut()
|
|
|
|
|
|
|
|
.for_each(|mut pos| pos.offset_y += offset_y);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Automatically scrolls dialog when a new batch of options are added
|
|
|
|
fn hover_dialog_option_out(
|
|
|
|
fn auto_scroll(
|
|
|
|
trigger: Trigger<Pointer<Out>>,
|
|
|
|
added: Query<Entity, Added<DialogOption>>,
|
|
|
|
mut query: Query<(&mut TextColor, &mut BackgroundColor)>,
|
|
|
|
mut scroll_positions: Query<&mut ScrollPosition>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
debug_assert!(!added.is_empty(), "Should only scroll when dialog options are added");
|
|
|
|
if let Ok((mut tc, mut bg)) = query.get_mut(trigger.target()) {
|
|
|
|
|
|
|
|
*tc = TextColor(ORANGE.into());
|
|
|
|
|
|
|
|
bg.0.set_alpha(0.0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
scroll_positions.iter_mut().for_each(|mut sp| {
|
|
|
|
/// When a (Text) dialog option is added:
|
|
|
|
sp.offset_y = f32::MAX;
|
|
|
|
/// 1. Add the Button component
|
|
|
|
});
|
|
|
|
/// 2. Change the color to Orange
|
|
|
|
|
|
|
|
/// 3. Add observers for click (select) and hover (change color)
|
|
|
|
|
|
|
|
fn add_dialog_option(trigger: Trigger<OnAdd, DialogOption>, mut commands: Commands) {
|
|
|
|
|
|
|
|
commands
|
|
|
|
|
|
|
|
.entity(trigger.target())
|
|
|
|
|
|
|
|
.insert(Button)
|
|
|
|
|
|
|
|
.insert(Node {
|
|
|
|
|
|
|
|
width: Val::Percent(100.0),
|
|
|
|
|
|
|
|
..default()
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.insert(TextLayout::new_with_justify(JustifyText::Center))
|
|
|
|
|
|
|
|
.insert(TextColor(ORANGE.into()))
|
|
|
|
|
|
|
|
.insert(BackgroundColor(BLACK.with_alpha(0.0).into()))
|
|
|
|
|
|
|
|
.observe(choose_dialog_option)
|
|
|
|
|
|
|
|
.observe(hover_dialog_option_over)
|
|
|
|
|
|
|
|
.observe(hover_dialog_option_out);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn add_dialog_line(trigger: Trigger<OnAdd, DialogLine>, mut commands: Commands) {
|
|
|
|
|
|
|
|
debug!("Adding dialog line");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|