mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Made characters carry lanterns higher when possible
This commit is contained in:
parent
b10718c568
commit
ed7cc12213
@ -167,6 +167,18 @@ impl CharacterState {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn is_using_hands(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
CharacterState::Climb(_)
|
||||
| CharacterState::Equipping(_)
|
||||
| CharacterState::Dance
|
||||
| CharacterState::Glide
|
||||
| CharacterState::GlideWield
|
||||
| CharacterState::Roll(_),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn is_block(&self) -> bool { matches!(self, CharacterState::BasicBlock) }
|
||||
|
||||
pub fn is_dodge(&self) -> bool { matches!(self, CharacterState::Roll(_)) }
|
||||
|
@ -192,6 +192,16 @@ impl Animation for JumpAnimation {
|
||||
next.lantern.scale = Vec3::one() * 0.65;
|
||||
next.hold.scale = Vec3::one() * 0.0;
|
||||
|
||||
if skeleton.holding_lantern {
|
||||
next.hand_r.position = Vec3::new(s_a.hand.0, s_a.hand.1 + 5.0, s_a.hand.2 + 9.0);
|
||||
next.hand_r.orientation = Quaternion::rotation_x(2.25) * Quaternion::rotation_z(0.9);
|
||||
|
||||
next.lantern.position = Vec3::new(0.0, 0.0, -3.5);
|
||||
next.lantern.orientation = next.hand_r.orientation.inverse()
|
||||
* Quaternion::rotation_x(slow * 0.5)
|
||||
* Quaternion::rotation_y(tilt * 4.0 * slow + tilt * 3.0);
|
||||
}
|
||||
|
||||
next.torso.position = Vec3::new(0.0, 0.0, 0.0) * s_a.scaler;
|
||||
next.torso.orientation = Quaternion::rotation_x(0.0);
|
||||
next.torso.scale = Vec3::one() / 11.0 * s_a.scaler;
|
||||
|
@ -69,8 +69,19 @@ skeleton_impls!(struct CharacterSkeleton {
|
||||
control,
|
||||
control_l,
|
||||
control_r,
|
||||
:: // Begin non-bone fields
|
||||
holding_lantern: bool,
|
||||
});
|
||||
|
||||
impl CharacterSkeleton {
|
||||
pub fn new(holding_lantern: bool) -> Self {
|
||||
Self {
|
||||
holding_lantern,
|
||||
..Self::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Skeleton for CharacterSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
@ -93,9 +104,14 @@ impl Skeleton for CharacterSkeleton {
|
||||
let control_mat = chest_mat * Mat4::<f32>::from(self.control);
|
||||
let control_l_mat = control_mat * Mat4::<f32>::from(self.control_l);
|
||||
let control_r_mat = control_mat * Mat4::<f32>::from(self.control_r);
|
||||
let hand_r_mat = control_r_mat * Mat4::<f32>::from(self.hand_r);
|
||||
|
||||
let hand_l_mat = Mat4::<f32>::from(self.hand_l);
|
||||
let lantern_mat = Mat4::<f32>::from(self.lantern);
|
||||
let lantern_mat = if self.holding_lantern {
|
||||
hand_r_mat
|
||||
} else {
|
||||
shorts_mat
|
||||
} * Mat4::<f32>::from(self.lantern);
|
||||
|
||||
*(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
|
||||
make_bone(head_mat),
|
||||
@ -104,7 +120,7 @@ impl Skeleton for CharacterSkeleton {
|
||||
make_bone(chest_mat * Mat4::<f32>::from(self.back)),
|
||||
make_bone(shorts_mat),
|
||||
make_bone(control_l_mat * hand_l_mat),
|
||||
make_bone(control_r_mat * Mat4::<f32>::from(self.hand_r)),
|
||||
make_bone(hand_r_mat),
|
||||
make_bone(torso_mat * Mat4::<f32>::from(self.foot_l)),
|
||||
make_bone(torso_mat * Mat4::<f32>::from(self.foot_r)),
|
||||
make_bone(chest_mat * Mat4::<f32>::from(self.shoulder_l)),
|
||||
@ -112,12 +128,11 @@ impl Skeleton for CharacterSkeleton {
|
||||
make_bone(chest_mat * Mat4::<f32>::from(self.glider)),
|
||||
make_bone(control_l_mat * Mat4::<f32>::from(self.main)),
|
||||
make_bone(control_r_mat * Mat4::<f32>::from(self.second)),
|
||||
make_bone(shorts_mat * lantern_mat),
|
||||
make_bone(lantern_mat),
|
||||
// FIXME: Should this be control_l_mat?
|
||||
make_bone(control_mat * hand_l_mat * Mat4::<f32>::from(self.hold)),
|
||||
];
|
||||
// NOTE: lantern_mat.cols.w = lantern_mat * Vec4::unit_w()
|
||||
Vec3::new(-0.3, 0.1, 0.8) + (lantern_mat.cols.w / 13.0).xyz()
|
||||
(lantern_mat * Vec4::new(-0.0, -0.0, -1.5, 1.0)).xyz()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,6 +256,20 @@ impl Animation for RunAnimation {
|
||||
next.lantern.scale = Vec3::one() * 0.65;
|
||||
next.hold.scale = Vec3::one() * 0.0;
|
||||
|
||||
if skeleton.holding_lantern {
|
||||
next.hand_r.position = Vec3::new(
|
||||
s_a.hand.0,
|
||||
s_a.hand.1 + 5.0 - impact * 0.2,
|
||||
s_a.hand.2 + 11.0 + impact * -0.1,
|
||||
);
|
||||
next.hand_r.orientation = Quaternion::rotation_x(2.25) * Quaternion::rotation_z(0.9);
|
||||
|
||||
next.lantern.position = Vec3::new(0.0, 0.0, -3.5);
|
||||
next.lantern.orientation = next.hand_r.orientation.inverse()
|
||||
* Quaternion::rotation_x((foothorir + 0.5) * 1.0 * speednorm)
|
||||
* Quaternion::rotation_y(tilt * 4.0 * foothorir + tilt * 3.0);
|
||||
}
|
||||
|
||||
next.torso.position = Vec3::new(0.0, 0.0, 0.0) * s_a.scaler;
|
||||
next.torso.scale = Vec3::one() / 11.0 * s_a.scaler;
|
||||
|
||||
|
@ -29,8 +29,16 @@ impl Animation for SitAnimation {
|
||||
let stop = (anim_time * 3.0).min(PI / 2.0).sin();
|
||||
|
||||
let head_look = Vec2::new(
|
||||
(global_time + anim_time / 18.0).floor().mul(7331.0).sin() * 0.25,
|
||||
(global_time + anim_time / 18.0).floor().mul(1337.0).sin() * 0.125,
|
||||
(global_time * 0.05 + anim_time / 15.0)
|
||||
.floor()
|
||||
.mul(7331.0)
|
||||
.sin()
|
||||
* 0.25,
|
||||
(global_time * 0.05 + anim_time / 15.0)
|
||||
.floor()
|
||||
.mul(1337.0)
|
||||
.sin()
|
||||
* 0.125,
|
||||
);
|
||||
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1 + slow * 0.1 + stop * -0.8);
|
||||
next.head.orientation = Quaternion::rotation_z(head_look.x + slow * 0.2 - slow * 0.1)
|
||||
@ -79,6 +87,21 @@ impl Animation for SitAnimation {
|
||||
|
||||
next.torso.position = Vec3::new(0.0, -0.2, stop * -0.16) * s_a.scaler;
|
||||
|
||||
if skeleton.holding_lantern {
|
||||
next.hand_r.position = Vec3::new(
|
||||
s_a.hand.0 - head_look.x * 10.0,
|
||||
s_a.hand.1 + 5.0 - head_look.y * 8.0,
|
||||
s_a.hand.2 + 11.0,
|
||||
);
|
||||
next.hand_r.orientation = Quaternion::rotation_x(2.25)
|
||||
* Quaternion::rotation_z(0.9)
|
||||
* Quaternion::rotation_y(head_look.x * 3.0)
|
||||
* Quaternion::rotation_x(head_look.y * 3.0);
|
||||
|
||||
next.lantern.position = Vec3::new(0.0, 0.0, -3.5);
|
||||
next.lantern.orientation = next.hand_r.orientation.inverse();
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
}
|
||||
|
@ -158,6 +158,15 @@ impl Animation for SneakAnimation {
|
||||
|
||||
next.foot_r.position = Vec3::new(s_a.foot.0, 4.0 + s_a.foot.1, s_a.foot.2);
|
||||
}
|
||||
|
||||
if skeleton.holding_lantern {
|
||||
next.hand_r.position = Vec3::new(s_a.hand.0, s_a.hand.1 + 5.0, s_a.hand.2 + 9.0);
|
||||
next.hand_r.orientation = Quaternion::rotation_x(2.5);
|
||||
|
||||
next.lantern.position = Vec3::new(0.0, 1.5, -5.5);
|
||||
next.lantern.orientation = next.hand_r.orientation.inverse();
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ impl Animation for StandAnimation {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let slow = (anim_time * 1.0).sin();
|
||||
let fast = (anim_time * 5.0).sin();
|
||||
let impact = (avg_vel.z).max(-15.0);
|
||||
let head_look = Vec2::new(
|
||||
((global_time + anim_time) / 10.0).floor().mul(7331.0).sin() * 0.15,
|
||||
@ -142,6 +143,22 @@ impl Animation for StandAnimation {
|
||||
next.lantern.position = Vec3::new(s_a.lantern.0, s_a.lantern.1, s_a.lantern.2);
|
||||
next.lantern.orientation = Quaternion::rotation_x(0.1) * Quaternion::rotation_y(0.1);
|
||||
|
||||
if skeleton.holding_lantern {
|
||||
next.hand_r.position = Vec3::new(
|
||||
s_a.hand.0 - head_look.x * 10.0,
|
||||
s_a.hand.1 + 5.0 - head_look.y * 8.0 + slow * 0.15 - impact * 0.2,
|
||||
s_a.hand.2 + 11.0 + slow * 0.5 + impact * -0.1,
|
||||
);
|
||||
next.hand_r.orientation = Quaternion::rotation_x(2.25 + slow * -0.06 + impact * -0.1)
|
||||
* Quaternion::rotation_z(0.9)
|
||||
* Quaternion::rotation_y(head_look.x * 3.0)
|
||||
* Quaternion::rotation_x(head_look.y * 3.0);
|
||||
|
||||
next.lantern.position = Vec3::new(0.0, 0.0, -3.5);
|
||||
next.lantern.orientation =
|
||||
next.hand_r.orientation.inverse() * Quaternion::rotation_x(fast * 0.1);
|
||||
}
|
||||
|
||||
next.torso.position = Vec3::new(0.0, 0.0, 0.0) * s_a.scaler;
|
||||
next.second.scale = Vec3::one();
|
||||
next.second.scale = match hands {
|
||||
|
@ -320,15 +320,17 @@ impl Animation for WieldAnimation {
|
||||
};
|
||||
match hands {
|
||||
(None, None) | (None, Some(Hands::One)) => {
|
||||
next.hand_l.position = Vec3::new(-4.5, 8.0, 5.0);
|
||||
next.hand_l.orientation = Quaternion::rotation_x(1.9) * Quaternion::rotation_y(-0.5)
|
||||
//next.hand_l.position = Vec3::new(-4.5, 8.0, 5.0);
|
||||
//next.hand_l.orientation = Quaternion::rotation_x(1.9) *
|
||||
// Quaternion::rotation_y(-0.5)
|
||||
},
|
||||
(_, _) => {},
|
||||
};
|
||||
match hands {
|
||||
(None, None) | (Some(Hands::One), None) => {
|
||||
next.hand_r.position = Vec3::new(4.5, 8.0, 5.0);
|
||||
next.hand_r.orientation = Quaternion::rotation_x(1.9) * Quaternion::rotation_y(0.5)
|
||||
//next.hand_r.position = Vec3::new(4.5, 8.0, 5.0);
|
||||
//next.hand_r.orientation = Quaternion::rotation_x(1.9) *
|
||||
// Quaternion::rotation_y(0.5)
|
||||
},
|
||||
(_, _) => {},
|
||||
};
|
||||
@ -337,6 +339,21 @@ impl Animation for WieldAnimation {
|
||||
next.second = next.main;
|
||||
}
|
||||
|
||||
if skeleton.holding_lantern {
|
||||
next.hand_r.position = Vec3::new(
|
||||
s_a.hand.0 - head_look.x * 10.0,
|
||||
s_a.hand.1 + 5.0 + slow * 0.15,
|
||||
s_a.hand.2 + 9.0 + head_look.y * 18.0 + slow * 0.5,
|
||||
);
|
||||
next.hand_r.orientation = Quaternion::rotation_x(2.25 + slow * -0.06)
|
||||
* Quaternion::rotation_z(0.9)
|
||||
* Quaternion::rotation_y(head_look.x * 3.0)
|
||||
* Quaternion::rotation_x(head_look.y * 3.0);
|
||||
|
||||
next.lantern.position = Vec3::new(0.0, 0.0, -3.5);
|
||||
next.lantern.orientation = next.hand_r.orientation.inverse();
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
}
|
||||
|
@ -5,12 +5,15 @@
|
||||
compile_error!("Can't use both \"be-dyn-lib\" and \"use-dyn-lib\" features at once");
|
||||
|
||||
macro_rules! skeleton_impls {
|
||||
{ struct $Skeleton:ident { $( $(+)? $bone:ident ),* $(,)? } } => {
|
||||
{ struct $Skeleton:ident { $( $(+)? $bone:ident ),* $(,)? $(:: $($field:ident : $field_ty:ty),* $(,)? )? } } => {
|
||||
#[derive(Clone, Default)]
|
||||
pub struct $Skeleton {
|
||||
$(
|
||||
$bone: $crate::Bone,
|
||||
)*
|
||||
$($(
|
||||
$field : $field_ty,
|
||||
)*)?
|
||||
}
|
||||
|
||||
impl<'a, Factor> $crate::vek::Lerp<Factor> for &'a $Skeleton
|
||||
@ -25,6 +28,9 @@ macro_rules! skeleton_impls {
|
||||
$(
|
||||
$bone: Lerp::lerp_unclamped_precise(from.$bone, to.$bone, factor),
|
||||
)*
|
||||
$($(
|
||||
$field : to.$field.clone(),
|
||||
)*)?
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,6 +39,9 @@ macro_rules! skeleton_impls {
|
||||
$(
|
||||
$bone: Lerp::lerp_unclamped(from.$bone, to.$bone, factor),
|
||||
)*
|
||||
$($(
|
||||
$field : to.$field.clone(),
|
||||
)*)?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ use anim::{
|
||||
use common::{
|
||||
comp::{
|
||||
inventory::slot::EquipSlot,
|
||||
item::{ItemKind, ToolKind},
|
||||
item::{Hands, ItemKind, ToolKind},
|
||||
Body, CharacterState, Controller, Health, Inventory, Item, Last, LightAnimation,
|
||||
LightEmitter, Ori, PhysicsState, PoiseState, Pos, Scale, Vel,
|
||||
},
|
||||
@ -584,6 +584,7 @@ impl FigureMgr {
|
||||
health,
|
||||
inventory,
|
||||
item,
|
||||
light_emitter,
|
||||
),
|
||||
) in (
|
||||
&ecs.entities(),
|
||||
@ -599,6 +600,7 @@ impl FigureMgr {
|
||||
ecs.read_storage::<Health>().maybe(),
|
||||
ecs.read_storage::<Inventory>().maybe(),
|
||||
ecs.read_storage::<Item>().maybe(),
|
||||
ecs.read_storage::<LightEmitter>().maybe(),
|
||||
)
|
||||
.join()
|
||||
.enumerate()
|
||||
@ -760,12 +762,20 @@ impl FigureMgr {
|
||||
&slow_jobs,
|
||||
);
|
||||
|
||||
let holding_lantern = inventory
|
||||
.map_or(false, |i| i.equipped(EquipSlot::Lantern).is_some())
|
||||
&& light_emitter.is_some()
|
||||
&& !(matches!(second_tool_hand, Some(_))
|
||||
&& character.map_or(false, |c| c.is_wield()))
|
||||
&& !character.map_or(false, |c| c.is_using_hands())
|
||||
&& physics.in_liquid().is_none();
|
||||
|
||||
let state = self
|
||||
.states
|
||||
.character_states
|
||||
.entry(entity)
|
||||
.or_insert_with(|| {
|
||||
FigureState::new(renderer, CharacterSkeleton::default())
|
||||
FigureState::new(renderer, CharacterSkeleton::new(holding_lantern))
|
||||
});
|
||||
|
||||
// Average velocity relative to the current ground
|
||||
@ -787,7 +797,7 @@ impl FigureMgr {
|
||||
) {
|
||||
// Standing
|
||||
(true, false, false) => anim::character::StandAnimation::update_skeleton(
|
||||
&CharacterSkeleton::default(),
|
||||
&CharacterSkeleton::new(holding_lantern),
|
||||
(active_tool_kind, second_tool_kind, hands, time, rel_avg_vel),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
@ -795,7 +805,7 @@ impl FigureMgr {
|
||||
),
|
||||
// Running
|
||||
(true, true, false) => anim::character::RunAnimation::update_skeleton(
|
||||
&CharacterSkeleton::default(),
|
||||
&CharacterSkeleton::new(holding_lantern),
|
||||
(
|
||||
active_tool_kind,
|
||||
second_tool_kind,
|
||||
@ -814,7 +824,7 @@ impl FigureMgr {
|
||||
),
|
||||
// In air
|
||||
(false, _, false) => anim::character::JumpAnimation::update_skeleton(
|
||||
&CharacterSkeleton::default(),
|
||||
&CharacterSkeleton::new(holding_lantern),
|
||||
(
|
||||
active_tool_kind,
|
||||
second_tool_kind,
|
||||
@ -831,7 +841,7 @@ impl FigureMgr {
|
||||
),
|
||||
// Swim
|
||||
(_, _, true) => anim::character::SwimAnimation::update_skeleton(
|
||||
&CharacterSkeleton::default(),
|
||||
&CharacterSkeleton::new(holding_lantern),
|
||||
(
|
||||
active_tool_kind,
|
||||
second_tool_kind,
|
||||
@ -1376,7 +1386,7 @@ impl FigureMgr {
|
||||
},
|
||||
CharacterState::BasicBlock { .. } => {
|
||||
anim::character::BlockAnimation::update_skeleton(
|
||||
&CharacterSkeleton::default(),
|
||||
&CharacterSkeleton::new(holding_lantern),
|
||||
(active_tool_kind, second_tool_kind, time),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
|
@ -560,7 +560,6 @@ impl Scene {
|
||||
lights.extend(
|
||||
(
|
||||
&scene_data.state.ecs().read_storage::<comp::Pos>(),
|
||||
scene_data.state.ecs().read_storage::<comp::Ori>().maybe(),
|
||||
scene_data
|
||||
.state
|
||||
.ecs()
|
||||
@ -572,23 +571,16 @@ impl Scene {
|
||||
.read_storage::<comp::LightAnimation>(),
|
||||
)
|
||||
.join()
|
||||
.filter(|(pos, _, _, light_anim)| {
|
||||
.filter(|(pos, _, light_anim)| {
|
||||
light_anim.col != Rgb::zero()
|
||||
&& light_anim.strength > 0.0
|
||||
&& (pos.0.distance_squared(player_pos) as f32)
|
||||
< loaded_distance.powi(2) + LIGHT_DIST_RADIUS
|
||||
})
|
||||
.map(|(pos, ori, interpolated, light_anim)| {
|
||||
.map(|(pos, interpolated, light_anim)| {
|
||||
// Use interpolated values if they are available
|
||||
let (pos, rot) = interpolated
|
||||
.map_or((pos.0, ori.copied().unwrap_or_default()), |i| {
|
||||
(i.pos, i.ori)
|
||||
});
|
||||
Light::new(
|
||||
pos + (rot.to_quat() * light_anim.offset),
|
||||
light_anim.col,
|
||||
light_anim.strength,
|
||||
)
|
||||
let pos = interpolated.map_or(pos.0, |i| i.pos);
|
||||
Light::new(pos + light_anim.offset, light_anim.col, light_anim.strength)
|
||||
})
|
||||
.chain(
|
||||
self.event_lights
|
||||
|
Loading…
Reference in New Issue
Block a user