mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'lboklin/auto-glide' into 'master'
Implement auto-glide See merge request veloren/veloren!2321
This commit is contained in:
commit
ee93803f4a
@ -931,6 +931,11 @@ impl Client {
|
|||||||
|
|
||||||
pub fn is_dead(&self) -> bool { self.current::<comp::Health>().map_or(false, |h| h.is_dead) }
|
pub fn is_dead(&self) -> bool { self.current::<comp::Health>().map_or(false, |h| h.is_dead) }
|
||||||
|
|
||||||
|
pub fn is_gliding(&self) -> bool {
|
||||||
|
self.current::<comp::CharacterState>()
|
||||||
|
.map_or(false, |cs| matches!(cs, comp::CharacterState::Glide(_)))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn split_swap_slots(&mut self, a: comp::slot::Slot, b: comp::slot::Slot) {
|
pub fn split_swap_slots(&mut self, a: comp::slot::Slot, b: comp::slot::Slot) {
|
||||||
match (a, b) {
|
match (a, b) {
|
||||||
(Slot::Equip(equip), slot) | (slot, Slot::Equip(equip)) => self.control_action(
|
(Slot::Equip(equip), slot) | (slot, Slot::Equip(equip)) => self.control_action(
|
||||||
@ -1234,7 +1239,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_glide(&mut self) {
|
pub fn toggle_glide(&mut self) {
|
||||||
let is_gliding = self
|
let using_glider = self
|
||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.read_storage::<comp::CharacterState>()
|
.read_storage::<comp::CharacterState>()
|
||||||
@ -1246,7 +1251,7 @@ impl Client {
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
match is_gliding {
|
match using_glider {
|
||||||
Some(true) => self.control_action(ControlAction::Unwield),
|
Some(true) => self.control_action(ControlAction::Unwield),
|
||||||
Some(false) => self.control_action(ControlAction::GlideWield),
|
Some(false) => self.control_action(ControlAction::GlideWield),
|
||||||
None => warn!("Can't toggle glide, client entity doesn't have a `CharacterState`"),
|
None => warn!("Can't toggle glide, client entity doesn't have a `CharacterState`"),
|
||||||
|
@ -22,6 +22,7 @@ pub struct Data {
|
|||||||
pub ori: Ori,
|
pub ori: Ori,
|
||||||
last_vel: Vel,
|
last_vel: Vel,
|
||||||
timer: f32,
|
timer: f32,
|
||||||
|
inputs_disabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Data {
|
impl Data {
|
||||||
@ -40,13 +41,19 @@ impl Data {
|
|||||||
ori,
|
ori,
|
||||||
last_vel: Vel::zero(),
|
last_vel: Vel::zero(),
|
||||||
timer: 0.0,
|
timer: 0.0,
|
||||||
|
inputs_disabled: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tgt_dir(&self, data: &JoinData) -> Dir {
|
fn tgt_dir(&self, data: &JoinData) -> Dir {
|
||||||
|
let move_dir = if self.inputs_disabled {
|
||||||
|
Vec2::zero()
|
||||||
|
} else {
|
||||||
|
data.inputs.move_dir
|
||||||
|
};
|
||||||
let look_ori = Ori::from(data.inputs.look_dir);
|
let look_ori = Ori::from(data.inputs.look_dir);
|
||||||
look_ori
|
look_ori
|
||||||
.yawed_right(PI / 3.0 * look_ori.right().xy().dot(data.inputs.move_dir))
|
.yawed_right(PI / 3.0 * look_ori.right().xy().dot(move_dir))
|
||||||
.pitched_up(PI * 0.04)
|
.pitched_up(PI * 0.04)
|
||||||
.pitched_down(
|
.pitched_down(
|
||||||
data.inputs
|
data.inputs
|
||||||
@ -54,7 +61,7 @@ impl Data {
|
|||||||
.xy()
|
.xy()
|
||||||
.try_normalized()
|
.try_normalized()
|
||||||
.map_or(0.0, |ld| {
|
.map_or(0.0, |ld| {
|
||||||
PI * 0.1 * ld.dot(data.inputs.move_dir) * self.timer.min(PITCH_SLOW_TIME)
|
PI * 0.1 * ld.dot(move_dir) * self.timer.min(PITCH_SLOW_TIME)
|
||||||
/ PITCH_SLOW_TIME
|
/ PITCH_SLOW_TIME
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@ -84,6 +91,8 @@ impl CharacterBehavior for Data {
|
|||||||
.map(|fluid| fluid.relative_flow(data.vel))
|
.map(|fluid| fluid.relative_flow(data.vel))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let inputs_disabled = self.inputs_disabled && !data.inputs.move_dir.is_approx_zero();
|
||||||
|
|
||||||
let ori = {
|
let ori = {
|
||||||
let slerp_s = {
|
let slerp_s = {
|
||||||
let angle = self.ori.look_dir().angle_between(*data.inputs.look_dir);
|
let angle = self.ori.look_dir().angle_between(*data.inputs.look_dir);
|
||||||
@ -178,6 +187,7 @@ impl CharacterBehavior for Data {
|
|||||||
ori,
|
ori,
|
||||||
last_vel: *data.vel,
|
last_vel: *data.vel,
|
||||||
timer: self.timer + data.dt.0,
|
timer: self.timer + data.dt.0,
|
||||||
|
inputs_disabled,
|
||||||
..*self
|
..*self
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -22,7 +22,7 @@ use common::{
|
|||||||
trade::TradeResult,
|
trade::TradeResult,
|
||||||
util::{
|
util::{
|
||||||
find_dist::{Cube, Cylinder, FindDist},
|
find_dist::{Cube, Cylinder, FindDist},
|
||||||
Dir,
|
Dir, Plane,
|
||||||
},
|
},
|
||||||
vol::ReadVol,
|
vol::ReadVol,
|
||||||
};
|
};
|
||||||
@ -520,6 +520,9 @@ impl PlayState for SessionState {
|
|||||||
},
|
},
|
||||||
GameInput::Glide => {
|
GameInput::Glide => {
|
||||||
if state {
|
if state {
|
||||||
|
if global_state.settings.gameplay.stop_auto_walk_on_input {
|
||||||
|
self.stop_auto_walk();
|
||||||
|
}
|
||||||
self.client.borrow_mut().toggle_glide();
|
self.client.borrow_mut().toggle_glide();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -682,7 +685,9 @@ impl PlayState for SessionState {
|
|||||||
&mut self.auto_walk,
|
&mut self.auto_walk,
|
||||||
|b| hud.auto_walk(b),
|
|b| hud.auto_walk(b),
|
||||||
);
|
);
|
||||||
self.key_state.auto_walk = self.auto_walk;
|
|
||||||
|
self.key_state.auto_walk =
|
||||||
|
self.auto_walk && !self.client.borrow().is_gliding();
|
||||||
},
|
},
|
||||||
GameInput::CameraClamp => {
|
GameInput::CameraClamp => {
|
||||||
let hud = &mut self.hud;
|
let hud = &mut self.hud;
|
||||||
@ -747,10 +752,57 @@ impl PlayState for SessionState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.free_look {
|
// If auto-gliding, point camera into the wind
|
||||||
self.walk_forward_dir = self.scene.camera().forward_xy();
|
if let Some(dir) = self
|
||||||
self.walk_right_dir = self.scene.camera().right_xy();
|
.auto_walk
|
||||||
self.inputs.look_dir = Dir::from_unnormalized(cam_dir + aim_dir_offset).unwrap();
|
.then_some(self.client.borrow())
|
||||||
|
.filter(|client| client.is_gliding())
|
||||||
|
.and_then(|client| {
|
||||||
|
let ecs = client.state().ecs();
|
||||||
|
let entity = client.entity();
|
||||||
|
let fluid = ecs
|
||||||
|
.read_storage::<comp::PhysicsState>()
|
||||||
|
.get(entity)?
|
||||||
|
.in_fluid?;
|
||||||
|
ecs.read_storage::<comp::Vel>()
|
||||||
|
.get(entity)
|
||||||
|
.map(|vel| fluid.relative_flow(vel).0)
|
||||||
|
.map(|rel_flow| {
|
||||||
|
let is_wind_downwards = rel_flow.dot(Vec3::unit_z()).is_sign_negative();
|
||||||
|
if !self.free_look {
|
||||||
|
if is_wind_downwards {
|
||||||
|
self.scene.camera().forward_xy().into()
|
||||||
|
} else {
|
||||||
|
let windwards = rel_flow
|
||||||
|
* self
|
||||||
|
.scene
|
||||||
|
.camera()
|
||||||
|
.forward_xy()
|
||||||
|
.dot(rel_flow.xy())
|
||||||
|
.signum();
|
||||||
|
Plane::from(Dir::new(self.scene.camera().right()))
|
||||||
|
.projection(windwards)
|
||||||
|
}
|
||||||
|
} else if is_wind_downwards {
|
||||||
|
Vec3::from(-rel_flow.xy())
|
||||||
|
} else {
|
||||||
|
-rel_flow
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.and_then(Dir::from_unnormalized)
|
||||||
|
})
|
||||||
|
{
|
||||||
|
self.key_state.auto_walk = false;
|
||||||
|
self.inputs.move_dir = Vec2::zero();
|
||||||
|
self.inputs.look_dir = dir;
|
||||||
|
} else {
|
||||||
|
self.key_state.auto_walk = self.auto_walk;
|
||||||
|
if !self.free_look {
|
||||||
|
self.walk_forward_dir = self.scene.camera().forward_xy();
|
||||||
|
self.walk_right_dir = self.scene.camera().right_xy();
|
||||||
|
self.inputs.look_dir =
|
||||||
|
Dir::from_unnormalized(cam_dir + aim_dir_offset).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the current state of movement related inputs
|
// Get the current state of movement related inputs
|
||||||
|
Loading…
Reference in New Issue
Block a user