veloren_voxygen_anim/character/
sneakwield.rs

1use super::{
2    super::{Animation, vek::*},
3    CharacterSkeleton, SkeletonAttr,
4};
5use common::comp::item::{AbilitySpec, Hands, ToolKind};
6use core::{f32::consts::PI, ops::Mul};
7
8pub struct SneakWieldAnimation;
9
10impl Animation for SneakWieldAnimation {
11    type Dependency<'a> = (
12        (Option<ToolKind>, Option<&'a AbilitySpec>),
13        Option<ToolKind>,
14        (Option<Hands>, Option<Hands>),
15        Vec3<f32>,
16        Vec3<f32>,
17        Vec3<f32>,
18        f32,
19    );
20    type Skeleton = CharacterSkeleton;
21
22    #[cfg(feature = "use-dyn-lib")]
23    const UPDATE_FN: &'static [u8] = b"character_sneakwield\0";
24
25    #[cfg_attr(feature = "be-dyn-lib", export_name = "character_sneakwield")]
26    fn update_skeleton_inner(
27        skeleton: &Self::Skeleton,
28        (
29            (active_tool_kind, active_tool_spec),
30            second_tool_kind,
31            hands,
32            velocity,
33            orientation,
34            last_ori,
35            global_time,
36        ): Self::Dependency<'_>,
37        anim_time: f32,
38        rate: &mut f32,
39        s_a: &SkeletonAttr,
40    ) -> Self::Skeleton {
41        let mut next = (*skeleton).clone();
42        let speed = Vec2::<f32>::from(velocity).magnitude();
43        *rate = 1.0;
44        let slow = (anim_time * 3.0).sin();
45        let breathe = ((anim_time * 0.5).sin()).abs();
46        let walkintensity = if speed > 5.0 { 1.0 } else { 0.45 };
47        let lower = if speed > 5.0 { 0.0 } else { 1.0 };
48        let _snapfoot = if speed > 5.0 { 1.1 } else { 2.0 };
49        let lab: f32 = 1.0;
50        let foothoril = (anim_time * 7.0 * lab + PI * 1.45).sin();
51        let foothorir = (anim_time * 7.0 * lab + PI * (0.45)).sin();
52        let speednorm = speed / 4.0;
53
54        let footvertl = (anim_time * 7.0 * lab).sin();
55        let footvertr = (anim_time * 7.0 * lab + PI).sin();
56
57        let footrotl = ((5.0 / (2.5 + (2.5) * ((anim_time * 7.0 * lab + PI * 1.4).sin()).powi(2)))
58            .sqrt())
59            * ((anim_time * 7.0 * lab + PI * 1.4).sin());
60
61        let footrotr = ((5.0 / (1.0 + (4.0) * ((anim_time * 7.0 * lab + PI * 0.4).sin()).powi(2)))
62            .sqrt())
63            * ((anim_time * 7.0 * lab + PI * 0.4).sin());
64
65        let short = (anim_time * lab * 7.0).sin();
66        let noisea = (anim_time * 11.0 + PI / 6.0).sin();
67        let noiseb = (anim_time * 19.0 + PI / 4.0).sin();
68
69        let shortalt = (anim_time * lab * 7.0 + PI / 2.0).sin();
70
71        let head_look = Vec2::new(
72            (global_time + anim_time / 18.0).floor().mul(7331.0).sin() * 0.2,
73            (global_time + anim_time / 18.0).floor().mul(1337.0).sin() * 0.1,
74        );
75
76        let orientation: Vec2<f32> = Vec2::from(orientation);
77        let last_ori = Vec2::from(last_ori);
78        let tilt = if vek::Vec2::new(orientation, last_ori)
79            .map(|o| o.magnitude_squared())
80            .map(|m| m > 0.001 && m.is_finite())
81            .reduce_and()
82            && orientation.angle_between(last_ori).is_finite()
83        {
84            orientation.angle_between(last_ori).min(0.2)
85                * last_ori.determine_side(Vec2::zero(), orientation).signum()
86        } else {
87            0.0
88        } * 1.3;
89        next.main.position = Vec3::new(0.0, 0.0, 0.0);
90        next.main.orientation = Quaternion::rotation_x(0.0);
91        next.second.position = Vec3::new(0.0, 0.0, 0.0);
92        next.second.orientation = Quaternion::rotation_x(0.0);
93        next.hold.scale = Vec3::one() * 0.0;
94
95        if speed > 0.5 {
96            next.hand_l.position = Vec3::new(1.0 - s_a.hand.0, 4.0 + s_a.hand.1, 1.0 + s_a.hand.2);
97            next.hand_l.orientation = Quaternion::rotation_x(1.0);
98
99            next.hand_r.position = Vec3::new(-1.0 + s_a.hand.0, -1.0 + s_a.hand.1, s_a.hand.2);
100            next.hand_r.orientation = Quaternion::rotation_x(0.4);
101            next.head.position = Vec3::new(0.0, 1.0 + s_a.head.0, -1.0 + s_a.head.1 + short * 0.06);
102            next.head.orientation =
103                Quaternion::rotation_z(tilt * -2.5 + head_look.x * 0.2 - short * 0.06)
104                    * Quaternion::rotation_x(head_look.y + 0.45);
105
106            next.chest.position = Vec3::new(0.0, s_a.chest.0, -1.0 + s_a.chest.1 + shortalt * -0.5);
107            next.chest.orientation = Quaternion::rotation_z(0.3 + short * 0.08 + tilt * -0.2)
108                * Quaternion::rotation_y(tilt * 0.8)
109                * Quaternion::rotation_x(-0.5);
110
111            next.belt.position = Vec3::new(0.0, 0.5 + s_a.belt.0, 0.7 + s_a.belt.1);
112            next.belt.orientation = Quaternion::rotation_z(short * 0.1 + tilt * -1.1)
113                * Quaternion::rotation_y(tilt * 0.5)
114                * Quaternion::rotation_x(0.2);
115
116            next.back.orientation =
117                Quaternion::rotation_x(-0.25 + short * 0.1 + noisea * 0.1 + noiseb * 0.1);
118
119            next.shorts.position = Vec3::new(0.0, 1.0 + s_a.shorts.0, 1.0 + s_a.shorts.1);
120            next.shorts.orientation = Quaternion::rotation_z(short * 0.16 + tilt * -1.5)
121                * Quaternion::rotation_y(tilt * 0.7)
122                * Quaternion::rotation_x(0.3);
123
124            next.foot_l.position = Vec3::new(
125                -s_a.foot.0,
126                s_a.foot.1 + foothoril * -10.5 * walkintensity - lower * 1.0,
127                1.0 + s_a.foot.2 + ((footvertl * -1.7).max(-1.0)) * walkintensity,
128            );
129            next.foot_l.orientation =
130                Quaternion::rotation_x(-0.2 + footrotl * -0.8 * walkintensity)
131                    * Quaternion::rotation_y(tilt * 1.8);
132
133            next.foot_r.position = Vec3::new(
134                s_a.foot.0,
135                s_a.foot.1 + foothorir * -10.5 * walkintensity - lower * 1.0,
136                1.0 + s_a.foot.2 + ((footvertr * -1.7).max(-1.0)) * walkintensity,
137            );
138            next.foot_r.orientation =
139                Quaternion::rotation_x(-0.2 + footrotr * -0.8 * walkintensity)
140                    * Quaternion::rotation_y(tilt * 1.8);
141
142            next.shoulder_l.orientation = Quaternion::rotation_x(short * 0.15 * walkintensity);
143
144            next.shoulder_r.orientation = Quaternion::rotation_x(short * -0.15 * walkintensity);
145        } else {
146            next.head.position = Vec3::new(
147                0.0,
148                1.0 + s_a.head.0,
149                -2.0 + s_a.head.1 + slow * 0.1 + breathe * -0.05,
150            );
151            next.head.orientation = Quaternion::rotation_z(head_look.x)
152                * Quaternion::rotation_x(0.6 + head_look.y.abs());
153
154            next.chest.position = Vec3::new(0.0, s_a.chest.0, -3.0 + s_a.chest.1 + slow * 0.1);
155            next.chest.orientation = Quaternion::rotation_x(-0.7);
156
157            next.belt.position = Vec3::new(0.0, s_a.belt.0, s_a.belt.1);
158            next.belt.orientation = Quaternion::rotation_z(0.3 + head_look.x * -0.1);
159
160            next.hand_l.position = Vec3::new(1.0 - s_a.hand.0, 5.0 + s_a.hand.1, 0.0 + s_a.hand.2);
161            next.hand_l.orientation = Quaternion::rotation_x(1.35);
162
163            next.hand_r.position = Vec3::new(-1.0 + s_a.hand.0, s_a.hand.1, s_a.hand.2);
164            next.hand_r.orientation = Quaternion::rotation_x(0.4);
165
166            next.shorts.position = Vec3::new(0.0, s_a.shorts.0, s_a.shorts.1);
167            next.shorts.orientation = Quaternion::rotation_z(0.6 + head_look.x * -0.2);
168
169            next.foot_l.position = Vec3::new(-s_a.foot.0, -6.0 + s_a.foot.1, 1.0 + s_a.foot.2);
170            next.foot_l.orientation = Quaternion::rotation_x(-0.5);
171
172            next.foot_r.position = Vec3::new(s_a.foot.0, 4.0 + s_a.foot.1, s_a.foot.2);
173        }
174
175        match (hands, active_tool_kind, second_tool_kind) {
176            ((Some(Hands::Two), _), tool, _) | ((None, Some(Hands::Two)), _, tool) => match tool {
177                Some(ToolKind::Sword) => {
178                    next.hand_l.position = Vec3::new(s_a.shl.0, s_a.shl.1, s_a.shl.2);
179                    next.hand_l.orientation =
180                        Quaternion::rotation_x(s_a.shl.3) * Quaternion::rotation_y(s_a.shl.4);
181                    next.hand_r.position = Vec3::new(s_a.shr.0, s_a.shr.1, s_a.shr.2);
182                    next.hand_r.orientation =
183                        Quaternion::rotation_x(s_a.shr.3) * Quaternion::rotation_y(s_a.shr.4);
184
185                    next.control.position = Vec3::new(s_a.sc.0, s_a.sc.1 - 3.0, s_a.sc.2);
186                    next.control.orientation =
187                        Quaternion::rotation_x(s_a.sc.3) * Quaternion::rotation_z(0.0);
188                },
189                Some(ToolKind::Axe) => {
190                    next.main.position = Vec3::new(0.0, 0.0, 0.0);
191                    next.main.orientation = Quaternion::rotation_x(0.0);
192
193                    if speed < 0.5 {
194                        next.head.position = Vec3::new(0.0, 0.0 + s_a.head.0, s_a.head.1);
195                        next.head.orientation = Quaternion::rotation_z(head_look.x)
196                            * Quaternion::rotation_x(0.35 + head_look.y.abs());
197                        next.chest.orientation = Quaternion::rotation_x(-0.35)
198                            * Quaternion::rotation_y(0.0)
199                            * Quaternion::rotation_z(0.15);
200                        next.belt.position = Vec3::new(0.0, 1.0 + s_a.belt.0, s_a.belt.1);
201                        next.belt.orientation = Quaternion::rotation_x(0.15)
202                            * Quaternion::rotation_y(0.0)
203                            * Quaternion::rotation_z(0.15);
204                        next.shorts.position = Vec3::new(0.0, 1.0 + s_a.shorts.0, s_a.shorts.1);
205                        next.shorts.orientation =
206                            Quaternion::rotation_x(0.15) * Quaternion::rotation_z(0.25);
207                    }
208                    next.hand_l.position = Vec3::new(s_a.ahl.0, s_a.ahl.1, s_a.ahl.2);
209                    next.hand_l.orientation =
210                        Quaternion::rotation_x(s_a.ahl.3) * Quaternion::rotation_y(s_a.ahl.4);
211                    next.hand_r.position = Vec3::new(s_a.ahr.0, s_a.ahr.1, s_a.ahr.2);
212                    next.hand_r.orientation =
213                        Quaternion::rotation_x(s_a.ahr.3) * Quaternion::rotation_z(s_a.ahr.5);
214
215                    next.control.position = Vec3::new(s_a.ac.0, s_a.ac.1, s_a.ac.2);
216                    next.control.orientation = Quaternion::rotation_x(s_a.ac.3)
217                        * Quaternion::rotation_y(s_a.ac.4)
218                        * Quaternion::rotation_z(s_a.ac.5);
219                },
220                Some(ToolKind::Hammer | ToolKind::Pick | ToolKind::Shovel) => {
221                    next.hand_l.position = Vec3::new(s_a.hhl.0, s_a.hhl.1, s_a.hhl.2);
222                    next.hand_l.orientation = Quaternion::rotation_x(s_a.hhl.3)
223                        * Quaternion::rotation_y(s_a.hhl.4)
224                        * Quaternion::rotation_z(s_a.hhl.5);
225                    next.hand_r.position = Vec3::new(s_a.hhr.0, s_a.hhr.1, s_a.hhr.2);
226                    next.hand_r.orientation = Quaternion::rotation_x(s_a.hhr.3)
227                        * Quaternion::rotation_y(s_a.hhr.4)
228                        * Quaternion::rotation_z(s_a.hhr.5);
229
230                    next.control.position =
231                        Vec3::new(s_a.hc.0, s_a.hc.1 + speed * 0.2, s_a.hc.2 + 6.0);
232                    next.control.orientation = Quaternion::rotation_x(s_a.hc.3)
233                        * Quaternion::rotation_y(s_a.hc.4 + speed * -0.04)
234                        * Quaternion::rotation_z(s_a.hc.5);
235                },
236                Some(ToolKind::Staff) | Some(ToolKind::Sceptre) => {
237                    if speed > 0.5 && velocity.z == 0.0 {
238                        next.hand_r.position = Vec3::new(
239                            7.0 + s_a.hand.0 + foothoril * 1.3,
240                            -4.0 + s_a.hand.1 + foothoril * -7.0,
241                            1.0 + s_a.hand.2 - foothoril * 5.5,
242                        );
243                        next.hand_r.orientation = Quaternion::rotation_x(0.6 + footrotl * -1.2)
244                            * Quaternion::rotation_y(footrotl * -0.4);
245                    } else {
246                        next.hand_r.position = Vec3::new(s_a.sthr.0, s_a.sthr.1, s_a.sthr.2);
247                        next.hand_r.orientation =
248                            Quaternion::rotation_x(s_a.sthr.3) * Quaternion::rotation_y(s_a.sthr.4);
249                    };
250
251                    next.control.position = Vec3::new(s_a.stc.0, s_a.stc.1 - 2.0, s_a.stc.2 + 4.0);
252
253                    next.hand_l.position = Vec3::new(s_a.sthl.0, s_a.sthl.1, s_a.sthl.2);
254                    next.hand_l.orientation = Quaternion::rotation_x(s_a.sthl.3);
255
256                    next.control.orientation = Quaternion::rotation_x(s_a.stc.3)
257                        * Quaternion::rotation_y(s_a.stc.4)
258                        * Quaternion::rotation_z(s_a.stc.5);
259                },
260                Some(ToolKind::Bow) => {
261                    next.main.position = Vec3::new(0.0, 0.0, 0.0);
262                    next.main.orientation = Quaternion::rotation_x(0.0);
263                    next.hand_l.position = Vec3::new(s_a.bhl.0, s_a.bhl.1, s_a.bhl.2);
264                    next.hand_l.orientation = Quaternion::rotation_x(s_a.bhl.3);
265                    next.hand_r.position = Vec3::new(s_a.bhr.0, s_a.bhr.1, s_a.bhr.2);
266                    next.hand_r.orientation = Quaternion::rotation_x(s_a.bhr.3);
267
268                    next.hold.position = Vec3::new(0.0, -1.0, -5.2);
269                    next.hold.orientation = Quaternion::rotation_x(-PI / 2.0);
270                    next.hold.scale = Vec3::one() * 1.0;
271
272                    next.control.position = Vec3::new(s_a.bc.0 + 2.0, s_a.bc.1, s_a.bc.2 + 5.0);
273                    next.control.orientation = Quaternion::rotation_x(speednorm * -0.5 + 0.8)
274                        * Quaternion::rotation_y(s_a.bc.4)
275                        * Quaternion::rotation_z(s_a.bc.5);
276                },
277                Some(ToolKind::Instrument) => {
278                    if let Some(AbilitySpec::Custom(spec)) = active_tool_spec {
279                        match spec.as_str() {
280                            "Washboard" => {
281                                next.hand_l.position = Vec3::new(-7.0, 0.0, 3.0);
282                                next.hand_l.orientation = Quaternion::rotation_x(1.27);
283                                next.main.position = Vec3::new(-5.0, -4.5, -5.0);
284                                next.main.orientation = Quaternion::rotation_x(5.5);
285                            },
286                            _ => {
287                                next.hand_l.position = Vec3::new(-7.0, 4.0, 3.0);
288                                next.hand_l.orientation = Quaternion::rotation_x(1.27);
289                                next.main.position = Vec3::new(-5.0, 5.0, 23.0);
290                                next.main.orientation = Quaternion::rotation_x(PI);
291                            },
292                        }
293                    }
294                },
295                Some(ToolKind::Debug) => {
296                    next.hand_l.position = Vec3::new(-7.0, 4.0, 3.0);
297                    next.hand_l.orientation = Quaternion::rotation_x(1.27);
298                    next.main.position = Vec3::new(-5.0, 5.0, 23.0);
299                    next.main.orientation = Quaternion::rotation_x(PI);
300                },
301                Some(ToolKind::Farming) => {
302                    if speed < 0.5 {
303                        next.head.orientation = Quaternion::rotation_z(head_look.x)
304                            * Quaternion::rotation_x(-0.2 + head_look.y.abs());
305                    }
306                    next.hand_l.position = Vec3::new(9.0, 1.0, 1.0);
307                    next.hand_l.orientation = Quaternion::rotation_x(PI / 2.0);
308                    next.hand_r.position = Vec3::new(9.0, 1.0, 11.0);
309                    next.hand_r.orientation = Quaternion::rotation_x(PI / 2.0);
310                    next.main.position = Vec3::new(7.5, 7.5, 13.2);
311                    next.main.orientation = Quaternion::rotation_y(PI);
312
313                    next.control.position = Vec3::new(-11.0 + slow * 2.0, 1.8, 4.0);
314                    next.control.orientation = Quaternion::rotation_x(0.0)
315                        * Quaternion::rotation_y(0.6)
316                        * Quaternion::rotation_z(0.0);
317                },
318                _ => {},
319            },
320            ((_, _), _, _) => {},
321        };
322        match hands {
323            (Some(Hands::One), _) => {
324                next.control_l.position = Vec3::new(-7.0, 6.0, 5.0);
325                next.control_l.orientation =
326                    Quaternion::rotation_x(-0.3) * Quaternion::rotation_y(0.2);
327                next.hand_l.position = Vec3::new(-1.0, -0.5, 0.0);
328                next.hand_l.orientation = Quaternion::rotation_x(PI / 2.0)
329            },
330            (_, _) => {},
331        };
332        match hands {
333            (None | Some(Hands::One), Some(Hands::One)) => {
334                next.control_r.position = Vec3::new(7.0, 6.0, 5.0);
335                next.control_r.orientation =
336                    Quaternion::rotation_x(-0.3) * Quaternion::rotation_y(-0.2);
337                next.hand_r.position = Vec3::new(1.0, -0.5, 0.0);
338                next.hand_r.orientation = Quaternion::rotation_x(PI / 2.0)
339            },
340            (_, _) => {},
341        };
342        match hands {
343            (None, None) | (None, Some(Hands::One)) => {
344                next.hand_l.position = Vec3::new(-8.0, 2.0, 1.0);
345                next.hand_l.orientation =
346                    Quaternion::rotation_x(0.5) * Quaternion::rotation_y(0.25);
347            },
348            (_, _) => {},
349        };
350        match hands {
351            (None, None) | (Some(Hands::One), None) => {
352                next.hand_r.position = Vec3::new(8.0, 2.0, 1.0);
353                next.hand_r.orientation =
354                    Quaternion::rotation_x(0.5) * Quaternion::rotation_y(-0.25);
355            },
356            (_, _) => {},
357        };
358
359        if let (None, Some(Hands::Two)) = hands {
360            next.second = next.main;
361        }
362
363        next.do_hold_lantern(s_a, anim_time, anim_time, speednorm, 0.0, tilt);
364
365        next
366    }
367}