2024-05-12 20:17:17 +00:00
|
|
|
// ▄████████▄ + ███ + ▄█████████ ███ +
|
|
|
|
// ███▀ ▀███ + + ███ ███▀ + ███ + +
|
|
|
|
// ███ + ███ ███ ███ █████████ ███ ███ ███ ███
|
|
|
|
// ███ +███ ███ ███ ███ ███▐██████ ███ ███ ███
|
|
|
|
// ███ + ███ ███+ ███ +███ ███ + ███ ███ + ███
|
|
|
|
// ███▄ ▄███ ███▄ ███ ███ + ███ + ███ ███▄ ███
|
|
|
|
// ▀████████▀ + ▀███████ ███▄ ███▄ ▀████ ▀███████
|
|
|
|
// + + + ███
|
|
|
|
// + ▀████████████████████████████████████████████████████▀
|
|
|
|
//
|
|
|
|
// This plugin manages game menus and the player death screen
|
|
|
|
|
|
|
|
use crate::prelude::*;
|
|
|
|
use bevy::prelude::*;
|
2024-05-12 23:42:22 +00:00
|
|
|
use fastrand;
|
|
|
|
|
|
|
|
pub const POEMS: &str = &include_str!("data/deathpoems.in");
|
2024-05-12 20:17:17 +00:00
|
|
|
|
|
|
|
pub struct MenuPlugin;
|
|
|
|
impl Plugin for MenuPlugin {
|
|
|
|
fn build(&self, app: &mut App) {
|
|
|
|
app.add_systems(Startup, setup.after(hud::setup));
|
|
|
|
app.add_systems(PreUpdate, show_deathscreen.run_if(on_event::<DeathScreenEvent>()));
|
|
|
|
app.add_systems(Update, handle_deathscreen_input);
|
|
|
|
app.add_event::<DeathScreenEvent>();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Component)] pub struct DeathScreenElement;
|
|
|
|
#[derive(Component)] pub struct BlackScreen;
|
|
|
|
#[derive(Component)] pub struct DeathText;
|
|
|
|
#[derive(Event, PartialEq)] pub enum DeathScreenEvent { Show, Hide }
|
|
|
|
|
|
|
|
pub fn setup(
|
|
|
|
mut commands: Commands,
|
|
|
|
asset_server: Res<AssetServer>,
|
|
|
|
settings: Res<Settings>,
|
|
|
|
) {
|
|
|
|
commands.spawn((
|
|
|
|
BlackScreen,
|
|
|
|
DeathScreenElement,
|
|
|
|
NodeBundle {
|
2024-05-12 22:44:03 +00:00
|
|
|
style: style_fullscreen(),
|
2024-05-12 20:17:17 +00:00
|
|
|
background_color: Color::BLACK.into(),
|
|
|
|
visibility: Visibility::Hidden,
|
|
|
|
..default()
|
|
|
|
},
|
|
|
|
));
|
|
|
|
|
|
|
|
let font_handle = asset_server.load(FONT);
|
|
|
|
let style_death = TextStyle {
|
|
|
|
font: font_handle.clone(),
|
|
|
|
font_size: settings.font_size_deathtext,
|
|
|
|
color: settings.hud_color_subtitles,
|
|
|
|
..default()
|
|
|
|
};
|
2024-05-12 23:42:22 +00:00
|
|
|
let style_death_poem = TextStyle {
|
|
|
|
font: font_handle.clone(),
|
|
|
|
font_size: settings.font_size_deathpoem,
|
|
|
|
color: settings.hud_color_deathpoem,
|
|
|
|
..default()
|
|
|
|
};
|
2024-05-12 20:17:17 +00:00
|
|
|
let style_death_subtext = TextStyle {
|
|
|
|
font: font_handle.clone(),
|
|
|
|
font_size: settings.font_size_deathsubtext,
|
|
|
|
color: settings.hud_color_subtitles,
|
|
|
|
..default()
|
|
|
|
};
|
|
|
|
let style_death_subsubtext = TextStyle {
|
|
|
|
font: font_handle.clone(),
|
|
|
|
font_size: settings.font_size_deathsubtext * 0.8,
|
|
|
|
color: settings.hud_color_subtitles,
|
|
|
|
..default()
|
|
|
|
};
|
|
|
|
commands.spawn((
|
|
|
|
DeathScreenElement,
|
|
|
|
NodeBundle {
|
2024-05-12 22:44:03 +00:00
|
|
|
style: style_centered(),
|
2024-05-12 20:17:17 +00:00
|
|
|
visibility: Visibility::Hidden,
|
|
|
|
..default()
|
|
|
|
},
|
|
|
|
)).with_children(|builder| {
|
|
|
|
builder.spawn((
|
|
|
|
DeathText,
|
|
|
|
TextBundle {
|
|
|
|
text: Text {
|
|
|
|
sections: vec![
|
2024-05-12 23:42:22 +00:00
|
|
|
TextSection::new("", style_death_poem),
|
2024-05-12 20:17:17 +00:00
|
|
|
TextSection::new("You are dead.\n", style_death),
|
|
|
|
TextSection::new("Cause: ", style_death_subtext.clone()),
|
|
|
|
TextSection::new("Unknown", style_death_subtext),
|
2024-05-12 23:42:22 +00:00
|
|
|
TextSection::new("\n\n\n\nPress E to begin anew.", style_death_subsubtext),
|
2024-05-12 20:17:17 +00:00
|
|
|
],
|
|
|
|
justify: JustifyText::Center,
|
|
|
|
..default()
|
|
|
|
},
|
|
|
|
..default()
|
|
|
|
},
|
|
|
|
));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn show_deathscreen(
|
|
|
|
mut er_deathscreen: EventReader<DeathScreenEvent>,
|
|
|
|
mut q_vis: Query<&mut Visibility, With<DeathScreenElement>>,
|
|
|
|
mut q_text: Query<&mut Text, With<DeathText>>,
|
2024-05-13 02:33:03 +00:00
|
|
|
mut ew_pausesfx: EventWriter<audio::PauseAllSfxEvent>,
|
2024-05-12 20:17:17 +00:00
|
|
|
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
|
|
|
mut ew_effect: EventWriter<visual::SpawnEffectEvent>,
|
2024-05-12 20:26:40 +00:00
|
|
|
mut ew_respawn: EventWriter<world::RespawnEvent>,
|
2024-05-13 02:41:17 +00:00
|
|
|
mut ew_respawnaudiosinks: EventWriter<audio::RespawnSinksEvent>,
|
2024-05-12 20:17:17 +00:00
|
|
|
mut settings: ResMut<Settings>,
|
|
|
|
) {
|
|
|
|
for event in er_deathscreen.read() {
|
|
|
|
let show = *event == DeathScreenEvent::Show;
|
|
|
|
for mut vis in &mut q_vis {
|
|
|
|
*vis = bool2vis(show);
|
|
|
|
}
|
|
|
|
settings.deathscreen_active = show;
|
|
|
|
|
|
|
|
if show {
|
2024-05-13 02:33:03 +00:00
|
|
|
ew_pausesfx.send(audio::PauseAllSfxEvent);
|
2024-05-12 20:17:17 +00:00
|
|
|
if let Ok(mut text) = q_text.get_single_mut() {
|
2024-05-12 23:42:22 +00:00
|
|
|
let poems: Vec<&str> = POEMS.split("\n\n").collect();
|
|
|
|
if poems.len() > 0 {
|
|
|
|
let poem_index = fastrand::usize(..poems.len());
|
|
|
|
let poem = poems[poem_index].to_string();
|
|
|
|
text.sections[0].value = poem + "\n\n\n\n";
|
|
|
|
}
|
|
|
|
text.sections[3].value = settings.death_cause.clone();
|
2024-05-12 20:17:17 +00:00
|
|
|
}
|
|
|
|
} else {
|
2024-05-13 02:41:17 +00:00
|
|
|
ew_respawnaudiosinks.send(audio::RespawnSinksEvent);
|
2024-05-12 20:17:17 +00:00
|
|
|
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::WakeUp));
|
|
|
|
ew_effect.send(visual::SpawnEffectEvent { class: visual::Effects::FadeIn(Color::BLACK), duration: 0.3 });
|
2024-05-12 20:26:40 +00:00
|
|
|
ew_respawn.send(world::RespawnEvent);
|
2024-05-12 20:17:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn handle_deathscreen_input(
|
|
|
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
|
|
|
mut ew_deathscreen: EventWriter<DeathScreenEvent>,
|
|
|
|
settings: ResMut<Settings>,
|
|
|
|
) {
|
|
|
|
if !settings.deathscreen_active {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if keyboard_input.pressed(settings.key_interact) {
|
|
|
|
ew_deathscreen.send(DeathScreenEvent::Hide);
|
|
|
|
}
|
|
|
|
}
|