diff --git a/CHANGELOG.md b/CHANGELOG.md index ee737abab2..9bb77bcb69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,21 +8,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added + - Added a skill tree for mining, which gains xp from mining ores and gems. - Added debug line info to release builds, enhancing the usefulness of panic backtraces - NPCs and animals can now make sounds in response to certain events - Players can press H to greet others +- Ability to toggle chat visibility ### Changed + - Entity-entity pushback is no longer applied in forced movement states like rolling and leaping. - Updated audio library (rodio 0.13 -> 0.14). - Improve entity-terrain physics performance by reducing the number of voxel lookups. - Clay Golem uses shockwave only after specific fraction of health and other difficulty adjustments. +- Made strafing slightly slower ### Removed + - Enemies no more spawn in dungeon boss room ### Fixed + - Crafting Stations aren't exploadable anymore - Cases where no audio output could be produced before. - Significantly improved the performance of playing sound effects diff --git a/assets/voxygen/i18n/en/hud/hud_settings.ron b/assets/voxygen/i18n/en/hud/hud_settings.ron index 24023e2ba3..1292fb06c7 100644 --- a/assets/voxygen/i18n/en/hud/hud_settings.ron +++ b/assets/voxygen/i18n/en/hud/hud_settings.ron @@ -11,6 +11,7 @@ "hud.settings.help_window": "Help Window", "hud.settings.debug_info": "Debug Info", "hud.settings.show_hitboxes": "Show hitboxes", + "hud.settings.show_chat": "Show chat", "hud.settings.tips_on_startup": "Tips-On-Startup", "hud.settings.ui_scale": "UI-Scale", "hud.settings.relative_scaling": "Relative Scaling", diff --git a/assets/voxygen/shaders/include/light.glsl b/assets/voxygen/shaders/include/light.glsl index 2567109c10..63001b605c 100644 --- a/assets/voxygen/shaders/include/light.glsl +++ b/assets/voxygen/shaders/include/light.glsl @@ -173,7 +173,7 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 /*cam_to_frag*/view_dir, vec3 mu, ve float light_distance = sqrt(distance_2); vec3 light_dir = -difference / light_distance; // normalize(-difference); // light_dir = faceforward(light_dir, wnorm, light_dir); - bool is_direct = dot(-light_dir, wnorm) > 0.0; + bool is_direct = dot(difference, wnorm) > 0.0; // reflected_light += color * (distance_2 == 0.0 ? vec3(1.0) : light_reflection_factor(wnorm, cam_to_frag, light_dir, k_d, k_s, alpha)); vec3 direct_light_dir = is_direct ? light_dir : -light_dir; // vec3 direct_norm_dir = is_direct ? wnorm : -wnorm; diff --git a/assets/voxygen/shaders/include/sky.glsl b/assets/voxygen/shaders/include/sky.glsl index f6587037ab..e358ea02da 100644 --- a/assets/voxygen/shaders/include/sky.glsl +++ b/assets/voxygen/shaders/include/sky.glsl @@ -54,7 +54,11 @@ const vec3 GLOW_COLOR = vec3(0.89, 0.95, 0.52); // Calculate glow from static light sources, + some noise for flickering. // TODO: Optionally disable the flickering for performance? vec3 glow_light(vec3 pos) { - return GLOW_COLOR * (1.0 + (noise_3d(vec3(pos.xy * 0.005, tick.x * 0.5)) - 0.5) * 1.0); + #if (SHADOW_MODE <= SHADOW_MODE_NONE) + return GLOW_COLOR; + #else + return GLOW_COLOR * (1.0 + (noise_3d(vec3(pos.xy * 0.005, tick.x * 0.5)) - 0.5) * 1.0); + #endif } //vec3 get_sun_dir(float time_of_day) { @@ -420,7 +424,7 @@ vec3 get_sky_light(vec3 dir, float time_of_day, bool with_stars) { // Add white dots for stars. Note these flicker and jump due to FXAA float star = 0.0; if (with_stars) { - vec3 star_dir = normalize(sun_dir.xyz * dir.z + cross(sun_dir.xyz, vec3(0, 1, 0)) * dir.x + vec3(0, 1, 0) * dir.y); + vec3 star_dir = sun_dir.xyz * dir.z + cross(sun_dir.xyz, vec3(0, 1, 0)) * dir.x + vec3(0, 1, 0) * dir.y; star = is_star_at(star_dir); } @@ -485,7 +489,13 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q pow(max(-sun_dir.z, 0.0), 0.5) ); - vec3 sun_halo = sun_halo_color * 25 * pow(max(dot(dir, -sun_dir), 0), 20.0); + float sun_halo_power = 20.0; + #if (CLOUD_MODE == CLOUD_MODE_NONE) + sun_halo_power = 1000.0; + sun_halo_color *= 0.1; + #endif + + vec3 sun_halo = sun_halo_color * 25 * pow(max(dot(dir, -sun_dir), 0), sun_halo_power); vec3 sun_surf = vec3(0); if (with_features) { float angle = 0.00035; @@ -498,7 +508,14 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q const vec3 MOON_HALO_COLOR = vec3(0.015, 0.015, 0.05) * 250; vec3 moon_halo_color = MOON_HALO_COLOR; - vec3 moon_halo = moon_halo_color * pow(max(dot(dir, -moon_dir), 0), 100.0); + + float moon_halo_power = 20.0; + #if (CLOUD_MODE == CLOUD_MODE_NONE) + moon_halo_power = 2500.0; + moon_halo_color *= 0.1; + #endif + + vec3 moon_halo = moon_halo_color * pow(max(dot(dir, -moon_dir), 0), moon_halo_power); vec3 moon_surf = vec3(0); if (with_features) { float angle = 0.00035; diff --git a/common/src/comp/controller.rs b/common/src/comp/controller.rs index 2979de12a5..7d4a1a7448 100644 --- a/common/src/comp/controller.rs +++ b/common/src/comp/controller.rs @@ -215,6 +215,20 @@ pub struct Controller { } impl ControllerInputs { + /// Sanitize inputs to avoid clients sending bad data. + pub fn sanitize(&mut self) { + self.move_dir = if self.move_dir.map(|e| e.is_finite()).reduce_and() { + self.move_dir / self.move_dir.magnitude().max(1.0) + } else { + Vec2::zero() + }; + self.move_z = if self.move_z.is_finite() { + self.move_z.clamped(-1.0, 1.0) + } else { + 0.0 + }; + } + /// Updates Controller inputs with new version received from the client pub fn update_with_new(&mut self, new: Self) { self.climb = new.climb; diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 876d049618..99236a42fa 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -216,6 +216,10 @@ impl Body { } pub fn can_climb(&self) -> bool { matches!(self, Body::Humanoid(_)) } + + /// Returns how well a body can move backwards while strafing (0.0 = not at + /// all, 1.0 = same as forward) + pub fn reverse_move_factor(&self) -> f32 { 0.5 } } /// Handles updating `Components` to move player based on state of `JoinData` @@ -257,6 +261,19 @@ fn basic_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) { * accel * if data.body.can_strafe() { data.inputs.move_dir + * if is_strafing(data, update) { + Lerp::lerp( + Vec2::from(update.ori) + .try_normalized() + .unwrap_or_else(Vec2::zero) + .dot(data.inputs.move_dir) + .max(0.0), + 1.0, + data.body.reverse_move_factor(), + ) + } else { + 1.0 + } } else { let fw = Vec2::from(update.ori); fw * data.inputs.move_dir.dot(fw).max(0.0) @@ -307,11 +324,7 @@ pub fn handle_forced_movement(data: &JoinData, update: &mut StateUpdate, movemen } pub fn handle_orientation(data: &JoinData, update: &mut StateUpdate, efficiency: f32) { - // TODO: Don't always check `character.is_aimed()`, allow the frontend to - // control whether the player strafes during an aimed `CharacterState`. - let strafe_aim = - (update.character.is_aimed() || update.should_strafe) && data.body.can_strafe(); - if let Some(dir) = (strafe_aim || update.character.is_attack()) + if let Some(dir) = (is_strafing(data, update) || update.character.is_attack()) .then(|| data.inputs.look_dir.to_horizontal().unwrap_or_default()) .or_else(|| Dir::from_unnormalized(data.inputs.move_dir.into())) { @@ -712,6 +725,12 @@ pub fn handle_dodge_input(data: &JoinData, update: &mut StateUpdate) { } } +pub fn is_strafing(data: &JoinData, update: &StateUpdate) -> bool { + // TODO: Don't always check `character.is_aimed()`, allow the frontend to + // control whether the player strafes during an aimed `CharacterState`. + (update.character.is_aimed() || update.should_strafe) && data.body.can_strafe() +} + pub fn unwrap_tool_data<'a>(data: &'a JoinData, equip_slot: EquipSlot) -> Option<&'a Tool> { if let Some(ItemKind::Tool(tool)) = data.inventory.equipped(equip_slot).map(|i| i.kind()) { Some(&tool) diff --git a/common/systems/src/controller.rs b/common/systems/src/controller.rs index 2aea04b55a..7cc1e67e23 100644 --- a/common/systems/src/controller.rs +++ b/common/systems/src/controller.rs @@ -37,16 +37,8 @@ impl<'a> System<'a> for Sys { let mut server_emitter = read_data.server_bus.emitter(); for (entity, controller) in (&read_data.entities, &mut controllers).join() { - let mut inputs = &mut controller.inputs; - - // Update `inputs.move_dir`. - inputs.move_dir = if inputs.move_dir.magnitude_squared() > 1.0 { - // Cap move_dir to 1 - inputs.move_dir.normalized() - } else { - inputs.move_dir - }; - inputs.move_z = inputs.move_z.clamped(-1.0, 1.0); + // Sanitize inputs to avoid clients sending bad data + controller.inputs.sanitize(); // Process other controller events for event in controller.events.drain(..) { diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index d409045156..fa478cb929 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -2706,43 +2706,45 @@ impl Hud { .retain(|m| !matches!(m.chat_type, comp::ChatType::Npc(_, _))); // Chat box - for event in Chat::new( - &mut self.new_messages, - &client, - global_state, - self.pulse, - &self.imgs, - &self.fonts, - i18n, - ) - .and_then(self.force_chat_input.take(), |c, input| c.input(input)) - .and_then(self.tab_complete.take(), |c, input| { - c.prepare_tab_completion(input) - }) - .and_then(self.force_chat_cursor.take(), |c, pos| c.cursor_pos(pos)) - .set(self.ids.chat, ui_widgets) - { - match event { - chat::Event::TabCompletionStart(input) => { - self.tab_complete = Some(input); - }, - chat::Event::SendMessage(message) => { - events.push(Event::SendMessage(message)); - }, - chat::Event::SendCommand(name, args) => { - events.push(Event::SendCommand(name, args)); - }, - chat::Event::Focus(focus_id) => { - self.to_focus = Some(Some(focus_id)); - }, - chat::Event::ChangeChatTab(tab) => { - events.push(Event::SettingsChange(ChatChange::ChangeChatTab(tab).into())); - }, - chat::Event::ShowChatTabSettings(tab) => { - self.show.chat_tab_settings_index = Some(tab); - self.show.settings_tab = SettingsTab::Chat; - self.show.settings(true); - }, + if global_state.settings.interface.toggle_chat { + for event in Chat::new( + &mut self.new_messages, + &client, + global_state, + self.pulse, + &self.imgs, + &self.fonts, + i18n, + ) + .and_then(self.force_chat_input.take(), |c, input| c.input(input)) + .and_then(self.tab_complete.take(), |c, input| { + c.prepare_tab_completion(input) + }) + .and_then(self.force_chat_cursor.take(), |c, pos| c.cursor_pos(pos)) + .set(self.ids.chat, ui_widgets) + { + match event { + chat::Event::TabCompletionStart(input) => { + self.tab_complete = Some(input); + }, + chat::Event::SendMessage(message) => { + events.push(Event::SendMessage(message)); + }, + chat::Event::SendCommand(name, args) => { + events.push(Event::SendCommand(name, args)); + }, + chat::Event::Focus(focus_id) => { + self.to_focus = Some(Some(focus_id)); + }, + chat::Event::ChangeChatTab(tab) => { + events.push(Event::SettingsChange(ChatChange::ChangeChatTab(tab).into())); + }, + chat::Event::ShowChatTabSettings(tab) => { + self.show.chat_tab_settings_index = Some(tab); + self.show.settings_tab = SettingsTab::Chat; + self.show.settings(true); + }, + } } } diff --git a/voxygen/src/hud/settings_window/interface.rs b/voxygen/src/hud/settings_window/interface.rs index 30478a2e20..11dd1ff536 100644 --- a/voxygen/src/hud/settings_window/interface.rs +++ b/voxygen/src/hud/settings_window/interface.rs @@ -38,6 +38,8 @@ widget_ids! { debug_button_label, hitboxes_button, hitboxes_button_label, + chat_button, + chat_button_label, ch_title, ch_transp_slider, ch_transp_value, @@ -266,9 +268,33 @@ impl<'a> Widget for Interface<'a> { .color(TEXT_COLOR) .set(state.ids.hitboxes_button_label, ui); + // Chat + let show_chat = ToggleButton::new( + self.global_state.settings.interface.toggle_chat, + self.imgs.checkbox, + self.imgs.checkbox_checked, + ) + .w_h(18.0, 18.0) + .down_from(state.ids.hitboxes_button, 8.0) + .hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo) + .press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked) + .set(state.ids.chat_button, ui); + + if self.global_state.settings.interface.toggle_chat != show_chat { + events.push(ToggleChat(show_chat)); + } + + Text::new(&self.localized_strings.get("hud.settings.show_chat")) + .right_from(state.ids.chat_button, 10.0) + .font_size(self.fonts.cyri.scale(14)) + .font_id(self.fonts.cyri.conrod_id) + .graphics_for(state.ids.chat_button) + .color(TEXT_COLOR) + .set(state.ids.chat_button_label, ui); + // Ui Scale Text::new(&self.localized_strings.get("hud.settings.ui_scale")) - .down_from(state.ids.hitboxes_button, 20.0) + .down_from(state.ids.chat_button, 20.0) .font_size(self.fonts.cyri.scale(18)) .font_id(self.fonts.cyri.conrod_id) .color(TEXT_COLOR) diff --git a/voxygen/src/session/settings_change.rs b/voxygen/src/session/settings_change.rs index cbb4fdaa64..0b62766580 100644 --- a/voxygen/src/session/settings_change.rs +++ b/voxygen/src/session/settings_change.rs @@ -97,6 +97,7 @@ pub enum Interface { ToggleHelp(bool), ToggleDebug(bool), ToggleHitboxes(bool), + ToggleChat(bool), ToggleTips(bool), CrosshairTransp(f32), @@ -450,6 +451,9 @@ impl SettingsChange { Interface::ToggleHitboxes(toggle_hitboxes) => { settings.interface.toggle_hitboxes = toggle_hitboxes; }, + Interface::ToggleChat(toggle_chat) => { + settings.interface.toggle_chat = toggle_chat; + }, Interface::ToggleTips(loading_tips) => { settings.interface.loading_tips = loading_tips; }, diff --git a/voxygen/src/settings/interface.rs b/voxygen/src/settings/interface.rs index 0e632d4765..b85caac831 100644 --- a/voxygen/src/settings/interface.rs +++ b/voxygen/src/settings/interface.rs @@ -11,6 +11,7 @@ use vek::*; pub struct InterfaceSettings { pub toggle_debug: bool, pub toggle_hitboxes: bool, + pub toggle_chat: bool, pub sct: bool, pub sct_player_batch: bool, pub sct_damage_batch: bool, @@ -46,6 +47,7 @@ impl Default for InterfaceSettings { Self { toggle_debug: false, toggle_hitboxes: false, + toggle_chat: true, sct: true, sct_player_batch: false, sct_damage_batch: false,