mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'zesterer/small-fixes' into 'master'
Small improvements See merge request veloren/veloren!2488
This commit is contained in:
commit
011f76dbf2
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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(..) {
|
||||
|
@ -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);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
},
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user