outfly/src/menu.rs

697 lines
25 KiB
Rust
Raw Normal View History

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));
2024-05-22 02:57:20 +00:00
app.add_systems(
PreUpdate,
show_deathscreen.run_if(on_event::<DeathScreenEvent>()),
);
2024-05-12 20:17:17 +00:00
app.add_systems(Update, handle_deathscreen_input);
2024-05-22 02:57:20 +00:00
app.add_systems(
PostUpdate,
update_menu
.after(game::handle_game_event)
.run_if(on_event::<UpdateMenuEvent>()),
);
2024-05-13 18:21:56 +00:00
app.add_systems(Update, handle_input.run_if(alive));
2024-05-22 02:57:20 +00:00
app.insert_resource(DeathScreenInputDelayTimer(Timer::from_seconds(
1.0,
TimerMode::Once,
)));
2024-05-13 18:21:56 +00:00
app.insert_resource(MenuState::default());
2024-05-12 20:17:17 +00:00
app.add_event::<DeathScreenEvent>();
2024-05-13 19:37:57 +00:00
app.add_event::<UpdateMenuEvent>();
2024-05-12 20:17:17 +00:00
}
}
2024-05-22 02:57:20 +00:00
#[derive(Resource)]
pub struct DeathScreenInputDelayTimer(pub Timer);
#[derive(Component)]
pub struct MenuElement;
#[derive(Component)]
pub struct MenuTopLevel;
#[derive(Component)]
pub struct MenuAchievements;
#[derive(Component)]
pub struct DeathScreenElement;
#[derive(Component)]
pub struct DeathText;
#[derive(Event)]
pub struct UpdateMenuEvent;
#[derive(Event, PartialEq)]
pub enum DeathScreenEvent {
Show,
Hide,
}
2024-05-12 20:17:17 +00:00
2024-05-13 18:21:56 +00:00
pub const MENUDEF: &[(&str, MenuAction)] = &[
2024-05-13 19:37:57 +00:00
("", MenuAction::ToggleAR),
2024-05-23 03:02:59 +00:00
("", MenuAction::ChangeARAvatar),
2024-09-22 14:21:18 +00:00
("", MenuAction::ToggleMap),
("", MenuAction::ModLightAmp),
2024-09-22 01:40:12 +00:00
("", MenuAction::ModFlashlightPower),
2024-09-22 02:34:36 +00:00
("", MenuAction::ModThrusterBoost),
("", MenuAction::ModReactor),
2024-05-13 19:37:57 +00:00
("", MenuAction::ToggleSound),
("", MenuAction::ToggleMusic),
2024-05-13 21:51:18 +00:00
("", MenuAction::ToggleCamera),
2024-05-13 19:37:57 +00:00
("", MenuAction::ToggleShadows),
2024-09-22 14:21:18 +00:00
("Fullscreen [F11]", MenuAction::ToggleFullscreen),
("Take Off Helmet", MenuAction::Restart),
2024-05-13 18:21:56 +00:00
("Quit", MenuAction::Quit),
];
#[derive(Component)]
pub enum MenuAction {
ToggleMap,
ToggleAR,
2024-05-23 03:02:59 +00:00
ChangeARAvatar,
ModLightAmp,
2024-09-22 01:40:12 +00:00
ModFlashlightPower,
2024-09-22 02:34:36 +00:00
ModThrusterBoost,
ModReactor,
2024-05-13 18:21:56 +00:00
ToggleSound,
ToggleMusic,
2024-05-13 21:51:18 +00:00
ToggleCamera,
2024-05-13 18:21:56 +00:00
ToggleFullscreen,
2024-05-13 19:11:27 +00:00
ToggleShadows,
2024-05-13 18:53:08 +00:00
Restart,
2024-05-13 18:21:56 +00:00
Quit,
}
2024-05-12 20:17:17 +00:00
pub fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
2024-05-14 03:33:35 +00:00
achievement_tracker: Res<var::AchievementTracker>,
2024-05-12 20:17:17 +00:00
settings: Res<Settings>,
) {
commands.spawn((
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,
2024-05-14 04:28:14 +00:00
color: settings.hud_color_death,
2024-05-12 20:17:17 +00:00
..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,
2024-05-14 04:28:14 +00:00
color: settings.hud_color_death,
2024-05-12 20:17:17 +00:00
..default()
};
let style_death_subsubtext = TextStyle {
font: font_handle.clone(),
font_size: settings.font_size_deathsubtext * 0.8,
2024-05-14 04:28:14 +00:00
color: settings.hud_color_death,
..default()
};
let style_death_achievements = TextStyle {
font: font_handle.clone(),
font_size: settings.font_size_death_achievements,
color: settings.hud_color_death_achievements,
2024-05-12 20:17:17 +00:00
..default()
};
2024-05-22 02:57:20 +00:00
commands
.spawn((
DeathScreenElement,
NodeBundle {
style: style_centered(),
visibility: Visibility::Hidden,
2024-05-12 20:17:17 +00:00
..default()
},
2024-05-22 02:57:20 +00:00
))
.with_children(|builder| {
builder.spawn((
DeathText,
TextBundle {
text: Text {
sections: vec![
TextSection::new("", style_death_poem),
TextSection::new("You are dead.\n", style_death),
TextSection::new("Cause: ", style_death_subtext.clone()),
TextSection::new("Unknown", style_death_subtext),
TextSection::new("", style_death_achievements),
TextSection::new(
"\n\n\n\nPress E to begin anew.",
style_death_subsubtext,
),
],
justify: JustifyText::Center,
..default()
},
..default()
},
));
});
2024-05-13 18:21:56 +00:00
let style_menu = TextStyle {
font: font_handle.clone(),
font_size: settings.font_size_hud,
color: settings.hud_color,
..default()
};
2024-05-22 02:57:20 +00:00
let sections: Vec<TextSection> = Vec::from_iter(
MENUDEF
.iter()
.map(|(label, _)| TextSection::new(label.to_string() + "\n", style_menu.clone())),
);
2024-05-13 18:21:56 +00:00
commands.spawn((
MenuElement,
NodeBundle {
style: style_fullscreen(),
background_color: Color::srgba(0.0, 0.0, 0.0, 0.8).into(),
2024-05-13 18:21:56 +00:00
visibility: Visibility::Hidden,
..default()
},
));
2024-05-22 02:57:20 +00:00
commands
.spawn((
MenuElement,
NodeBundle {
style: Style {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::SpaceAround,
2024-05-13 18:21:56 +00:00
..default()
},
2024-05-22 02:57:20 +00:00
visibility: Visibility::Hidden,
2024-05-13 18:21:56 +00:00
..default()
},
2024-05-22 02:57:20 +00:00
))
.with_children(|builder| {
builder.spawn((
MenuTopLevel,
TextBundle {
text: Text {
sections,
justify: JustifyText::Center,
..default()
},
..default()
},
));
});
2024-05-14 03:17:32 +00:00
let style_achievement_header = TextStyle {
font: font_handle.clone(),
font_size: settings.font_size_achievement_header,
color: settings.hud_color_achievement_header,
..default()
};
let style_achievement = TextStyle {
font: font_handle.clone(),
font_size: settings.font_size_achievement,
color: settings.hud_color_achievement,
..default()
};
2024-05-14 03:33:35 +00:00
let achievement_count = achievement_tracker.to_bool_vec().len();
2024-05-14 03:17:32 +00:00
2024-05-22 02:57:20 +00:00
commands
.spawn((
MenuElement,
NodeBundle {
style: Style {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
left: Val::Percent(2.0),
top: Val::Percent(2.0),
align_items: AlignItems::Start,
justify_content: JustifyContent::Start,
2024-05-14 03:17:32 +00:00
..default()
},
2024-05-22 02:57:20 +00:00
visibility: Visibility::Hidden,
2024-05-14 03:17:32 +00:00
..default()
},
2024-05-22 02:57:20 +00:00
))
.with_children(|builder| {
let mut sections = vec![TextSection::new(
"Achievements\n",
style_achievement_header.clone(),
)];
sections.extend(Vec::from_iter(
(0..achievement_count).map(|_| TextSection::new("", style_achievement.clone())),
));
builder.spawn((
MenuAchievements,
TextBundle {
text: Text {
sections,
justify: JustifyText::Left,
..default()
},
..default()
},
));
});
let keybindings = include_str!("data/keybindings.in");
let style_keybindings = TextStyle {
font: font_handle.clone(),
font_size: settings.font_size_keybindings,
color: settings.hud_color_keybindings,
..default()
};
2024-05-22 02:57:20 +00:00
commands
.spawn((
MenuElement,
NodeBundle {
style: Style {
width: Val::Percent(96.0),
height: Val::Percent(96.0),
left: Val::Percent(2.0),
top: Val::Percent(2.0),
align_items: AlignItems::Start,
justify_content: JustifyContent::End,
..default()
},
visibility: Visibility::Hidden,
..default()
},
2024-05-22 02:57:20 +00:00
))
.with_children(|builder| {
builder.spawn((TextBundle {
text: Text {
sections: vec![
2024-05-14 17:40:53 +00:00
TextSection::new("Controls\n", style_achievement_header),
2024-05-22 02:57:20 +00:00
TextSection::new(keybindings, style_keybindings),
],
justify: JustifyText::Right,
..default()
},
..default()
2024-05-22 02:57:20 +00:00
},));
});
2024-05-14 17:08:18 +00:00
let style_version = TextStyle {
font: font_handle.clone(),
font_size: settings.font_size_version,
color: settings.hud_color_version,
..default()
};
2024-05-22 02:57:20 +00:00
commands
.spawn((
MenuElement,
NodeBundle {
style: Style {
width: Val::Percent(96.0),
height: Val::Percent(96.0),
left: Val::Percent(2.0),
top: Val::Percent(2.0),
align_items: AlignItems::End,
justify_content: JustifyContent::End,
..default()
},
visibility: Visibility::Hidden,
2024-05-14 17:08:18 +00:00
..default()
},
2024-05-22 02:57:20 +00:00
))
.with_children(|builder| {
builder.spawn((TextBundle {
2024-05-14 17:08:18 +00:00
text: Text {
2024-05-22 02:57:20 +00:00
sections: vec![TextSection::new(
format!("{} {}", GAME_NAME, settings.version.as_str()),
style_version,
)],
2024-05-14 17:08:18 +00:00
justify: JustifyText::Right,
..default()
},
..default()
2024-05-22 02:57:20 +00:00
},));
});
2024-05-12 20:17:17 +00:00
}
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-13 18:53:08 +00:00
mut ew_game: EventWriter<GameEvent>,
2024-05-12 20:17:17 +00:00
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
mut ew_effect: EventWriter<visual::SpawnEffectEvent>,
mut ew_respawn: EventWriter<world::RespawnEvent>,
2024-05-13 02:41:17 +00:00
mut ew_respawnaudiosinks: EventWriter<audio::RespawnSinksEvent>,
mut timer: ResMut<DeathScreenInputDelayTimer>,
2024-05-13 18:53:08 +00:00
mut menustate: ResMut<MenuState>,
2024-05-12 20:17:17 +00:00
mut settings: ResMut<Settings>,
2024-05-14 04:28:14 +00:00
achievement_tracker: Res<var::AchievementTracker>,
2024-05-12 20:17:17 +00:00
) {
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;
2024-05-13 02:47:47 +00:00
settings.alive = !show;
2024-05-12 20:17:17 +00:00
if show {
timer.0.reset();
2024-05-13 18:53:08 +00:00
*menustate = MenuState::default();
ew_game.send(GameEvent::SetMenu(Turn::Off));
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-14 04:28:14 +00:00
text.sections[4].value = achievement_tracker.to_summary();
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));
2024-05-22 02:57:20 +00:00
ew_effect.send(visual::SpawnEffectEvent {
class: visual::Effects::FadeIn(Color::BLACK),
duration: 0.3,
});
ew_respawn.send(world::RespawnEvent);
2024-05-12 20:17:17 +00:00
}
}
}
pub fn handle_deathscreen_input(
time: Res<Time>,
2024-05-12 20:17:17 +00:00
keyboard_input: Res<ButtonInput<KeyCode>>,
mut timer: ResMut<DeathScreenInputDelayTimer>,
2024-05-12 20:17:17 +00:00
mut ew_deathscreen: EventWriter<DeathScreenEvent>,
2024-05-13 15:19:07 +00:00
settings: Res<Settings>,
2024-05-12 20:17:17 +00:00
) {
if !settings.deathscreen_active || !timer.0.tick(time.delta()).finished() {
2024-05-12 20:17:17 +00:00
return;
}
if keyboard_input.pressed(settings.key_interact) {
ew_deathscreen.send(DeathScreenEvent::Hide);
}
}
2024-05-13 18:21:56 +00:00
#[derive(Resource, Debug, Default)]
pub struct MenuState {
cursor: usize,
}
pub fn update_menu(
mut q_text: Query<&mut Text, With<MenuTopLevel>>,
2024-05-14 03:17:32 +00:00
mut q_achievement_text: Query<&mut Text, (With<MenuAchievements>, Without<MenuTopLevel>)>,
2024-05-13 19:37:57 +00:00
mut q_vis: Query<&mut Visibility, With<menu::MenuElement>>,
2024-05-14 03:17:32 +00:00
achievement_tracker: Res<var::AchievementTracker>,
2024-05-13 18:21:56 +00:00
menustate: Res<MenuState>,
settings: Res<Settings>,
prefs: Res<Preferences>,
2024-05-13 18:21:56 +00:00
) {
2024-05-13 19:37:57 +00:00
for mut vis in &mut q_vis {
*vis = bool2vis(settings.menu_active);
}
fn bool2string(boolean: bool) -> String {
if boolean { "On" } else { "Off" }.to_string()
2024-05-13 18:21:56 +00:00
}
2024-05-14 03:17:32 +00:00
let bools = achievement_tracker.to_bool_vec();
let rendered = achievement_tracker.to_textsections();
if let Ok(mut text) = q_achievement_text.get_single_mut() {
for i in 0..text.sections.len() - 1 {
text.sections[i + 1].style.color = if bools[i] {
settings.hud_color_achievement_accomplished
} else {
settings.hud_color_achievement
};
text.sections[i + 1].value = rendered[i].clone();
}
}
2024-05-13 18:21:56 +00:00
if let Ok(mut text) = q_text.get_single_mut() {
for i in 0..text.sections.len() {
if menustate.cursor == i {
text.sections[i].style.color = settings.hud_color_subtitles;
} else {
text.sections[i].style.color = settings.hud_color;
}
2024-05-13 19:37:57 +00:00
match MENUDEF[i].1 {
MenuAction::ToggleSound => {
2024-06-16 23:16:53 +00:00
let noisecancel = if let Some(noisecancel) = settings
.noise_cancellation_modes
.get(settings.noise_cancellation_mode)
{
2024-10-03 21:59:15 +00:00
&noisecancel.0
2024-06-16 23:16:53 +00:00
} else {
2024-10-03 21:59:15 +00:00
&settings.noise_cancellation_modes[0].0
2024-06-16 23:16:53 +00:00
};
2024-09-22 14:21:18 +00:00
text.sections[i].value = format!("\nNoise Cancellation: {noisecancel}\n");
2024-05-13 19:37:57 +00:00
}
MenuAction::ToggleMusic => {
2024-06-13 01:26:19 +00:00
let station =
if let Some(station) = settings.radio_modes.get(settings.radio_mode) {
station
} else {
&settings.radio_modes[0]
};
text.sections[i].value = format!("Speakers: {station}\n");
2024-05-13 19:37:57 +00:00
}
MenuAction::ToggleAR => {
let onoff = bool2string(settings.hud_active);
2024-10-03 04:08:51 +00:00
let p = if settings.hud_active {
actor::POWER_DRAIN_AR
} else {
0.0
};
let w = if p > 0.0 {
format!(" ({p}W)")
} else {
String::from("")
};
text.sections[i].value = format!("Augmented Reality: {onoff}{w} [TAB]\n");
2024-05-13 19:37:57 +00:00
}
MenuAction::ModLightAmp => {
let p = actor::POWER_DRAIN_LIGHTAMP[prefs.light_amp];
text.sections[i].value = format!("\nLight Amplification: {p}W\n");
}
2024-09-22 01:40:12 +00:00
MenuAction::ModFlashlightPower => {
let p = actor::POWER_DRAIN_FLASHLIGHT[prefs.flashlight_power];
text.sections[i].value = format!("Flashlight Power: {p}W\n");
2024-09-22 01:40:12 +00:00
}
2024-09-22 02:34:36 +00:00
MenuAction::ModThrusterBoost => {
let state = match prefs.thruster_boost {
2024-09-22 04:42:56 +00:00
0 => "For braking",
2024-09-22 04:39:21 +00:00
1 => "Always",
2024-09-22 02:34:36 +00:00
2 => "Off",
_ => "ERROR",
};
let p = actor::POWER_DRAIN_THRUSTER[prefs.thruster_boost];
2024-10-03 04:08:51 +00:00
let w = if p > 0.0 {
format!(" ({p}W)")
} else {
String::from("")
};
text.sections[i].value = format!("Thruster Boost: {state}{w}\n");
2024-09-22 02:34:36 +00:00
}
MenuAction::ModReactor => {
let state = match settings.reactor_state {
0 => "Off",
2024-09-22 04:42:56 +00:00
1 => "On",
2 => "OVERLOAD",
_ => "ERROR",
};
let p = actor::POWER_GAIN_REACTOR[settings.reactor_state];
2024-10-03 04:08:51 +00:00
let w = if p > 0.0 {
format!(" (+{p}W)")
} else {
String::from("")
};
text.sections[i].value = format!("Reactor: {state}{w}\n");
}
2024-05-23 03:02:59 +00:00
MenuAction::ChangeARAvatar => {
if let Some(ava) = hud::PLAYER_AR_AVATARS.get(settings.ar_avatar) {
let avatar_title = ava.3;
text.sections[i].value = format!("Avatar: {avatar_title}\n");
}
}
2024-05-13 19:37:57 +00:00
MenuAction::ToggleMap => {
let onoff = bool2string(settings.map_active);
text.sections[i].value = format!("Map: {onoff} [M]\n");
}
2024-05-13 21:51:18 +00:00
MenuAction::ToggleCamera => {
let onoff = if settings.third_person {
"3rd Person"
} else {
"1st Person"
};
2024-09-22 14:21:18 +00:00
text.sections[i].value = format!("\nCamera: {onoff} [C]\n");
2024-05-13 21:51:18 +00:00
}
2024-05-13 19:37:57 +00:00
MenuAction::ToggleShadows => {
2024-10-03 04:08:51 +00:00
let onoff = if settings.shadows_sun { "High" } else { "Low" };
2024-05-13 19:37:57 +00:00
text.sections[i].value = format!("Shadows: {onoff}\n");
}
_ => {}
}
2024-05-13 18:21:56 +00:00
}
}
}
pub fn handle_input(
keyboard_input: Res<ButtonInput<KeyCode>>,
mut settings: ResMut<Settings>,
mut prefs: ResMut<Preferences>,
2024-05-13 18:21:56 +00:00
mut menustate: ResMut<MenuState>,
2024-07-09 00:19:44 +00:00
mut app_exit_events: ResMut<Events<AppExit>>,
2024-05-13 18:21:56 +00:00
mut ew_game: EventWriter<game::GameEvent>,
2024-05-13 18:53:08 +00:00
mut ew_playerdies: EventWriter<game::PlayerDiesEvent>,
2024-05-13 18:21:56 +00:00
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
2024-05-13 19:37:57 +00:00
mut ew_updatemenu: EventWriter<UpdateMenuEvent>,
2024-05-23 03:02:59 +00:00
mut ew_updateavatar: EventWriter<hud::UpdateAvatarEvent>,
mut ew_updateoverlays: EventWriter<hud::UpdateOverlayVisibility>,
2024-05-13 18:21:56 +00:00
) {
2024-05-14 16:58:47 +00:00
let last_menu_entry = MENUDEF.len() - 1;
2024-05-13 18:21:56 +00:00
if keyboard_input.just_pressed(settings.key_menu)
2024-05-22 02:57:20 +00:00
|| keyboard_input.just_pressed(settings.key_vehicle) && settings.menu_active
2024-05-13 18:21:56 +00:00
{
2024-05-13 18:53:08 +00:00
ew_game.send(GameEvent::SetMenu(Toggle));
2024-05-13 18:21:56 +00:00
}
if !settings.menu_active {
return;
}
if keyboard_input.just_pressed(settings.key_forward)
2024-05-22 02:57:20 +00:00
|| keyboard_input.just_pressed(settings.key_mouseup)
|| keyboard_input.just_pressed(KeyCode::ArrowUp)
2024-05-13 18:21:56 +00:00
{
2024-05-14 16:58:47 +00:00
menustate.cursor = if menustate.cursor == 0 {
last_menu_entry
} else {
menustate.cursor.saturating_sub(1)
};
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Click3));
2024-05-13 19:37:57 +00:00
ew_updatemenu.send(UpdateMenuEvent);
2024-05-13 18:21:56 +00:00
}
if keyboard_input.just_pressed(settings.key_back)
2024-05-22 02:57:20 +00:00
|| keyboard_input.just_pressed(settings.key_mousedown)
|| keyboard_input.just_pressed(KeyCode::ArrowDown)
2024-05-13 18:21:56 +00:00
{
2024-05-14 16:58:47 +00:00
menustate.cursor = if menustate.cursor == last_menu_entry {
0
} else {
menustate.cursor.saturating_add(1)
};
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Click3));
2024-05-13 19:37:57 +00:00
ew_updatemenu.send(UpdateMenuEvent);
2024-05-13 18:21:56 +00:00
}
if keyboard_input.just_pressed(settings.key_interact)
2024-05-22 02:57:20 +00:00
|| keyboard_input.just_pressed(KeyCode::Enter)
2024-05-13 18:21:56 +00:00
{
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Click));
match MENUDEF[menustate.cursor].1 {
MenuAction::ToggleMap => {
ew_game.send(GameEvent::SetMap(Toggle));
2024-05-13 18:53:08 +00:00
ew_game.send(GameEvent::SetMenu(Turn::Off));
2024-05-13 19:37:57 +00:00
ew_updatemenu.send(UpdateMenuEvent);
2024-05-22 02:57:20 +00:00
}
2024-05-13 18:21:56 +00:00
MenuAction::ToggleAR => {
ew_game.send(GameEvent::SetAR(Toggle));
2024-05-13 19:37:57 +00:00
ew_updatemenu.send(UpdateMenuEvent);
2024-05-22 02:57:20 +00:00
}
2024-05-23 03:02:59 +00:00
MenuAction::ChangeARAvatar => {
settings.ar_avatar += 1;
ew_updateavatar.send(hud::UpdateAvatarEvent);
ew_updatemenu.send(UpdateMenuEvent);
}
MenuAction::ModLightAmp => {
prefs.light_amp += 1;
if prefs.light_amp > 3 {
prefs.light_amp = 0;
}
2024-09-22 05:15:07 +00:00
prefs.save();
ew_updateoverlays.send(hud::UpdateOverlayVisibility);
ew_updatemenu.send(UpdateMenuEvent);
}
2024-09-22 01:40:12 +00:00
MenuAction::ModFlashlightPower => {
prefs.flashlight_power += 1;
2024-09-22 04:39:21 +00:00
if prefs.flashlight_power > 3 {
2024-09-22 01:40:12 +00:00
prefs.flashlight_power = 0;
}
2024-09-22 05:15:07 +00:00
prefs.save();
2024-09-22 01:40:12 +00:00
ew_game.send(GameEvent::UpdateFlashlight);
ew_updatemenu.send(UpdateMenuEvent);
}
2024-09-22 02:34:36 +00:00
MenuAction::ModThrusterBoost => {
prefs.thruster_boost += 1;
if prefs.thruster_boost > 2 {
prefs.thruster_boost = 0;
}
2024-09-22 05:15:07 +00:00
prefs.save();
2024-09-22 02:34:36 +00:00
ew_updatemenu.send(UpdateMenuEvent);
}
MenuAction::ModReactor => {
settings.reactor_state += 1;
if settings.reactor_state > 2 {
settings.reactor_state = 0;
}
ew_updatemenu.send(UpdateMenuEvent);
}
2024-05-13 18:21:56 +00:00
MenuAction::ToggleMusic => {
2024-06-13 01:26:19 +00:00
ew_game.send(GameEvent::SetMusic(Next));
2024-05-13 19:37:57 +00:00
ew_updatemenu.send(UpdateMenuEvent);
2024-05-22 02:57:20 +00:00
}
2024-05-13 18:21:56 +00:00
MenuAction::ToggleSound => {
2024-06-13 02:06:15 +00:00
ew_game.send(GameEvent::SetSound(Next));
2024-05-13 19:37:57 +00:00
ew_updatemenu.send(UpdateMenuEvent);
2024-05-22 02:57:20 +00:00
}
2024-05-13 21:51:18 +00:00
MenuAction::ToggleCamera => {
ew_game.send(GameEvent::SetThirdPerson(Toggle));
ew_updatemenu.send(UpdateMenuEvent);
2024-05-22 02:57:20 +00:00
}
2024-05-13 18:21:56 +00:00
MenuAction::ToggleFullscreen => {
ew_game.send(GameEvent::SetFullscreen(Toggle));
2024-05-22 02:57:20 +00:00
}
2024-05-13 19:11:27 +00:00
MenuAction::ToggleShadows => {
ew_game.send(GameEvent::SetShadows(Toggle));
2024-05-13 19:37:57 +00:00
ew_updatemenu.send(UpdateMenuEvent);
2024-05-22 02:57:20 +00:00
}
2024-05-13 18:53:08 +00:00
MenuAction::Restart => {
settings.god_mode = false;
ew_playerdies.send(game::PlayerDiesEvent(actor::DamageType::Depressurization));
2024-05-22 02:57:20 +00:00
}
2024-05-13 18:21:56 +00:00
MenuAction::Quit => {
2024-07-09 00:19:44 +00:00
app_exit_events.send(AppExit::Success);
2024-05-22 02:57:20 +00:00
}
2024-05-13 18:21:56 +00:00
};
}
}