Compare commits
8 commits
6c8cdf9af8
...
a1c4fbb821
Author | SHA1 | Date | |
---|---|---|---|
yuni | a1c4fbb821 | ||
yuni | 65f57cbccb | ||
yuni | 594b05f638 | ||
yuni | 76548d86a4 | ||
yuni | f01fd06bac | ||
yuni | 8533b689b2 | ||
yuni | f85e01c6f6 | ||
yuni | fd741ae905 |
|
@ -152,7 +152,7 @@ pub struct Engine {
|
||||||
pub reaction_wheels: f32,
|
pub reaction_wheels: f32,
|
||||||
pub engine_type: EngineType,
|
pub engine_type: EngineType,
|
||||||
pub warmup_seconds: f32,
|
pub warmup_seconds: f32,
|
||||||
pub current_warmup: f32,
|
pub current_warmup: f32, // between 0.0 and 1.0
|
||||||
}
|
}
|
||||||
impl Default for Engine {
|
impl Default for Engine {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
|
|
@ -79,6 +79,7 @@ pub fn setup(
|
||||||
source: asset_server.load(ASSET_THRUSTER),
|
source: asset_server.load(ASSET_THRUSTER),
|
||||||
settings: PlaybackSettings {
|
settings: PlaybackSettings {
|
||||||
mode: PlaybackMode::Loop,
|
mode: PlaybackMode::Loop,
|
||||||
|
volume: Volume::new(0.0),
|
||||||
paused: true,
|
paused: true,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
@ -90,6 +91,7 @@ pub fn setup(
|
||||||
source: asset_server.load(ASSET_ROCKET),
|
source: asset_server.load(ASSET_ROCKET),
|
||||||
settings: PlaybackSettings {
|
settings: PlaybackSettings {
|
||||||
mode: PlaybackMode::Loop,
|
mode: PlaybackMode::Loop,
|
||||||
|
volume: Volume::new(0.0),
|
||||||
paused: true,
|
paused: true,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
@ -101,6 +103,7 @@ pub fn setup(
|
||||||
source: asset_server.load(ASSET_ION),
|
source: asset_server.load(ASSET_ION),
|
||||||
settings: PlaybackSettings {
|
settings: PlaybackSettings {
|
||||||
mode: PlaybackMode::Loop,
|
mode: PlaybackMode::Loop,
|
||||||
|
volume: Volume::new(0.0),
|
||||||
paused: true,
|
paused: true,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
|
|
@ -277,7 +277,8 @@ pub fn apply_input_to_player(
|
||||||
let mut mouse_delta = Vec2::ZERO;
|
let mut mouse_delta = Vec2::ZERO;
|
||||||
let mut pitch_yaw_rot = Vec3::ZERO;
|
let mut pitch_yaw_rot = Vec3::ZERO;
|
||||||
let sensitivity_factor = if settings.is_zooming { settings.zoom_sensitivity_factor } else { 1.0 };
|
let sensitivity_factor = if settings.is_zooming { settings.zoom_sensitivity_factor } else { 1.0 };
|
||||||
let mouseless_sensitivity = 40.0 * sensitivity_factor;
|
let mouseless_sensitivity = 8.0 * sensitivity_factor;
|
||||||
|
let mouseless_rotation_sensitivity = 40.0 * sensitivity_factor;
|
||||||
if key_input.pressed(settings.key_mouseup) {
|
if key_input.pressed(settings.key_mouseup) {
|
||||||
pitch_yaw_rot[0] -= mouseless_sensitivity;
|
pitch_yaw_rot[0] -= mouseless_sensitivity;
|
||||||
}
|
}
|
||||||
|
@ -290,10 +291,10 @@ pub fn apply_input_to_player(
|
||||||
pitch_yaw_rot[1] -= mouseless_sensitivity;
|
pitch_yaw_rot[1] -= mouseless_sensitivity;
|
||||||
}
|
}
|
||||||
if key_input.pressed(settings.key_rotateleft) {
|
if key_input.pressed(settings.key_rotateleft) {
|
||||||
pitch_yaw_rot[2] -= mouseless_sensitivity;
|
pitch_yaw_rot[2] -= mouseless_rotation_sensitivity;
|
||||||
}
|
}
|
||||||
if key_input.pressed(settings.key_rotateright) {
|
if key_input.pressed(settings.key_rotateright) {
|
||||||
pitch_yaw_rot[2] += mouseless_sensitivity;
|
pitch_yaw_rot[2] += mouseless_rotation_sensitivity;
|
||||||
}
|
}
|
||||||
for mouse_event in mouse_events.read() {
|
for mouse_event in mouse_events.read() {
|
||||||
mouse_delta += mouse_event.delta;
|
mouse_delta += mouse_event.delta;
|
||||||
|
@ -349,25 +350,39 @@ pub fn apply_input_to_player(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Ok(sink) = thruster_sound_controller.get_single() {
|
let sinks = vec![
|
||||||
if play_thruster_sound && !settings.mute_sfx && engine.engine_type == actor::EngineType::Monopropellant {
|
(1.2, actor::EngineType::Monopropellant, thruster_sound_controller.get_single()),
|
||||||
sink.play()
|
(1.0, actor::EngineType::Rocket, rocket_sound_controller.get_single()),
|
||||||
|
(1.4, actor::EngineType::Ion, ion_sound_controller.get_single()),
|
||||||
|
];
|
||||||
|
let seconds_to_max_vol = 0.05;
|
||||||
|
let seconds_to_min_vol = 0.05;
|
||||||
|
for sink_data in sinks {
|
||||||
|
if let (vol_boost, engine_type, Ok(sink)) = sink_data {
|
||||||
|
if settings.mute_sfx {
|
||||||
|
sink.pause();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let volume = sink.volume();
|
||||||
|
if engine.engine_type == engine_type {
|
||||||
|
if play_thruster_sound {
|
||||||
|
sink.play();
|
||||||
|
if volume < 1.0 {
|
||||||
|
let maxvol = vol_boost;
|
||||||
|
//let maxvol = engine.current_warmup * vol_boost;
|
||||||
|
sink.set_volume((volume + dt / seconds_to_max_vol).clamp(0.0, maxvol));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sink.pause()
|
sink.set_volume((volume - dt / seconds_to_min_vol).clamp(0.0, 1.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Ok(sink) = rocket_sound_controller.get_single() {
|
else if volume > 0.0 {
|
||||||
if play_thruster_sound && !settings.mute_sfx && engine.engine_type == actor::EngineType::Rocket {
|
sink.set_volume((volume - dt / seconds_to_min_vol).clamp(0.0, 1.0));
|
||||||
sink.play()
|
}
|
||||||
} else {
|
if volume < 0.0001 {
|
||||||
sink.pause()
|
sink.pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Ok(sink) = ion_sound_controller.get_single() {
|
|
||||||
if play_thruster_sound && !settings.mute_sfx && engine.engine_type == actor::EngineType::Ion {
|
|
||||||
sink.play()
|
|
||||||
} else {
|
|
||||||
sink.pause()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -685,7 +685,7 @@ pub fn handle_chat_events(
|
||||||
hud::LogLevel::Chat => {
|
hud::LogLevel::Chat => {
|
||||||
log.chat(message.into(), chat.talker.name.clone().unwrap_or("".to_string()));
|
log.chat(message.into(), chat.talker.name.clone().unwrap_or("".to_string()));
|
||||||
}
|
}
|
||||||
hud::LogLevel::Info | hud::LogLevel::Notice => {
|
hud::LogLevel::Info => {
|
||||||
log.info(message.into());
|
log.info(message.into());
|
||||||
}
|
}
|
||||||
hud::LogLevel::Warning => {
|
hud::LogLevel::Warning => {
|
||||||
|
|
|
@ -183,7 +183,7 @@ actor -3300 10 0 pizzeria
|
||||||
|
|
||||||
actor -45 -4 -4 suit
|
actor -45 -4 -4 suit
|
||||||
relativeto pizzeria
|
relativeto pizzeria
|
||||||
name "Space Pizza™"
|
name "Nox"
|
||||||
chatid PizzaChef
|
chatid PizzaChef
|
||||||
armodel suit_ar_chefhat
|
armodel suit_ar_chefhat
|
||||||
alive yes
|
alive yes
|
||||||
|
|
302
src/hud.rs
302
src/hud.rs
|
@ -9,9 +9,10 @@ use std::time::SystemTime;
|
||||||
|
|
||||||
pub const HUD_REFRESH_TIME: f32 = 0.1;
|
pub const HUD_REFRESH_TIME: f32 = 0.1;
|
||||||
pub const FONT: &str = "fonts/Yupiter-Regular.ttf";
|
pub const FONT: &str = "fonts/Yupiter-Regular.ttf";
|
||||||
pub const LOG_MAX: usize = 4;
|
pub const LOG_MAX: usize = 16;
|
||||||
pub const LOG_MAX_TIME_S: f64 = 15.0;
|
pub const LOG_MAX_TIME_S: f64 = 30.0;
|
||||||
pub const LOG_MAX_ROWS: usize = 30;
|
pub const LOG_MAX_ROWS: usize = 30;
|
||||||
|
pub const MAX_CHOICES: usize = 10;
|
||||||
pub const AMBIENT_LIGHT: f32 = 0.0; // Space is DARK
|
pub const AMBIENT_LIGHT: f32 = 0.0; // Space is DARK
|
||||||
pub const AMBIENT_LIGHT_AR: f32 = 15.0;
|
pub const AMBIENT_LIGHT_AR: f32 = 15.0;
|
||||||
//pub const REPLY_NUMBERS: [char; 10] = ['❶', '❷', '❸', '❹', '❺', '❻', '❼', '❽', '❾', '⓿'];
|
//pub const REPLY_NUMBERS: [char; 10] = ['❶', '❷', '❸', '❹', '❺', '❻', '❼', '❽', '❾', '⓿'];
|
||||||
|
@ -48,8 +49,10 @@ impl Plugin for HudPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Event)] pub struct TargetEvent(pub Option<Entity>);
|
#[derive(Event)] pub struct TargetEvent(pub Option<Entity>);
|
||||||
#[derive(Component)] struct GaugesText;
|
#[derive(Component)] struct NodeHud;
|
||||||
#[derive(Component)] struct ChatText;
|
#[derive(Component)] struct NodeConsole;
|
||||||
|
#[derive(Component)] struct NodeChoiceText;
|
||||||
|
#[derive(Component)] struct NodeCurrentChatLine;
|
||||||
#[derive(Component)] struct Reticule;
|
#[derive(Component)] struct Reticule;
|
||||||
#[derive(Component)] struct ToggleableHudElement;
|
#[derive(Component)] struct ToggleableHudElement;
|
||||||
#[derive(Component)] struct OnlyHideWhenTogglingHud;
|
#[derive(Component)] struct OnlyHideWhenTogglingHud;
|
||||||
|
@ -77,7 +80,6 @@ pub enum LogLevel {
|
||||||
//Debug,
|
//Debug,
|
||||||
Chat,
|
Chat,
|
||||||
//Ping,
|
//Ping,
|
||||||
Notice,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Message {
|
struct Message {
|
||||||
|
@ -93,6 +95,14 @@ impl Message {
|
||||||
}
|
}
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
pub fn format(&self) -> String {
|
||||||
|
if self.sender.is_empty() {
|
||||||
|
return self.text.clone() + "\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return format!("{}: {}\n", self.sender, self.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
|
@ -124,10 +134,6 @@ impl Log {
|
||||||
self.add(message, "WARNING".to_string(), LogLevel::Warning);
|
self.add(message, "WARNING".to_string(), LogLevel::Warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn notice(&mut self, message: String) {
|
|
||||||
self.add(message, "".to_string(), LogLevel::Notice);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add(&mut self, text: String, sender: String, level: LogLevel) {
|
pub fn add(&mut self, text: String, sender: String, level: LogLevel) {
|
||||||
if self.logs.len() == LOG_MAX {
|
if self.logs.len() == LOG_MAX {
|
||||||
self.logs.pop_front();
|
self.logs.pop_front();
|
||||||
|
@ -163,22 +169,40 @@ fn setup(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
settings: Res<var::Settings>,
|
settings: Res<var::Settings>,
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
mut log: ResMut<Log>,
|
|
||||||
mut ambient_light: ResMut<AmbientLight>,
|
mut ambient_light: ResMut<AmbientLight>,
|
||||||
) {
|
) {
|
||||||
log.notice("Resuming from suspend".to_string());
|
|
||||||
log.notice("WARNING: Oxygen Low".to_string());
|
|
||||||
let visibility = if settings.hud_active {
|
let visibility = if settings.hud_active {
|
||||||
Visibility::Inherited
|
Visibility::Inherited
|
||||||
} else {
|
} else {
|
||||||
Visibility::Hidden
|
Visibility::Hidden
|
||||||
};
|
};
|
||||||
let style = TextStyle {
|
let font_handle = asset_server.load(FONT);
|
||||||
font: asset_server.load(FONT),
|
let style_conversations = TextStyle {
|
||||||
font_size: settings.font_size_hud,
|
font: font_handle.clone(),
|
||||||
color: Color::GRAY,
|
font_size: settings.font_size_conversations,
|
||||||
|
color: settings.hud_color_subtitles,
|
||||||
..default()
|
..default()
|
||||||
};
|
};
|
||||||
|
let style_console = TextStyle {
|
||||||
|
font: font_handle.clone(),
|
||||||
|
font_size: settings.font_size_console,
|
||||||
|
color: settings.hud_color_console,
|
||||||
|
..default()
|
||||||
|
};
|
||||||
|
let style_choices = TextStyle {
|
||||||
|
font: font_handle.clone(),
|
||||||
|
font_size: settings.font_size_choices,
|
||||||
|
color: settings.hud_color_choices,
|
||||||
|
..default()
|
||||||
|
};
|
||||||
|
let style = TextStyle {
|
||||||
|
font: font_handle,
|
||||||
|
font_size: settings.font_size_hud,
|
||||||
|
color: settings.hud_color,
|
||||||
|
..default()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add Statistics HUD
|
||||||
let mut bundle_fps = TextBundle::from_sections([
|
let mut bundle_fps = TextBundle::from_sections([
|
||||||
TextSection::new("", style.clone()),
|
TextSection::new("", style.clone()),
|
||||||
TextSection::new(" ⚡ ", style.clone()),
|
TextSection::new(" ⚡ ", style.clone()),
|
||||||
|
@ -194,77 +218,52 @@ fn setup(
|
||||||
TextSection::new("", style.clone()),
|
TextSection::new("", style.clone()),
|
||||||
TextSection::new("\nVitals ", style.clone()),
|
TextSection::new("\nVitals ", style.clone()),
|
||||||
TextSection::new("", style.clone()),
|
TextSection::new("", style.clone()),
|
||||||
|
TextSection::new("", style.clone()), // Speed
|
||||||
TextSection::new("", style.clone()), // Target
|
TextSection::new("", style.clone()), // Target
|
||||||
]).with_style(Style {
|
]).with_style(Style {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::VMin(2.0),
|
top: Val::VMin(2.0),
|
||||||
right: Val::VMin(3.0),
|
left: Val::VMin(3.0),
|
||||||
..default()
|
..default()
|
||||||
}).with_text_justify(JustifyText::Right);
|
}).with_text_justify(JustifyText::Left);
|
||||||
bundle_fps.visibility = visibility;
|
bundle_fps.visibility = visibility;
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
GaugesText,
|
NodeHud,
|
||||||
ToggleableHudElement,
|
ToggleableHudElement,
|
||||||
bundle_fps,
|
bundle_fps,
|
||||||
));
|
));
|
||||||
|
|
||||||
// Add Chat Box
|
// Add Console
|
||||||
let bundle_chatbox = TextBundle::from_sections([
|
let bundle_chatbox = TextBundle::from_sections((0..LOG_MAX_ROWS).map(|_|
|
||||||
TextSection::new("", style.clone()),
|
TextSection::new("", style_console.clone()))
|
||||||
TextSection::new("", style.clone()),
|
).with_style(Style {
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
TextSection::new("", style.clone()),
|
|
||||||
]).with_style(Style {
|
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::VMin(0.0),
|
top: Val::VMin(0.0),
|
||||||
left: Val::VMin(0.0),
|
right: Val::VMin(0.0),
|
||||||
..default()
|
..default()
|
||||||
}).with_text_justify(JustifyText::Left);
|
}).with_text_justify(JustifyText::Right);
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
|
ToggleableHudElement,
|
||||||
NodeBundle {
|
NodeBundle {
|
||||||
style: Style {
|
style: Style {
|
||||||
width: Val::Percent(45.0),
|
width: Val::Percent(50.0),
|
||||||
align_items: AlignItems::Start,
|
align_items: AlignItems::Start,
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::VMin(2.0),
|
top: Val::VMin(2.0),
|
||||||
left: Val::VMin(3.0),
|
right: Val::VMin(3.0),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
visibility,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
)).with_children(|parent| {
|
)).with_children(|parent| {
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
bundle_chatbox,
|
bundle_chatbox,
|
||||||
ChatText,
|
NodeConsole,
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add Reticule
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Reticule,
|
Reticule,
|
||||||
ToggleableHudElement,
|
ToggleableHudElement,
|
||||||
|
@ -283,6 +282,54 @@ fn setup(
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// Chat "subtitles" and choices
|
||||||
|
commands.spawn(NodeBundle {
|
||||||
|
style: Style {
|
||||||
|
width: Val::Vw(100.0),
|
||||||
|
align_items: AlignItems::Center,
|
||||||
|
flex_direction: FlexDirection::Column,
|
||||||
|
position_type: PositionType::Absolute,
|
||||||
|
bottom: Val::Vh(2.0),
|
||||||
|
left: Val::Px(0.0),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
..default()
|
||||||
|
}).with_children(|builder| {
|
||||||
|
builder.spawn((
|
||||||
|
TextBundle {
|
||||||
|
text: Text {
|
||||||
|
sections: vec![
|
||||||
|
TextSection::new("", style_conversations),
|
||||||
|
],
|
||||||
|
justify: JustifyText::Center,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
style: Style {
|
||||||
|
max_width: Val::Percent(50.0),
|
||||||
|
margin: UiRect {
|
||||||
|
bottom: Val::Vh(1.0),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
NodeCurrentChatLine,
|
||||||
|
));
|
||||||
|
let choice_sections = (0..MAX_CHOICES).map(|_|
|
||||||
|
TextSection::new("", style_choices.clone()));
|
||||||
|
builder.spawn((
|
||||||
|
TextBundle {
|
||||||
|
text: Text {
|
||||||
|
sections: choice_sections.collect(),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
NodeChoiceText,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
// Selectagon
|
// Selectagon
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Selectagon,
|
Selectagon,
|
||||||
|
@ -310,9 +357,12 @@ fn update_hud(
|
||||||
player: Query<(&actor::HitPoints, &actor::Suit, &actor::ExperiencesGForce), With<actor::Player>>,
|
player: Query<(&actor::HitPoints, &actor::Suit, &actor::ExperiencesGForce), With<actor::Player>>,
|
||||||
q_camera: Query<(&Position, &LinearVelocity), With<actor::PlayerCamera>>,
|
q_camera: Query<(&Position, &LinearVelocity), With<actor::PlayerCamera>>,
|
||||||
mut timer: ResMut<FPSUpdateTimer>,
|
mut timer: ResMut<FPSUpdateTimer>,
|
||||||
mut query: Query<&mut Text, With<GaugesText>>,
|
|
||||||
q_choices: Query<&chat::Choice>,
|
q_choices: Query<&chat::Choice>,
|
||||||
mut query_chat: Query<&mut Text, (With<ChatText>, Without<GaugesText>)>,
|
q_chat: Query<&chat::Chat>,
|
||||||
|
mut q_node_hud: Query<&mut Text, With<NodeHud>>,
|
||||||
|
mut q_node_console: Query<&mut Text, (With<NodeConsole>, Without<NodeHud>, Without<NodeChoiceText>)>,
|
||||||
|
mut q_node_choice: Query<&mut Text, (With<NodeChoiceText>, Without<NodeHud>, Without<NodeConsole>)>,
|
||||||
|
mut q_node_currentline: Query<&mut Text, (With<NodeCurrentChatLine>, Without<NodeHud>, Without<NodeConsole>, Without<NodeChoiceText>)>,
|
||||||
query_all_actors: Query<&actor::Actor>,
|
query_all_actors: Query<&actor::Actor>,
|
||||||
settings: Res<var::Settings>,
|
settings: Res<var::Settings>,
|
||||||
q_target: Query<(&IsClickable, Option<&Position>, Option<&LinearVelocity>), With<IsTargeted>>,
|
q_target: Query<(&IsClickable, Option<&Position>, Option<&LinearVelocity>), With<IsTargeted>>,
|
||||||
|
@ -325,7 +375,7 @@ fn update_hud(
|
||||||
if player.is_ok() && q_camera_result.is_ok() {
|
if player.is_ok() && q_camera_result.is_ok() {
|
||||||
let (hp, suit, gforce) = player.unwrap();
|
let (hp, suit, gforce) = player.unwrap();
|
||||||
let (pos, cam_v) = q_camera_result.unwrap();
|
let (pos, cam_v) = q_camera_result.unwrap();
|
||||||
for mut text in &mut query {
|
for mut text in &mut q_node_hud {
|
||||||
text.sections[0].value = format!("2524-03-12 03:02");
|
text.sections[0].value = format!("2524-03-12 03:02");
|
||||||
if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) {
|
if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) {
|
||||||
if let Some(value) = fps.smoothed() {
|
if let Some(value) = fps.smoothed() {
|
||||||
|
@ -341,29 +391,30 @@ fn update_hud(
|
||||||
if suit.oxygen > nature::OXY_H {
|
if suit.oxygen > nature::OXY_H {
|
||||||
let oxy_hour = suit.oxygen / nature::OXY_H;
|
let oxy_hour = suit.oxygen / nature::OXY_H;
|
||||||
text.sections[7].value = format!("{oxy_percent:.1}% [lasts {oxy_hour:.1} hours]");
|
text.sections[7].value = format!("{oxy_percent:.1}% [lasts {oxy_hour:.1} hours]");
|
||||||
text.sections[7].style.color = Color::GRAY;
|
text.sections[7].style.color = settings.hud_color;
|
||||||
} else {
|
} else {
|
||||||
let oxy_min = suit.oxygen / nature::OXY_M;
|
let oxy_min = suit.oxygen / nature::OXY_M;
|
||||||
text.sections[7].value = format!("{oxy_percent:.1}% [lasts {oxy_min:.1} min]");
|
text.sections[7].value = format!("{oxy_percent:.1}% [lasts {oxy_min:.1} min]");
|
||||||
text.sections[7].style.color = Color::MAROON;
|
text.sections[7].style.color = settings.hud_color_alert;
|
||||||
}
|
}
|
||||||
//let adrenaline = lifeform.adrenaline * 990.0 + 10.0;
|
//let adrenaline = lifeform.adrenaline * 990.0 + 10.0;
|
||||||
//text.sections[11].value = format!("{adrenaline:.0}pg/mL");
|
//text.sections[11].value = format!("{adrenaline:.0}pg/mL");
|
||||||
let vitals = 100.0 * hp.current / hp.max;
|
let vitals = 100.0 * hp.current / hp.max;
|
||||||
text.sections[13].value = format!("{vitals:.0}%");
|
text.sections[13].value = format!("{vitals:.0}%");
|
||||||
if vitals < 50.0 {
|
if vitals < 50.0 {
|
||||||
text.sections[13].style.color = Color::MAROON;
|
text.sections[13].style.color = settings.hud_color_alert;
|
||||||
} else {
|
} else {
|
||||||
text.sections[13].style.color = Color::GRAY;
|
text.sections[13].style.color = settings.hud_color;
|
||||||
}
|
}
|
||||||
let all_actors = query_all_actors.iter().len();
|
let all_actors = query_all_actors.iter().len();
|
||||||
text.sections[9].value = format!("{all_actors:.0}");
|
text.sections[9].value = format!("{all_actors:.0}");
|
||||||
let integrity = suit.integrity * 100.0;
|
let integrity = suit.integrity * 100.0;
|
||||||
text.sections[11].value = format!("{integrity:.0}%");
|
|
||||||
if integrity < 50.0 {
|
if integrity < 50.0 {
|
||||||
text.sections[11].style.color = Color::MAROON;
|
text.sections[11].style.color = settings.hud_color_alert;
|
||||||
|
text.sections[11].value = format!("{integrity:.0}% [LEAKING]");
|
||||||
} else {
|
} else {
|
||||||
text.sections[11].style.color = Color::GRAY;
|
text.sections[11].style.color = settings.hud_color;
|
||||||
|
text.sections[11].value = format!("{integrity:.0}%");
|
||||||
}
|
}
|
||||||
//text.sections[17].value = format!("{speed_readable}/s / {kmh:.0}km/h / {gforce:.1}g");
|
//text.sections[17].value = format!("{speed_readable}/s / {kmh:.0}km/h / {gforce:.1}g");
|
||||||
|
|
||||||
|
@ -401,6 +452,10 @@ fn update_hud(
|
||||||
"".to_string()
|
"".to_string()
|
||||||
};
|
};
|
||||||
let gforce = gforce.gforce;
|
let gforce = gforce.gforce;
|
||||||
|
let speed = cam_v.length();
|
||||||
|
let speed_readable = nature::readable_distance(speed);
|
||||||
|
text.sections[14].value = format!("\n{speed_readable}/s\n{gforce:.1}g{dev_speed}");
|
||||||
|
|
||||||
if let Ok((clickable, _, target_v_maybe)) = q_target.get_single() {
|
if let Ok((clickable, _, target_v_maybe)) = q_target.get_single() {
|
||||||
let distance = if dist_scalar.is_nan() {
|
let distance = if dist_scalar.is_nan() {
|
||||||
"UNKNOWN".to_string()
|
"UNKNOWN".to_string()
|
||||||
|
@ -416,61 +471,84 @@ fn update_hud(
|
||||||
};
|
};
|
||||||
let speed_readable = nature::readable_distance(speed);
|
let speed_readable = nature::readable_distance(speed);
|
||||||
let target_name = clickable.name.clone().unwrap_or("Unnamed".to_string());
|
let target_name = clickable.name.clone().unwrap_or("Unnamed".to_string());
|
||||||
text.sections[14].value = format!("\n\nTarget: {target_name}\nDistance: {distance}\nΔv {speed_readable}/s + {gforce:.1}g{dev_speed}");
|
text.sections[15].value = format!("\n\nTarget: {target_name}\nDistance: {distance}\nΔv {speed_readable}/s");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let speed = cam_v.length();
|
text.sections[15].value = "".to_string();
|
||||||
let speed_readable = nature::readable_distance(speed);
|
|
||||||
text.sections[14].value = format!("\nv {speed_readable}/s + {gforce:.1}g{dev_speed}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(mut chat) = query_chat.get_single_mut() {
|
let chat = q_node_console.get_single_mut();
|
||||||
|
if chat.is_err() {
|
||||||
|
error!("Couldn't find HUD UI text section");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut chat = chat.unwrap();
|
||||||
|
|
||||||
|
let choicebox = q_node_choice.get_single_mut();
|
||||||
|
if choicebox.is_err() {
|
||||||
|
error!("Couldn't find HUD UI text section");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut choicebox = choicebox.unwrap();
|
||||||
|
|
||||||
|
let node_currentline = q_node_currentline.get_single_mut();
|
||||||
|
if node_currentline.is_err() {
|
||||||
|
error!("Couldn't find HUD UI text section");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut node_currentline = node_currentline.unwrap();
|
||||||
|
|
||||||
let mut row = 0;
|
let mut row = 0;
|
||||||
let bright = Color::rgb(0.8, 0.75, 0.78);
|
|
||||||
|
|
||||||
// Chat Log and System Log
|
// Chat Log and System Log
|
||||||
let logfilter = if settings.hud_active {
|
let messages: Vec<&Message> = log.logs.iter()
|
||||||
|_msg: &&Message| { true }
|
|
||||||
} else {
|
|
||||||
|msg: &&Message| { match msg.level {
|
|
||||||
LogLevel::Chat => true,
|
|
||||||
LogLevel::Warning => true,
|
|
||||||
LogLevel::Info => true,
|
|
||||||
_ => false
|
|
||||||
}}
|
|
||||||
};
|
|
||||||
let mut messages: Vec<&Message> = log.logs.iter()
|
|
||||||
.filter(logfilter)
|
|
||||||
.rev()
|
.rev()
|
||||||
.take(15)
|
.take(LOG_MAX_ROWS)
|
||||||
.collect();
|
.collect();
|
||||||
messages.reverse();
|
//messages.reverse();
|
||||||
for msg in &messages {
|
for msg in &messages {
|
||||||
if msg.sender.is_empty() {
|
chat.sections[row].value = msg.format();
|
||||||
chat.sections[row].value = msg.text.clone() + "\n";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
chat.sections[row].value = format!("{}: {}\n", msg.sender, msg.text);
|
|
||||||
}
|
|
||||||
let freshness = msg.get_freshness();
|
let freshness = msg.get_freshness();
|
||||||
let clr: f32 = (freshness.powf(1.5) as f32).clamp(0.1, 1.0);
|
let clr: f32 = (freshness.powf(1.5) as f32).clamp(0.1, 1.0);
|
||||||
freshest_line = freshest_line.max(freshness);
|
freshest_line = freshest_line.max(freshness);
|
||||||
chat.sections[row].style.color = Color::rgba(0.7, 0.7, 0.7, clr);
|
chat.sections[row].style.color = match msg.level {
|
||||||
|
LogLevel::Warning => settings.hud_color_console_warn,
|
||||||
|
LogLevel::Info => settings.hud_color_console_system,
|
||||||
|
_ => settings.hud_color_console,
|
||||||
|
};
|
||||||
|
chat.sections[row].style.color.set_a(clr);
|
||||||
row += 1;
|
row += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Highlight most recent line if in a conversation
|
// Display the last chat line as "subtitles"
|
||||||
if row > 0 && (q_choices.is_empty() || freshest_line > 0.5) {
|
if !q_chat.is_empty() {
|
||||||
chat.sections[row-1].style.color = bright;
|
let messages: Vec<&Message> = log.logs.iter()
|
||||||
|
.filter(|msg: &&Message| { match msg.level {
|
||||||
|
LogLevel::Chat => true,
|
||||||
|
_ => false
|
||||||
|
}})
|
||||||
|
.rev()
|
||||||
|
.take(1)
|
||||||
|
.collect();
|
||||||
|
if messages.len() > 0 {
|
||||||
|
node_currentline.sections[0].value = messages[0].format();
|
||||||
|
} else {
|
||||||
|
node_currentline.sections[0].value = "".to_string();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
node_currentline.sections[0].value = "".to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add padding between chat and choices
|
// Blank the remaining rows
|
||||||
chat.sections[row].value = "\n".to_string();
|
while row < LOG_MAX_ROWS {
|
||||||
|
chat.sections[row].value = "".to_string();
|
||||||
row += 1;
|
row += 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Choices
|
// Choices
|
||||||
|
row = 0;
|
||||||
let mut choices: Vec<String> = Vec::new();
|
let mut choices: Vec<String> = Vec::new();
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
for choice in &q_choices {
|
for choice in &q_choices {
|
||||||
|
@ -484,28 +562,28 @@ fn update_hud(
|
||||||
choices.push(format!("{press_this} {reply}"));
|
choices.push(format!("{press_this} {reply}"));
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
if count < 4 {
|
|
||||||
for _padding in 0..(4-count) {
|
|
||||||
choices.push(" ".to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for choice in choices {
|
for choice in choices {
|
||||||
chat.sections[row].value = choice + "\n";
|
if row >= MAX_CHOICES {
|
||||||
chat.sections[row].style.color = bright;
|
break;
|
||||||
|
}
|
||||||
|
choicebox.sections[row].value = choice + "\n";
|
||||||
row += 1;
|
row += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blank the remaining rows
|
while row < MAX_CHOICES {
|
||||||
while row < LOG_MAX_ROWS {
|
choicebox.sections[row].value = if row < 4 {
|
||||||
chat.sections[row].value = "".to_string();
|
" \n".to_string()
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
};
|
||||||
row += 1;
|
row += 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
log.needs_rerendering = false;
|
log.needs_rerendering = false;
|
||||||
|
|
||||||
if q_choices.is_empty() && freshest_line < 0.2 {
|
//if q_choices.is_empty() && freshest_line < 0.2 {
|
||||||
log.remove_old();
|
log.remove_old();
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
src/var.rs
20
src/var.rs
|
@ -29,6 +29,15 @@ pub struct Settings {
|
||||||
pub zoom_sensitivity_factor: f32,
|
pub zoom_sensitivity_factor: f32,
|
||||||
pub font_size_hud: f32,
|
pub font_size_hud: f32,
|
||||||
pub font_size_conversations: f32,
|
pub font_size_conversations: f32,
|
||||||
|
pub font_size_choices: f32,
|
||||||
|
pub font_size_console: f32,
|
||||||
|
pub hud_color: Color,
|
||||||
|
pub hud_color_console: Color,
|
||||||
|
pub hud_color_console_warn: Color,
|
||||||
|
pub hud_color_console_system: Color,
|
||||||
|
pub hud_color_alert: Color,
|
||||||
|
pub hud_color_subtitles: Color,
|
||||||
|
pub hud_color_choices: Color,
|
||||||
pub chat_speed: f32,
|
pub chat_speed: f32,
|
||||||
pub hud_active: bool,
|
pub hud_active: bool,
|
||||||
pub is_zooming: bool,
|
pub is_zooming: bool,
|
||||||
|
@ -113,8 +122,17 @@ impl Default for Settings {
|
||||||
fov_highspeed: 25.0,
|
fov_highspeed: 25.0,
|
||||||
zoom_fov: 15.0,
|
zoom_fov: 15.0,
|
||||||
zoom_sensitivity_factor: 0.25,
|
zoom_sensitivity_factor: 0.25,
|
||||||
font_size_hud: 32.0,
|
font_size_hud: 24.0,
|
||||||
font_size_conversations: 32.0,
|
font_size_conversations: 32.0,
|
||||||
|
font_size_choices: 28.0,
|
||||||
|
font_size_console: 20.0,
|
||||||
|
hud_color: Color::rgb(0.2, 0.5, 0.2),
|
||||||
|
hud_color_console: Color::rgb(0.2, 0.5, 0.2),
|
||||||
|
hud_color_console_warn: Color::rgb(1.0, 0.3, 0.3),
|
||||||
|
hud_color_console_system: Color::rgb(0.5, 0.5, 0.5),
|
||||||
|
hud_color_alert: Color::rgb(0.7, 0.3, 0.3),
|
||||||
|
hud_color_subtitles: Color::rgb(0.8, 0.8, 0.8),
|
||||||
|
hud_color_choices: Color::rgb(0.45, 0.45, 0.45),
|
||||||
chat_speed: DEFAULT_CHAT_SPEED * if dev_mode { 2.5 } else { 1.0 },
|
chat_speed: DEFAULT_CHAT_SPEED * if dev_mode { 2.5 } else { 1.0 },
|
||||||
hud_active: false,
|
hud_active: false,
|
||||||
is_zooming: false,
|
is_zooming: false,
|
||||||
|
|
Loading…
Reference in a new issue