Merge branch 'aweinstock/cameraclamp' into 'master'

Add a vertical camera clamp option and toggle to voxygen.

See merge request veloren/veloren!1962
This commit is contained in:
Imbris 2021-03-24 00:58:01 +00:00
commit cffb7ea677
8 changed files with 215 additions and 51 deletions

View File

@ -51,6 +51,7 @@
"gameinput.interact": "Interact",
"gameinput.freelook": "Free Look",
"gameinput.autowalk": "Auto Walk",
"gameinput.cameraclamp": "Camera Clamp",
"gameinput.dance": "Dance",
"gameinput.select": "Select Entity",
"gameinput.acceptgroupinvite": "Accept Group Invite",

View File

@ -40,12 +40,14 @@
"hud.settings.pan_sensitivity": "Pan Sensitivity",
"hud.settings.zoom_sensitivity": "Zoom Sensitivity",
"hud.settings.camera_clamp_angle": "Angle for vertical camera clamp mode",
"hud.settings.invert_scroll_zoom": "Invert Scroll Zoom",
"hud.settings.invert_mouse_y_axis": "Invert Mouse Y Axis",
"hud.settings.invert_controller_y_axis": "Invert Controller Y Axis",
"hud.settings.enable_mouse_smoothing": "Camera Smoothing",
"hud.settings.free_look_behavior": "Free look behavior",
"hud.settings.auto_walk_behavior": "Auto walk behavior",
"hud.settings.camera_clamp_behavior": "Camera clamp behavior",
"hud.settings.stop_auto_walk_on_input": "Stop auto walk on movement",
"hud.settings.reset_gameplay": "Reset to Defaults",

View File

@ -43,6 +43,7 @@ Whenever you feel ready, try to get even better equipment from the many challeng
"hud.diary": "Diary",
"hud.free_look_indicator": "Free look active. Press {key} to disable.",
"hud.camera_clamp_indicator": "Camera vertical clamp active. Press {key} to disable.",
"hud.auto_walk_indicator": "Auto walk active",
},

View File

