|
|
|
@ -3,7 +3,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
mod mono;
|
|
|
|
mod mono;
|
|
|
|
|
|
|
|
|
|
|
|
use bevy::{color::palettes::css::{DARK_ORANGE, ORANGE}, window::WindowResized};
|
|
|
|
use bevy::{
|
|
|
|
|
|
|
|
asset::LoadedFolder,
|
|
|
|
|
|
|
|
color::palettes::css::{DARK_GREY, DARK_ORANGE, GREY, ORANGE, PINK},
|
|
|
|
|
|
|
|
window::WindowResized,
|
|
|
|
|
|
|
|
};
|
|
|
|
use games::*;
|
|
|
|
use games::*;
|
|
|
|
use mono::*;
|
|
|
|
use mono::*;
|
|
|
|
|
|
|
|
|
|
|
|
@ -16,7 +20,13 @@ fn main() {
|
|
|
|
.insert_resource(ClearColor(WHITE.into()))
|
|
|
|
.insert_resource(ClearColor(WHITE.into()))
|
|
|
|
.add_systems(
|
|
|
|
.add_systems(
|
|
|
|
Startup,
|
|
|
|
Startup,
|
|
|
|
(init_trees, init_ui, position_camera.after(setup_camera)),
|
|
|
|
(
|
|
|
|
|
|
|
|
init_trees,
|
|
|
|
|
|
|
|
init_ui,
|
|
|
|
|
|
|
|
init_debug_ui,
|
|
|
|
|
|
|
|
load_monologues,
|
|
|
|
|
|
|
|
position_camera.after(setup_camera),
|
|
|
|
|
|
|
|
),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.add_systems(
|
|
|
|
.add_systems(
|
|
|
|
Update,
|
|
|
|
Update,
|
|
|
|
@ -29,13 +39,14 @@ fn main() {
|
|
|
|
end_dialog
|
|
|
|
end_dialog
|
|
|
|
.run_if(in_state(DialogState::Idle))
|
|
|
|
.run_if(in_state(DialogState::Idle))
|
|
|
|
.run_if(on_event::<Pointer<Click>>),
|
|
|
|
.run_if(on_event::<Pointer<Click>>),
|
|
|
|
|
|
|
|
spawn_debug_buttons.run_if(on_event::<AssetEvent<Monologue>>),
|
|
|
|
dialog_engine.run_if(on_event::<DialogEvent>),
|
|
|
|
dialog_engine.run_if(on_event::<DialogEvent>),
|
|
|
|
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>),
|
|
|
|
dialog_box_visibility.run_if(state_changed::<DialogState>),
|
|
|
|
dialog_box_visibility.run_if(state_changed::<DialogState>),
|
|
|
|
monologue_asset_tooltip
|
|
|
|
monologue_asset_tooltip
|
|
|
|
.run_if(on_event::<Pointer<Over>>.or(on_event::<Pointer<Out>>)),
|
|
|
|
.run_if(on_event::<Pointer<Over>>.or(on_event::<Pointer<Out>>)),
|
|
|
|
scale_window.run_if(on_event::<WindowResized>)
|
|
|
|
scale_window.run_if(on_event::<WindowResized>),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.add_observer(add_dialog_option)
|
|
|
|
.add_observer(add_dialog_option)
|
|
|
|
@ -69,7 +80,8 @@ fn init_trees(
|
|
|
|
|
|
|
|
|
|
|
|
// Spawn placeholder tree (red)
|
|
|
|
// Spawn placeholder tree (red)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
commands.spawn((
|
|
|
|
commands
|
|
|
|
|
|
|
|
.spawn((
|
|
|
|
Tree,
|
|
|
|
Tree,
|
|
|
|
TreeMonologue(server.load("trees/red.mono")),
|
|
|
|
TreeMonologue(server.load("trees/red.mono")),
|
|
|
|
Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(1.0)))),
|
|
|
|
Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(1.0)))),
|
|
|
|
@ -80,12 +92,14 @@ fn init_trees(
|
|
|
|
..default()
|
|
|
|
..default()
|
|
|
|
})),
|
|
|
|
})),
|
|
|
|
Transform::from_xyz(-15.0, 0.0, 15.0).with_scale(Vec3::splat(10.0)),
|
|
|
|
Transform::from_xyz(-15.0, 0.0, 15.0).with_scale(Vec3::splat(10.0)),
|
|
|
|
)).observe(delete_tree);
|
|
|
|
))
|
|
|
|
|
|
|
|
.observe(delete_tree);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Spawn placeholder tree (green)
|
|
|
|
// Spawn placeholder tree (green)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
commands.spawn((
|
|
|
|
commands
|
|
|
|
|
|
|
|
.spawn((
|
|
|
|
Tree,
|
|
|
|
Tree,
|
|
|
|
TreeMonologue(server.load("trees/green.mono")),
|
|
|
|
TreeMonologue(server.load("trees/green.mono")),
|
|
|
|
Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(1.0)))),
|
|
|
|
Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(1.0)))),
|
|
|
|
@ -96,12 +110,14 @@ fn init_trees(
|
|
|
|
..default()
|
|
|
|
..default()
|
|
|
|
})),
|
|
|
|
})),
|
|
|
|
Transform::from_xyz(15.0, 0.0, 15.0).with_scale(Vec3::splat(10.0)),
|
|
|
|
Transform::from_xyz(15.0, 0.0, 15.0).with_scale(Vec3::splat(10.0)),
|
|
|
|
)).observe(delete_tree);
|
|
|
|
))
|
|
|
|
|
|
|
|
.observe(delete_tree);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Spawn placeholder tree (blue)
|
|
|
|
// Spawn placeholder tree (blue)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
commands.spawn((
|
|
|
|
commands
|
|
|
|
|
|
|
|
.spawn((
|
|
|
|
Tree,
|
|
|
|
Tree,
|
|
|
|
TreeMonologue(server.load("trees/blue.mono")),
|
|
|
|
TreeMonologue(server.load("trees/blue.mono")),
|
|
|
|
Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(1.0)))),
|
|
|
|
Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(1.0)))),
|
|
|
|
@ -112,7 +128,8 @@ fn init_trees(
|
|
|
|
..default()
|
|
|
|
..default()
|
|
|
|
})),
|
|
|
|
})),
|
|
|
|
Transform::from_xyz(0.0, 0.0, -15.0).with_scale(Vec3::splat(10.0)),
|
|
|
|
Transform::from_xyz(0.0, 0.0, -15.0).with_scale(Vec3::splat(10.0)),
|
|
|
|
)).observe(delete_tree);
|
|
|
|
))
|
|
|
|
|
|
|
|
.observe(delete_tree);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -145,6 +162,56 @@ fn init_ui(mut commands: Commands) {
|
|
|
|
.observe(hover_dialog_box_out);
|
|
|
|
.observe(hover_dialog_box_out);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Component)]
|
|
|
|
|
|
|
|
struct MonologuesList;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Component)]
|
|
|
|
|
|
|
|
struct MonologuePreview;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Panel for selecting which monologue tree to spawn
|
|
|
|
|
|
|
|
/// TODO: When monologue is loaded, add a button for it in this
|
|
|
|
|
|
|
|
/// TODO: When mouse over button, preview it in the "MonologuePreview" box
|
|
|
|
|
|
|
|
fn init_debug_ui(mut commands: Commands) {
|
|
|
|
|
|
|
|
commands
|
|
|
|
|
|
|
|
.spawn((
|
|
|
|
|
|
|
|
Node {
|
|
|
|
|
|
|
|
height: Val::Percent(90.0),
|
|
|
|
|
|
|
|
align_self: AlignSelf::Center,
|
|
|
|
|
|
|
|
justify_self: JustifySelf::Start,
|
|
|
|
|
|
|
|
..default()
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
GlobalZIndex(i32::MAX - 1),
|
|
|
|
|
|
|
|
DebuggingState::On,
|
|
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
.with_children(|parent| {
|
|
|
|
|
|
|
|
parent.spawn((
|
|
|
|
|
|
|
|
Node {
|
|
|
|
|
|
|
|
min_width: Val::Px(5.0),
|
|
|
|
|
|
|
|
min_height: Val::Px(5.0),
|
|
|
|
|
|
|
|
max_height: Val::Percent(90.0),
|
|
|
|
|
|
|
|
flex_direction: FlexDirection::Column,
|
|
|
|
|
|
|
|
padding: UiRect::all(Val::Px(10.0)),
|
|
|
|
|
|
|
|
margin: UiRect::all(Val::Px(10.0)),
|
|
|
|
|
|
|
|
..default()
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
BackgroundColor(PINK.into()),
|
|
|
|
|
|
|
|
MonologuesList,
|
|
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
parent.spawn((
|
|
|
|
|
|
|
|
Node {
|
|
|
|
|
|
|
|
min_height: Val::Px(5.0),
|
|
|
|
|
|
|
|
max_height: Val::Percent(90.0),
|
|
|
|
|
|
|
|
flex_direction: FlexDirection::Column,
|
|
|
|
|
|
|
|
padding: UiRect::all(Val::Px(10.0)),
|
|
|
|
|
|
|
|
margin: UiRect::all(Val::Px(10.0)),
|
|
|
|
|
|
|
|
..default()
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
BackgroundColor(ORANGE.into()),
|
|
|
|
|
|
|
|
MonologuePreview,
|
|
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn hover_dialog_box_over(
|
|
|
|
fn hover_dialog_box_over(
|
|
|
|
trigger: Trigger<Pointer<Over>>,
|
|
|
|
trigger: Trigger<Pointer<Over>>,
|
|
|
|
mut query: Query<&mut BackgroundColor, With<DialogBox>>,
|
|
|
|
mut query: Query<&mut BackgroundColor, With<DialogBox>>,
|
|
|
|
@ -522,3 +589,95 @@ fn delete_tree(trigger: Trigger<Pointer<Click>>, mut commands: Commands) {
|
|
|
|
commands.entity(trigger.target()).despawn();
|
|
|
|
commands.entity(trigger.target()).despawn();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn load_monologues(server: ResMut<AssetServer>, mut loaded_folder: Local<Handle<LoadedFolder>>) {
|
|
|
|
|
|
|
|
*loaded_folder = server.load_folder("trees");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn spawn_debug_buttons(
|
|
|
|
|
|
|
|
mut events: EventReader<AssetEvent<Monologue>>,
|
|
|
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
|
|
|
container: Single<Entity, (With<MonologuesList>, Without<Button>)>,
|
|
|
|
|
|
|
|
server: Res<AssetServer>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
debug_assert!(
|
|
|
|
|
|
|
|
!events.is_empty(),
|
|
|
|
|
|
|
|
"Should only spawn buttons when monologues are loaded"
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
events.read().for_each(|event| {
|
|
|
|
|
|
|
|
// If this is an "Asset was loaded" event
|
|
|
|
|
|
|
|
// These are just asset events for monologues so no need to check the asset type
|
|
|
|
|
|
|
|
if let AssetEvent::LoadedWithDependencies { id } = event {
|
|
|
|
|
|
|
|
// Get the handle from the asset ID
|
|
|
|
|
|
|
|
let handle = server.get_id_handle(*id).unwrap();
|
|
|
|
|
|
|
|
// Spawn a button in the box containing buttons
|
|
|
|
|
|
|
|
commands.entity(*container).with_children(|parent| {
|
|
|
|
|
|
|
|
parent
|
|
|
|
|
|
|
|
.spawn((
|
|
|
|
|
|
|
|
Button,
|
|
|
|
|
|
|
|
Text::new(handle.path().unwrap().to_string()),
|
|
|
|
|
|
|
|
TreeMonologue(handle.clone()),
|
|
|
|
|
|
|
|
MonologuesList,
|
|
|
|
|
|
|
|
BackgroundColor(PINK.into()),
|
|
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
.observe(preview_monologue)
|
|
|
|
|
|
|
|
.observe(spawn_monologue_tree)
|
|
|
|
|
|
|
|
.observe(toggle_debug_button_color_over)
|
|
|
|
|
|
|
|
.observe(toggle_debug_button_color_out);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn toggle_debug_button_color_over(
|
|
|
|
|
|
|
|
trigger: Trigger<Pointer<Over>>,
|
|
|
|
|
|
|
|
mut buttons: Query<&mut BackgroundColor, With<Button>>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
if let Ok(mut bg) = buttons.get_mut(trigger.target()) {
|
|
|
|
|
|
|
|
bg.0 = RED.into();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn toggle_debug_button_color_out(
|
|
|
|
|
|
|
|
trigger: Trigger<Pointer<Out>>,
|
|
|
|
|
|
|
|
mut buttons: Query<&mut BackgroundColor, With<Button>>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
if let Ok(mut bg) = buttons.get_mut(trigger.target()) {
|
|
|
|
|
|
|
|
bg.0 = PINK.into();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn preview_monologue(
|
|
|
|
|
|
|
|
trigger: Trigger<Pointer<Over>>,
|
|
|
|
|
|
|
|
container: Single<Entity, (With<MonologuePreview>, Without<Button>, Without<Text>)>,
|
|
|
|
|
|
|
|
tree_monologue: Query<&TreeMonologue, With<Button>>,
|
|
|
|
|
|
|
|
monologues: Res<Assets<Monologue>>,
|
|
|
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
// Get the handle for this button's monologuie
|
|
|
|
|
|
|
|
if let Ok(TreeMonologue(handle)) = tree_monologue.get(trigger.target()) {
|
|
|
|
|
|
|
|
// Get the monologue data
|
|
|
|
|
|
|
|
if let Some(monologue) = monologues.get(handle) {
|
|
|
|
|
|
|
|
commands.entity(*container).despawn_related::<Children>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Spawn the monologue
|
|
|
|
|
|
|
|
let mut i = 0;
|
|
|
|
|
|
|
|
commands.entity(*container).with_children(|parent| {
|
|
|
|
|
|
|
|
while let Some(options) = monologue.get(i) {
|
|
|
|
|
|
|
|
parent.spawn((Text::new(format!("{i}. ---")), MonologuePreview));
|
|
|
|
|
|
|
|
for (n, item) in options.iter().enumerate() {
|
|
|
|
|
|
|
|
parent.spawn((Text::new(format!("{i}.{n}. {item}")), MonologuePreview));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Just implement iter_batches or something
|
|
|
|
|
|
|
|
i += 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn spawn_monologue_tree(trigger: Trigger<Pointer<Click>>, mut commands: Commands) {
|
|
|
|
|
|
|
|
// todo!("Spawn monologue tree when button is clicked")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|