veloren_voxygen_anim/biped_small/
shoot.rs

1use super::{
2    super::{Animation, vek::*},
3    BipedSmallSkeleton, SkeletonAttr,
4};
5use common::{comp::item::ToolKind, states::utils::StageSection};
6use std::f32::consts::PI;
7
8pub struct ShootAnimation;
9
10type ShootAnimationDependency<'a> = (
11    Option<ToolKind>,
12    Vec3<f32>,
13    Vec3<f32>,
14    Vec3<f32>,
15    f32,
16    Vec3<f32>,
17    f32,
18    Option<StageSection>,
19    f32,
20    Option<&'a str>,
21);
22
23impl Animation for ShootAnimation {
24    type Dependency<'a> = ShootAnimationDependency<'a>;
25    type Skeleton = BipedSmallSkeleton;
26
27    #[cfg(feature = "use-dyn-lib")]
28    const UPDATE_FN: &'static [u8] = b"biped_small_shoot\0";
29
30    #[cfg_attr(feature = "be-dyn-lib", export_name = "biped_small_shoot")]
31
32    fn update_skeleton_inner(
33        skeleton: &Self::Skeleton,
34        (
35            active_tool_kind,
36            velocity,
37            _orientation,
38            _last_ori,
39            _global_time,
40            _avg_vel,
41            _acc_vel,
42            stage_section,
43            _timer,
44            ability_id,
45        ): Self::Dependency<'_>,
46        anim_time: f32,
47        _rate: &mut f32,
48        s_a: &SkeletonAttr,
49    ) -> Self::Skeleton {
50        let mut next = (*skeleton).clone();
51        let speed = Vec2::<f32>::from(velocity).magnitude();
52
53        let fast = (anim_time * 10.0).sin();
54        let fastalt = (anim_time * 10.0 + PI / 2.0).sin();
55
56        let speednorm = speed / 9.4;
57        let speednormcancel = 1.0 - speednorm;
58
59        next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1 + fast * -0.1 * speednormcancel);
60        next.head.orientation = Quaternion::rotation_x(0.45 * speednorm)
61            * Quaternion::rotation_y(fast * 0.07 * speednormcancel);
62        next.chest.position = Vec3::new(
63            0.0,
64            s_a.chest.0,
65            s_a.chest.1 + fastalt * 0.4 * speednormcancel + speednormcancel * -0.5,
66        );
67
68        next.pants.position = Vec3::new(0.0, s_a.pants.0, s_a.pants.1);
69
70        next.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1);
71        next.tail.orientation = Quaternion::rotation_x(0.05 * fastalt * speednormcancel)
72            * Quaternion::rotation_z(fast * 0.15 * speednormcancel);
73
74        match ability_id {
75            Some("common.abilities.adlet.hunter.throw") => {
76                next.main.position = Vec3::new(8.0, -7.0, 2.0);
77                next.main.orientation = Quaternion::rotation_x(PI / -2.0);
78
79                next.hand_l.position = Vec3::new(s_a.grip.0 * 4.0, 0.0, s_a.grip.2);
80                next.hand_r.position = Vec3::new(5.0, -2.0, s_a.grip.2);
81
82                next.hand_l.orientation = Quaternion::rotation_x(0.0);
83                next.hand_r.orientation = Quaternion::rotation_x(PI / 2.0);
84            },
85            Some("common.abilities.adlet.tracker.trap") => {
86                next.main.position = Vec3::new(10.0, 0.0, 9.0);
87
88                next.hand_l.position = Vec3::new(s_a.grip.0 * 4.0, 0.0, s_a.grip.2);
89                next.hand_r.position = Vec3::new(5.0, -2.0, s_a.grip.2);
90
91                next.hand_l.orientation = Quaternion::rotation_x(0.0);
92                next.hand_r.orientation = Quaternion::rotation_x(PI / 2.0);
93            },
94            _ => {
95                next.main.position = Vec3::new(0.0, 0.0, 0.0);
96                next.main.orientation = Quaternion::rotation_x(0.0);
97
98                next.hand_l.position = Vec3::new(s_a.grip.0 * 4.0, 0.0, s_a.grip.2);
99                next.hand_r.position = Vec3::new(-s_a.grip.0 * 4.0, 0.0, s_a.grip.2);
100
101                next.hand_l.orientation = Quaternion::rotation_x(0.0);
102                next.hand_r.orientation = Quaternion::rotation_x(0.0);
103            },
104        };
105
106        match active_tool_kind {
107            Some(ToolKind::Bow) => match ability_id {
108                Some("common.abilities.adlet.tracker.trap") => {
109                    let (move1base, move2base, move3) = match stage_section {
110                        Some(StageSection::Buildup) => (anim_time, 0.0, 0.0),
111                        Some(StageSection::Action) => (1.0, anim_time.powf(0.25), 0.0),
112                        Some(StageSection::Recover) => (1.0, 1.0, anim_time),
113                        _ => (0.0, 0.0, 0.0),
114                    };
115                    let pullback = 1.0 - move3;
116                    let move1abs = move1base * pullback;
117                    let move2abs = move2base * pullback;
118                    next.main.position = Vec3::new(2.0, -3.0, -3.0);
119
120                    next.hand_l.position = Vec3::new(-s_a.hand.0, s_a.hand.1, s_a.hand.2 - 2.0);
121                    next.hand_r.position = Vec3::new(
122                        s_a.hand.0,
123                        s_a.hand.1 + move2abs * 1.5,
124                        s_a.hand.2 - 2.5 + move1abs * 2.5,
125                    );
126
127                    next.hand_r.orientation =
128                        Quaternion::rotation_x(move1abs * 4.0 + move2abs * -0.7)
129                            * Quaternion::rotation_y(0.0 + move1abs * -0.7);
130
131                    next.hand_l.orientation = Quaternion::rotation_x(PI / 3.0 * move1abs)
132                        * Quaternion::rotation_y(-0.7 * move1abs + move2abs * 0.1);
133                },
134                _ => {
135                    let (move1base, move2base, move3) = match stage_section {
136                        Some(StageSection::Buildup) => (anim_time, 0.0, 0.0),
137                        Some(StageSection::Action) => (1.0, anim_time.powf(0.25), 0.0),
138                        Some(StageSection::Recover) => (1.0, 1.0, anim_time),
139                        _ => (0.0, 0.0, 0.0),
140                    };
141                    let pullback = 1.0 - move3;
142                    let move1abs = move1base * pullback;
143                    let move2abs = move2base * pullback;
144                    next.control_l.position = Vec3::new(
145                        -1.0 - s_a.grip.0 * 2.0 + move2abs * -4.0,
146                        move2abs * -8.0,
147                        0.0,
148                    );
149                    next.control_r.position = Vec3::new(1.0 + s_a.grip.0 * 2.0, 3.0, -2.0);
150
151                    next.control.position = Vec3::new(
152                        -1.0,
153                        2.0 + move1abs * 3.0 + s_a.grip.2,
154                        3.0 + move1abs * 7.0 - s_a.grip.2 / 2.5 + s_a.grip.0 * -2.0,
155                    );
156
157                    next.control_l.orientation =
158                        Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.3);
159                    next.control_r.orientation =
160                        Quaternion::rotation_x(PI / 2.0 + s_a.grip.0 * 0.2)
161                            * Quaternion::rotation_y(0.5 + s_a.grip.0 * 0.2);
162
163                    next.control.orientation = Quaternion::rotation_x(-0.3 + move1abs * 0.4)
164                        * Quaternion::rotation_y(0.5 * speednorm);
165                },
166            },
167            Some(ToolKind::Natural) => match ability_id {
168                Some("common.abilities.custom.irrwurz.magicball") => {
169                    let (move1base, move2base, move3) = match stage_section {
170                        Some(StageSection::Buildup) => (anim_time, 0.0, 0.0),
171                        Some(StageSection::Action) => (1.0, anim_time.powf(0.25), 0.0),
172                        Some(StageSection::Recover) => (1.0, 1.0, anim_time),
173                        _ => (0.0, 0.0, 0.0),
174                    };
175                    let pullback = 1.0 - move3;
176                    let move1abs = move1base * pullback;
177                    let move2abs = move2base * pullback;
178                    next.main.position = Vec3::new(2.0, -3.0, -3.0);
179
180                    next.hand_l.position = Vec3::new(-s_a.hand.0, s_a.hand.1, s_a.hand.2 - 2.0);
181                    next.hand_r.position = Vec3::new(
182                        s_a.hand.0,
183                        s_a.hand.1 + move2abs * 1.5,
184                        s_a.hand.2 - 2.5 + move1abs * 2.5,
185                    );
186
187                    next.hand_r.orientation =
188                        Quaternion::rotation_x(move1abs * 4.0 + move2abs * -0.7);
189
190                    next.hand_l.orientation = Quaternion::rotation_x(PI / 3.0 * move1abs)
191                        * Quaternion::rotation_y(-0.7 * move1abs + move2abs * 0.1);
192                },
193                Some("common.abilities.custom.goblin_chucker.throw") => {
194                    let (move1base, move2base, move3) = match stage_section {
195                        Some(StageSection::Buildup) => (anim_time, 0.0, 0.0),
196                        Some(StageSection::Action) => (1.0, anim_time.powf(0.25), 0.0),
197                        Some(StageSection::Recover) => (1.0, 1.0, anim_time),
198                        _ => (0.0, 0.0, 0.0),
199                    };
200                    let pullback = 1.0 - move3;
201                    let move1abs = move1base * pullback;
202                    let move2abs = move2base * pullback;
203
204                    next.hand_l.position = Vec3::new(-s_a.hand.0, s_a.hand.1, s_a.hand.2 - 2.0);
205                    next.hand_r.position = Vec3::new(
206                        s_a.hand.0,
207                        s_a.hand.1 + move2abs * 1.5,
208                        s_a.hand.2 - 2.5 + move1abs * 2.5,
209                    );
210
211                    next.hand_r.orientation =
212                        Quaternion::rotation_x(move1abs * 4.0 + move2abs * -0.7)
213                            * Quaternion::rotation_y(0.0 + move1abs * -0.7);
214
215                    next.hand_l.orientation = Quaternion::rotation_x(PI / 3.0 * move1abs)
216                        * Quaternion::rotation_y(-0.7 * move1abs + move2abs * 0.1);
217                },
218                _ => {
219                    let (move1base, move2base, move3) = match stage_section {
220                        Some(StageSection::Buildup) => (anim_time, 0.0, 0.0),
221                        Some(StageSection::Action) => (1.0, anim_time.powf(0.25), 0.0),
222                        Some(StageSection::Recover) => (1.0, 1.0, anim_time),
223                        _ => (0.0, 0.0, 0.0),
224                    };
225                    let pullback = 1.0 - move3;
226                    let move1abs = move1base * pullback;
227                    let move2abs = move2base * pullback;
228                    next.control_l.position = Vec3::new(
229                        1.0 - s_a.grip.0 * 2.0 + move2abs * -4.0,
230                        move2abs * -8.0,
231                        0.0,
232                    );
233                    next.control_r.position = Vec3::new(-1.0 + s_a.grip.0 * 2.0, 6.0, -2.0);
234
235                    next.control.position = Vec3::new(
236                        -1.0,
237                        2.0 + move1abs * 3.0 + s_a.grip.2,
238                        3.0 + move1abs * 7.0 - s_a.grip.2 / 2.5 + s_a.grip.0 * -2.0,
239                    );
240
241                    next.control_l.orientation =
242                        Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.3);
243                    next.control_r.orientation =
244                        Quaternion::rotation_x(PI / 2.0 + s_a.grip.0 * 0.2)
245                            * Quaternion::rotation_y(0.5 + s_a.grip.0 * 0.2);
246
247                    next.control.orientation = Quaternion::rotation_x(-0.3 + move1abs * 0.4)
248                        * Quaternion::rotation_y(0.5 * speednorm);
249                },
250            },
251            Some(ToolKind::Blowgun) => {
252                let (move1base, move2base, move3) = match stage_section {
253                    Some(StageSection::Buildup) => (anim_time, 0.0, 0.0),
254                    Some(StageSection::Action) => (1.0, anim_time.powf(0.25), 0.0),
255                    Some(StageSection::Recover) => (1.0, 1.0, anim_time),
256                    _ => (0.0, 0.0, 0.0),
257                };
258                let pullback = 1.0 - move3;
259                let move1abs = move1base * pullback;
260                let move2abs = move2base * pullback;
261                next.head.orientation = Quaternion::rotation_x(move1abs * 0.5 + move2abs * -0.7);
262                next.control_l.position = Vec3::new(1.0 - s_a.grip.0 * 2.0, 0.0, 3.0);
263                next.control_r.position = Vec3::new(-1.0 + s_a.grip.0 * 2.0, 0.0, 4.0);
264
265                next.control.position = Vec3::new(
266                    0.0,
267                    move1abs * -2.0 + move2abs * 1.0 + s_a.grip.2,
268                    move1abs * 3.5 + move2abs * -2.0 + 4.0 - s_a.grip.2 / 2.5 + s_a.grip.0 * -2.0,
269                );
270
271                next.control_l.orientation =
272                    Quaternion::rotation_x(3.8 + move1abs * 0.4 + move2abs * -0.5)
273                        * Quaternion::rotation_y(-0.3);
274                next.control_r.orientation = Quaternion::rotation_x(
275                    3.5 + move1abs * 0.4 + move2abs * -0.5 + s_a.grip.0 * 0.2,
276                ) * Quaternion::rotation_y(0.5 + s_a.grip.0 * 0.2);
277
278                next.control.orientation = Quaternion::rotation_x(
279                    -2.2 + move1abs * 0.7 + move2abs * -0.2 + 0.5 * speednorm,
280                );
281            },
282            Some(ToolKind::Staff) => match ability_id {
283                Some(
284                    "common.abilities.custom.dwarves.flamekeeper.mines"
285                    | "common.abilities.custom.dwarves.flamekeeper.lava_mortar",
286                ) => {
287                    let (move1base, _move2base, move3) = match stage_section {
288                        Some(StageSection::Buildup) => (anim_time.powf(0.25), 0.0, 0.0),
289                        Some(StageSection::Action) => (1.0, anim_time.powf(0.25), 0.0),
290                        Some(StageSection::Recover) => (1.0, 1.0, anim_time),
291                        _ => (0.0, 0.0, 0.0),
292                    };
293                    let pullback = 1.0 - move3;
294                    let move1abs = move1base * pullback;
295                    next.control_l.position = Vec3::new(2.0 - s_a.grip.0 * 2.0, 1.0, 3.0);
296                    next.control_r.position = Vec3::new(
297                        7.0 + s_a.grip.0 * 2.0 + move1abs * -8.0,
298                        -4.0 + move1abs * 4.0,
299                        3.0,
300                    );
301
302                    next.control.position = Vec3::new(
303                        -5.0,
304                        -1.0 + s_a.grip.2,
305                        -2.0 + -s_a.grip.2 / 2.5 + s_a.grip.0 * -2.0 + move1abs * 5.0,
306                    );
307
308                    next.control_l.orientation = Quaternion::rotation_x(PI / 2.0 + move1abs * 0.8)
309                        * Quaternion::rotation_y(-0.3)
310                        * Quaternion::rotation_z(-0.3);
311                    next.control_r.orientation =
312                        Quaternion::rotation_x(PI / 2.0 + s_a.grip.0 * 0.2 + move1abs * 0.8)
313                            * Quaternion::rotation_y(-0.4 + s_a.grip.0 * 0.2 + move1abs * 0.8)
314                            * Quaternion::rotation_z(-0.0);
315
316                    next.control.orientation = Quaternion::rotation_x(-0.3 + move1abs * -0.3)
317                        * Quaternion::rotation_y(-0.2 * speednorm + move1abs * 0.3)
318                        * Quaternion::rotation_z(0.5 + move1abs * 0.6);
319                },
320                _ => {
321                    let (move1base, _move2base, move3) = match stage_section {
322                        Some(StageSection::Buildup) => (anim_time.powf(0.25), 0.0, 0.0),
323                        Some(StageSection::Action) => (1.0, anim_time.powf(0.25), 0.0),
324                        Some(StageSection::Recover) => (1.0, 1.0, anim_time),
325                        _ => (0.0, 0.0, 0.0),
326                    };
327                    let pullback = 1.0 - move3;
328                    let move1abs = move1base * pullback;
329                    next.control_l.position = Vec3::new(2.0 - s_a.grip.0 * 2.0, 1.0, 3.0);
330                    next.control_r.position = Vec3::new(
331                        7.0 + s_a.grip.0 * 2.0 + move1abs * -8.0,
332                        -4.0 + move1abs * 4.0,
333                        3.0,
334                    );
335
336                    next.control.position = Vec3::new(
337                        -5.0,
338                        -1.0 + s_a.grip.2,
339                        -2.0 + -s_a.grip.2 / 2.5 + s_a.grip.0 * -2.0 + move1abs * 5.0,
340                    );
341
342                    next.control_l.orientation = Quaternion::rotation_x(PI / 2.0 + move1abs * 0.8)
343                        * Quaternion::rotation_y(-0.3)
344                        * Quaternion::rotation_z(-0.3);
345                    next.control_r.orientation =
346                        Quaternion::rotation_x(PI / 2.0 + s_a.grip.0 * 0.2 + move1abs * 0.8)
347                            * Quaternion::rotation_y(-0.4 + s_a.grip.0 * 0.2 + move1abs * 0.8)
348                            * Quaternion::rotation_z(-0.0);
349
350                    next.control.orientation = Quaternion::rotation_x(-0.3 + move1abs * -0.6)
351                        * Quaternion::rotation_y(-0.2 * speednorm)
352                        * Quaternion::rotation_z(0.5 + move1abs * 0.6);
353                },
354            },
355            Some(ToolKind::Spear) => {
356                let (move1base, move2base, move3) = match stage_section {
357                    Some(StageSection::Buildup) => (anim_time, 0.0, 0.0),
358                    Some(StageSection::Action) => (1.0, anim_time.powf(0.25), 0.0),
359                    Some(StageSection::Recover) => (1.0, 1.0, anim_time),
360                    _ => (0.0, 0.0, 0.0),
361                };
362                let pullback = 1.0 - move3;
363                let move1abs = move1base * pullback;
364                let move2abs = move2base * pullback;
365                next.control_l.position = Vec3::new(
366                    0.0,
367                    0.0 + move1abs * 4.0 + move2abs * -4.0,
368                    -2.0 + move1abs * -8.0,
369                );
370                next.control_r.position = Vec3::new(
371                    -1.0 + s_a.grip.0 * 2.0,
372                    2.0 + move3 * -4.0,
373                    -2.0 + move3 * -4.0,
374                );
375
376                next.control.position = Vec3::new(
377                    -1.0,
378                    0.0 + move1abs * -8.0 + move2abs * 8.0 + s_a.grip.2,
379                    3.0 + move1abs * 7.0 - s_a.grip.2 / 2.5 + s_a.grip.0 * -2.0,
380                );
381
382                next.control_l.orientation =
383                    Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.3);
384                next.control_r.orientation = Quaternion::rotation_x(PI / 2.0 + s_a.grip.0 * 0.2)
385                    * Quaternion::rotation_y(0.5 + s_a.grip.0 * 0.2 + move3 * -1.5);
386
387                next.control.orientation =
388                    Quaternion::rotation_x(-0.3 + move1abs * 0.5 + move2abs * -0.5 + move3 * 0.5)
389                        * Quaternion::rotation_y(0.5 * speednorm);
390
391                if matches!(stage_section, Some(StageSection::Recover)) {
392                    if move3 < 0.05 {
393                        next.main.position += Vec3::new(0.0, 100000.0, -10000000.0);
394                    }
395                    if move3 < 0.3 {
396                        next.main.scale = Vec3::zero();
397                    }
398                }
399            },
400            Some(ToolKind::Dagger) => {
401                let (move1base, move2base, move3) = match stage_section {
402                    Some(StageSection::Buildup) => (anim_time, 0.0, 0.0),
403                    Some(StageSection::Action) => (1.0, anim_time.powf(0.25), 0.0),
404                    Some(StageSection::Recover) => (1.0, 1.0, anim_time),
405                    _ => (0.0, 0.0, 0.0),
406                };
407                let pullback = 1.0 - move3;
408                let move1abs = move1base * pullback;
409                let move2abs = move2base * pullback;
410                next.main.position = Vec3::new(0.0, 2.0, -5.0);
411                next.control_l.position = Vec3::new(
412                    0.0,
413                    0.0 + move1abs * 1.0 + move2abs * -1.0,
414                    -2.0 + move1abs * -2.0,
415                );
416                next.control_r.position = Vec3::new(
417                    -1.0 + s_a.grip.0 * 2.0,
418                    2.0 + move3 * -4.0,
419                    -2.0 + move3 * -4.0,
420                );
421
422                next.control.position = Vec3::new(
423                    -1.0,
424                    0.0 + move1abs * -3.0 + move2abs * 3.0 + s_a.grip.2,
425                    3.0 + move1abs * 3.0 - s_a.grip.2 / 2.5 + s_a.grip.0 * -2.0,
426                );
427
428                next.control_l.orientation =
429                    Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.3);
430                next.control_r.orientation = Quaternion::rotation_x(PI / 2.0 + s_a.grip.0 * 0.2)
431                    * Quaternion::rotation_y(0.5 + s_a.grip.0 * 0.2 + move3 * -1.5);
432
433                next.control.orientation =
434                    Quaternion::rotation_x(-0.3 + move1abs * 0.5 + move2abs * -0.5 + move3 * 0.5)
435                        * Quaternion::rotation_y(0.5 * speednorm);
436
437                if matches!(stage_section, Some(StageSection::Recover)) {
438                    next.main.scale = Vec3::zero();
439                }
440            },
441            _ => {},
442        }
443
444        next
445    }
446}