@ -272,6 +272,10 @@ widget_ids! {
auto_walk_txt,
auto_walk_bg,
// Camera clamp indicator
camera_clamp_txt,
camera_clamp_bg,
// Tutorial
quest_bg,
q_headline_bg,
@ -345,6 +349,7 @@ pub enum Event {
SendMessage(String),
AdjustMousePan(u32),
AdjustMouseZoom(u32),
AdjustCameraClamp(u32),
ToggleZoomInvert(bool),
ToggleMouseYInvert(bool),
ToggleControllerYInvert(bool),
@ -421,6 +426,7 @@ pub enum Event {
ChangeFreeLookBehavior(PressBehavior),
ChangeRenderMode(Box<RenderMode>),
ChangeAutoWalkBehavior(PressBehavior),
ChangeCameraClampBehavior(PressBehavior),
ChangeStopAutoWalkOnInput(bool),
CraftRecipe(String),
InviteMember(Uid),
@ -494,6 +500,25 @@ pub enum PressBehavior {
Toggle = 0,
}
impl PressBehavior {
pub fn update(&self, keystate: bool, setting: &mut bool, f: impl FnOnce(bool)) {
match (self, keystate) {
// flip the state on key press in toggle mode
(PressBehavior::Toggle, true) => {
*setting ^= true;
f(*setting);
},
// do nothing on key release in toggle mode
(PressBehavior::Toggle, false) => {},
// set the setting to the key state in hold mode
(PressBehavior::Hold, state) => {
*setting = state;
f(*setting);
},
}
}
}
pub struct Show {
ui: bool,
intro: bool,
@ -518,6 +543,7 @@ pub struct Show {
stats: bool,
free_look: bool,
auto_walk: bool,
camera_clamp: bool,
prompt_dialog: Option<PromptDialogSettings>,
}
impl Show {
@ -835,6 +861,7 @@ impl Hud {
stats: false,
free_look: false,
auto_walk: false,
camera_clamp: false,
prompt_dialog: None,
},
to_focus: None,
@ -2456,6 +2483,9 @@ impl Hud {
settings_window::Event::AdjustMouseZoom(sensitivity) => {
events.push(Event::AdjustMouseZoom(sensitivity));
},
settings_window::Event::AdjustCameraClamp(sensitivity) => {
events.push(Event::AdjustCameraClamp(sensitivity));
},
settings_window::Event::ChatTransp(chat_transp) => {
events.push(Event::ChatTransp(chat_transp));
},
@ -2552,6 +2582,9 @@ impl Hud {
settings_window::Event::ChangeAutoWalkBehavior(behavior) => {
events.push(Event::ChangeAutoWalkBehavior(behavior));
},
settings_window::Event::ChangeCameraClampBehavior(behavior) => {
events.push(Event::ChangeCameraClampBehavior(behavior));
},
settings_window::Event::ChangeStopAutoWalkOnInput(state) => {
events.push(Event::ChangeStopAutoWalkOnInput(state));
},
@ -2737,6 +2770,8 @@ impl Hud {
}
}
let mut indicator_offset = 40.0;
// Free look indicator
if let Some(freelook_key) = global_state
.settings
@ -2744,26 +2779,22 @@ impl Hud {
.get_binding(GameInput::FreeLook)
{
if self.show.free_look {
Text::new(
&i18n
.get("hud.free_look_indicator")
.replace("{key}", freelook_key.to_string().as_str()),
)
.color(TEXT_BG)
.mid_top_with_margin_on(ui_widgets.window, 40.0)
.font_id(self.fonts.cyri.conrod_id)
.font_size(self.fonts.cyri.scale(20))
.set(self.ids.free_look_bg, ui_widgets);
Text::new(
&i18n
.get("hud.free_look_indicator")
.replace("{key}", freelook_key.to_string().as_str()),
)
.color(KILL_COLOR)
.top_left_with_margins_on(self.ids.free_look_bg, -1.0, -1.0)
.font_id(self.fonts.cyri.conrod_id)
.font_size(self.fonts.cyri.scale(20))
.set(self.ids.free_look_txt, ui_widgets);
let msg = i18n
.get("hud.free_look_indicator")
.replace("{key}", freelook_key.to_string().as_str());
Text::new(&msg)
.color(TEXT_BG)
.mid_top_with_margin_on(ui_widgets.window, indicator_offset)
.font_id(self.fonts.cyri.conrod_id)
.font_size(self.fonts.cyri.scale(20))
.set(self.ids.free_look_bg, ui_widgets);
indicator_offset += 30.0;
Text::new(&msg)
.color(KILL_COLOR)
.top_left_with_margins_on(self.ids.free_look_bg, -1.0, -1.0)
.font_id(self.fonts.cyri.conrod_id)
.font_size(self.fonts.cyri.scale(20))
.set(self.ids.free_look_txt, ui_widgets);
}
};
@ -2771,10 +2802,11 @@ impl Hud {
if self.show.auto_walk {
Text::new(i18n.get("hud.auto_walk_indicator"))
.color(TEXT_BG)
.mid_top_with_margin_on(ui_widgets.window, 70.0)
.mid_top_with_margin_on(ui_widgets.window, indicator_offset)
.font_id(self.fonts.cyri.conrod_id)
.font_size(self.fonts.cyri.scale(20))
.set(self.ids.auto_walk_bg, ui_widgets);
indicator_offset += 30.0;
Text::new(i18n.get("hud.auto_walk_indicator"))
.color(KILL_COLOR)
.top_left_with_margins_on(self.ids.auto_walk_bg, -1.0, -1.0)
@ -2783,6 +2815,31 @@ impl Hud {
.set(self.ids.auto_walk_txt, ui_widgets);
}
// Camera clamp indicator
if let Some(cameraclamp_key) = global_state
.settings
.controls
.get_binding(GameInput::CameraClamp)
{
if self.show.camera_clamp {
let msg = i18n
.get("hud.camera_clamp_indicator")
.replace("{key}", cameraclamp_key.to_string().as_str());
Text::new(&msg)
.color(TEXT_BG)
.mid_top_with_margin_on(ui_widgets.window, indicator_offset)
.font_id(self.fonts.cyri.conrod_id)
.font_size(self.fonts.cyri.scale(20))
.set(self.ids.camera_clamp_bg, ui_widgets);
Text::new(&msg)
.color(KILL_COLOR)
.top_left_with_margins_on(self.ids.camera_clamp_bg, -1.0, -1.0)
.font_id(self.fonts.cyri.conrod_id)
.font_size(self.fonts.cyri.scale(20))
.set(self.ids.camera_clamp_txt, ui_widgets);
}
}
// Maintain slot manager
for event in self.slot_manager.maintain(ui_widgets) {
use comp::slot::Slot;
@ -3233,6 +3290,8 @@ impl Hud {
pub fn auto_walk(&mut self, auto_walk: bool) { self.show.auto_walk = auto_walk; }
pub fn camera_clamp(&mut self, camera_clamp: bool) { self.show.camera_clamp = camera_clamp; }
pub fn handle_outcome(&mut self, outcome: &Outcome) {
match outcome {
Outcome::ExpChange { uid, exp } => self.exp_floaters.push(ExpFloater {

View File

@ -97,6 +97,9 @@ widget_ids! {
mouse_zoom_value,
mouse_zoom_invert_button,
mouse_zoom_invert_label,
camera_clamp_slider,
camera_clamp_label,
camera_clamp_value,
mouse_y_invert_button,
mouse_y_invert_label,
controller_y_invert_button,
@ -236,6 +239,8 @@ widget_ids! {
free_look_behavior_list,
auto_walk_behavior_text,
auto_walk_behavior_list,
camera_clamp_behavior_text,
camera_clamp_behavior_list,
stop_auto_walk_on_input_button,
stop_auto_walk_on_input_label,
}
@ -303,6 +308,7 @@ pub enum Event {
Close,
AdjustMousePan(u32),
AdjustMouseZoom(u32),
AdjustCameraClamp(u32),
ToggleZoomInvert(bool),
ToggleMouseYInvert(bool),
ToggleControllerYInvert(bool),
@ -342,6 +348,7 @@ pub enum Event {
ResetAudioSettings,
ChangeFreeLookBehavior(PressBehavior),
ChangeAutoWalkBehavior(PressBehavior),
ChangeCameraClampBehavior(PressBehavior),
ChangeStopAutoWalkOnInput(bool),
}
@ -1367,6 +1374,7 @@ impl<'a> Widget for SettingsWindow<'a> {
if let SettingsTab::Gameplay = self.show.settings_tab {
let display_pan = self.global_state.settings.gameplay.pan_sensitivity;
let display_zoom = self.global_state.settings.gameplay.zoom_sensitivity;
let display_clamp = self.global_state.settings.gameplay.camera_clamp_angle;
// Mouse Pan Sensitivity
Text::new(&self.localized_strings.get("hud.settings.pan_sensitivity"))
@ -1432,6 +1440,42 @@ impl<'a> Widget for SettingsWindow<'a> {
.color(TEXT_COLOR)
.set(state.ids.mouse_zoom_value, ui);
// Camera clamp angle
Text::new(
&self
.localized_strings
.get("hud.settings.camera_clamp_angle"),
)
.down_from(state.ids.mouse_zoom_slider, 10.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.camera_clamp_label, ui);
if let Some(new_val) = ImageSlider::discrete(
display_clamp,
1,
90,
self.imgs.slider_indicator,
self.imgs.slider,
)
.w_h(550.0, 22.0)
.down_from(state.ids.camera_clamp_label, 10.0)
.track_breadth(30.0)
.slider_length(10.0)
.pad_track((5.0, 5.0))
.set(state.ids.camera_clamp_slider, ui)
{
events.push(Event::AdjustCameraClamp(new_val));
}
Text::new(&format!("{}", display_clamp))
.right_from(state.ids.camera_clamp_slider, 8.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.camera_clamp_value, ui);
// Zoom Inversion
let zoom_inverted = ToggleButton::new(
self.global_state.settings.gameplay.zoom_inversion,
@ -1439,7 +1483,7 @@ impl<'a> Widget for SettingsWindow<'a> {
self.imgs.checkbox_checked,
)
.w_h(18.0, 18.0)
.down_from(state.ids.mouse_zoom_slider, 20.0)
.down_from(state.ids.camera_clamp_slider, 20.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.mouse_zoom_invert_button, ui);
@ -1622,6 +1666,36 @@ impl<'a> Widget for SettingsWindow<'a> {
}
}
// Camera clamp behavior
Text::new(
&self
.localized_strings
.get("hud.settings.camera_clamp_behavior"),
)
.down_from(state.ids.free_look_behavior_list, 10.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.camera_clamp_behavior_text, ui);
let camera_clamp_selected =
self.global_state.settings.gameplay.camera_clamp_behavior as usize;
if let Some(clicked) = DropDownList::new(&mode_label_list, Some(camera_clamp_selected))
.w_h(200.0, 30.0)
.color(MENU_BG)
.label_color(TEXT_COLOR)
.label_font_id(self.fonts.cyri.conrod_id)
.down_from(state.ids.camera_clamp_behavior_text, 8.0)
.set(state.ids.camera_clamp_behavior_list, ui)
{
match clicked {
0 => events.push(Event::ChangeCameraClampBehavior(PressBehavior::Toggle)),
1 => events.push(Event::ChangeCameraClampBehavior(PressBehavior::Hold)),
_ => unreachable!(),
}
}
// Stop autowalk on input toggle
let stop_auto_walk_on_input_toggle = ToggleButton::new(
self.global_state.settings.gameplay.stop_auto_walk_on_input,
@ -1659,7 +1733,7 @@ impl<'a> Widget for SettingsWindow<'a> {
.w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.down_from(state.ids.free_look_behavior_list, 12.0)
.down_from(state.ids.camera_clamp_behavior_list, 12.0)
.label(&self.localized_strings.get("hud.settings.reset_gameplay"))
.label_font_size(self.fonts.cyri.scale(14))
.label_color(TEXT_COLOR)

View File

@ -34,7 +34,7 @@ use common_net::{
use crate::{
audio::sfx::SfxEvent,
controller::ControllerSettings,
hud::{DebugInfo, Event as HudEvent, Hud, HudInfo, PressBehavior, PromptDialogSettings},
hud::{DebugInfo, Event as HudEvent, Hud, HudInfo, PromptDialogSettings},
i18n::{i18n_asset_key, Localization},
key_state::KeyState,
menu::char_selection::CharSelectionState,
@ -69,6 +69,7 @@ pub struct SessionState {
freefly_vel: Vec3<f32>,
free_look: bool,
auto_walk: bool,
camera_clamp: bool,
is_aiming: bool,
target_entity: Option<specs::Entity>,
selected_entity: Option<(specs::Entity, std::time::Instant)>,
@ -106,6 +107,7 @@ impl SessionState {
freefly_vel: Vec3::zero(),
free_look: false,
auto_walk: false,
camera_clamp: false,
is_aiming: false,
target_entity: None,
selected_entity: None,
@ -267,10 +269,19 @@ impl PlayState for SessionState {
(client.presence(), client.registered())
};
if client_presence.is_some() {
let camera = self.scene.camera_mut();
// Clamp camera's vertical angle if the toggle is enabled
if self.camera_clamp {
let mut cam_dir = camera.get_orientation();
let cam_dir_clamp =
(global_state.settings.gameplay.camera_clamp_angle as f32).to_radians();
cam_dir.y = (-cam_dir_clamp).max(cam_dir.y).min(cam_dir_clamp);
camera.set_orientation(cam_dir);
}
// Compute camera data
self.scene
.camera_mut()
.compute_dependents(&*self.client.borrow().state().terrain());
camera.compute_dependents(&*self.client.borrow().state().terrain());
let camera::Dependents {
cam_pos, cam_dir, ..
} = self.scene.camera().dependents();
@ -608,32 +619,29 @@ impl PlayState for SessionState {
}
},
GameInput::FreeLook => {
match (global_state.settings.gameplay.free_look_behavior, state) {
(PressBehavior::Toggle, true) => {
self.free_look = !self.free_look;
self.hud.free_look(self.free_look);
},
(PressBehavior::Hold, state) => {
self.free_look = state;
self.hud.free_look(self.free_look);
},
_ => {},
};
let hud = &mut self.hud;
global_state.settings.gameplay.free_look_behavior.update(
state,
&mut self.free_look,
|b| hud.free_look(b),
);
},
GameInput::AutoWalk => {
match (global_state.settings.gameplay.auto_walk_behavior, state) {
(PressBehavior::Toggle, true) => {
self.auto_walk = !self.auto_walk;
self.key_state.auto_walk = self.auto_walk;
self.hud.auto_walk(self.auto_walk);
},
(PressBehavior::Hold, state) => {
self.auto_walk = state;
self.key_state.auto_walk = self.auto_walk;
self.hud.auto_walk(self.auto_walk);
},
_ => {},
}
let hud = &mut self.hud;
global_state.settings.gameplay.auto_walk_behavior.update(
state,
&mut self.auto_walk,
|b| hud.auto_walk(b),
);
self.key_state.auto_walk = self.auto_walk;
},
GameInput::CameraClamp => {
let hud = &mut self.hud;
global_state.settings.gameplay.camera_clamp_behavior.update(
state,
&mut self.camera_clamp,
|b| hud.camera_clamp(b),
);
},
GameInput::CycleCamera if state => {
// Prevent accessing camera modes which aren't available in
@ -880,6 +888,10 @@ impl PlayState for SessionState {
global_state.settings.gameplay.zoom_sensitivity = sensitivity;
global_state.settings.save_to_file_warn();
},
HudEvent::AdjustCameraClamp(angle) => {
global_state.settings.gameplay.camera_clamp_angle = angle;
global_state.settings.save_to_file_warn();
},
HudEvent::ToggleZoomInvert(zoom_inverted) => {
global_state.window.zoom_inversion = zoom_inverted;
global_state.settings.gameplay.zoom_inversion = zoom_inverted;
@ -1344,12 +1356,19 @@ impl PlayState for SessionState {
},
HudEvent::ChangeFreeLookBehavior(behavior) => {
global_state.settings.gameplay.free_look_behavior = behavior;
global_state.settings.save_to_file_warn();
},
HudEvent::ChangeAutoWalkBehavior(behavior) => {
global_state.settings.gameplay.auto_walk_behavior = behavior;
global_state.settings.save_to_file_warn();
},
HudEvent::ChangeCameraClampBehavior(behavior) => {
global_state.settings.gameplay.camera_clamp_behavior = behavior;
global_state.settings.save_to_file_warn();
},
HudEvent::ChangeStopAutoWalkOnInput(state) => {
global_state.settings.gameplay.stop_auto_walk_on_input = state;
global_state.settings.save_to_file_warn();
},
HudEvent::CraftRecipe(r) => {
self.client.borrow_mut().craft_recipe(&r);

View File

@ -159,6 +159,7 @@ impl ControlSettings {
GameInput::ToggleWield => KeyMouse::Key(VirtualKeyCode::T),
GameInput::FreeLook => KeyMouse::Key(VirtualKeyCode::L),
GameInput::AutoWalk => KeyMouse::Key(VirtualKeyCode::Period),
GameInput::CameraClamp => KeyMouse::Key(VirtualKeyCode::Apostrophe),
GameInput::CycleCamera => KeyMouse::Key(VirtualKeyCode::Key0),
GameInput::Slot1 => KeyMouse::Key(VirtualKeyCode::Key1),
GameInput::Slot2 => KeyMouse::Key(VirtualKeyCode::Key2),
@ -494,11 +495,13 @@ impl Default for InterfaceSettings {
pub struct GameplaySettings {
pub pan_sensitivity: u32,
pub zoom_sensitivity: u32,
pub camera_clamp_angle: u32,
pub zoom_inversion: bool,
pub mouse_y_inversion: bool,
pub smooth_pan_enable: bool,
pub free_look_behavior: PressBehavior,
pub auto_walk_behavior: PressBehavior,
pub camera_clamp_behavior: PressBehavior,
pub stop_auto_walk_on_input: bool,
}
@ -507,11 +510,13 @@ impl Default for GameplaySettings {
Self {
pan_sensitivity: 100,
zoom_sensitivity: 100,
camera_clamp_angle: 45,
zoom_inversion: false,
mouse_y_inversion: false,
smooth_pan_enable: false,
free_look_behavior: PressBehavior::Toggle,
auto_walk_behavior: PressBehavior::Toggle,
camera_clamp_behavior: PressBehavior::Toggle,
stop_auto_walk_on_input: true,
}
}

View File

@ -71,6 +71,7 @@ pub enum GameInput {
SwapLoadout,
FreeLook,
AutoWalk,
CameraClamp,
CycleCamera,
Select,
AcceptGroupInvite,
@ -122,6 +123,7 @@ impl GameInput {
GameInput::ToggleWield => "gameinput.togglewield",
GameInput::FreeLook => "gameinput.freelook",
GameInput::AutoWalk => "gameinput.autowalk",
GameInput::CameraClamp => "gameinput.cameraclamp",
GameInput::Slot1 => "gameinput.slot1",
GameInput::Slot2 => "gameinput.slot2",
GameInput::Slot3 => "gameinput.slot3",
@ -182,6 +184,7 @@ impl GameInput {
GameInput::ToggleWield,
GameInput::FreeLook,
GameInput::AutoWalk,
GameInput::CameraClamp,
GameInput::Slot1,
GameInput::Slot2,
GameInput::Slot3,